In a compute shader in Direct X 12 (cs_5_1 profile) I am using dynamic indexing of RWStructuredBuffer types. When accessing the resource in the shader using the dynamic index as shown in the code below:
/**
* Inputs that are passed to a compute shader.
*/
struct ComputeShaderInput
{
uint3 GroupID : SV_GroupID; // 3D index of the thread group in the dispatch.
uint3 GroupThreadID : SV_GroupThreadID; // 3D index of local thread ID in a thread group.
uint3 DispatchThreadID : SV_DispatchThreadID; // 3D index of global thread ID in the dispatch.
uint GroupIndex : SV_GroupIndex; // Flattened local index of the thread within a thread group.
};
RWTexture2D<float4> DebugTexture : register( u0 );
// Global counter for current index into the light index list.
RWStructuredBuffer<uint> PointLightIndexCounter[2] : register( u1 );
#define TestShader_RootSignature \
"RootFlags(0)," \
"DescriptorTable(UAV(u0, numDescriptors=3))"
[RootSignature( TestShader_RootSignature )]
[numthreads( 16, 16, 1 )]
void main( ComputeShaderInput IN )
{
int2 texCoord = IN.DispatchThreadID.xy;
uint pointLightIndexCounter0 = PointLightIndexCounter[0][0];
uint pointLightIndexCounter1 = PointLightIndexCounter[1][0];
DebugTexture[texCoord] = float4( pointLightIndexCounter0, pointLightIndexCounter1, 0, 1 );
}
Then the Debug validation layer generates an error:
D3D12: Removing Device.
D3D12 ERROR: ID3D12Device::RemoveDevice: Device removal has been triggered for the following reason (DXGI_ERROR_DEVICE_HUNG: The Device took an unreasonable amount of time to execute its commands, or the hardware crashed/hung. As a result, the TDR (Timeout Detection and Recovery) mechanism has been triggered. The current Device Context was executing commands when the hang occurred. The application may want to respawn and fallback to less aggressive use of the display hardware). [ EXECUTION ERROR #232: DEVICE_REMOVAL_PROCESS_AT_FAULT]
If I change the shader to not use dynamic index of the resources:
/**
* Inputs that are passed to a compute shader.
*/
struct ComputeShaderInput
{
uint3 GroupID : SV_GroupID; // 3D index of the thread group in the dispatch.
uint3 GroupThreadID : SV_GroupThreadID; // 3D index of local thread ID in a thread group.
uint3 DispatchThreadID : SV_DispatchThreadID; // 3D index of global thread ID in the dispatch.
uint GroupIndex : SV_GroupIndex; // Flattened local index of the thread within a thread group.
};
RWTexture2D<float4> DebugTexture : register( u0 );
// Global counter for current index into the light index list.
RWStructuredBuffer<uint> PointLightIndexCounter0 : register( u1 );
RWStructuredBuffer<uint> PointLightIndexCounter1 : register( u2 );
#define TestShader_RootSignature \
"RootFlags(0)," \
"DescriptorTable(UAV(u0, numDescriptors=3))"
[RootSignature( TestShader_RootSignature )]
[numthreads( 16, 16, 1 )]
void main( ComputeShaderInput IN )
{
int2 texCoord = IN.DispatchThreadID.xy;
uint pointLightIndexCounter0 = PointLightIndexCounter0[0];
uint pointLightIndexCounter1 = PointLightIndexCounter1[0];
DebugTexture[texCoord] = float4( pointLightIndexCounter0, pointLightIndexCounter1, 0, 1 );
}
(Note the changes on lines 15, 16 and 28, 29) Then everything works fine.
I’ve also run the D3D12DynamicIndexing sample in the Microsfot DirectX Samples on GitHub (https://github.com/Microsoft/DirectX-Graphics-Samples/tree/master/Samples/Desktop/D3D12DynamicIndexing/src) which seems to work fine which leads me to believe that this is only an issue for the cs_5_1 profile.
I am running Windows 10 (build 14332) with NVIDIA GeForce GTX Titan X and driver version 365.19.