Skip to content

Commit ff623f8

Browse files
authored
PIX: Emit correct input sig elements and view ID state into PSV0 when input sigs are changed by debug instrumentation (#6351)
Two intertwined issues: 1: The shader-debug-instrumentation and pixel-hit-counter passes add SV_VertexId+SV_InstanceId to the input sig for a VS if they are not present, and SV_Position for the PS. The changes in PixPassHelpers.cpp centralize the SV_Position case and fix up a few missing fields whose absence was breaking PIX shader debugging on WARP. The calller now has to pass the upstream shader's SV_Position row, if it exists. (PIX has been updated to do this.) 2: However, independent of these tweaks, adding these new values means that the view id metadata would be incorrect. A long-standing assert would fire, but is herein fixed, since the above work exacerbated this problem. The assert in question is this one in CopyViewIDStateForOutputToPSV that previously fired when a debug-instrumented shader was subsequently wrapped into a container: ``` DXASSERT_NOMSG((InputScalars <= IOTable.InputVectors * 4) && (IOTable.InputVectors * 4 - InputScalars < 4)); ``` (InputScalars, which comes from the serialized state in PSV0, was too small, since it did not include the added system values.) To fix up these data, the caller now has to invoke the generate-view-id-state pass, and follow that with the emit-metadata pass, since emitting the metadata in the debug pass itself is now too early (and that call has been deleted). (PIX has been updated to do invoke these passes.) These changes together are sufficient to allow PIX shader debugging to operate on WARP in those cases where these system-values were not included by the application, with correct view-id metadata, and the assert is happy.
1 parent 8fe99be commit ff623f8

File tree

10 files changed

+229
-84
lines changed

10 files changed

+229
-84
lines changed

lib/DxilPIXPasses/DxilAddPixelHitInstrumentation.cpp

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,25 @@ class DxilAddPixelHitInstrumentation : public ModulePass {
3232
bool AddPixelCost = false;
3333
int RTWidth = 1024;
3434
int NumPixels = 128;
35-
int SVPositionIndex = -1;
3635

3736
public:
3837
static char ID; // Pass identification, replacement for typeid
3938
explicit DxilAddPixelHitInstrumentation() : ModulePass(ID) {}
40-
StringRef getPassName() const override { return "DXIL Constant Color Mod"; }
39+
StringRef getPassName() const override {
40+
return "DXIL Add Pixel Hit Instrumentation";
41+
}
4142
void applyOptions(PassOptions O) override;
4243
bool runOnModule(Module &M) override;
44+
unsigned m_upstreamSVPositionRow;
4345
};
4446

4547
void DxilAddPixelHitInstrumentation::applyOptions(PassOptions O) {
4648
GetPassOptionBool(O, "force-early-z", &ForceEarlyZ, false);
4749
GetPassOptionBool(O, "add-pixel-cost", &AddPixelCost, false);
4850
GetPassOptionInt(O, "rt-width", &RTWidth, 0);
4951
GetPassOptionInt(O, "num-pixels", &NumPixels, 0);
50-
GetPassOptionInt(O, "sv-position-index", &SVPositionIndex, 0);
52+
GetPassOptionUnsigned(O, "upstream-sv-position-row", &m_upstreamSVPositionRow,
53+
0);
5154
}
5255

5356
bool DxilAddPixelHitInstrumentation::runOnModule(Module &M) {
@@ -63,37 +66,8 @@ bool DxilAddPixelHitInstrumentation::runOnModule(Module &M) {
6366
DM.m_ShaderFlags.SetForceEarlyDepthStencil(true);
6467
}
6568

66-
hlsl::DxilSignature &InputSignature = DM.GetInputSignature();
67-
68-
auto &InputElements = InputSignature.GetElements();
69-
70-
unsigned SV_Position_ID;
71-
72-
auto SV_Position =
73-
std::find_if(InputElements.begin(), InputElements.end(),
74-
[](const std::unique_ptr<DxilSignatureElement> &Element) {
75-
return Element->GetSemantic()->GetKind() ==
76-
hlsl::DXIL::SemanticKind::Position;
77-
});
78-
79-
// SV_Position, if present, has to have full mask, so we needn't worry
80-
// about the shader having selected components that don't include x or y.
81-
// If not present, we add it.
82-
if (SV_Position == InputElements.end()) {
83-
auto SVPosition =
84-
llvm::make_unique<DxilSignatureElement>(DXIL::SigPointKind::PSIn);
85-
SVPosition->Initialize("Position", hlsl::CompType::getF32(),
86-
hlsl::DXIL::InterpolationMode::Linear, 1, 4,
87-
SVPositionIndex == -1 ? 0 : SVPositionIndex, 0);
88-
SVPosition->AppendSemanticIndex(0);
89-
SVPosition->SetSigPointKind(DXIL::SigPointKind::PSIn);
90-
SVPosition->SetKind(hlsl::DXIL::SemanticKind::Position);
91-
92-
auto index = InputSignature.AppendElement(std::move(SVPosition));
93-
SV_Position_ID = InputElements[index]->GetID();
94-
} else {
95-
SV_Position_ID = SV_Position->get()->GetID();
96-
}
69+
auto SV_Position_ID =
70+
PIXPassHelpers::FindOrAddSV_Position(DM, m_upstreamSVPositionRow);
9771

9872
auto EntryPointFunction = PIXPassHelpers::GetEntryFunction(DM);
9973

lib/DxilPIXPasses/DxilDebugInstrumentation.cpp

Lines changed: 39 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "dxc/DxilPIXPasses/DxilPIXPasses.h"
2020
#include "dxc/DxilPIXPasses/DxilPIXVirtualRegisters.h"
2121
#include "dxc/HLSL/DxilGenerationPass.h"
22+
#include "dxc/Support/Global.h"
2223

2324
#include "llvm/ADT/STLExtras.h"
2425
#include "llvm/IR/Constants.h"
@@ -282,6 +283,8 @@ class DxilDebugInstrumentation : public ModulePass {
282283
unsigned m_LastInstruction = static_cast<unsigned>(-1);
283284

284285
uint64_t m_UAVSize = 1024 * 1024;
286+
unsigned m_upstreamSVPositionRow;
287+
285288
struct PerFunctionValues {
286289
CallInst *UAVHandle = nullptr;
287290
Instruction *CounterOffset = nullptr;
@@ -378,17 +381,33 @@ void DxilDebugInstrumentation::applyOptions(PassOptions O) {
378381
GetPassOptionUnsigned(O, "parameter1", &m_Parameters.Parameters[1], 0);
379382
GetPassOptionUnsigned(O, "parameter2", &m_Parameters.Parameters[2], 0);
380383
GetPassOptionUInt64(O, "UAVSize", &m_UAVSize, 1024 * 1024);
384+
GetPassOptionUnsigned(O, "upstreamSVPositionRow", &m_upstreamSVPositionRow,
385+
0);
381386
}
382387

383388
uint32_t DxilDebugInstrumentation::UAVDumpingGroundOffset() {
384389
return static_cast<uint32_t>(m_UAVSize / 2);
385390
}
386391

387-
static unsigned FindOrAddInputSignatureElement(
388-
hlsl::DxilSignature &InputSignature, const char *name,
389-
DXIL::SigPointKind sigPointKind, hlsl::DXIL::SemanticKind semanticKind) {
392+
unsigned int GetNextEmptyRow(
393+
std::vector<std::unique_ptr<DxilSignatureElement>> const &Elements) {
394+
unsigned int Row = 0;
395+
for (auto const &Element : Elements) {
396+
Row = std::max<unsigned>(Row, Element->GetStartRow() + Element->GetRows());
397+
}
398+
return Row;
399+
}
390400

391-
auto &InputElements = InputSignature.GetElements();
401+
unsigned FindOrAddVSInSignatureElementForInstanceOrVertexID(
402+
hlsl::DxilSignature &InputSignature,
403+
hlsl::DXIL::SemanticKind semanticKind) {
404+
DXASSERT(InputSignature.GetSigPointKind() == DXIL::SigPointKind::VSIn,
405+
"Unexpected SigPointKind in input signature");
406+
DXASSERT(semanticKind == DXIL::SemanticKind::InstanceID ||
407+
semanticKind == DXIL::SemanticKind::VertexID,
408+
"This function only expects InstaceID or VertexID");
409+
410+
auto const &InputElements = InputSignature.GetElements();
392411

393412
auto ExistingElement =
394413
std::find_if(InputElements.begin(), InputElements.end(),
@@ -397,13 +416,16 @@ static unsigned FindOrAddInputSignatureElement(
397416
});
398417

399418
if (ExistingElement == InputElements.end()) {
400-
auto AddedElement = llvm::make_unique<DxilSignatureElement>(sigPointKind);
401-
AddedElement->Initialize(name, hlsl::CompType::getF32(),
402-
hlsl::DXIL::InterpolationMode::Undefined, 1, 1);
419+
auto AddedElement =
420+
llvm::make_unique<DxilSignatureElement>(DXIL::SigPointKind::VSIn);
421+
unsigned Row = GetNextEmptyRow(InputElements);
422+
AddedElement->Initialize(
423+
hlsl::Semantic::Get(semanticKind)->GetName(), hlsl::CompType::getU32(),
424+
hlsl::DXIL::InterpolationMode::Constant, 1, 1, Row, 0);
403425
AddedElement->AppendSemanticIndex(0);
404-
AddedElement->SetSigPointKind(sigPointKind);
405426
AddedElement->SetKind(semanticKind);
406-
427+
AddedElement->SetUsageMask(1);
428+
// AppendElement sets the element's ID by default
407429
auto index = InputSignature.AppendElement(std::move(AddedElement));
408430
return InputElements[index]->GetID();
409431
} else {
@@ -429,12 +451,12 @@ DxilDebugInstrumentation::addRequiredSystemValues(BuilderContext &BC,
429451
break;
430452
case DXIL::ShaderKind::Vertex: {
431453
hlsl::DxilSignature &InputSignature = BC.DM.GetInputSignature();
432-
SVIndices.VertexShader.VertexId = FindOrAddInputSignatureElement(
433-
InputSignature, "VertexId", DXIL::SigPointKind::VSIn,
434-
hlsl::DXIL::SemanticKind::VertexID);
435-
SVIndices.VertexShader.InstanceId = FindOrAddInputSignatureElement(
436-
InputSignature, "InstanceId", DXIL::SigPointKind::VSIn,
437-
hlsl::DXIL::SemanticKind::InstanceID);
454+
SVIndices.VertexShader.VertexId =
455+
FindOrAddVSInSignatureElementForInstanceOrVertexID(
456+
InputSignature, hlsl::DXIL::SemanticKind::VertexID);
457+
SVIndices.VertexShader.InstanceId =
458+
FindOrAddVSInSignatureElementForInstanceOrVertexID(
459+
InputSignature, hlsl::DXIL::SemanticKind::InstanceID);
438460
} break;
439461
case DXIL::ShaderKind::Geometry:
440462
case DXIL::ShaderKind::Hull:
@@ -443,34 +465,8 @@ DxilDebugInstrumentation::addRequiredSystemValues(BuilderContext &BC,
443465
// in the input signature
444466
break;
445467
case DXIL::ShaderKind::Pixel: {
446-
hlsl::DxilSignature &InputSignature = BC.DM.GetInputSignature();
447-
auto &InputElements = InputSignature.GetElements();
448-
449-
auto Existing_SV_Position =
450-
std::find_if(InputElements.begin(), InputElements.end(),
451-
[](const std::unique_ptr<DxilSignatureElement> &Element) {
452-
return Element->GetSemantic()->GetKind() ==
453-
hlsl::DXIL::SemanticKind::Position;
454-
});
455-
456-
// SV_Position, if present, has to have full mask, so we needn't worry
457-
// about the shader having selected components that don't include x or y.
458-
// If not present, we add it.
459-
if (Existing_SV_Position == InputElements.end()) {
460-
auto Added_SV_Position =
461-
llvm::make_unique<DxilSignatureElement>(DXIL::SigPointKind::PSIn);
462-
Added_SV_Position->Initialize("Position", hlsl::CompType::getF32(),
463-
hlsl::DXIL::InterpolationMode::Linear, 1,
464-
4);
465-
Added_SV_Position->AppendSemanticIndex(0);
466-
Added_SV_Position->SetSigPointKind(DXIL::SigPointKind::PSIn);
467-
Added_SV_Position->SetKind(hlsl::DXIL::SemanticKind::Position);
468-
469-
auto index = InputSignature.AppendElement(std::move(Added_SV_Position));
470-
SVIndices.PixelShader.Position = InputElements[index]->GetID();
471-
} else {
472-
SVIndices.PixelShader.Position = Existing_SV_Position->get()->GetID();
473-
}
468+
SVIndices.PixelShader.Position =
469+
PIXPassHelpers::FindOrAddSV_Position(BC.DM, m_upstreamSVPositionRow);
474470
} break;
475471
default:
476472
assert(false); // guaranteed by runOnModule
@@ -1515,8 +1511,6 @@ bool DxilDebugInstrumentation::RunOnFunction(Module &M, DxilModule &DM,
15151511
}
15161512
}
15171513

1518-
DM.ReEmitDxilResources();
1519-
15201514
return true;
15211515
}
15221516

lib/DxilPIXPasses/PixPassHelpers.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,41 @@ void ReplaceAllUsesOfInstructionWithNewValueAndDeleteInstruction(
450450
delete Instr;
451451
}
452452

453+
unsigned int FindOrAddSV_Position(hlsl::DxilModule &DM,
454+
unsigned UpStreamSVPosRow) {
455+
hlsl::DxilSignature &InputSignature = DM.GetInputSignature();
456+
auto &InputElements = InputSignature.GetElements();
457+
458+
auto Existing_SV_Position =
459+
std::find_if(InputElements.begin(), InputElements.end(),
460+
[](const std::unique_ptr<DxilSignatureElement> &Element) {
461+
return Element->GetSemantic()->GetKind() ==
462+
hlsl::DXIL::SemanticKind::Position;
463+
});
464+
465+
// SV_Position, if present, has to have full mask, so we needn't worry
466+
// about the shader having selected components that don't include x or y.
467+
// If not present, we add it.
468+
if (Existing_SV_Position == InputElements.end()) {
469+
unsigned int StartColumn = 0;
470+
unsigned int RowCount = 1;
471+
unsigned int ColumnCount = 4;
472+
auto Added_SV_Position =
473+
llvm::make_unique<DxilSignatureElement>(DXIL::SigPointKind::PSIn);
474+
Added_SV_Position->Initialize("Position", hlsl::CompType::getF32(),
475+
hlsl::DXIL::InterpolationMode::Linear,
476+
RowCount, ColumnCount, UpStreamSVPosRow,
477+
StartColumn);
478+
Added_SV_Position->AppendSemanticIndex(0);
479+
Added_SV_Position->SetKind(hlsl::DXIL::SemanticKind::Position);
480+
// AppendElement sets the element's ID by default
481+
auto index = InputSignature.AppendElement(std::move(Added_SV_Position));
482+
return InputElements[index]->GetID();
483+
} else {
484+
return Existing_SV_Position->get()->GetID();
485+
}
486+
}
487+
453488
#ifdef PIX_DEBUG_DUMP_HELPER
454489

455490
static int g_logIndent = 0;

lib/DxilPIXPasses/PixPassHelpers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,6 @@ ExpandedStruct ExpandStructType(llvm::LLVMContext &Ctx,
7474
llvm::Type *OriginalPayloadStructType);
7575
void ReplaceAllUsesOfInstructionWithNewValueAndDeleteInstruction(
7676
llvm::Instruction *Instr, llvm::Value *newValue, llvm::Type *newType);
77+
unsigned int FindOrAddSV_Position(hlsl::DxilModule &DM,
78+
unsigned UpStreamSVPosRow);
7779
} // namespace PIXPassHelpers

tools/clang/test/HLSLFileCheck/pix/DebugBasic.hlsl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %dxc -Emain -Tps_6_0 %s | %opt -S -hlsl-dxil-debug-instrumentation,UAVSize=128 | %FileCheck %s
1+
// RUN: %dxc -Emain -Tps_6_0 %s | %opt -S -hlsl-dxil-debug-instrumentation,UAVSize=128,upstreamSVPositionRow=2 -hlsl-dxilemit | %FileCheck %s
22

33
// Check that the basic starting header is present:
44

@@ -22,7 +22,12 @@
2222
// CHECK: and i32
2323
// CHECK: or i32
2424

25-
25+
// Check that the correct metadata was emitted for the requested SV_Position at row 2, col 0, 1 row, 4 cols.
26+
// See DxilMDHelper::EmitSignatureElement for the meaning of these entries:
27+
// ID TypeF32 SemKin Sem-Idx-Vec interp Rows Cols Row Col
28+
// | | | | | | | | |
29+
// CHECK: !{i32 0, !"SV_Position", i8 9, i8 3, ![[SEMIDXVEC:[0-9]*]], i8 2, i32 1, i8 4, i32 2, i8 0, null}
30+
// CHECK: ![[SEMIDXVEC]] = !{i32 0}
2631

2732
[RootSignature("")]
2833
float4 main() : SV_Target {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %dxc -Emain -Tvs_6_0 %s | %opt -S -hlsl-dxil-debug-instrumentation,parameter0=1,parameter1=2 -viewid-state -hlsl-dxilemit | %FileCheck %s
2+
3+
// CHECK: !dx.viewIdState = !{![[VIEWIDDATA:[0-9]*]]}
4+
5+
// The debug instrumentation will have added SV_InstanceId and SV_VertexId to the input signature for this VS.
6+
// If view id state is correct, then this entry should have expanded to 7 i32s (previously it would have been 2)
7+
// CHECK: ![[VIEWIDDATA]] = !{[7 x i32]
8+
9+
10+
[RootSignature("")]
11+
float4 main() : SV_Position{
12+
return float4(0,0,0,0);
13+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %dxc -Emain -Tps_6_0 %s | %opt -S -hlsl-dxil-debug-instrumentation,parameter0=1,parameter1=2 -viewid-state -hlsl-dxilemit | %FileCheck %s
2+
3+
// CHECK: !dx.viewIdState = !{![[VIEWIDDATA:[0-9]*]]}
4+
5+
// The debug instrumentation will have added SV_Position to the input signature for this PS.
6+
// If view id state is correct, then this entry should have expanded to 6 i32s (previously it would have been 4)
7+
// CHECK: ![[VIEWIDDATA]] = !{[6 x i32]
8+
9+
10+
struct VS_OUTPUT {
11+
float2 Tex : TEXCOORD0;
12+
};
13+
14+
float4 main(VS_OUTPUT input) : SV_Target {
15+
return input.Tex.xyxy;
16+
}

tools/clang/test/HLSLFileCheck/pix/DebugVSParameters.hlsl

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %dxc -Emain -Tvs_6_0 %s | %opt -S -hlsl-dxil-debug-instrumentation,parameter0=1,parameter1=2 | %FileCheck %s
1+
// RUN: %dxc -Emain -Tvs_6_0 %s | %opt -S -hlsl-dxil-debug-instrumentation,parameter0=1,parameter1=2 -hlsl-dxilemit | %FileCheck %s
22

33
// Check that the instance and vertex id are parsed and present:
44

@@ -9,7 +9,15 @@
99
// CHECK: %CompareToInstanceId = icmp eq i32 %InstanceId, 2
1010
// CHECK: %CompareBoth = and i1 %CompareToVertId, %CompareToInstanceId
1111

12-
12+
// Check that the correct metadata was emitted for vertex id and instance id.
13+
// They should have 1 row, 1 column each. Vertex ID first at row 0, then instnce at row 1.
14+
// (With each row have the same value as the corresponding ID)
15+
// See DxilMDHelper::EmitSignatureElement for the meaning of these entries:
16+
// ID TypeU32 SemKin Sem-Idx interp Rows Cols Row Col
17+
// | | | | | | | | |
18+
// CHECK: = !{i32 0, !"SV_VertexID", i8 5, i8 1, ![[VIDID:[0-9]*]], i8 1, i32 1, i8 1, i32 0, i8 0,
19+
// | | | | | | | | |
20+
// CHECK: = !{i32 1, !"SV_InstanceID", i8 5, i8 2, ![[IID:[0-9]*]], i8 1, i32 1, i8 1, i32 1, i8 0,
1321
[RootSignature("")]
1422
float4 main() : SV_Position{
1523
return float4(0,0,0,0);

0 commit comments

Comments
 (0)