mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-24 23:46:41 +00:00
Add SPIR-V reflection for task/mesh shaders
This commit is contained in:
@@ -468,6 +468,21 @@ StructSizes CalculateStructProps(uint32_t emptyStructSize, const ShaderConstant
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CalculateScalarLayout(uint32_t offset, rdcarray<ShaderConstant> &consts)
|
||||
{
|
||||
for(size_t i = 0; i < consts.size(); i++)
|
||||
{
|
||||
consts[i].byteOffset = offset;
|
||||
|
||||
CalculateScalarLayout(offset, consts[i].type.members);
|
||||
|
||||
StructSizes sizes = CalculateStructProps(1, consts[i]);
|
||||
if(consts[i].type.elements > 1)
|
||||
consts[i].type.arrayByteStride = sizes.scalarSize / consts[i].type.elements;
|
||||
offset += sizes.scalarSize;
|
||||
}
|
||||
}
|
||||
|
||||
namespace rdcspv
|
||||
{
|
||||
Reflector::Reflector()
|
||||
@@ -857,7 +872,7 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
|
||||
}
|
||||
|
||||
// pick up execution mode size
|
||||
if(stage == ShaderStage::Compute)
|
||||
if(stage == ShaderStage::Compute || stage == ShaderStage::Task || stage == ShaderStage::Mesh)
|
||||
{
|
||||
const EntryPoint &e = *entry;
|
||||
|
||||
@@ -1082,6 +1097,9 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
|
||||
// $Globals gathering - for GL global values
|
||||
ConstantBlock globalsblock;
|
||||
|
||||
// for mesh shaders, the task-mesh communication payload
|
||||
ConstantBlock taskPayloadBlock;
|
||||
|
||||
// specialisation constant gathering
|
||||
ConstantBlock specblock;
|
||||
|
||||
@@ -1222,7 +1240,8 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
|
||||
global.storage == StorageClass::UniformConstant ||
|
||||
global.storage == StorageClass::AtomicCounter ||
|
||||
global.storage == StorageClass::StorageBuffer ||
|
||||
global.storage == StorageClass::PushConstant)
|
||||
global.storage == StorageClass::PushConstant ||
|
||||
global.storage == StorageClass::TaskPayloadWorkgroupEXT)
|
||||
{
|
||||
// variable type must be a pointer of the same storage class
|
||||
RDCASSERT(dataTypes[global.type].type == DataType::PointerType);
|
||||
@@ -1250,6 +1269,7 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
|
||||
(decorations[varType->id].flags & Decorations::BufferBlock);
|
||||
const bool pushConst = (global.storage == StorageClass::PushConstant);
|
||||
const bool atomicCounter = (global.storage == StorageClass::AtomicCounter);
|
||||
const bool taskPayload = (global.storage == StorageClass::TaskPayloadWorkgroupEXT);
|
||||
|
||||
rdcspv::StorageClass effectiveStorage = global.storage;
|
||||
if(ssbo)
|
||||
@@ -1392,6 +1412,18 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
|
||||
|
||||
globalsblock.variables.push_back(constant);
|
||||
}
|
||||
else if(taskPayload)
|
||||
{
|
||||
taskPayloadBlock.name = strings[global.id];
|
||||
if(taskPayloadBlock.name.empty())
|
||||
taskPayloadBlock.name = StringFormat::Fmt("payload%u", global.id.value());
|
||||
taskPayloadBlock.bufferBacked = false;
|
||||
|
||||
MakeConstantBlockVariables(effectiveStorage, *varType, 0, 0, taskPayloadBlock.variables,
|
||||
pointerTypes, specInfo);
|
||||
|
||||
CalculateScalarLayout(0, taskPayloadBlock.variables);
|
||||
}
|
||||
else
|
||||
{
|
||||
// on Vulkan should never have elements that have no binding declared but are used, unless
|
||||
@@ -1513,6 +1545,8 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
|
||||
cblocks.push_back(cblockpair(bindmap, globalsblock));
|
||||
}
|
||||
|
||||
reflection.taskPayload = taskPayloadBlock;
|
||||
|
||||
// look for execution modes that affect the reflection and apply them
|
||||
{
|
||||
const EntryPoint &e = *entry;
|
||||
@@ -1534,7 +1568,14 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
|
||||
}
|
||||
}
|
||||
|
||||
patchData.outTopo = e.executionModes.outTopo;
|
||||
reflection.outputTopology = e.executionModes.outTopo;
|
||||
|
||||
if(e.executionModes.others.contains(rdcspv::ExecutionMode::OutputPoints))
|
||||
reflection.outputTopology = Topology::PointList;
|
||||
else if(e.executionModes.others.contains(rdcspv::ExecutionMode::OutputLinesEXT))
|
||||
reflection.outputTopology = Topology::LineList;
|
||||
else if(e.executionModes.others.contains(rdcspv::ExecutionMode::OutputTrianglesEXT))
|
||||
reflection.outputTopology = Topology::TriangleList;
|
||||
}
|
||||
|
||||
for(auto it = extSets.begin(); it != extSets.end(); it++)
|
||||
|
||||
@@ -72,9 +72,6 @@ struct SPIRVPatchData
|
||||
// for mesh shaders, the maximum number of vertices/primitives generated by each meshlet
|
||||
uint32_t maxVertices = 0, maxPrimitives = 0;
|
||||
|
||||
// the output topology for tessellation and geometry shaders
|
||||
Topology outTopo = Topology::Unknown;
|
||||
|
||||
bool usesPrintf = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -2990,7 +2990,7 @@ void VulkanReplay::FetchTessGSOut(uint32_t eventId, VulkanRenderState &state)
|
||||
uint32_t primitiveMultiplier = 1;
|
||||
|
||||
// transform feedback expands strips to lists
|
||||
switch(pipeInfo.shaders[stageIndex].patchData->outTopo)
|
||||
switch(lastRefl->outputTopology)
|
||||
{
|
||||
case Topology::PointList: ret.gsout.topo = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; break;
|
||||
case Topology::LineList:
|
||||
@@ -2999,8 +2999,7 @@ void VulkanReplay::FetchTessGSOut(uint32_t eventId, VulkanRenderState &state)
|
||||
primitiveMultiplier = 2;
|
||||
break;
|
||||
default:
|
||||
RDCERR("Unexpected output topology %s",
|
||||
ToStr(pipeInfo.shaders[stageIndex].patchData->outTopo).c_str());
|
||||
RDCERR("Unexpected output topology %s", ToStr(lastRefl->outputTopology).c_str());
|
||||
DELIBERATE_FALLTHROUGH();
|
||||
case Topology::TriangleList:
|
||||
case Topology::TriangleStrip:
|
||||
|
||||
Reference in New Issue
Block a user