Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions lib/DxilPIXPasses/DxilNonUniformResourceIndexInstrumentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ bool DxilNonUniformResourceIndexInstrumentation::runOnModule(Module &M) {

std::map<Function *, CallInst *> FunctionToUAVHandle;

// Set if any dynamically indexed handle lacks the PIX instruction ordinal
// this pass needs to address its diagnostic.
bool FoundHandleWithoutInstructionNumber = false;

// This is the main pass that will iterate through all of the resources that
// are dynamically indexed. If not already marked NonUniformResourceIndex,
// then insert WaveActiveAllEqual to determine if the index is uniform
Expand All @@ -72,6 +76,16 @@ bool DxilNonUniformResourceIndexInstrumentation::runOnModule(Module &M) {
return true;
}

// Address each diagnostic by the PIX instruction ordinal. Skip a
// handle that has no ordinal instead of writing a record for
// instruction 0.
uint32_t InstructionNumber = 0;
if (!pix_dxil::PixDxilInstNum::FromInst(CreateHandle,
&InstructionNumber)) {
FoundHandleWithoutInstructionNumber = true;
return true;
}

if (!PixUAVResource) {
PixUAVResource =
PIXPassHelpers::CreateGlobalUAVResource(DM, 0, "PixUAVResource");
Expand All @@ -97,12 +111,6 @@ bool DxilNonUniformResourceIndexInstrumentation::runOnModule(Module &M) {

IRBuilder<> Builder(CreateHandle);

uint32_t InstructionNumber = 0;
if (!pix_dxil::PixDxilInstNum::FromInst(CreateHandle,
&InstructionNumber)) {
DXASSERT_NOMSG(false);
}

// The output UAV is treated as a bit array where each bit corresponds
// to an instruction number. This determines what byte offset to write
// our result to based on the instruction number.
Expand Down Expand Up @@ -161,6 +169,11 @@ bool DxilNonUniformResourceIndexInstrumentation::runOnModule(Module &M) {
}
}

if (FoundHandleWithoutInstructionNumber && OSOverride != nullptr) {
formatted_raw_ostream FOS(*OSOverride);
FOS << "\nNuriNotInstrumentedMissingInstructionNumber\n";
}

return modified;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// RUN: %dxc -Emain -Tps_6_0 %s | %opt -S -dxil-annotate-with-virtual-regs -hlsl-dxil-non-uniform-resource-index-instrumentation | %FileCheck %s

// With the annotation prepass in place, the diagnostic is addressed to
// the ordinal of the createHandle that performed the unmarked dynamic
// indexing. The pass encodes that ordinal as a shift. A shift of zero
// aliases the diagnostic onto bit 0.
//
// Match any non-zero shift rather than a literal ordinal. A createHandle
// whose index comes from an interpolated input is never the first
// numbered instruction.
Comment on lines +3 to +10

// CHECK-NOT: NuriNotInstrumentedMissingInstructionNumber
// CHECK: @dx.op.waveActiveAllEqual
// CHECK: shl i32 %{{[0-9]+}}, {{[1-9][0-9]*}}
// CHECK: @dx.op.atomicBinOp.i32(i32 78

Texture2D tex[8] : register(t0);

float4 main(float2 uv : TEXCOORD0) : SV_TARGET
{
uint index = uv.x * uv.y;
return tex[index].Load(int3(0, 0, 0));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// RUN: %dxc -T lib_6_6 -Od %s | %opt -S -dxil-annotate-with-virtual-regs -hlsl-dxil-non-uniform-resource-index-instrumentation | %FileCheck %s

// Coverage for an unmarked dynamic index that stays in a library helper.
// The helper remains a separate function. The diagnostic is addressed to
// a non-zero instruction ordinal.

// CHECK-NOT: NuriNotInstrumentedMissingInstructionNumber
// CHECK: define void {{.*}}IndexInHelper
// CHECK: @dx.op.waveActiveAllEqual
// CHECK: shl i32 %{{[0-9]+}}, {{[1-9][0-9]*}}
// CHECK: @dx.op.atomicBinOp.i32(i32 78

RWTexture2D<float> RT[] : register(u0);

[noinline]
export void IndexInHelper(uint index)
{
float2 rayIndex = DispatchRaysIndex().xy;
RT[index][rayIndex] = 1;
}

[shader("raygeneration")]
void RayGen()
{
IndexInHelper(DispatchRaysIndex().x);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// RUN: %dxc -Emain -Tps_6_0 %s | %opt -S -hlsl-dxil-non-uniform-resource-index-instrumentation | %FileCheck %s

// This pass addresses each diagnostic by the PIX instruction ordinal.
// This RUN line omits the annotation prepass, so no createHandle carries
// an ordinal. The pass leaves the handle uninstrumented and reports the
// missing precondition.
//
// The pass writes its messages to the same stream as the -S module print,
// and writes them before the module, so the message checks come first.

// CHECK-NOT: FoundDynamicIndexingNoNuri
// CHECK: NuriNotInstrumentedMissingInstructionNumber
// CHECK-NOT: @dx.op.waveActiveAllEqual
// CHECK-NOT: @dx.op.atomicBinOp

Texture2D tex[8] : register(t0);

float4 main(float2 uv : TEXCOORD0) : SV_TARGET
{
uint index = uv.x * uv.y;
return tex[index].Load(int3(0, 0, 0));
}
Loading