From 5b2ec79df35a6188dc24d9c1cb1e9984c1894216 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 4 Mar 2025 13:14:55 +0000 Subject: [PATCH] Fix missing handling of dynamic offsets. Closes #3547 --- .../VulkanPipelineStateViewer.cpp | 47 +++++++++++-------- .../PipelineState/VulkanPipelineStateViewer.h | 3 +- renderdoc/api/replay/pipestate.inl | 7 ++- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index 2f6c50e98..c3b2c060a 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -81,15 +81,20 @@ Q_DECLARE_METATYPE(VulkanVBIBTag); struct VulkanCBufferTag { VulkanCBufferTag() { index = DescriptorAccess::NoShaderBinding; } - VulkanCBufferTag(uint32_t index, uint32_t arrayElement) : index(index), arrayElement(arrayElement) + VulkanCBufferTag(uint32_t index, uint32_t arrayElement, uint32_t dynOffset) + : index(index), arrayElement(arrayElement), dynamicOffset(dynOffset) { } - VulkanCBufferTag(Descriptor descriptor) - : index(DescriptorAccess::NoShaderBinding), arrayElement(0), descriptor(descriptor) + VulkanCBufferTag(Descriptor descriptor, uint32_t dynOffset) + : index(DescriptorAccess::NoShaderBinding), + arrayElement(0), + descriptor(descriptor), + dynamicOffset(dynOffset) { } Descriptor descriptor; + uint32_t dynamicOffset; uint32_t index, arrayElement; }; @@ -98,8 +103,8 @@ Q_DECLARE_METATYPE(VulkanCBufferTag); struct VulkanBufferTag { VulkanBufferTag() {} - VulkanBufferTag(const DescriptorAccess &access, const Descriptor &desc) - : access(access), descriptor(desc) + VulkanBufferTag(const DescriptorAccess &access, const Descriptor &desc, uint32_t dynOffset) + : access(access), descriptor(desc), dynamicOffset(dynOffset) { } VulkanBufferTag(ResourceId id, uint64_t offset, uint64_t length) @@ -108,9 +113,11 @@ struct VulkanBufferTag descriptor.resource = id; descriptor.byteOffset = offset; descriptor.byteSize = length; + dynamicOffset = 0; } DescriptorAccess access; Descriptor descriptor; + uint32_t dynamicOffset = 0; }; Q_DECLARE_METATYPE(VulkanBufferTag); @@ -774,20 +781,21 @@ bool VulkanPipelineStateViewer::setViewDetails(RDTreeWidgetItem *node, const Des } bool VulkanPipelineStateViewer::setViewDetails(RDTreeWidgetItem *node, const Descriptor &descriptor, - BufferDescription *buf) + BufferDescription *buf, uint32_t dynamicOffset) { if(buf == NULL) return false; QString text; - if(descriptor.byteOffset > 0 || descriptor.byteSize < buf->length) + if(descriptor.byteOffset + dynamicOffset > 0 || descriptor.byteSize < buf->length) { - text += tr("The view covers bytes %1-%2.\nThe buffer is %3 bytes in length.\n") - .arg(Formatter::HumanFormat(descriptor.byteOffset, Formatter::OffsetSize)) - .arg(Formatter::HumanFormat(descriptor.byteOffset + descriptor.byteSize, - Formatter::OffsetSize)) - .arg(Formatter::HumanFormat(buf->length, Formatter::OffsetSize)); + text += + tr("The view covers bytes %1-%2.\nThe buffer is %3 bytes in length.\n") + .arg(Formatter::HumanFormat(descriptor.byteOffset + dynamicOffset, Formatter::OffsetSize)) + .arg(Formatter::HumanFormat(descriptor.byteOffset + dynamicOffset + descriptor.byteSize, + Formatter::OffsetSize)) + .arg(Formatter::HumanFormat(buf->length, Formatter::OffsetSize)); } else { @@ -1294,7 +1302,7 @@ void VulkanPipelineStateViewer::addResourceRow(const ShaderResource *shaderRes, a = 0; restype = TextureType::Buffer; - tag = QVariant::fromValue(VulkanBufferTag(used.access, used.descriptor)); + tag = QVariant::fromValue(VulkanBufferTag(used.access, used.descriptor, dynamicOffset)); isbuf = true; } @@ -1541,7 +1549,7 @@ void VulkanPipelineStateViewer::addResourceRow(const ShaderResource *shaderRes, } else if(buf) { - setViewDetails(node, descriptor, buf); + setViewDetails(node, descriptor, buf, dynamicOffset); } resources->addTopLevelItem(node); @@ -1557,7 +1565,7 @@ void VulkanPipelineStateViewer::addConstantBlockRow(const ConstantBlock *cblock, { const Descriptor &descriptor = used.descriptor; - VulkanCBufferTag tag(used.access.index, used.access.arrayElement); + VulkanCBufferTag tag(used.access.index, used.access.arrayElement, dynamicOffset); bool filledSlot = (descriptor.resource != ResourceId()); // Vulkan does not report unused elements at all because we enumerate exclusively from the @@ -3085,8 +3093,9 @@ void VulkanPipelineStateViewer::resource_itemActivated(RDTreeWidgetItem *item, i if(buf.descriptor.resource != ResourceId()) { - IBufferViewer *viewer = m_Ctx.ViewBuffer(buf.descriptor.byteOffset, buf.descriptor.byteSize, - buf.descriptor.resource, format); + IBufferViewer *viewer = + m_Ctx.ViewBuffer(buf.descriptor.byteOffset + buf.dynamicOffset, buf.descriptor.byteSize, + buf.descriptor.resource, format); m_Ctx.AddDockWindow(viewer->Widget(), DockReference::AddTo, this); } @@ -3139,8 +3148,8 @@ void VulkanPipelineStateViewer::ubo_itemActivated(RDTreeWidgetItem *item, int co { if(cb.descriptor.resource != ResourceId()) { - IBufferViewer *viewer = - m_Ctx.ViewBuffer(cb.descriptor.byteOffset, cb.descriptor.byteSize, cb.descriptor.resource); + IBufferViewer *viewer = m_Ctx.ViewBuffer(cb.descriptor.byteOffset + cb.dynamicOffset, + cb.descriptor.byteSize, cb.descriptor.resource); m_Ctx.AddDockWindow(viewer->Widget(), DockReference::AddTo, this); } diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h index dbaf59d1d..767752545 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h @@ -136,7 +136,8 @@ private: const QString &hiddenCombinedSampler, bool includeSampleLocations = false, bool includeOffsets = false); - bool setViewDetails(RDTreeWidgetItem *node, const Descriptor &descriptor, BufferDescription *buf); + bool setViewDetails(RDTreeWidgetItem *node, const Descriptor &descriptor, BufferDescription *buf, + uint32_t dynamicOffset); bool showNode(bool usedSlot, bool filledSlot); diff --git a/renderdoc/api/replay/pipestate.inl b/renderdoc/api/replay/pipestate.inl index 51a93a97f..35f915db3 100644 --- a/renderdoc/api/replay/pipestate.inl +++ b/renderdoc/api/replay/pipestate.inl @@ -1042,7 +1042,7 @@ rdcarray PipeState::GetSamplers(ShaderStage stage, bool onlyUsed if(m_Access[i].stage == stage && IsSamplerDescriptor(m_Access[i].type) && (onlyUsed == false || !m_Access[i].staticallyUnused)) { - if(i < m_Descriptors.size()) + if(i < m_SamplerDescriptors.size()) { ret.push_back({m_Access[i], Descriptor(), m_SamplerDescriptors[i]}); ApplyVulkanDynamicOffsets(ret.back()); @@ -1062,8 +1062,11 @@ rdcarray PipeState::GetReadWriteResources(ShaderStage stage, boo if(m_Access[i].stage == stage && IsReadWriteDescriptor(m_Access[i].type) && (onlyUsed == false || !m_Access[i].staticallyUnused)) { - if(i < m_SamplerDescriptors.size()) + if(i < m_Descriptors.size()) + { ret.push_back({m_Access[i], m_Descriptors[i], SamplerDescriptor()}); + ApplyVulkanDynamicOffsets(ret.back()); + } } }