From 1b2e58f0e3c84e45b40e89b07939e89e7a211179 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 19 Dec 2021 00:00:32 +0200 Subject: [PATCH] Keep track of the buffers of bound uniform blocks ProgramData may recreate the buffer when creating new blocks, but existing block objects will be retained. As such, the block object alone isn't enough to determine whether the binding has changed. --- source/backends/opengl/pipelinestate_backend.cpp | 2 +- source/backends/vulkan/pipelinestate_backend.cpp | 3 ++- source/core/pipelinestate.cpp | 5 ++++- source/core/pipelinestate.h | 2 ++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/backends/opengl/pipelinestate_backend.cpp b/source/backends/opengl/pipelinestate_backend.cpp index 78ba7978..fb802995 100644 --- a/source/backends/opengl/pipelinestate_backend.cpp +++ b/source/backends/opengl/pipelinestate_backend.cpp @@ -112,7 +112,7 @@ void OpenGLPipelineState::apply() const { if(u.binding>=0) { - glBindBufferRange(GL_UNIFORM_BUFFER, u.binding, u.block->get_buffer()->id, u.block->get_offset(), u.block->get_data_size()); + glBindBufferRange(GL_UNIFORM_BUFFER, u.binding, u.buffer->id, u.block->get_offset(), u.block->get_data_size()); dev_state.bound_uniform_blocks[u.binding] = 1; } else if(u.binding==ReflectData::DEFAULT_BLOCK && self.shprog) diff --git a/source/backends/vulkan/pipelinestate_backend.cpp b/source/backends/vulkan/pipelinestate_backend.cpp index a1a03d3d..a6c9d8ce 100644 --- a/source/backends/vulkan/pipelinestate_backend.cpp +++ b/source/backends/vulkan/pipelinestate_backend.cpp @@ -275,6 +275,7 @@ uint64_t VulkanPipelineState::compute_descriptor_set_hash(unsigned index) const { result = hash_update<64>(result, b.binding); result = hash_update<64>(result, reinterpret_cast(b.block)); + result = hash_update<64>(result, reinterpret_cast(b.buffer)); } for(const PipelineState::BoundTexture &t: self.textures) if(t.used && (t.binding>>20)==index) @@ -319,7 +320,7 @@ unsigned VulkanPipelineState::fill_descriptor_writes(unsigned index, vector=0 && static_cast(u.binding>>20)==index) { - buffer_ptr->buffer = handle_cast<::VkBuffer>(u.block->get_buffer()->handle); + buffer_ptr->buffer = handle_cast<::VkBuffer>(u.buffer->handle); buffer_ptr->offset = u.block->get_offset(); buffer_ptr->range = u.block->get_data_size(); diff --git a/source/core/pipelinestate.cpp b/source/core/pipelinestate.cpp index 210a0703..fd474d28 100644 --- a/source/core/pipelinestate.cpp +++ b/source/core/pipelinestate.cpp @@ -2,6 +2,7 @@ #include #include "error.h" #include "pipelinestate.h" +#include "uniformblock.h" using namespace std; @@ -44,9 +45,11 @@ void PipelineState::set_uniform_block(int binding, const UniformBlock *block) if(i==uniform_blocks.end() || i->binding!=binding) i = uniform_blocks.insert(i, BoundUniformBlock(binding)); i->used = block; - if(block!=i->block || binding<0) + 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; changes |= UNIFORMS; } diff --git a/source/core/pipelinestate.h b/source/core/pipelinestate.h index d0ff3490..bc6087c7 100644 --- a/source/core/pipelinestate.h +++ b/source/core/pipelinestate.h @@ -11,6 +11,7 @@ namespace Msp { namespace GL { class Blend; +class Buffer; class DepthTest; class Framebuffer; class Program; @@ -49,6 +50,7 @@ private: mutable bool changed = false; mutable bool used = false; const UniformBlock *block = 0; + const Buffer *buffer = 0; BoundUniformBlock(int b): binding(b) { } }; -- 2.43.0