From 3e38e8a7bfffb0b6d622b849b402f4f04a7536c4 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 14 Sep 2021 00:17:12 +0300 Subject: [PATCH] Simplify pipeline state management Instead of unbinding things immediately, defer it to when the state is cleared. This results in less binding calls overall. The only reason to unbind anything is to allow those objects to be destroyed, and that shouldn't happen in the middle of rendering anyway. --- source/core/pipelinestate.cpp | 93 ++++++++--------------------------- source/core/pipelinestate.h | 1 + 2 files changed, 21 insertions(+), 73 deletions(-) diff --git a/source/core/pipelinestate.cpp b/source/core/pipelinestate.cpp index 0d91f759..f855eed6 100644 --- a/source/core/pipelinestate.cpp +++ b/source/core/pipelinestate.cpp @@ -26,6 +26,7 @@ namespace GL { const PipelineState *PipelineState::last_applied = 0; vector PipelineState::bound_tex_targets; +vector PipelineState::bound_uniform_blocks; unsigned PipelineState::restart_index = 0; PipelineState::PipelineState(): @@ -42,8 +43,10 @@ PipelineState::PipelineState(): blend(0), changes(0) { - if(!ARB_direct_state_access && bound_tex_targets.empty()) + if(bound_tex_targets.empty()) bound_tex_targets.resize(Limits::get_global().max_texture_bindings); + if(bound_uniform_blocks.empty()) + bound_uniform_blocks.resize(Limits::get_global().max_uniform_bindings); } PipelineState::~PipelineState() @@ -242,35 +245,6 @@ void PipelineState::apply(unsigned mask) const if(mask&TEXTURES) { - if(last_applied && this!=last_applied) - { - vector::const_iterator i = textures.begin(); - vector::const_iterator j = last_applied->textures.begin(); - while(j!=last_applied->textures.end()) - { - if(i==textures.end() || j->bindingbinding) - { - if(bound_tex_targets[j->binding]) - { - if(ARB_direct_state_access) - glBindTextureUnit(j->binding, 0); - else - { - glActiveTexture(GL_TEXTURE0+j->binding); - glBindTexture(bound_tex_targets[j->binding], 0); - } - } - ++j; - } - else - { - if(i->binding==j->binding) - ++j; - ++i; - } - } - } - for(vector::const_iterator i=textures.begin(); i!=textures.end(); ++i) if(i->changed || mask==~0U) { @@ -284,23 +258,13 @@ void PipelineState::apply(unsigned mask) const if(bound_tex_targets[i->binding] && static_cast(i->texture->get_target())!=bound_tex_targets[i->binding]) glBindTexture(bound_tex_targets[i->binding], 0); glBindTexture(i->texture->get_target(), i->texture->get_id()); - bound_tex_targets[i->binding] = i->texture->get_target(); } + bound_tex_targets[i->binding] = i->texture->get_target(); + glBindSampler(i->binding, i->sampler->get_id()); i->sampler->refresh(); } - else if(bound_tex_targets[i->binding]) - { - if(ARB_direct_state_access) - glBindTextureUnit(i->binding, 0); - else - { - glActiveTexture(GL_TEXTURE0+i->binding); - glBindTexture(bound_tex_targets[i->binding], 0); - bound_tex_targets[i->binding] = 0; - } - } i->changed = false; } @@ -308,26 +272,6 @@ void PipelineState::apply(unsigned mask) const if(mask&UNIFORMS) { - if(last_applied && this!=last_applied) - { - vector::const_iterator i = uniform_blocks.begin(); - vector::const_iterator j = last_applied->uniform_blocks.begin(); - while(j!=last_applied->uniform_blocks.end()) - { - if(i==uniform_blocks.end() || j->bindingbinding) - { - glBindBufferBase(GL_UNIFORM_BUFFER, j->binding, 0); - ++j; - } - else - { - if(i->binding==j->binding) - ++j; - ++i; - } - } - } - for(vector::const_iterator i=uniform_blocks.begin(); i!=uniform_blocks.end(); ++i) if(i->changed || mask==~0U) { @@ -340,9 +284,9 @@ void PipelineState::apply(unsigned mask) const } else static_cast(i->block)->apply(); + + bound_uniform_blocks[i->binding] = 1; } - else - glBindBufferBase(GL_UNIFORM_BUFFER, i->binding, 0); i->changed = false; } @@ -402,22 +346,25 @@ void PipelineState::clear() if((last_applied->enabled_clip_planes>>i)&1) glDisable(GL_CLIP_PLANE0+i); - for(vector::const_iterator i=last_applied->textures.begin(); i!=last_applied->textures.end(); ++i) - if(i->texture && i->sampler) + for(unsigned i=0; ibinding, 0); + glBindTextureUnit(i, 0); else { - glActiveTexture(GL_TEXTURE0+i->binding); - glBindTexture(bound_tex_targets[i->binding], 0); - bound_tex_targets[i->binding] = 0; + glActiveTexture(GL_TEXTURE0+i); + glBindTexture(bound_tex_targets[i], 0); } + bound_tex_targets[i] = 0; } - for(vector::const_iterator i=last_applied->uniform_blocks.begin(); i!=last_applied->uniform_blocks.end(); ++i) - if(i->block) - glBindBufferBase(GL_UNIFORM_BUFFER, i->binding, 0); + for(unsigned i=0; i bound_tex_targets; + static std::vector bound_uniform_blocks; static unsigned restart_index; public: -- 2.43.0