From 362534d5838123150311360b465026edba38bb7d Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 9 Jan 2022 15:38:54 +0200 Subject: [PATCH] Only set pipeline resources as used when the resource changes This avoids an issue on Vulkan where invalid descriptor set writes were generated if a resource unused by the current shader was set to the same value it already had and the shader wasn't changed. I'm not really sure if the flags should be set in the common part at all, since the OpenGL bckend barely uses them. But other approaches are not clearly superior either. --- source/backends/vulkan/pipelinestate_backend.cpp | 6 ++++-- source/core/pipelinestate.cpp | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source/backends/vulkan/pipelinestate_backend.cpp b/source/backends/vulkan/pipelinestate_backend.cpp index 65c98b94..84609ab0 100644 --- a/source/backends/vulkan/pipelinestate_backend.cpp +++ b/source/backends/vulkan/pipelinestate_backend.cpp @@ -49,7 +49,8 @@ void VulkanPipelineState::update() const for(const PipelineState::BoundUniformBlock &u: self.uniform_blocks) if(u.changed || changed_sets==~0U) { - u.used = self.shprog->uses_uniform_block_binding(u.binding); + if(u.block) + u.used = self.shprog->uses_uniform_block_binding(u.binding); if(u.binding>=0) changed_sets |= 1<<(u.binding>>20); u.changed = false; @@ -57,7 +58,8 @@ void VulkanPipelineState::update() const for(const PipelineState::BoundTexture &t: self.textures) if(t.changed || changed_sets==~0U) { - t.used = self.shprog->uses_texture_binding(t.binding); + if(t.texture && t.sampler) + t.used = self.shprog->uses_texture_binding(t.binding); changed_sets |= 1<<(t.binding>>20); if(t.texture && t.level>=0) t.texture->refresh_mip_views(); diff --git a/source/core/pipelinestate.cpp b/source/core/pipelinestate.cpp index fd474d28..feb429a6 100644 --- a/source/core/pipelinestate.cpp +++ b/source/core/pipelinestate.cpp @@ -44,13 +44,13 @@ void PipelineState::set_uniform_block(int binding, const UniformBlock *block) 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; const Buffer *buffer = (block ? block->get_buffer() : 0); if(block!=i->block || buffer!=i->buffer || binding<0) { i->block = block; i->buffer = buffer; i->changed = true; + i->used = block; changes |= UNIFORMS; } } @@ -70,13 +70,13 @@ void PipelineState::set_texture(unsigned binding, const Texture *tex, int level, 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 || level!=i->level || samp!=i->sampler) { i->texture = tex; i->sampler = samp; i->level = level; i->changed = true; + i->used = (tex && samp); changes |= TEXTURES; } } -- 2.45.2