@@ -56,3 +56,119 @@ bool InRange(BlasAddressRange addressRange, GPUAddress address)
56
56
// This might cause device hang but at least we won't access incorrect addresses
57
57
instanceDescs[dispatchGroup.x].blasAddress = 0 ;
58
58
}
59
+
60
+ struct StateObjectLookup
61
+ {
62
+ uint2 id; // ResourceId
63
+ uint offset;
64
+ };
65
+
66
+ StructuredBuffer<StateObjectLookup> stateObjects : register (t0);
67
+
68
+ struct RecordData
69
+ {
70
+ uint4 identifier[2 ]; // 32-byte real identifier
71
+ uint rootSigIndex; // only lower 16-bits are valid
72
+ };
73
+
74
+ StructuredBuffer<RecordData> records : register (t1);
75
+
76
+ struct RootSig
77
+ {
78
+ uint numHandles;
79
+ uint handleOffsets[MAX_LOCALSIG_HANDLES];
80
+ };
81
+
82
+ StructuredBuffer<RootSig> rootsigs : register (t2);
83
+
84
+ struct WrappedRecord
85
+ {
86
+ uint2 id; // ResourceId
87
+ uint index;
88
+ };
89
+
90
+ RWByteAddressBuffer bufferToPatch : register (u0);
91
+
92
+ void PatchTable (uint byteOffset)
93
+ {
94
+ // load our wrapped record from the start of the table
95
+ WrappedRecord wrappedRecord;
96
+ wrappedRecord.id = bufferToPatch.Load2 (byteOffset);
97
+ wrappedRecord.index = bufferToPatch.Load (byteOffset + 8 );
98
+
99
+ // find the state object it came from
100
+ int i = 0 ;
101
+ StateObjectLookup objectLookup;
102
+ do
103
+ {
104
+ objectLookup = stateObjects[i];
105
+
106
+ if (objectLookup.id.x == wrappedRecord.id.x && objectLookup.id.y == wrappedRecord.id.y)
107
+ break ;
108
+
109
+ // terminate when the lookup is empty, we're out of state objects
110
+ } while (objectLookup.id.x != 0 || objectLookup.id.y != 0 );
111
+
112
+ // if didn't find a match, set a NULL shader identifier. This will fail if it's raygen but others
113
+ // will in theory not crash.
114
+ if (objectLookup.id.x == 0 && objectLookup.id.y == 0 )
115
+ {
116
+ bufferToPatch.Store4 (byteOffset, uint4 (0 , 0 , 0 , 0 ));
117
+ bufferToPatch.Store4 (byteOffset + 16 , uint4 (0 , 0 , 0 , 0 ));
118
+ return ;
119
+ }
120
+
121
+ // the exports from this state object are contiguous starting from the given index, look up this
122
+ // identifier's export
123
+ RecordData recordData = records[objectLookup.offset + wrappedRecord.index];
124
+
125
+ // store the unwrapped shader identifier
126
+ bufferToPatch.Store4 (byteOffset, recordData.identifier[0 ]);
127
+ bufferToPatch.Store4 (byteOffset + 16 , recordData.identifier[1 ]);
128
+
129
+ if (recordData.rootSigIndex & 0xffff != 0xffff )
130
+ {
131
+ RootSig sig = rootsigs[recordData.rootSigIndex];
132
+
133
+ for (int i = 0 ; i < sig.numHandles; i++)
134
+ {
135
+ // TODO: patch descriptor handle at offset sig.handleOffsets[i]
136
+ }
137
+ }
138
+ }
139
+
140
+ // Each SV_GroupId corresponds to one shader record to patch
141
+ [numthreads (1 , 1 , 1 )] void RENDERDOC_PatchRayDispatchCS (uint3 dispatchGroup
142
+ : SV_GroupId ) {
143
+ uint group = dispatchGroup.x;
144
+
145
+ if (group == 0 )
146
+ {
147
+ PatchTable (0 );
148
+ return ;
149
+ }
150
+
151
+ group--;
152
+
153
+ if (group < raydispatch_misscount)
154
+ {
155
+ PatchTable (raydispatch_missoffs + raydispatch_missstride * group);
156
+ return ;
157
+ }
158
+
159
+ group -= raydispatch_misscount;
160
+
161
+ if (group < raydispatch_hitcount)
162
+ {
163
+ PatchTable (raydispatch_hitoffs + raydispatch_hitstride * group);
164
+ return ;
165
+ }
166
+
167
+ group -= raydispatch_hitcount;
168
+
169
+ if (group < raydispatch_callcount)
170
+ {
171
+ PatchTable (raydispatch_calloffs + raydispatch_callstride * group);
172
+ return ;
173
+ }
174
+ }
0 commit comments