Skip to content

Commit 080aeb7

Browse files
authored
PIX: Implement shader access tracking for descriptor-heap-indexed TLAS for TraceRay (microsoft#6950)
Simple missing case, should have implemented it in the first place. Also noticed that from a recent change to move to raw buffer writes, the debug output UAV offset was being set to a non-dword aligned offset. No drivers/hardware seem to care, but it's a concerning thing to leave as-is.
1 parent b26fd80 commit 080aeb7

File tree

4 files changed

+89
-5
lines changed

4 files changed

+89
-5
lines changed

lib/DxilPIXPasses/DxilDebugInstrumentation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -795,12 +795,12 @@ void DxilDebugInstrumentation::determineLimitANDAndInitializeCounter(
795795
auto *PHIForCounterOffset =
796796
BC.Builder.CreatePHI(Type::getInt32Ty(BC.Ctx), 2, "PIXCounterLocation");
797797
const uint32_t InterestingCounterOffset =
798-
static_cast<uint32_t>(m_UAVSize / 2 - 1);
798+
static_cast<uint32_t>(m_UAVSize / 2 - sizeof(uint32_t));
799799
PHIForCounterOffset->addIncoming(
800800
BC.HlslOP->GetU32Const(InterestingCounterOffset),
801801
InterestingInvocationBlock);
802802
const uint32_t UninterestingCounterOffsetValue =
803-
static_cast<uint32_t>(m_UAVSize - 1);
803+
static_cast<uint32_t>(m_UAVSize - sizeof(uint32_t));
804804
PHIForCounterOffset->addIncoming(
805805
BC.HlslOP->GetU32Const(UninterestingCounterOffsetValue),
806806
NonInterestingInvocationBlock);

lib/DxilPIXPasses/DxilShaderAccessTracking.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -980,9 +980,17 @@ bool DxilShaderAccessTracking::runOnModule(Module &M) {
980980
case DXIL::OpCode::BufferUpdateCounter:
981981
readWrite = ShaderAccessFlags::Counter;
982982
break;
983-
case DXIL::OpCode::TraceRay:
983+
case DXIL::OpCode::TraceRay: {
984984
// Read of AccelerationStructure; doesn't match function attribute
985-
// readWrite = ShaderAccessFlags::Read; // TODO: Support
985+
auto res = GetResourceFromHandle(Call->getArgOperand(1), DM);
986+
if (res.accessStyle == AccessStyle::None) {
987+
continue;
988+
}
989+
if (EmitResourceAccess(DM, res, Call, HlslOP, Ctx,
990+
ShaderAccessFlags::Read)) {
991+
Modified = true;
992+
}
993+
}
986994
continue;
987995
case DXIL::OpCode::RayQuery_TraceRayInline: {
988996
// Read of AccelerationStructure; doesn't match function attribute
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// RUN: %dxc -T lib_6_6 %s | %opt -S -hlsl-dxil-pix-shader-access-instrumentation,config=.256;512;1024. | %FileCheck %s
2+
3+
// This file is checking for the correct access tracking for a descriptor-heap-indexed TLAS for TraceRay.
4+
5+
// First advance through the output text to where the handle for heap index 7 is created:
6+
// CHECK: call %dx.types.Handle @dx.op.createHandleFromHeap(i32 218, i32 7
7+
8+
// The next buffer store should be for this resource.
9+
// See DxilShaderAccessTracking::EmitResourceAccess for how this index is calculated.
10+
// It's the descriptor heap index (7, as seen in the HLSL below) plus 1 (to skip
11+
// over the "out-of-bounds" entry in the output UAV) times 8 DWORDs per record
12+
// (the first DWORD for write, the second for read), plus 4 to offset to the "read" record.
13+
// Read access for descriptor 7 is therefore at (7+1)*8+4 = 68.
14+
// This is then added to the base address for dynamic writes, which is 256
15+
// (from the config=.256 in the command-line above), for a total of 324.
16+
17+
// CHECK: call void @dx.op.bufferStore.i32(i32 69, %dx.types.Handle %[[UAV:[0-9+]]], i32 324,
18+
19+
RWTexture2D<float4> RTOutput : register(u0);
20+
21+
struct PayloadData
22+
{
23+
uint index : INDEX;
24+
};
25+
26+
struct AttributeData
27+
{
28+
float2 barycentrics;
29+
};
30+
31+
struct ColorConstant
32+
{
33+
uint3 color;
34+
};
35+
36+
struct AlphaConstant
37+
{
38+
uint alpha;
39+
};
40+
41+
42+
ConstantBuffer<ColorConstant> color : register(b0);
43+
ConstantBuffer<AlphaConstant> alpha : register(b1);
44+
45+
[shader("raygeneration")]
46+
void RayGenMain()
47+
{
48+
uint2 index = DispatchRaysIndex().xy;
49+
uint2 dim = DispatchRaysDimensions().xy;
50+
51+
PayloadData payload;
52+
payload.index = index.y * dim.x + index.x;
53+
54+
RayDesc ray;
55+
ray.Origin.x = 2.0 * (index.x + 0.5) / dim.x - 1.0;
56+
ray.Origin.y = 1.0 - 2.0 * (index.y + 0.5) / dim.y;
57+
ray.Origin.z = 0.0;
58+
ray.Direction = float3(0, 0, -1);
59+
ray.TMin = 0.01;
60+
ray.TMax = 100.0;
61+
62+
RaytracingAccelerationStructure scene = ResourceDescriptorHeap[7];
63+
64+
TraceRay(
65+
scene, // Acceleration structure
66+
0, // Ray flags
67+
0xFF, // Instance inclusion mask
68+
0, // RayContributionToHitGroupIndex
69+
1, // MultiplierForGeometryContributionToHitGroupIndex
70+
0, // MissShaderIndex
71+
ray,
72+
payload);
73+
74+
RTOutput[index] = float4(color.color.r / 255.0f, color.color.g / 255.0f, color.color.b / 255.0f, alpha.alpha / 255.0f);
75+
}
76+

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
// Check for branches-for-interest and AND value and counter location for a UAV size of 128
1717
// CHECK: br i1 %ComparePos, label %PIXInterestingBlock, label %PIXNonInterestingBlock
1818
// CHECK: %PIXOffsetOr = phi i32 [ 0, %PIXInterestingBlock ], [ 64, %PIXNonInterestingBlock ]
19-
// CHECK: %PIXCounterLocation = phi i32 [ 63, %PIXInterestingBlock ], [ 127, %PIXNonInterestingBlock ]
19+
// CHECK: %PIXCounterLocation = phi i32 [ 60, %PIXInterestingBlock ], [ 124, %PIXNonInterestingBlock ]
2020

2121
// Check the first block header was emitted: (increment, AND + OR)
2222
// CHECK: call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %PIX_DebugUAV_Handle, i32 0

0 commit comments

Comments
 (0)