mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Detect and prevent crashes on broken dxc-produced task shaders
This commit is contained in:
@@ -1393,24 +1393,39 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
|
||||
{
|
||||
if(varType->type != DataType::StructType)
|
||||
{
|
||||
// global loose variable - add to $Globals block
|
||||
RDCASSERT(varType->type == DataType::ScalarType || varType->type == DataType::VectorType ||
|
||||
varType->type == DataType::MatrixType || varType->type == DataType::ArrayType);
|
||||
RDCASSERT(sourceAPI == GraphicsAPI::OpenGL);
|
||||
|
||||
ShaderConstant constant;
|
||||
|
||||
MakeConstantBlockVariable(constant, pointerTypes, effectiveStorage, *varType,
|
||||
strings[global.id], decorations[global.id], specInfo);
|
||||
|
||||
if(isArray)
|
||||
constant.type.elements = arraySize;
|
||||
if(taskPayload)
|
||||
{
|
||||
if(!patchData.invalidTaskPayload)
|
||||
{
|
||||
RDCWARN(
|
||||
"Unhandled case - non-struct task payload. Most likely DXC bug as only one task "
|
||||
"payload variable allowed per entry point.");
|
||||
taskPayloadBlock.name = "invalid";
|
||||
taskPayloadBlock.bufferBacked = false;
|
||||
patchData.invalidTaskPayload = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
constant.type.elements = 0;
|
||||
{
|
||||
// global loose variable - add to $Globals block
|
||||
RDCASSERT(varType->type == DataType::ScalarType || varType->type == DataType::VectorType ||
|
||||
varType->type == DataType::MatrixType || varType->type == DataType::ArrayType);
|
||||
RDCASSERT(sourceAPI == GraphicsAPI::OpenGL);
|
||||
|
||||
constant.byteOffset = decorations[global.id].location;
|
||||
ShaderConstant constant;
|
||||
|
||||
globalsblock.variables.push_back(constant);
|
||||
MakeConstantBlockVariable(constant, pointerTypes, effectiveStorage, *varType,
|
||||
strings[global.id], decorations[global.id], specInfo);
|
||||
|
||||
if(isArray)
|
||||
constant.type.elements = arraySize;
|
||||
else
|
||||
constant.type.elements = 0;
|
||||
|
||||
constant.byteOffset = decorations[global.id].location;
|
||||
|
||||
globalsblock.variables.push_back(constant);
|
||||
}
|
||||
}
|
||||
else if(taskPayload)
|
||||
{
|
||||
|
||||
@@ -72,6 +72,10 @@ struct SPIRVPatchData
|
||||
// for mesh shaders, the maximum number of vertices/primitives generated by each meshlet
|
||||
uint32_t maxVertices = 0, maxPrimitives = 0;
|
||||
|
||||
// if an invalid task payload is detected (non-struct, due to dxc bug generating many scalars
|
||||
// instead of one struct)
|
||||
bool invalidTaskPayload = false;
|
||||
|
||||
bool usesPrintf = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -2848,6 +2848,12 @@ void VulkanReplay::FetchMeshOut(uint32_t eventId, VulkanRenderState &state)
|
||||
ret.taskout = ret.meshout;
|
||||
}
|
||||
|
||||
if(meshShad.patchData->invalidTaskPayload)
|
||||
{
|
||||
ret.meshout.status = ret.taskout.status = "Invalid task payload, likely generated by dxc bug";
|
||||
return;
|
||||
}
|
||||
|
||||
if(meshrefl->outputSignature.empty())
|
||||
{
|
||||
ret.meshout.status = "mesh shader has no declared outputs";
|
||||
@@ -2952,6 +2958,12 @@ void VulkanReplay::FetchMeshOut(uint32_t eventId, VulkanRenderState &state)
|
||||
const VulkanCreationInfo::Pipeline::Shader &taskShad =
|
||||
pipeInfo.shaders[(size_t)ShaderStage::Task];
|
||||
|
||||
if(taskShad.patchData->invalidTaskPayload)
|
||||
{
|
||||
ret.meshout.status = ret.taskout.status = "Invalid task payload, likely generated by dxc bug";
|
||||
return;
|
||||
}
|
||||
|
||||
const VulkanCreationInfo::ShaderModule &taskInfo = creationInfo.m_ShaderModule[taskShad.module];
|
||||
|
||||
rdcarray<uint32_t> taskSpirv = taskInfo.spirv.GetSPIRV();
|
||||
|
||||
Reference in New Issue
Block a user