четверг, 8 октября 2015 г.

D3D12. Немного про Descriptors Tables.

Детали, собранные из разных мест MSDN
картинка из MSDN
Виды Descriptor Heap-ов:
Code Snippet
  1. typedef enum D3D12_DESCRIPTOR_HEAP_TYPE
  2. {
  3.     D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
  4.     D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
  5.     D3D12_DESCRIPTOR_HEAP_TYPE_RTV,
  6.     D3D12_DESCRIPTOR_HEAP_TYPE_DSV,
  7.     D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES
  8. } D3D12_DESCRIPTOR_HEAP_TYPE;

Constant Buffer View, Shader Resource View и Unordered Access View можно комбинировать в одной куче.
Создается куча методом:
Code Snippet
  1. HRESULT ID3D12Device::CreateDescriptorHeap(...)
В Descriptor Heap хранятся Descriptor Handle. Его размер зависит от типа кучи.
Code Snippet
  1. HRESULT ID3D12Device::GetDescriptorHandleIncrementSize(...)
Handle-ы бывают GPU- и CPU-side:
Code Snippet
  1. D3D12_CPU_DESCRIPTOR_HANDLE cpuDescriptorHandle = m_DescriptorHeap->GetCPUDescriptorHandleForHeapStart();
  2. D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle = m_DescriptorHeap->GetGPUDescriptorHandleForHeapStart();
Для получения Descriptor Handle-а с индексом idx достаточно передвинуть его указатель (подходит и для CPU Descriptor Handle и GPU Descriptor Handle):
Code Snippet
  1. descriptorHandle.ptr += idx * descriptorHandleIncrementSize;
Descriptor Handle используется, например, (1) при создании различных View (CPU Descriptor):
Code Snippet
  1. HRESULT ID3D12Device::CreateConstantBufferView(...)
(2) при очистке Render Target-ов:
Code Snippet
  1. HRESULT ID3D12GraphicsCommandList::ClearRenderTargetView(...)
(3) при назначении Descriptor Table (просто непрерывная последовательность Descriptor Handle-ов в Descriptor Heap-е) для доступа шейдера к ресурсам
Code Snippet
  1. HRESULT ID3D12GraphicsCommandList::SetGraphicsRootDescriptorTable(...)
После того, как CommandList был отправлен на выполнение, нельзя модифицировать Descriptor Table не убедившись, что GPU закончил с ними работать. (Fences)
Шейдеры "видят" HEAP_TYPE_CBV_SRV_UAV и HEAP_TYPE_SAMPLER. Одновременно "активными" могут быть только по одной куче каждого из этих двух типов:
Code Snippet
  1. HRESULT ID3D12GraphicsCommandList::SetDescriptorHeaps(...)
При вызове SetGraphicsRootDescriptorTable таблицы назначаются с указанием RootParameterIndex - это индекс Root Parameter-а инициализированного как DescriptorTable. Например:
Code Snippet
  1. const int ranges_num = 2;
  2. const int parameters_num = 2;
  3. CD3DX12_DESCRIPTOR_RANGE ranges[ranges_num];
  4. ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0);
  5. ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
  6.  
  7. CD3DX12_ROOT_PARAMETER rootParameters[parameters_num];
  8. rootParameters[0].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL);
  9. rootParameters[1].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_VERTEX);
Потом при заполнении Command List-а вызываем 2 раза SetGraphicsRootDescriptorTable (указываем 2 таблицы из одной кучи. 1-я c SRV Descriptor-ми, вторая с CBV Descriptor-ми):
Code Snippet
  1. m_commandList->SetGraphicsRootDescriptorTable(0, m_SRV_CBR_DescriptorsHeap.GetGPUDescriptorHandleForHeapStart());
Code Snippet
  1. D3D12_GPU_DESCRIPTOR_HANDLE gpuCBVdescriptor = m_SRV_CBR_DescriptorsHeap.GetGPUDescriptorHandleForHeapStart();
  2. gpuCBVdescriptor.ptr += 2 * m_SRV_CBR_DescriptorsHeap.GetDescriptorIncrementSize();
  3. m_commandList->SetGraphicsRootDescriptorTable(1, gpuCBVdescriptor);

И в шейдере можно получить доступ к ресурсам указав нужные регистры:
Code Snippet
  1. Texture2D g_texture : register(t0);
  2. cbuffer g_constants: register(b0)
  3. {
  4.     float4 offset;
  5. }

Про наследование состояния:

  • Descriptor Table State неопределен в начале записи Command List-а и после того, как меняется Descriptors Heaps в Command List-е.
  • Повторное назначение того же самого Descriptors Heap-а не приводит к неопределенному состоянию Descriptors Table State.
  • В Draw Bundle назначать Descriptors Heaps можно только 1 раз. (Повторное назначение тех же самых куч не приводит к ошибке).

Комментариев нет:

Отправить комментарий