change pipelines
This commit is contained in:
@@ -276,15 +276,37 @@ function make_shader(sh_file)
|
||||
return shader
|
||||
}
|
||||
|
||||
var usepipe
|
||||
def material_pipeline_cache = {};
|
||||
|
||||
function get_pipeline_for_material(mat = {}) {
|
||||
def key = json.encode({
|
||||
vert: mat.vertex || sprite_pipeline.vertex,
|
||||
frag: mat.fragment || sprite_pipeline.fragment,
|
||||
blend: mat.blend || sprite_pipeline.blend,
|
||||
cull: mat.cull || sprite_pipeline.cull,
|
||||
});
|
||||
|
||||
if (!material_pipeline_cache[key]) {
|
||||
def cfg = Object.assign({}, sprite_pipeline, {
|
||||
vertex: mat.vertex || sprite_pipeline.vertex,
|
||||
fragment: mat.fragment || sprite_pipeline.fragment,
|
||||
blend: mat.blend || sprite_pipeline.blend,
|
||||
cull: mat.cull || sprite_pipeline.cull,
|
||||
});
|
||||
|
||||
cfg.__proto__ = sprite_pipeline
|
||||
material_pipeline_cache[key] = load_pipeline(cfg)
|
||||
log.console(`created pipeline for ${json.encode(cfg)}`)
|
||||
}
|
||||
|
||||
return material_pipeline_cache[key];
|
||||
}
|
||||
|
||||
function load_pipeline(config)
|
||||
{
|
||||
if (usepipe) return usepipe
|
||||
config.vertex = make_shader(config.vertex)[GPU]
|
||||
config.fragment = make_shader(config.fragment)[GPU]
|
||||
usepipe = new sdl_gpu.graphics_pipeline(device, config)
|
||||
log.console(usepipe)
|
||||
return usepipe
|
||||
return new sdl_gpu.graphics_pipeline(device, config)
|
||||
}
|
||||
|
||||
// Initialize ImGui with the window and renderer
|
||||
@@ -483,8 +505,6 @@ var sprite_pipeline = {
|
||||
blend: alpha_blend_state
|
||||
}
|
||||
|
||||
var pipey = load_pipeline(sprite_pipeline)
|
||||
|
||||
var GPU = Symbol()
|
||||
|
||||
var cur_cam
|
||||
@@ -562,7 +582,7 @@ var draw_queue = []
|
||||
var index_count = 0
|
||||
var vertex_count = 0
|
||||
|
||||
function render_geom(geom, img)
|
||||
function render_geom(geom, img, pipeline = get_pipeline_for_material(null))
|
||||
{
|
||||
if (!img[GPU]) {
|
||||
if (img.surface)
|
||||
@@ -579,7 +599,7 @@ function render_geom(geom, img)
|
||||
index_blob.write_blob(geom.indices)
|
||||
|
||||
draw_queue.push({
|
||||
pipeline:pipey,
|
||||
pipeline,
|
||||
texture: img[GPU],
|
||||
num_indices: geom.num_indices,
|
||||
first_index: index_count,
|
||||
@@ -605,7 +625,8 @@ cmd_fns.draw_image = function(cmd)
|
||||
geom.indices = geometry.make_quad_indices(1)
|
||||
geom.num_indices = 6
|
||||
|
||||
render_geom(geom, img)
|
||||
var pipeline = get_pipeline_for_material(cmd.material)
|
||||
render_geom(geom, img, pipeline)
|
||||
}
|
||||
|
||||
cmd_fns.draw_text = function(cmd)
|
||||
@@ -623,31 +644,36 @@ cmd_fns.draw_text = function(cmd)
|
||||
font
|
||||
)
|
||||
|
||||
render_geom(mesh, font)
|
||||
var pipeline = get_pipeline_for_material(cmd.material)
|
||||
render_geom(mesh, font, pipeline)
|
||||
}
|
||||
|
||||
cmd_fns.tilemap = function(cmd)
|
||||
{
|
||||
var geometryCommands = cmd.tilemap.draw()
|
||||
|
||||
var pipeline = get_pipeline_for_material(cmd.material)
|
||||
|
||||
for (var geomCmd of geometryCommands) {
|
||||
var img = graphics.texture(geomCmd.image)
|
||||
if (!img) continue
|
||||
|
||||
render_geom(geomCmd.geometry, img)
|
||||
render_geom(geomCmd.geometry, img, pipeline)
|
||||
}
|
||||
}
|
||||
|
||||
cmd_fns.geometry = function(cmd)
|
||||
{
|
||||
var pipeline = get_pipeline_for_material(cmd.material)
|
||||
|
||||
if (typeof cmd.image == 'object') {
|
||||
render_geom(cmd.geometry, cmd.image)
|
||||
render_geom(cmd.geometry, cmd.image, pipeline)
|
||||
return
|
||||
}
|
||||
var img = graphics.texture(cmd.image)
|
||||
if (!img) return
|
||||
|
||||
render_geom(cmd.geometry, img)
|
||||
render_geom(cmd.geometry, img, pipeline)
|
||||
}
|
||||
|
||||
cmd_fns.draw_slice9 = function(cmd)
|
||||
@@ -678,22 +704,23 @@ cmd_fns.draw_slice9 = function(cmd)
|
||||
|
||||
var mesh = geometry.slice9(img, cmd.rect, slice_lrtb, slice_info)
|
||||
|
||||
render_geom(mesh, img)
|
||||
var pipeline = get_pipeline_for_material(cmd.material)
|
||||
render_geom(mesh, img, pipeline)
|
||||
}
|
||||
|
||||
cmd_fns.draw_rect = function(cmd)
|
||||
{
|
||||
// Create geometry for a rectangle quad
|
||||
var geom = geometry.make_rect_quad(cmd.rect, null, cmd.material.color || [1,1,1,1])
|
||||
var geom = geometry.make_rect_quad(cmd.rect, null, cmd.material.color)
|
||||
geom.indices = geometry.make_quad_indices(1)
|
||||
geom.num_indices = 6
|
||||
|
||||
// Use white_pixel as the texture so the color modulation works
|
||||
if (!white_pixel[GPU]) {
|
||||
if (!white_pixel[GPU])
|
||||
white_pixel[GPU] = get_img_gpu(white_pixel)
|
||||
}
|
||||
|
||||
render_geom(geom, {[GPU]: white_pixel[GPU]})
|
||||
var pipeline = get_pipeline_for_material(cmd.material)
|
||||
render_geom(geom, {[GPU]: white_pixel[GPU]}, pipeline)
|
||||
}
|
||||
|
||||
var copy_pass
|
||||
@@ -733,6 +760,11 @@ prosperon.create_batch = function create_batch(draw_cmds, done) {
|
||||
var render_pass
|
||||
var render_target
|
||||
|
||||
// State tracking for optimization
|
||||
var current_pipeline = null
|
||||
var current_camera_blob = null
|
||||
var buffers_bound = false
|
||||
|
||||
for (var cmd of draw_queue) {
|
||||
if (cmd.camera) {
|
||||
if (!cmd.camera.surface && render_target != "swap") {
|
||||
@@ -740,6 +772,9 @@ prosperon.create_batch = function create_batch(draw_cmds, done) {
|
||||
render_pass.end()
|
||||
render_target = "swap"
|
||||
render_pass = render_queue.swapchain_pass(window)
|
||||
// Reset state tracking when render pass changes
|
||||
current_pipeline = null
|
||||
buffers_bound = false
|
||||
} else if (cmd.camera.surface && render_target != cmd.camera.surface) {
|
||||
if (render_pass)
|
||||
render_pass.end()
|
||||
@@ -754,18 +789,11 @@ prosperon.create_batch = function create_batch(draw_cmds, done) {
|
||||
store: "store",
|
||||
}]
|
||||
})
|
||||
// Reset state tracking when render pass changes
|
||||
current_pipeline = null
|
||||
buffers_bound = false
|
||||
}
|
||||
render_pass.bind_pipeline(pipey)
|
||||
render_pass.bind_buffers(0, [
|
||||
{ buffer: pos_buffer, offset: 0 },
|
||||
{ buffer: uv_buffer, offset: 0 },
|
||||
{ buffer: color_buffer, offset: 0 }
|
||||
])
|
||||
|
||||
render_pass.bind_index_buffer(
|
||||
{ buffer: index_buffer, offset: 0 }, // the binding itself is in bytes
|
||||
16 // 16 = Uint32 indices
|
||||
);
|
||||
var vpW, vpH
|
||||
|
||||
if (render_target == "swap") {
|
||||
@@ -783,10 +811,45 @@ prosperon.create_batch = function create_batch(draw_cmds, done) {
|
||||
height: cmd.camera.viewport.height * vpH
|
||||
})
|
||||
|
||||
cur_cam = make_camera_pblob(cmd.camera)
|
||||
render_queue.push_vertex_uniform_data(0, cur_cam)
|
||||
var new_cam_blob = make_camera_pblob(cmd.camera)
|
||||
// Only update camera uniform if it changed
|
||||
if (current_camera_blob != new_cam_blob) {
|
||||
render_queue.push_vertex_uniform_data(0, new_cam_blob)
|
||||
current_camera_blob = new_cam_blob
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Only bind pipeline if it changed
|
||||
if (current_pipeline != cmd.pipeline) {
|
||||
render_pass.bind_pipeline(cmd.pipeline)
|
||||
current_pipeline = cmd.pipeline
|
||||
// When pipeline changes, we need to rebind buffers and uniforms
|
||||
buffers_bound = false
|
||||
current_camera_blob = null
|
||||
}
|
||||
|
||||
// Only bind buffers if not already bound or pipeline changed
|
||||
if (!buffers_bound) {
|
||||
render_pass.bind_buffers(0, [
|
||||
{ buffer: pos_buffer, offset: 0 },
|
||||
{ buffer: uv_buffer, offset: 0 },
|
||||
{ buffer: color_buffer, offset: 0 }
|
||||
])
|
||||
|
||||
render_pass.bind_index_buffer(
|
||||
{ buffer: index_buffer, offset: 0 }, // the binding itself is in bytes
|
||||
16 // 16 = Uint32 indices
|
||||
);
|
||||
buffers_bound = true
|
||||
}
|
||||
|
||||
// Rebind camera uniform if needed after pipeline change
|
||||
if (!current_camera_blob && cur_cam) {
|
||||
render_queue.push_vertex_uniform_data(0, cur_cam)
|
||||
current_camera_blob = cur_cam
|
||||
}
|
||||
|
||||
// Use texture's sampler if it has one, otherwise use standard sampler
|
||||
var sampler_to_use = std_sampler
|
||||
if (cmd.texture && cmd.texture.sampler_desc) {
|
||||
|
||||
Reference in New Issue
Block a user