DirectX-12 — Как использовать список команд с несколькими кучами дескрипторов?

В настоящее время, просматривая примеры microsofts, следует отметить, что в каждом списке команд используется только одна куча cbv_srv_uav (+ возможно в дополнительной куче сэмплера).

Можно ли использовать несколько куч к одному списку команд?

Так что я настроил кучу и диапазоны

this->mRSVHeap = new urd::DescriptorHeap(
*this->mDevice,
urd::DescriptorHeapType::CBV_SRV_UAV,
1, // shader visible
2); // space for 2 descriptors (2 textures)

this->mConstHeap = new urd::DescriptorHeap(
*this->mDevice,
urd::DescriptorHeapType::CBV_SRV_UAV,
1, // shader visible
1); // space for 1 descriptor

urd::DescriptorRange ranges[3];
ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0); // first and second descriptor in rsv heap (t0, t1)
ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); // first descriptor in cbv heap (b0)
ranges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 2); // same texture used as first range (again first descriptor in rsv, accessable by t2)

после этого я определяю таблицы дескрипторов

rootParam[0].InitDescTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL);
rootParam[1].InitDescTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_ALL);
rootParam[2].InitDescTable(1, &ranges[2], D3D12_SHADER_VISIBILITY_PIXEL);

Поэтому я создаю shaderResourceViews для текстуры 1 и 2 со смещением процессора 0 и 1 в куче rsv и с постоянным буфером просмотра для константного буфера со смещением процессора 0 в куче cbv

как это:

D3D12_CPU_DESCRIPTOR_HANDLE handle = this->ConstHeap->GetCPUDescriptorHandleForHeapStart();
handle.ptr += index * SIZE_OF_ONE_DESCRIPTOR_CBV_SRV_UAV_TYPE;
CreateConstantBufferView(&desc, handle)

теперь пришло время сказать командному списку, чтобы он ссылался на эти кучи

ID3D12DescriptorHeap* ppHeaps[] = { this->mRSVHeap.Get(), this->mConstHeap.Get() };
this->mCommandList->GetRef()->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps);

после этого закрытие списка команд всегда выдает.

ThrowIfFailed(this->mCommandList->Close());

Вот как я говорю командному списку, какая куча для какой таблицы:

this->mCommandList->GetRef()->SetGraphicsRootDescriptorTable(0, this->mRSVHeap->GetGPUHeapAddressAtOffset(0));
this->mCommandList->GetRef()->SetGraphicsRootDescriptorTable(1, this->mConstHeap->GetGPUHeapAddressAtOffset(0));
this->mCommandList->GetRef()->SetGraphicsRootDescriptorTable(2, this->mRSVHeap->GetGPUHeapAddressAtOffset(0));

Это прекрасно работает, если я опишу все объекты в одну кучу дескрипторов (как в примерах) и просто использую разные смещения этой кучи.

Отладочный вывод:

D3D12 ОШИБКА: ID3D12CommandList :: SetDescriptorHeaps: pDescriptorHeaps [1] устанавливает тип кучи дескриптора, который появляется ранее в массиве pDescriptorHeaps. Только один из любого данного типа кучи дескриптора может быть установлен за один раз. [ИСПОЛНЕНИЕ ОШИБКИ № 554: SET_DESCRIPTOR_HEAP_INVALID] D3D12 ОШИБКА: CCommandList :: SetGraphicsRootDescriptorTable: в данный момент в списке команд не задана куча дескриптора CBV_SRV_UAV, поэтому установка таблицы корневых дескрипторов дескрипторов CBV_SRV_UAV недопустима. [ИСПОЛНЕНИЕ ОШИБКИ № 708: SET_DESCRIPTOR_TABLE_INVALID] D3D12 ОШИБКА: CCommandList :: SetGraphicsRootDescriptorTable: в данный момент в списке команд не задана куча дескриптора CBV_SRV_UAV, поэтому установка таблицы корневых дескрипторов дескрипторов CBV_SRV_UAV недопустима. [ИСПОЛНЕНИЕ ОШИБКИ № 708: SET_DESCRIPTOR_TABLE_INVALID] D3D12 ОШИБКА: CCommandList :: SetGraphicsRootDescriptorTable: в данный момент в списке команд не задана куча дескриптора CBV_SRV_UAV, поэтому установка таблицы корневых дескрипторов дескрипторов CBV_SRV_UAV недопустима. [ИСПОЛНЕНИЕ ОШИБКИ № 708: SET_DESCRIPTOR_TABLE_INVALID]

2

Решение

Ограничение заключается в том, что в каждый момент времени может быть установлена ​​только одна куча каждого типа (CBV / SRV / UAV и Samplers). Таким образом, только две кучи дескриптора могут быть установлены одновременно.

Тем не менее, важно отметить, что набор куч дескрипторов может меняться в списке команд.

6

Другие решения


По вопросам рекламы [email protected]