From d7dc8a5cd03416ee5bda31f87da5eefbecc328dd Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 21 Mar 2022 11:08:11 +0000 Subject: [PATCH] Fix code not properly using vulkan dynamic vertex inputs. Closes #2527 --- .../shaders/spirv/spirv_debug_setup.cpp | 2 +- renderdoc/driver/vulkan/vk_postvs.cpp | 30 ++++++++++++------- renderdoc/driver/vulkan/vk_replay.cpp | 23 +++++++------- renderdoc/driver/vulkan/vk_shaderdebug.cpp | 24 +++++++-------- 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp index f2fdc2632..e2cf5a159 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp @@ -370,6 +370,7 @@ void Reflector::CheckDebuggable(bool &debuggable, rdcstr &debugStatus) const case Capability::ExpectAssumeKHR: case Capability::BitInstructions: case Capability::UniformDecoration: + case Capability::SignedZeroInfNanPreserve: { supported = true; break; @@ -390,7 +391,6 @@ void Reflector::CheckDebuggable(bool &debuggable, rdcstr &debugStatus) const // float controls case Capability::DenormPreserve: case Capability::DenormFlushToZero: - case Capability::SignedZeroInfNanPreserve: case Capability::RoundingModeRTE: case Capability::RoundingModeRTZ: diff --git a/renderdoc/driver/vulkan/vk_postvs.cpp b/renderdoc/driver/vulkan/vk_postvs.cpp index 255c17af4..00dd6297e 100644 --- a/renderdoc/driver/vulkan/vk_postvs.cpp +++ b/renderdoc/driver/vulkan/vk_postvs.cpp @@ -923,6 +923,16 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, // might actually have an impact on the behaviour of the shader. switch(execMode.mode) { + // these execution modes should be applied to our entry point + case rdcspv::ExecutionMode::DenormPreserve: + case rdcspv::ExecutionMode::DenormFlushToZero: + case rdcspv::ExecutionMode::SignedZeroInfNanPreserve: + case rdcspv::ExecutionMode::RoundingModeRTE: + case rdcspv::ExecutionMode::RoundingModeRTZ: + case rdcspv::ExecutionMode::SubgroupUniformControlFlowKHR: + editor.AddExecutionMode(rdcspv::OpExecutionMode( + wrapperEntry, rdcspv::ExecutionModeAndParamData(execMode.mode))); + break; case rdcspv::ExecutionMode::Xfb: break; default: RDCERR("Unexpected execution mode"); } @@ -2009,9 +2019,7 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state) rdcarray descWrites(MeshOutputBufferArraySize); uint32_t numWrites = 0; - const VkPipelineVertexInputStateCreateInfo *vi = pipeCreateInfo.pVertexInputState; - - RDCASSERT(vi->vertexAttributeDescriptionCount <= MeshOutputBufferArraySize); + RDCASSERT(state.vertexAttributes.size() <= MeshOutputBufferArraySize); // we fetch the vertex buffer data up front here since there's a very high chance of either // overlap due to interleaved attributes, or no overlap and no wastage due to separate compact @@ -2019,9 +2027,9 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state) rdcarray origVBs; origVBs.reserve(16); - for(uint32_t vb = 0; vb < vi->vertexBindingDescriptionCount; vb++) + for(uint32_t vb = 0; vb < state.vertexBindings.size(); vb++) { - uint32_t binding = vi->pVertexBindingDescriptions[vb].binding; + uint32_t binding = state.vertexBindings[vb].binding; if(binding >= state.vbuffers.size()) { origVBs.push_back(bytebuf()); @@ -2032,7 +2040,7 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state) VkDeviceSize stride = state.vbuffers[binding].stride; uint64_t len = 0; - if(vi->pVertexBindingDescriptions[vb].inputRate == VK_VERTEX_INPUT_RATE_INSTANCE) + if(state.vertexBindings[vb].inputRate == VK_VERTEX_INPUT_RATE_INSTANCE) { len = (uint64_t(maxInstance) + 1) * stride; @@ -2052,9 +2060,9 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state) GetBufferData(state.vbuffers[binding].buf, offs, len, origVBs.back()); } - for(uint32_t i = 0; i < vi->vertexAttributeDescriptionCount; i++) + for(uint32_t i = 0; i < state.vertexAttributes.size(); i++) { - const VkVertexInputAttributeDescription &attrDesc = vi->pVertexAttributeDescriptions[i]; + const VkVertexInputAttributeDescription2EXT &attrDesc = state.vertexAttributes[i]; uint32_t attr = attrDesc.location; RDCASSERT(attr < 64); @@ -2070,9 +2078,9 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state) const byte *origVBBegin = NULL; const byte *origVBEnd = NULL; - for(uint32_t vb = 0; vb < vi->vertexBindingDescriptionCount; vb++) + for(uint32_t vb = 0; vb < state.vertexBindings.size(); vb++) { - const VkVertexInputBindingDescription &vbDesc = vi->pVertexBindingDescriptions[vb]; + const VkVertexInputBindingDescription2EXT &vbDesc = state.vertexBindings[vb]; if(vbDesc.binding == attrDesc.binding) { origVBBegin = origVBs[vb].data() + attrDesc.offset; @@ -2083,7 +2091,7 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state) stride = vbDesc.stride; if(vbDesc.inputRate == VK_VERTEX_INPUT_RATE_INSTANCE) - instDivisor = pipeInfo.vertexBindings[vbDesc.binding].instanceDivisor; + instDivisor = vbDesc.divisor; else instDivisor = ~0U; break; diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index fe8f9c4fc..0e833373d 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -1190,21 +1190,22 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) MakePrimitiveTopology(state.primitiveTopology, state.patchControlPoints); // Vertex Input - ret.vertexInput.attributes.resize(p.vertexAttrs.size()); - for(size_t i = 0; i < p.vertexAttrs.size(); i++) + ret.vertexInput.attributes.resize(state.vertexAttributes.size()); + for(size_t i = 0; i < state.vertexAttributes.size(); i++) { - ret.vertexInput.attributes[i].location = p.vertexAttrs[i].location; - ret.vertexInput.attributes[i].binding = p.vertexAttrs[i].binding; - ret.vertexInput.attributes[i].byteOffset = p.vertexAttrs[i].byteoffset; - ret.vertexInput.attributes[i].format = MakeResourceFormat(p.vertexAttrs[i].format); + ret.vertexInput.attributes[i].location = state.vertexAttributes[i].location; + ret.vertexInput.attributes[i].binding = state.vertexAttributes[i].binding; + ret.vertexInput.attributes[i].byteOffset = state.vertexAttributes[i].offset; + ret.vertexInput.attributes[i].format = MakeResourceFormat(state.vertexAttributes[i].format); } - ret.vertexInput.bindings.resize(p.vertexBindings.size()); - for(size_t i = 0; i < p.vertexBindings.size(); i++) + ret.vertexInput.bindings.resize(state.vertexBindings.size()); + for(size_t i = 0; i < state.vertexBindings.size(); i++) { - ret.vertexInput.bindings[i].vertexBufferBinding = p.vertexBindings[i].vbufferBinding; - ret.vertexInput.bindings[i].perInstance = p.vertexBindings[i].perInstance; - ret.vertexInput.bindings[i].instanceDivisor = p.vertexBindings[i].instanceDivisor; + ret.vertexInput.bindings[i].vertexBufferBinding = state.vertexBindings[i].binding; + ret.vertexInput.bindings[i].perInstance = + state.vertexBindings[i].inputRate == VK_VERTEX_INPUT_RATE_INSTANCE; + ret.vertexInput.bindings[i].instanceDivisor = state.vertexBindings[i].divisor; } ret.vertexInput.vertexBuffers.resize(state.vbuffers.size()); diff --git a/renderdoc/driver/vulkan/vk_shaderdebug.cpp b/renderdoc/driver/vulkan/vk_shaderdebug.cpp index c8cec4e65..bcba3e013 100644 --- a/renderdoc/driver/vulkan/vk_shaderdebug.cpp +++ b/renderdoc/driver/vulkan/vk_shaderdebug.cpp @@ -3880,7 +3880,7 @@ ShaderDebugTrace *VulkanReplay::DebugVertex(uint32_t eventId, uint32_t vertid, u builtins[ShaderBuiltin::ViewportIndex] = ShaderVariable(rdcstr(), view, 0U, 0U, 0U); rdcarray &locations = apiWrapper->location_inputs; - for(const VulkanCreationInfo::Pipeline::Attribute &attr : pipe.vertexAttrs) + for(const VkVertexInputAttributeDescription2EXT &attr : state.vertexAttributes) { locations.resize_for_index(attr.location); @@ -3895,14 +3895,14 @@ ShaderDebugTrace *VulkanReplay::DebugVertex(uint32_t eventId, uint32_t vertid, u bool found = false; - for(const VulkanCreationInfo::Pipeline::VertBinding &bind : pipe.vertexBindings) + for(const VkVertexInputBindingDescription2EXT &bind : state.vertexBindings) { - if(bind.vbufferBinding != attr.binding) + if(bind.binding != attr.binding) continue; - if(bind.vbufferBinding < state.vbuffers.size()) + if(bind.binding < state.vbuffers.size()) { - const VulkanRenderState::VertBuffer &vb = state.vbuffers[bind.vbufferBinding]; + const VulkanRenderState::VertBuffer &vb = state.vbuffers[bind.binding]; if(vb.buf != ResourceId()) { @@ -3910,12 +3910,12 @@ ShaderDebugTrace *VulkanReplay::DebugVertex(uint32_t eventId, uint32_t vertid, u found = true; - if(bind.perInstance) + if(bind.inputRate == VK_VERTEX_INPUT_RATE_INSTANCE) { - if(bind.instanceDivisor == 0) + if(bind.divisor == 0) vertexOffset = instOffset * vb.stride; else - vertexOffset = (instOffset + (instid / bind.instanceDivisor)) * vb.stride; + vertexOffset = (instOffset + (instid / bind.divisor)) * vb.stride; } else { @@ -3925,17 +3925,17 @@ ShaderDebugTrace *VulkanReplay::DebugVertex(uint32_t eventId, uint32_t vertid, u if(Vulkan_Debug_ShaderDebugLogging()) { RDCLOG("Fetching from %s at %llu offset %zu bytes", ToStr(vb.buf).c_str(), - vb.offs + attr.byteoffset + vertexOffset, size); + vb.offs + attr.offset + vertexOffset, size); } - if(attr.byteoffset + vertexOffset < vb.size) - GetDebugManager()->GetBufferData(vb.buf, vb.offs + attr.byteoffset + vertexOffset, size, + if(attr.offset + vertexOffset < vb.size) + GetDebugManager()->GetBufferData(vb.buf, vb.offs + attr.offset + vertexOffset, size, data); } } else if(Vulkan_Debug_ShaderDebugLogging()) { - RDCLOG("Vertex binding %u out of bounds from %zu vertex buffers", bind.vbufferBinding, + RDCLOG("Vertex binding %u out of bounds from %zu vertex buffers", bind.binding, state.vbuffers.size()); } }