SetGraphicsRootDescriptorTable дает неоднозначную ошибку - PullRequest
0 голосов
/ 08 июня 2018

Один из моих вызовов SetGraphicsRootDescriptorTable возвращает следующую ошибку:

D3D12 ОШИБКА: CGraphicsCommandList :: SetGraphicsRootDescriptorTable: куча дескриптора (дескриптор 0x052184B0f0: 0) 0_0_0 0отличается от текущей установленной кучи дескриптора (null).[ОШИБКА ИСПОЛНЕНИЯ # 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());

1 Ответ

0 голосов
/ 08 июня 2018

установленная куча дескриптора (ноль)

Кажется, это ключ.Вы звонили 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. Если вы этого не сделаете, вам стоит взглянуть на эти руководства .Если да, то вам может пригодиться DirectX Tool Kit для DX12 .Существует также серия образцов вводной графики для Xbox-ATG-Graphics , которые охватывают как DirectX 11, так и DirectX 12.

DirectX 12 ставит приложение во главе, поэтому отладкаочень сложныйТаким образом, вы действительно должны освоить отладку DirectX 11, иначе у вас возникнут проблемы с производительностью.

...