SetGraphicsRootDescriptorTable给出了模糊错误

时间:2018-06-08 16:20:45

标签: 3d directx-12

我对 SetGraphicsRootDescriptorTable 的一次调用会返回以下错误:

  

D3D12错误:CGraphicsCommandList :: SetGraphicsRootDescriptorTable:包含句柄0x0546DDE0的描述符堆(0x052184B0:'m_lightBufHeap')与当前设置的描述符堆(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);

这是我创建根签名参数的方法(param 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());

1 个答案:

答案 0 :(得分:1)

  

当前设置描述符堆(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是专业图形API,假设您已经了解DirectX 11.如果不这样做,您应该真正了解these tutorials。如果是,您可能会发现DirectX Tool Kit for DX12很有用。 Xbox-ATG-Graphics上还有一系列介绍性图形样本,涵盖DirectX 11和DirectX 12。

     

DirectX 12使应用程序负责很多,因此调试非常具有挑战性。因此,您应该真正掌握DirectX 11调试,否则您将遇到高效问题。