0

这花了我一段时间才成为 D3D12 新手,但我没有在网上找到任何东西。着色器编译得很好,获得了所有资源,但输出一直是黑色的。在将调试级别设置为最大值并启用 GPU 验证后,我收到了错误消息,然后是某种汇编程序跟踪和操作数转储。

4

1 回答 1

0

如果您在 RootSignature 中设置了根参数,而不是为渲染循环中的每个插槽设置了 SetGraphicsRootDescritporTable() 或 SetGraphicsRootConstantBufferView() 或类似参数,则会引发此错误。不小心只写了

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

它是从 D3D12HelloTexture 示例中复制的,并且在我的程序的许多方面都出错了。

我为后期处理着色器使用了一个 volatile 常量缓冲区、几个静态纹理和一个 volatile 渲染纹理。所以根签名的资源部分如下所示:

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 );

我所有的 SRV 都适合同一个描述符表,但具有不同的访问标志。所以我们需要2个范围。注意:描述符范围(表)的最后一个参数是您的 DescriptorHeap 中的偏移量。您需要确保每个描述符都有自己的索引。这对应于 GPU 上 DescriptorHeap 中的 GetDescriptorHandleIncrementSize 插槽。确保在稍后 CreateShaderResourceView 时使用这些值:

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 直接进入根描述符以保存一个间接寻址,因此它不在 DescriptorHeap 中,因此我们需要在渲染循环中设置它:

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

注意:第一个参数对应于上面的 rootParameter[] 槽。

现在解决并运行良好。

于 2020-09-16T09:22:12.267 回答