Add proper support for KHR_shader_draw_parameters in Vulkan mesh output

This commit is contained in:
baldurk
2018-05-08 17:51:56 +01:00
parent 788cc9f675
commit 1393b84fb6
8 changed files with 94 additions and 1 deletions
+7
View File
@@ -951,6 +951,7 @@ struct DrawcallDescription
baseVertex = 0;
vertexOffset = 0;
instanceOffset = 0;
drawIndex = 0;
dispatchDimension[0] = dispatchDimension[1] = dispatchDimension[2] = 0;
dispatchThreadsDimension[0] = dispatchThreadsDimension[1] = dispatchThreadsDimension[2] = 0;
@@ -1010,6 +1011,12 @@ struct DrawcallDescription
"For instanced drawcalls, the offset applied before looking up instanced vertex inputs.");
uint32_t instanceOffset;
DOCUMENT(R"(The index of this draw in an call with multiple draws, e.g. an indirect draw.
0 if not part of a multi-draw.
)");
uint32_t drawIndex;
DOCUMENT("The 3D number of workgroups to dispatch in a dispatch call.");
uint32_t dispatchDimension[3];
+17
View File
@@ -702,6 +702,20 @@ to apply to multiple related things - see :data:`ClipDistance`, :data:`CullDista
be less than or equal to the original depth produced by the rasterizer.
Related to :data:`DepthOutputGreaterEqual` and :data:`DepthOutput`.
.. data:: BaseVertex
The first vertex processed in this draw, as specified by the ``firstVertex`` / ``baseVertex``
parameter to the draw call.
.. data:: BaseInstance
The first instance processed in this draw call, as specified by the ``firstInstance`` parameter.
.. data:: DrawIndex
For indirect or multi-draw commands, the index of this draw call within the overall draw command.
)");
enum class ShaderBuiltin : uint32_t
{
@@ -735,6 +749,9 @@ enum class ShaderBuiltin : uint32_t
DepthOutput,
DepthOutputGreaterEqual,
DepthOutputLessEqual,
BaseVertex,
BaseInstance,
DrawIndex,
Count,
};
@@ -3423,6 +3423,7 @@ void WrappedID3D12GraphicsCommandList::PatchExecuteIndirect(BakedCmdListInfo &in
D3D12_DRAW_ARGUMENTS *args = (D3D12_DRAW_ARGUMENTS *)data;
data += sizeof(D3D12_DRAW_ARGUMENTS);
curDraw.drawIndex = a;
curDraw.numIndices = args->VertexCountPerInstance;
curDraw.numInstances = args->InstanceCount;
curDraw.vertexOffset = args->StartVertexLocation;
@@ -3463,6 +3464,7 @@ void WrappedID3D12GraphicsCommandList::PatchExecuteIndirect(BakedCmdListInfo &in
D3D12_DRAW_INDEXED_ARGUMENTS *args = (D3D12_DRAW_INDEXED_ARGUMENTS *)data;
data += sizeof(D3D12_DRAW_INDEXED_ARGUMENTS);
curDraw.drawIndex = a;
curDraw.numIndices = args->IndexCountPerInstance;
curDraw.numInstances = args->InstanceCount;
curDraw.baseVertex = args->BaseVertexLocation;
@@ -1933,6 +1933,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawArrays(SerialiserType &ser, GLenum mode
m_CurEventID++;
DrawcallDescription multidraw;
multidraw.drawIndex = i;
multidraw.numIndices = count[i];
multidraw.vertexOffset = first[i];
@@ -2080,6 +2081,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElements(SerialiserType &ser, GLenum mo
m_CurEventID++;
DrawcallDescription multidraw;
multidraw.drawIndex = i;
multidraw.numIndices = count[i];
multidraw.indexOffset = (uint32_t)(indices[i] & 0xFFFFFFFF);
multidraw.indexByteWidth = IdxSize;
@@ -2232,6 +2234,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsBaseVertex(SerialiserType &ser,
m_CurEventID++;
DrawcallDescription multidraw;
multidraw.drawIndex = i;
multidraw.numIndices = count[i];
multidraw.indexOffset = (uint32_t)(indices[i] & 0xFFFFFFFF);
multidraw.baseVertex = basevertex[i];
@@ -2389,6 +2392,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirect(SerialiserType &ser, GLe
offs += sizeof(params);
DrawcallDescription multidraw;
multidraw.drawIndex = i;
multidraw.numIndices = params.count;
multidraw.numInstances = params.instanceCount;
multidraw.vertexOffset = params.first;
@@ -2582,6 +2586,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirect(SerialiserType &ser, G
offs += sizeof(params);
DrawcallDescription multidraw;
multidraw.drawIndex = i;
multidraw.numIndices = params.count;
multidraw.numInstances = params.instanceCount;
multidraw.indexOffset = params.firstIndex;
@@ -2783,6 +2788,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirectCountARB(SerialiserType &
offs += sizeof(params);
DrawcallDescription multidraw;
multidraw.drawIndex = i;
multidraw.numIndices = params.count;
multidraw.numInstances = params.instanceCount;
multidraw.vertexOffset = params.first;
@@ -2986,6 +2992,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirectCountARB(SerialiserType
offs += sizeof(params);
DrawcallDescription multidraw;
multidraw.drawIndex = i;
multidraw.numIndices = params.count;
multidraw.numInstances = params.instanceCount;
multidraw.indexOffset = params.firstIndex;
@@ -3678,6 +3678,9 @@ ShaderBuiltin BuiltInToSystemAttribute(ShaderStage stage, const spv::BuiltIn el)
case spv::BuiltInFragDepth: return ShaderBuiltin::DepthOutput;
case spv::BuiltInVertexIndex: return ShaderBuiltin::VertexIndex;
case spv::BuiltInInstanceIndex: return ShaderBuiltin::InstanceIndex;
case spv::BuiltInBaseVertex: return ShaderBuiltin::BaseVertex;
case spv::BuiltInBaseInstance: return ShaderBuiltin::BaseInstance;
case spv::BuiltInDrawIndex: return ShaderBuiltin::DrawIndex;
default: break;
}
@@ -4432,6 +4435,37 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
cblocks.push_back(cblockpair(bindmap, cblock));
}
// look for execution modes that affect the reflection and apply them
for(SPVInstruction *inst : entries)
{
if(inst->entry && inst->entry->name == entryPoint)
{
for(const SPVExecutionMode &mode : inst->entry->modes)
{
if(mode.mode == spv::ExecutionModeDepthGreater)
{
for(SigParameter &sig : outputs)
{
if(sig.systemValue == ShaderBuiltin::DepthOutput)
sig.systemValue = ShaderBuiltin::DepthOutputGreaterEqual;
}
break;
}
if(mode.mode == spv::ExecutionModeDepthLess)
{
for(SigParameter &sig : outputs)
{
if(sig.systemValue == ShaderBuiltin::DepthOutput)
sig.systemValue = ShaderBuiltin::DepthOutputLessEqual;
}
break;
}
}
break;
}
}
// sort system value semantics to the start of the list
struct sig_param_sort
{
+23
View File
@@ -818,6 +818,29 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
{
ops.push_back(SPIRVOperation(spv::OpStore, {ins[i].variableID, instIndex}));
}
else if(builtin == ShaderBuiltin::BaseVertex)
{
if(draw->flags & DrawFlags::UseIBuffer)
ops.push_back(SPIRVOperation(
spv::OpStore, {ins[i].variableID, editor.AddConstantImmediate(
int32_t(draw->vertexOffset & 0x7fffffff))}));
else
ops.push_back(SPIRVOperation(
spv::OpStore, {ins[i].variableID,
editor.AddConstantImmediate(int32_t(draw->baseVertex & 0x7fffffff))}));
}
else if(builtin == ShaderBuiltin::BaseInstance)
{
ops.push_back(SPIRVOperation(
spv::OpStore, {ins[i].variableID, editor.AddConstantImmediate(
int32_t(draw->instanceOffset & 0x7fffffff))}));
}
else if(builtin == ShaderBuiltin::DrawIndex)
{
ops.push_back(SPIRVOperation(
spv::OpStore, {ins[i].variableID,
editor.AddConstantImmediate(int32_t(draw->drawIndex & 0x7fffffff))}));
}
else if(builtin != ShaderBuiltin::Undefined)
{
RDCERR("Unsupported/unsupported built-in input %s", ToStr(builtin).c_str());
@@ -483,6 +483,7 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndirect(SerialiserType &ser, VkCommandBu
multi.numInstances = params.instanceCount;
multi.vertexOffset = params.firstVertex;
multi.instanceOffset = params.firstInstance;
multi.drawIndex = i;
multi.name = "vkCmdDrawIndirect[" + ToStr(i) + "](<" + ToStr(multi.numIndices) + ", " +
ToStr(multi.numInstances) + ">)";
@@ -800,6 +801,7 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirect(SerialiserType &ser,
multi.vertexOffset = params.vertexOffset;
multi.indexOffset = params.firstIndex;
multi.instanceOffset = params.firstInstance;
multi.drawIndex = i;
multi.name = "vkCmdDrawIndexedIndirect[" + ToStr(i) + "](<" + ToStr(multi.numIndices) +
", " + ToStr(multi.numInstances) + ">)";
+2 -1
View File
@@ -480,6 +480,7 @@ void DoSerialise(SerialiserType &ser, DrawcallDescription &el)
SERIALISE_MEMBER(indexOffset);
SERIALISE_MEMBER(vertexOffset);
SERIALISE_MEMBER(instanceOffset);
SERIALISE_MEMBER(drawIndex);
SERIALISE_MEMBER(dispatchDimension);
SERIALISE_MEMBER(dispatchThreadsDimension);
@@ -501,7 +502,7 @@ void DoSerialise(SerialiserType &ser, DrawcallDescription &el)
SERIALISE_MEMBER(events);
SERIALISE_MEMBER(children);
SIZE_CHECK(256);
SIZE_CHECK(264);
}
template <typename SerialiserType>