Fix code not properly using vulkan dynamic vertex inputs. Closes #2527

This commit is contained in:
baldurk
2022-03-21 11:08:11 +00:00
parent 2ace1fe84d
commit d7dc8a5cd0
4 changed files with 44 additions and 35 deletions
@@ -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:
+19 -11
View File
@@ -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<VkWriteDescriptorSet> 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<bytebuf> 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;
+12 -11
View File
@@ -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());
+12 -12
View File
@@ -3880,7 +3880,7 @@ ShaderDebugTrace *VulkanReplay::DebugVertex(uint32_t eventId, uint32_t vertid, u
builtins[ShaderBuiltin::ViewportIndex] = ShaderVariable(rdcstr(), view, 0U, 0U, 0U);
rdcarray<ShaderVariable> &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());
}
}