From 779f2f878ef3997c703be26a2fc444cecce335db Mon Sep 17 00:00:00 2001 From: Jeff Noyle Date: Mon, 14 Oct 2019 16:14:38 -0700 Subject: [PATCH] PIX: Add Amplification/Mesh shader to shader debugging instrumentation (#2521) --- .../DxilDebugInstrumentation.cpp | 82 ++++++++++--------- .../clang/test/HLSLFileCheck/pix/DebugAs.hlsl | 23 ++++++ .../clang/test/HLSLFileCheck/pix/DebugMs.hlsl | 38 +++++++++ 3 files changed, 106 insertions(+), 37 deletions(-) create mode 100644 tools/clang/test/HLSLFileCheck/pix/DebugAs.hlsl create mode 100644 tools/clang/test/HLSLFileCheck/pix/DebugMs.hlsl diff --git a/lib/DxilPIXPasses/DxilDebugInstrumentation.cpp b/lib/DxilPIXPasses/DxilDebugInstrumentation.cpp index 9e3459d3a..04507bd32 100644 --- a/lib/DxilPIXPasses/DxilDebugInstrumentation.cpp +++ b/lib/DxilPIXPasses/DxilDebugInstrumentation.cpp @@ -225,7 +225,7 @@ private: void addInvocationSelectionProlog(BuilderContext &BC, SystemValueIndices SVIndices); Value * addPixelShaderProlog(BuilderContext &BC, SystemValueIndices SVIndices); Value * addGeometryShaderProlog(BuilderContext &BC, SystemValueIndices SVIndices); - Value * addComputeShaderProlog(BuilderContext &BC); + Value * addDispatchedShaderProlog(BuilderContext &BC); Value * addVertexShaderProlog(BuilderContext &BC, SystemValueIndices SVIndices); void addDebugEntryValue(BuilderContext &BC, Value * TheValue); void addInvocationStartMarker(BuilderContext &BC); @@ -260,30 +260,11 @@ DxilDebugInstrumentation::SystemValueIndices DxilDebugInstrumentation::addRequir auto ShaderModel = BC.DM.GetShaderModel(); switch (ShaderModel->GetKind()) { - case DXIL::ShaderKind::Pixel: { - auto Existing_SV_Position = std::find_if( - InputElements.begin(), InputElements.end(), - [](const std::unique_ptr & Element) { - return Element->GetSemantic()->GetKind() == hlsl::DXIL::SemanticKind::Position; }); - - // SV_Position, if present, has to have full mask, so we needn't worry - // about the shader having selected components that don't include x or y. - // If not present, we add it. - if (Existing_SV_Position == InputElements.end()) { - auto Added_SV_Position = llvm::make_unique(DXIL::SigPointKind::PSIn); - Added_SV_Position->Initialize("Position", hlsl::CompType::getF32(), hlsl::DXIL::InterpolationMode::Linear, 1, 4); - Added_SV_Position->AppendSemanticIndex(0); - Added_SV_Position->SetSigPointKind(DXIL::SigPointKind::PSIn); - Added_SV_Position->SetKind(hlsl::DXIL::SemanticKind::Position); - - auto index = InputSignature.AppendElement(std::move(Added_SV_Position)); - SVIndices.PixelShader.Position = InputElements[index]->GetID(); - } - else { - SVIndices.PixelShader.Position = Existing_SV_Position->get()->GetID(); - } - } - break; + case DXIL::ShaderKind::Amplification: + case DXIL::ShaderKind::Mesh: + case DXIL::ShaderKind::Compute: + // Dispatch* thread Id is not in the input signature + break; case DXIL::ShaderKind::Vertex: { { auto Existing_SV_VertexId = std::find_if( @@ -325,14 +306,37 @@ DxilDebugInstrumentation::SystemValueIndices DxilDebugInstrumentation::addRequir SVIndices.VertexShader.InstanceId = Existing_SV_InstanceId->get()->GetID(); } } - } - break; + } break; case DXIL::ShaderKind::Geometry: // GS Instance Id and Primitive Id are not in the input signature break; - case DXIL::ShaderKind::Compute: - // Compute thread Id is not in the input signature - break; + case DXIL::ShaderKind::Pixel: { + auto Existing_SV_Position = + std::find_if(InputElements.begin(), InputElements.end(), + [](const std::unique_ptr &Element) { + return Element->GetSemantic()->GetKind() == + hlsl::DXIL::SemanticKind::Position; + }); + + // SV_Position, if present, has to have full mask, so we needn't worry + // about the shader having selected components that don't include x or y. + // If not present, we add it. + if (Existing_SV_Position == InputElements.end()) { + auto Added_SV_Position = + llvm::make_unique(DXIL::SigPointKind::PSIn); + Added_SV_Position->Initialize("Position", hlsl::CompType::getF32(), + hlsl::DXIL::InterpolationMode::Linear, 1, + 4); + Added_SV_Position->AppendSemanticIndex(0); + Added_SV_Position->SetSigPointKind(DXIL::SigPointKind::PSIn); + Added_SV_Position->SetKind(hlsl::DXIL::SemanticKind::Position); + + auto index = InputSignature.AppendElement(std::move(Added_SV_Position)); + SVIndices.PixelShader.Position = InputElements[index]->GetID(); + } else { + SVIndices.PixelShader.Position = Existing_SV_Position->get()->GetID(); + } + } break; default: assert(false); // guaranteed by runOnModule } @@ -340,7 +344,7 @@ DxilDebugInstrumentation::SystemValueIndices DxilDebugInstrumentation::addRequir return SVIndices; } -Value * DxilDebugInstrumentation::addComputeShaderProlog(BuilderContext &BC) { +Value * DxilDebugInstrumentation::addDispatchedShaderProlog(BuilderContext &BC) { Constant* Zero32Arg = BC.HlslOP->GetU32Const(0); Constant* One32Arg = BC.HlslOP->GetU32Const(1); Constant* Two32Arg = BC.HlslOP->GetU32Const(2); @@ -482,8 +486,10 @@ void DxilDebugInstrumentation::addInvocationSelectionProlog(BuilderContext &BC, Value * ParameterTestResult = nullptr; switch (ShaderModel->GetKind()) { - case DXIL::ShaderKind::Pixel: - ParameterTestResult = addPixelShaderProlog(BC, SVIndices); + case DXIL::ShaderKind::Compute: + case DXIL::ShaderKind::Amplification: + case DXIL::ShaderKind::Mesh: + ParameterTestResult = addDispatchedShaderProlog(BC); break; case DXIL::ShaderKind::Geometry: ParameterTestResult = addGeometryShaderProlog(BC, SVIndices); @@ -491,8 +497,8 @@ void DxilDebugInstrumentation::addInvocationSelectionProlog(BuilderContext &BC, case DXIL::ShaderKind::Vertex: ParameterTestResult = addVertexShaderProlog(BC, SVIndices); break; - case DXIL::ShaderKind::Compute: - ParameterTestResult = addComputeShaderProlog(BC); + case DXIL::ShaderKind::Pixel: + ParameterTestResult = addPixelShaderProlog(BC, SVIndices); break; default: assert(false); // guaranteed by runOnModule @@ -744,10 +750,12 @@ bool DxilDebugInstrumentation::runOnModule(Module &M) { auto ShaderModel = DM.GetShaderModel(); switch (ShaderModel->GetKind()) { - case DXIL::ShaderKind::Pixel: + case DXIL::ShaderKind::Amplification: + case DXIL::ShaderKind::Mesh: case DXIL::ShaderKind::Vertex: - case DXIL::ShaderKind::Compute: case DXIL::ShaderKind::Geometry: + case DXIL::ShaderKind::Pixel: + case DXIL::ShaderKind::Compute: break; default: return false; diff --git a/tools/clang/test/HLSLFileCheck/pix/DebugAs.hlsl b/tools/clang/test/HLSLFileCheck/pix/DebugAs.hlsl new file mode 100644 index 000000000..c9c834469 --- /dev/null +++ b/tools/clang/test/HLSLFileCheck/pix/DebugAs.hlsl @@ -0,0 +1,23 @@ +// RUN: %dxc -Emain -Tas_6_5 %s | %opt -S -hlsl-dxil-debug-instrumentation,parameter0=10,parameter1=20,parameter2=30 | %FileCheck %s + +// Check that the AS thread IDs are added properly + +// CHECK: %PIX_DebugUAV_Handle = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false) +// CHECK: %ThreadIdX = call i32 @dx.op.threadId.i32(i32 93, i32 0) +// CHECK: %ThreadIdY = call i32 @dx.op.threadId.i32(i32 93, i32 1) +// CHECK: %ThreadIdZ = call i32 @dx.op.threadId.i32(i32 93, i32 2) +// CHECK: %CompareToThreadIdX = icmp eq i32 %ThreadIdX, 10 +// CHECK: %CompareToThreadIdY = icmp eq i32 %ThreadIdY, 20 +// CHECK: %CompareToThreadIdZ = icmp eq i32 %ThreadIdZ, 30 +// CHECK: %CompareXAndY = and i1 %CompareToThreadIdX, %CompareToThreadIdY +// CHECK: %CompareAll = and i1 %CompareXAndY, %CompareToThreadIdZ + +struct smallPayload { + uint dummy; +}; + +[numthreads(1, 1, 1)] void main() { + smallPayload p; + p.dummy = 0; + DispatchMesh(2, 1, 1, p); +} diff --git a/tools/clang/test/HLSLFileCheck/pix/DebugMs.hlsl b/tools/clang/test/HLSLFileCheck/pix/DebugMs.hlsl new file mode 100644 index 000000000..43b950f99 --- /dev/null +++ b/tools/clang/test/HLSLFileCheck/pix/DebugMs.hlsl @@ -0,0 +1,38 @@ +// RUN: %dxc -Emain -Tms_6_5 %s | %opt -S -hlsl-dxil-debug-instrumentation,parameter0=10,parameter1=20,parameter2=30 | %FileCheck %s + +// Check that the MS thread IDs are added properly + +// CHECK: %PIX_DebugUAV_Handle = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false) +// CHECK: %ThreadIdX = call i32 @dx.op.threadId.i32(i32 93, i32 0) +// CHECK: %ThreadIdY = call i32 @dx.op.threadId.i32(i32 93, i32 1) +// CHECK: %ThreadIdZ = call i32 @dx.op.threadId.i32(i32 93, i32 2) +// CHECK: %CompareToThreadIdX = icmp eq i32 %ThreadIdX, 10 +// CHECK: %CompareToThreadIdY = icmp eq i32 %ThreadIdY, 20 +// CHECK: %CompareToThreadIdZ = icmp eq i32 %ThreadIdZ, 30 +// CHECK: %CompareXAndY = and i1 %CompareToThreadIdX, %CompareToThreadIdY +// CHECK: %CompareAll = and i1 %CompareXAndY, %CompareToThreadIdZ + +struct smallPayload { + uint dummy; +}; + +struct PSInput { + float4 position : SV_POSITION; + float4 color : COLOR; +}; + +[outputtopology("triangle")] +[numthreads(3, 1, 1)] +void main( + in payload smallPayload small, + in uint tid : SV_DispatchThreadID, + in uint tig : SV_GroupIndex, + in uint groupId : SV_GroupID, + out vertices PSInput verts[3], + out indices uint3 triangles[1]) { + + SetMeshOutputCounts(3 /*verts*/, 1 /*prims*/); + verts[tid].position = float4(0, 0, 0, 0); + verts[tid].color = float4(0,0,0,0); + triangles[0] = uint3(0, 1, 2); +}