From 7b1a814276741e1aff68c6e9066537374c19c283 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 13 Mar 2022 09:34:18 +0200 Subject: [PATCH] Treat standard and camera shader data specially in Renderer Don't add them to the generic shdata stack. Some effects apply their own camera, which led to two overlapping ProgramData objects on the stack. Although the results were correct, this caused PipelineState to flag the uniform blocks as dirty every frame and do unnecessary work. --- source/render/renderer.cpp | 22 +++++++++++++++------- source/render/renderer.h | 1 + 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/source/render/renderer.cpp b/source/render/renderer.cpp index 336b631a..fceee6e8 100644 --- a/source/render/renderer.cpp +++ b/source/render/renderer.cpp @@ -40,7 +40,6 @@ void Renderer::begin() RendererBackend::begin(); - add_shader_data(standard_shdata); commands.begin_frame(frame_index); } @@ -103,7 +102,6 @@ void Renderer::set_pipeline_key(uintptr_t key) void Renderer::set_camera(const Camera &c) { get_state().camera = &c; - add_shader_data(c.get_shader_data()); set_matrix(Matrix()); } @@ -347,6 +345,17 @@ void Renderer::apply_state() bool shprog_changed = (state.shprog!=ps.get_shader_program()); ps.set_shader_program(state.shprog); + bool shdata_changed = changed&SHADER_DATA; + for(auto i=shdata_stack.begin(); (!shdata_changed && i!=shdata_stack.end()); ++i) + shdata_changed = (i->shdata->get_generation()!=i->generation); + bool extra_shdata = (shdata_stack.size()>state.shdata_count); + + if(changed&CAMERA) + { + shdata_changed = true; + changed &= ~CAMERA; + } + if(changed&MATRIX) { standard_shdata.uniform("world_obj_matrix", state.model_matrix); @@ -354,17 +363,16 @@ void Renderer::apply_state() nm = transpose(invert(nm)); standard_shdata.uniform("world_obj_normal_matrix", nm); changed &= ~MATRIX; + shdata_changed = true; } - bool shdata_changed = changed&SHADER_DATA; - for(auto i=shdata_stack.begin(); (!shdata_changed && i!=shdata_stack.end()); ++i) - shdata_changed = (i->shdata->get_generation()!=i->generation); - bool extra_shdata = (shdata_stack.size()>state.shdata_count); - if(shdata_changed || shprog_changed || pipeline_changed || extra_shdata) { if(extra_shdata) shdata_stack.erase(shdata_stack.begin()+state.shdata_count, shdata_stack.end()); + standard_shdata.apply(*state.shprog, ps, frame_index); + if(state.camera) + state.camera->get_shader_data().apply(*state.shprog, ps, frame_index); for(const BoundProgramData &d: shdata_stack) { d.shdata->apply(*state.shprog, ps, frame_index); diff --git a/source/render/renderer.h b/source/render/renderer.h index 75c8cc8b..31ad65ea 100644 --- a/source/render/renderer.h +++ b/source/render/renderer.h @@ -105,6 +105,7 @@ private: { PIPELINE_KEY = 1, MATRIX = 2, + CAMERA = 4, SHADER_DATA = 16 }; -- 2.43.0