if(changed_sets)
{
descriptor_set_slots.resize(self.shprog->get_n_descriptor_sets());
+ first_changed_desc_set = descriptor_set_slots.size();
for(unsigned i=0; i<descriptor_set_slots.size(); ++i)
if(changed_sets&(1<<i))
+ {
descriptor_set_slots[i] = device.get_descriptor_pool().get_descriptor_set_slot(self, i);
+ first_changed_desc_set = min(first_changed_desc_set, i);
+ }
+
unapplied |= PipelineState::UNIFORMS;
}
}
const PipelineState &self = *static_cast<const PipelineState *>(this);
uint64_t result = hash<64>(0, 0);
+ bool empty = true;
auto i = lower_bound_member(self.uniform_blocks, static_cast<int>(index)<<20, &PipelineState::BoundUniformBlock::binding);
for(; (i!=self.uniform_blocks.end() && static_cast<unsigned>(i->binding)>>20==index); ++i)
result = hash_update<64>(result, i->binding);
result = hash_update<64>(result, reinterpret_cast<uintptr_t>(i->block));
result = hash_update<64>(result, reinterpret_cast<uintptr_t>(i->buffer->handle));
+ empty = false;
}
auto j = lower_bound_member(self.textures, index<<20, &PipelineState::BoundTexture::binding);
result = hash_update<64>(result, reinterpret_cast<uintptr_t>(j->texture->handle));
result = hash_update<64>(result, reinterpret_cast<uintptr_t>(j->sampler->handle));
result = hash_update<64>(result, j->level);
+ empty = false;
}
+ if(!empty)
+ result = hash_update<64>(result, self.shprog->stage_flags);
+
return result;
}
const VulkanFunctions &vk = device.get_functions();
if(!last)
+ {
unapplied = ~0U;
+ first_changed_desc_set = 0;
+ }
else if(last!=this)
{
const PipelineState &last_ps = *static_cast<const PipelineState *>(last);
if(handle!=last->handle)
+ {
unapplied |= PipelineState::SHPROG;
+ if(self.shprog->stage_flags!=last_ps.shprog->stage_flags)
+ {
+ unapplied |= PipelineState::UNIFORMS;
+ first_changed_desc_set = 0;
+ }
+ }
if(self.vertex_setup!=last_ps.vertex_setup)
unapplied |= PipelineState::VERTEX_SETUP;
- for(unsigned i=0; (i<descriptor_set_slots.size() && i<last->descriptor_set_slots.size()); ++i)
- if(descriptor_set_slots[i]!=last->descriptor_set_slots[i])
+ for(unsigned i=0; i<descriptor_set_slots.size(); ++i)
+ if(i>=last->descriptor_set_slots.size() || descriptor_set_slots[i]!=last->descriptor_set_slots[i])
{
unapplied |= PipelineState::UNIFORMS;
+ first_changed_desc_set = min(first_changed_desc_set, i);
break;
}
if(self.viewport!=last_ps.viewport)
if((unapplied&PipelineState::UNIFORMS) && !descriptor_set_slots.empty())
{
vector<VkDescriptorSet> descriptor_set_handles;
- descriptor_set_handles.reserve(self.descriptor_set_slots.size());
- for(unsigned i=0; i<self.descriptor_set_slots.size(); ++i)
- descriptor_set_handles.push_back(device.get_descriptor_pool().get_descriptor_set(self.descriptor_set_slots[i], self, i, frame));
+ descriptor_set_handles.reserve(descriptor_set_slots.size()-first_changed_desc_set);
+ for(unsigned i=first_changed_desc_set; i<descriptor_set_slots.size(); ++i)
+ descriptor_set_handles.push_back(device.get_descriptor_pool().get_descriptor_set(
+ self.descriptor_set_slots[i], self, i, frame));
vk.CmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, self.shprog->layout_handle,
- 0, descriptor_set_handles.size(), descriptor_set_handles.data(), 0, 0);
+ first_changed_desc_set, descriptor_set_handles.size(), descriptor_set_handles.data(), 0, 0);
}
if(unapplied&(PipelineState::VIEWPORT|PipelineState::SCISSOR))
}
unapplied = 0;
+ first_changed_desc_set = descriptor_set_slots.size();
}
} // namespace GL