SetGraphicsRootDescriptorTable 给出不明确的错误
SetGraphicsRootDescriptorTable gives ambiguous error
我的一个调用 SetGraphicsRootDescriptorTable returns 出现以下错误:
D3D12 ERROR: CGraphicsCommandList::SetGraphicsRootDescriptorTable: The descriptor heap (0x052184B0:'m_lightBufHeap') containing handle 0x0546DDE0 is different from currently set descriptor heap (null). [ EXECUTION ERROR #708: SET_DESCRIPTOR_TABLE_INVALID]
我不明白它想告诉我什么。到底有什么不同,为什么会出现问题?
更改我尝试设置的描述符堆的内容似乎无法解决任何问题。
我减小了描述符堆的大小以仅容纳 1 个元素。
这就是我创建描述符堆的方式:
D3D12_DESCRIPTOR_HEAP_DESC heapDsc = {};
heapDsc.NumDescriptors = 1;
heapDsc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
heapDsc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
ThrowIfFailed(pDevice->CreateDescriptorHeap(&heapDsc, IID_PPV_ARGS(&m_lightBufHeap)));
NAME_D3D12_OBJECT(m_lightBufHeap);
这是我创建根签名参数的方式(参数 4 是我的缓冲区):
CD3DX12_DESCRIPTOR_RANGE1 ranges[5];
ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 1, 0, D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC);
ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 0, D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC);
ranges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);
ranges[3].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 2, 0);
ranges[4].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 3, 0, D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); // parameter 4, t3
CD3DX12_ROOT_PARAMETER1 rootParameters[5];
rootParameters[0].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL);
rootParameters[1].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_ALL);
rootParameters[2].InitAsDescriptorTable(1, &ranges[2], D3D12_SHADER_VISIBILITY_PIXEL);
rootParameters[3].InitAsDescriptorTable(1, &ranges[3], D3D12_SHADER_VISIBILITY_PIXEL);
rootParameters[4].InitAsDescriptorTable(1, &ranges[4], D3D12_SHADER_VISIBILITY_ALL);
CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc;
rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
这就是我创建着色器资源视图的方式:
CD3DX12_CPU_DESCRIPTOR_HANDLE lightHeapHandle(m_lightBufHeap->GetCPUDescriptorHandleForHeapStart());
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.Buffer.FirstElement = 0;
srvDesc.Buffer.NumElements = lights.size();
srvDesc.Buffer.StructureByteStride = sizeof(LightStruct);
pDevice->CreateShaderResourceView(m_lightsBuffer.Get(), &srvDesc, lightHeapHandle);
缓冲区 m_lightsBuffer 似乎没问题,我也尝试用有效的 Texture2D 填充描述符堆,结果相同。所以它不是来自缓冲区。
这是我的着色器声明缓冲区的方式:
StructuredBuffer<LightBlob> lightBlobs : register(t3);
在我的命令列表中调用:
//Parameter 4 in root signature
pSceneCommandList->SetGraphicsRootDescriptorTable(4, m_lightBufHeap->GetGPUDescriptorHandleForHeapStart());
currently set descriptor heap (null)
这似乎是线索。在提交您的命令列表之前,您是否曾致电 SetDescriptorHeaps
?
DirectX 12 的典型绘制代码是:
commandList->SetGraphicsRootSignature(m_rootSignature.Get());
commandList->SetPipelineState(m_pipelineState.Get());
auto heap = m_srvHeap.Get();
commandList->SetDescriptorHeaps(1, &heap);
commandList->SetGraphicsRootDescriptorTable(0,
m_srvHeap->GetGPUDescriptorHandleForHeapStart());
// Set necessary state.
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView);
commandList->IASetIndexBuffer(&m_indexBufferView);
// Draw quad.
commandList->DrawIndexedInstanced(6, 1, 0, 0, 0);
DirectX 12 is an expert graphics API that assumes you already know DirectX 11. If you don't, you should really take a look at these tutorials. If you are, you might find the DirectX Tool Kit for DX12 useful. There are also a series of Introductory Graphics samples on Xbox-ATG-Graphics which cover both DirectX 11 and DirectX 12.
DirectX 12 puts the application in charge of a lot, so debugging is very challenging. As such, you should really have mastered DirectX 11 debugging or you'll have problems being productive.
我的一个调用 SetGraphicsRootDescriptorTable returns 出现以下错误:
D3D12 ERROR: CGraphicsCommandList::SetGraphicsRootDescriptorTable: The descriptor heap (0x052184B0:'m_lightBufHeap') containing handle 0x0546DDE0 is different from currently set descriptor heap (null). [ EXECUTION ERROR #708: SET_DESCRIPTOR_TABLE_INVALID]
我不明白它想告诉我什么。到底有什么不同,为什么会出现问题?
更改我尝试设置的描述符堆的内容似乎无法解决任何问题。
我减小了描述符堆的大小以仅容纳 1 个元素。
这就是我创建描述符堆的方式:
D3D12_DESCRIPTOR_HEAP_DESC heapDsc = {};
heapDsc.NumDescriptors = 1;
heapDsc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
heapDsc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
ThrowIfFailed(pDevice->CreateDescriptorHeap(&heapDsc, IID_PPV_ARGS(&m_lightBufHeap)));
NAME_D3D12_OBJECT(m_lightBufHeap);
这是我创建根签名参数的方式(参数 4 是我的缓冲区):
CD3DX12_DESCRIPTOR_RANGE1 ranges[5];
ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 1, 0, D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC);
ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 0, D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC);
ranges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);
ranges[3].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 2, 0);
ranges[4].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 3, 0, D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC); // parameter 4, t3
CD3DX12_ROOT_PARAMETER1 rootParameters[5];
rootParameters[0].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL);
rootParameters[1].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_ALL);
rootParameters[2].InitAsDescriptorTable(1, &ranges[2], D3D12_SHADER_VISIBILITY_PIXEL);
rootParameters[3].InitAsDescriptorTable(1, &ranges[3], D3D12_SHADER_VISIBILITY_PIXEL);
rootParameters[4].InitAsDescriptorTable(1, &ranges[4], D3D12_SHADER_VISIBILITY_ALL);
CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc;
rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
这就是我创建着色器资源视图的方式:
CD3DX12_CPU_DESCRIPTOR_HANDLE lightHeapHandle(m_lightBufHeap->GetCPUDescriptorHandleForHeapStart());
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.Buffer.FirstElement = 0;
srvDesc.Buffer.NumElements = lights.size();
srvDesc.Buffer.StructureByteStride = sizeof(LightStruct);
pDevice->CreateShaderResourceView(m_lightsBuffer.Get(), &srvDesc, lightHeapHandle);
缓冲区 m_lightsBuffer 似乎没问题,我也尝试用有效的 Texture2D 填充描述符堆,结果相同。所以它不是来自缓冲区。
这是我的着色器声明缓冲区的方式:
StructuredBuffer<LightBlob> lightBlobs : register(t3);
在我的命令列表中调用:
//Parameter 4 in root signature
pSceneCommandList->SetGraphicsRootDescriptorTable(4, m_lightBufHeap->GetGPUDescriptorHandleForHeapStart());
currently set descriptor heap (null)
这似乎是线索。在提交您的命令列表之前,您是否曾致电 SetDescriptorHeaps
?
DirectX 12 的典型绘制代码是:
commandList->SetGraphicsRootSignature(m_rootSignature.Get());
commandList->SetPipelineState(m_pipelineState.Get());
auto heap = m_srvHeap.Get();
commandList->SetDescriptorHeaps(1, &heap);
commandList->SetGraphicsRootDescriptorTable(0,
m_srvHeap->GetGPUDescriptorHandleForHeapStart());
// Set necessary state.
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView);
commandList->IASetIndexBuffer(&m_indexBufferView);
// Draw quad.
commandList->DrawIndexedInstanced(6, 1, 0, 0, 0);
DirectX 12 is an expert graphics API that assumes you already know DirectX 11. If you don't, you should really take a look at these tutorials. If you are, you might find the DirectX Tool Kit for DX12 useful. There are also a series of Introductory Graphics samples on Xbox-ATG-Graphics which cover both DirectX 11 and DirectX 12.
DirectX 12 puts the application in charge of a lot, so debugging is very challenging. As such, you should really have mastered DirectX 11 debugging or you'll have problems being productive.