This took me a while to figure as a D3D12 newbie and I did not find anything searching the web. Shaders compiled fine, all resources acquired but the output kept being black. After setting debug level to max and enabled GPU validation I got the error message, followed by some kind of assembler trace and operand dump.

1

There are 1 answers

1
JKrahmann On

This error is raised if you have set root parameters in your RootSignature and not SetGraphicsRootDescritporTable() or SetGraphicsRootConstantBufferView() or similar for each slot in your render loop. I accidentally wrote only

m_cl->SetGraphicsRootDescriptorTable( 0, m_srvHeap->GetGPUDescriptorHandleForHeapStart() );

which was copied from D3D12HelloTexture example and turned wrong in many ways for my program.

I use a volatile constant buffer, a couple of static textures and a volatile render texture for a post processing shader. So root signature's resource part looks like this:

CD3DX12_DESCRIPTOR_RANGE1 ranges[2] = {};
ranges[0].Init( D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 4, 0, 0, D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC, 0 );
ranges[1].Init( D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 4, 0, D3D12_DESCRIPTOR_RANGE_FLAG_NONE, 4 );
CD3DX12_ROOT_PARAMETER1 rootParameters[2] = {};
rootParameters[0].InitAsConstantBufferView( 0 );
rootParameters[1].InitAsDescriptorTable( _countof( ranges ), ranges, D3D12_SHADER_VISIBILITY_PIXEL );

All my SRVs fit to same descriptor table but have different access flags. So we need 2 ranges. Note: The last parameter for the descriptor range (table) is the offset in your DescriptorHeap. You need to make sure, every descriptor gets it's own index. This corresponds to a slot of GetDescriptorHandleIncrementSize in your DescriptorHeap on GPU. Make sure to use these values, when CreateShaderResourceView later:

ID3D12Resource* textureRes[]{ m_tex1, m_tex2, ... };
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = 1;
SIZE_T descSize = m_device->GetDescriptorHandleIncrementSize( D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV );

for( SIZE_T i = 0; i != _countof( textureRes ); i++ )
{
    m_device->CreateShaderResourceView( textureRes[i], NULL, { m_srvHeap->GetCPUDescriptorHandleForHeapStart().ptr + i * descSize } );
}

CBV goes directly to root descriptor to save one indirection, thus it dosn't live in the DescriptorHeap so we need to set the it in render loop:

ID3D12DescriptorHeap* ppHeaps[] = { m_srvHeap };
m_cl->SetDescriptorHeaps( _countof(ppHeaps) , ppHeaps );
m_cl->SetGraphicsRootConstantBufferView( 0, m_cb->GetGPUVirtualAddress() );
m_cl->SetGraphicsRootDescriptorTable( 1, m_srvHeap->GetGPUDescriptorHandleForHeapStart() );

Note: first parameter corresponds to rootParameter[] slot from above.

Solved and running fine now.