D3D12错误:基于GPU的验证:绘制,访问未初始化的根参数着色器阶段:PIXEL,根参数索引:[1]

问题描述

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

解决方法

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

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

它是从D3D12HelloTexture示例复制而来的,但在我的程序中有很多错误。

我为后期处理着色器使用了易失性常量缓冲区,一些静态纹理和易失性渲染纹理。因此,根签名的资源部分如下所示:

CD3DX12_DESCRIPTOR_RANGE1 ranges[2] = {};
ranges[0].Init( D3D12_DESCRIPTOR_RANGE_TYPE_SRV,4,D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC,0 );
ranges[1].Init( D3D12_DESCRIPTOR_RANGE_TYPE_SRV,1,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 []插槽。

已解决,现在可以正常运行。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...