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.
const PipelineState *PipelineState::last_applied = 0;
vector<int> PipelineState::bound_tex_targets;
const PipelineState *PipelineState::last_applied = 0;
vector<int> PipelineState::bound_tex_targets;
+vector<char> PipelineState::bound_uniform_blocks;
unsigned PipelineState::restart_index = 0;
PipelineState::PipelineState():
unsigned PipelineState::restart_index = 0;
PipelineState::PipelineState():
- if(!ARB_direct_state_access && bound_tex_targets.empty())
+ if(bound_tex_targets.empty())
bound_tex_targets.resize(Limits::get_global().max_texture_bindings);
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()
}
PipelineState::~PipelineState()
- if(last_applied && this!=last_applied)
- {
- vector<BoundTexture>::const_iterator i = textures.begin();
- vector<BoundTexture>::const_iterator j = last_applied->textures.begin();
- while(j!=last_applied->textures.end())
- {
- if(i==textures.end() || j->binding<i->binding)
- {
- 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<BoundTexture>::const_iterator i=textures.begin(); i!=textures.end(); ++i)
if(i->changed || mask==~0U)
{
for(vector<BoundTexture>::const_iterator i=textures.begin(); i!=textures.end(); ++i)
if(i->changed || mask==~0U)
{
if(bound_tex_targets[i->binding] && static_cast<int>(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());
if(bound_tex_targets[i->binding] && static_cast<int>(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();
}
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;
- }
- }
- if(last_applied && this!=last_applied)
- {
- vector<BoundUniformBlock>::const_iterator i = uniform_blocks.begin();
- vector<BoundUniformBlock>::const_iterator j = last_applied->uniform_blocks.begin();
- while(j!=last_applied->uniform_blocks.end())
- {
- if(i==uniform_blocks.end() || j->binding<i->binding)
- {
- glBindBufferBase(GL_UNIFORM_BUFFER, j->binding, 0);
- ++j;
- }
- else
- {
- if(i->binding==j->binding)
- ++j;
- ++i;
- }
- }
- }
-
for(vector<BoundUniformBlock>::const_iterator i=uniform_blocks.begin(); i!=uniform_blocks.end(); ++i)
if(i->changed || mask==~0U)
{
for(vector<BoundUniformBlock>::const_iterator i=uniform_blocks.begin(); i!=uniform_blocks.end(); ++i)
if(i->changed || mask==~0U)
{
}
else
static_cast<const DefaultUniformBlock *>(i->block)->apply();
}
else
static_cast<const DefaultUniformBlock *>(i->block)->apply();
+
+ bound_uniform_blocks[i->binding] = 1;
- else
- glBindBufferBase(GL_UNIFORM_BUFFER, i->binding, 0);
if((last_applied->enabled_clip_planes>>i)&1)
glDisable(GL_CLIP_PLANE0+i);
if((last_applied->enabled_clip_planes>>i)&1)
glDisable(GL_CLIP_PLANE0+i);
- for(vector<BoundTexture>::const_iterator i=last_applied->textures.begin(); i!=last_applied->textures.end(); ++i)
- if(i->texture && i->sampler)
+ for(unsigned i=0; i<bound_tex_targets.size(); ++i)
+ if(bound_tex_targets[i])
{
if(ARB_direct_state_access)
{
if(ARB_direct_state_access)
- glBindTextureUnit(i->binding, 0);
+ glBindTextureUnit(i, 0);
- 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<BoundUniformBlock>::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_uniform_blocks.size(); ++i)
+ if(bound_uniform_blocks[i])
+ {
+ glBindBufferBase(GL_UNIFORM_BUFFER, i, 0);
+ bound_uniform_blocks[i] = 0;
+ }
glDisable(GL_DEPTH_TEST);
glDepthMask(true);
glDisable(GL_DEPTH_TEST);
glDepthMask(true);
static const PipelineState *last_applied;
static std::vector<int> bound_tex_targets;
static const PipelineState *last_applied;
static std::vector<int> bound_tex_targets;
+ static std::vector<char> bound_uniform_blocks;
static unsigned restart_index;
public:
static unsigned restart_index;
public: