change pipelines
This commit is contained in:
@@ -276,15 +276,37 @@ function make_shader(sh_file)
|
|||||||
return shader
|
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)
|
function load_pipeline(config)
|
||||||
{
|
{
|
||||||
if (usepipe) return usepipe
|
|
||||||
config.vertex = make_shader(config.vertex)[GPU]
|
config.vertex = make_shader(config.vertex)[GPU]
|
||||||
config.fragment = make_shader(config.fragment)[GPU]
|
config.fragment = make_shader(config.fragment)[GPU]
|
||||||
usepipe = new sdl_gpu.graphics_pipeline(device, config)
|
return new sdl_gpu.graphics_pipeline(device, config)
|
||||||
log.console(usepipe)
|
|
||||||
return usepipe
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize ImGui with the window and renderer
|
// Initialize ImGui with the window and renderer
|
||||||
@@ -483,8 +505,6 @@ var sprite_pipeline = {
|
|||||||
blend: alpha_blend_state
|
blend: alpha_blend_state
|
||||||
}
|
}
|
||||||
|
|
||||||
var pipey = load_pipeline(sprite_pipeline)
|
|
||||||
|
|
||||||
var GPU = Symbol()
|
var GPU = Symbol()
|
||||||
|
|
||||||
var cur_cam
|
var cur_cam
|
||||||
@@ -562,7 +582,7 @@ var draw_queue = []
|
|||||||
var index_count = 0
|
var index_count = 0
|
||||||
var vertex_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[GPU]) {
|
||||||
if (img.surface)
|
if (img.surface)
|
||||||
@@ -579,7 +599,7 @@ function render_geom(geom, img)
|
|||||||
index_blob.write_blob(geom.indices)
|
index_blob.write_blob(geom.indices)
|
||||||
|
|
||||||
draw_queue.push({
|
draw_queue.push({
|
||||||
pipeline:pipey,
|
pipeline,
|
||||||
texture: img[GPU],
|
texture: img[GPU],
|
||||||
num_indices: geom.num_indices,
|
num_indices: geom.num_indices,
|
||||||
first_index: index_count,
|
first_index: index_count,
|
||||||
@@ -605,7 +625,8 @@ cmd_fns.draw_image = function(cmd)
|
|||||||
geom.indices = geometry.make_quad_indices(1)
|
geom.indices = geometry.make_quad_indices(1)
|
||||||
geom.num_indices = 6
|
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)
|
cmd_fns.draw_text = function(cmd)
|
||||||
@@ -623,31 +644,36 @@ cmd_fns.draw_text = function(cmd)
|
|||||||
font
|
font
|
||||||
)
|
)
|
||||||
|
|
||||||
render_geom(mesh, font)
|
var pipeline = get_pipeline_for_material(cmd.material)
|
||||||
|
render_geom(mesh, font, pipeline)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_fns.tilemap = function(cmd)
|
cmd_fns.tilemap = function(cmd)
|
||||||
{
|
{
|
||||||
var geometryCommands = cmd.tilemap.draw()
|
var geometryCommands = cmd.tilemap.draw()
|
||||||
|
|
||||||
|
var pipeline = get_pipeline_for_material(cmd.material)
|
||||||
|
|
||||||
for (var geomCmd of geometryCommands) {
|
for (var geomCmd of geometryCommands) {
|
||||||
var img = graphics.texture(geomCmd.image)
|
var img = graphics.texture(geomCmd.image)
|
||||||
if (!img) continue
|
if (!img) continue
|
||||||
|
|
||||||
render_geom(geomCmd.geometry, img)
|
render_geom(geomCmd.geometry, img, pipeline)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_fns.geometry = function(cmd)
|
cmd_fns.geometry = function(cmd)
|
||||||
{
|
{
|
||||||
|
var pipeline = get_pipeline_for_material(cmd.material)
|
||||||
|
|
||||||
if (typeof cmd.image == 'object') {
|
if (typeof cmd.image == 'object') {
|
||||||
render_geom(cmd.geometry, cmd.image)
|
render_geom(cmd.geometry, cmd.image, pipeline)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var img = graphics.texture(cmd.image)
|
var img = graphics.texture(cmd.image)
|
||||||
if (!img) return
|
if (!img) return
|
||||||
|
|
||||||
render_geom(cmd.geometry, img)
|
render_geom(cmd.geometry, img, pipeline)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_fns.draw_slice9 = function(cmd)
|
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)
|
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)
|
cmd_fns.draw_rect = function(cmd)
|
||||||
{
|
{
|
||||||
// Create geometry for a rectangle quad
|
// 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.indices = geometry.make_quad_indices(1)
|
||||||
geom.num_indices = 6
|
geom.num_indices = 6
|
||||||
|
|
||||||
// Use white_pixel as the texture so the color modulation works
|
// 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)
|
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
|
var copy_pass
|
||||||
@@ -733,6 +760,11 @@ prosperon.create_batch = function create_batch(draw_cmds, done) {
|
|||||||
var render_pass
|
var render_pass
|
||||||
var render_target
|
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) {
|
for (var cmd of draw_queue) {
|
||||||
if (cmd.camera) {
|
if (cmd.camera) {
|
||||||
if (!cmd.camera.surface && render_target != "swap") {
|
if (!cmd.camera.surface && render_target != "swap") {
|
||||||
@@ -740,6 +772,9 @@ prosperon.create_batch = function create_batch(draw_cmds, done) {
|
|||||||
render_pass.end()
|
render_pass.end()
|
||||||
render_target = "swap"
|
render_target = "swap"
|
||||||
render_pass = render_queue.swapchain_pass(window)
|
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) {
|
} else if (cmd.camera.surface && render_target != cmd.camera.surface) {
|
||||||
if (render_pass)
|
if (render_pass)
|
||||||
render_pass.end()
|
render_pass.end()
|
||||||
@@ -754,18 +789,11 @@ prosperon.create_batch = function create_batch(draw_cmds, done) {
|
|||||||
store: "store",
|
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
|
var vpW, vpH
|
||||||
|
|
||||||
if (render_target == "swap") {
|
if (render_target == "swap") {
|
||||||
@@ -783,10 +811,45 @@ prosperon.create_batch = function create_batch(draw_cmds, done) {
|
|||||||
height: cmd.camera.viewport.height * vpH
|
height: cmd.camera.viewport.height * vpH
|
||||||
})
|
})
|
||||||
|
|
||||||
cur_cam = make_camera_pblob(cmd.camera)
|
var new_cam_blob = make_camera_pblob(cmd.camera)
|
||||||
render_queue.push_vertex_uniform_data(0, cur_cam)
|
// 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
|
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
|
// Use texture's sampler if it has one, otherwise use standard sampler
|
||||||
var sampler_to_use = std_sampler
|
var sampler_to_use = std_sampler
|
||||||
if (cmd.texture && cmd.texture.sampler_desc) {
|
if (cmd.texture && cmd.texture.sampler_desc) {
|
||||||
|
|||||||
Reference in New Issue
Block a user