for(const PipelineState::BoundUniformBlock &u: self.uniform_blocks)
if(u.changed || mask==~0U)
{
- if(u.block)
+ if(u.used)
{
if(u.binding>=0)
{
for(const PipelineState::BoundTexture &t: self.textures)
if(t.changed || mask==~0U)
{
- if(t.texture && t.sampler)
+ if(t.used)
{
if(ARB_direct_state_access)
glBindTextureUnit(t.binding, t.texture->id);
{
unsigned changed_sets = (self.changes&PipelineState::SHPROG ? ~0U : 0U);
for(const PipelineState::BoundUniformBlock &u: self.uniform_blocks)
- if(u.changed && u.binding>=0)
+ if(u.changed || changed_sets==~0U)
{
- changed_sets |= 1<<(u.binding>>20);
+ u.used = self.shprog->uses_binding(u.binding);
+ if(u.binding>=0)
+ changed_sets |= 1<<(u.binding>>20);
u.changed = false;
}
uint64_t result = hash<64>(0, 0);
for(const PipelineState::BoundUniformBlock &b: self.uniform_blocks)
- if(b.block && b.binding>=0 && static_cast<unsigned>(b.binding>>20)==index)
+ if(b.used && b.binding>=0 && static_cast<unsigned>(b.binding>>20)==index)
{
result = hash_update<64>(result, b.binding);
result = hash_update<64>(result, reinterpret_cast<uintptr_t>(b.block));
unsigned n_buffers = 0;
for(const PipelineState::BoundUniformBlock &u: self.uniform_blocks)
- if(u.block && u.binding>=0 && static_cast<unsigned>(u.binding>>20)==index)
+ if(u.used && u.binding>=0 && static_cast<unsigned>(u.binding>>20)==index)
++n_buffers;
StructureBuilder sb(buffer, 2);
VkDescriptorBufferInfo *buffer_ptr = buffers;
for(const PipelineState::BoundUniformBlock &u: self.uniform_blocks)
- if(u.block && u.binding>=0 && static_cast<unsigned>(u.binding>>20)==index)
+ if(u.used && u.binding>=0 && static_cast<unsigned>(u.binding>>20)==index)
{
buffer_ptr->buffer = handle_cast<::VkBuffer>(u.block->get_buffer()->handle);
buffer_ptr->offset = u.block->get_offset();
if(!self.uniform_blocks.empty())
{
const PipelineState::BoundUniformBlock &first_block = self.uniform_blocks.front();
- if(first_block.block && first_block.binding==ReflectData::PUSH_CONSTANT && first_block.changed)
+ if(first_block.used && first_block.binding==ReflectData::PUSH_CONSTANT && first_block.changed)
{
const UniformBlock &pc_block = *first_block.block;
vk.CmdPushConstants(command_buffer, self.shprog->layout_handle, VK_SHADER_STAGE_ALL,
auto i = lower_bound_member(uniform_blocks, binding, &BoundUniformBlock::binding);
if(i==uniform_blocks.end() || i->binding!=binding)
i = uniform_blocks.insert(i, BoundUniformBlock(binding));
+ i->used = block;
if(block!=i->block || binding<0)
{
i->block = block;
auto i = lower_bound_member(textures, binding, &BoundTexture::binding);
if(i==textures.end() || i->binding!=binding)
i = textures.insert(i, BoundTexture(binding));
+ i->used = (tex && samp);
if(tex!=i->texture || samp!=i->sampler)
{
i->texture = tex;
{
unsigned binding = 0;
mutable bool changed = false;
+ mutable bool used = false;
const Texture *texture = 0;
const Sampler *sampler = 0;
{
int binding = 0;
mutable bool changed = false;
+ mutable bool used = false;
const UniformBlock *block = 0;
BoundUniformBlock(int b): binding(b) { }
finalize_uniforms();
+ for(const ReflectData::UniformInfo &u: reflect_data.uniforms)
+ if(u.binding>=0)
+ reflect_data.used_bindings.push_back(u.binding);
+ for(const ReflectData::UniformBlockInfo &b: reflect_data.uniform_blocks)
+ reflect_data.used_bindings.push_back(b.bind_point);
+ sort(reflect_data.used_bindings);
+
for(const ReflectData::UniformInfo &u: reflect_data.uniforms)
require_type(u.type);
for(const ReflectData::AttributeInfo &a: reflect_data.attributes)
return i!=reflect_data.uniforms.end() && i->tag==tag ? i->binding : -1;
}
+bool Program::uses_binding(int binding) const
+{
+ auto i = lower_bound(reflect_data.used_bindings, binding);
+ return i!=reflect_data.used_bindings.end() && *i==binding;
+}
+
const ReflectData::AttributeInfo &Program::get_attribute_info(const string &name) const
{
auto i = lower_bound_member(reflect_data.attributes, name, &ReflectData::AttributeInfo::name);
int get_uniform_location(const std::string &) const;
int get_uniform_location(Tag) const;
int get_uniform_binding(Tag) const;
+ bool uses_binding(int) const;
const std::vector<ReflectData::AttributeInfo> &get_attributes() const { return reflect_data.attributes; }
const ReflectData::AttributeInfo &get_attribute_info(const std::string &) const;
int get_attribute_location(const std::string &) const;
std::vector<AttributeInfo> attributes;
unsigned n_clip_distances = 0;
unsigned n_descriptor_sets = 0;
+ std::vector<int> used_bindings;
void update_layout_hash();
};