So these days i'm writing a D3D12/Vulkan abstraction for a project and i've hit a wall tackling resource binding. In an older renderer i wrote, i put all of my per-object uniforms into one big Uniform Buffer/Constant Buffer, copied all the data in one go and bound ranges of it using glBindBufferRange (GL) and XSSetConstantBuffers1 (D3D11) for each object in the scene. It seemed to be a more efficient approach than copying between draws.
The same thing can be done in Vulkan by creating a dynamic uniform buffer and providing Dynamic Offsets to vkCmdBindDescriptorSets.
But when it comes to Direct3D 12, i haven't seen an equivalent approach yet. The only thing that i came up with so far is to create multiple ConstantBufferViews for a Constant Buffer into a Descriptor Table and bind it by adding the appropriate offset to the Descriptor Table's address.
// Get the descriptor increment size
const UINT cbvSrvDescriptorSize = pDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
// Handle for the first object's constant buffer view
CD3DX12_GPU_DESCRIPTOR_HANDLE cbvSrvGpuHandle1(pCbvSrvHeap->GetGPUDescriptorHandleForHeapStart(), 0);
pCommandList->SetGraphicsRootDescriptorTable(0, cbvSrvGpuHandle1);
// Draw first object...
// Add offset to get the handle for the second object's constant buffer view
CD3DX12_GPU_DESCRIPTOR_HANDLE cbvSrvGpuHandle2(pCbvSrvHeap->GetGPUDescriptorHandleForHeapStart(), cbvSrvDescriptorSize);
pCommandList->SetGraphicsRootDescriptorTable(0, cbvSrvGpuHandle2);
// Draw second object...
While this approach works fine, it doesn't necessarily match Vulkan's dynamic offset approach, so i can't make a clean abstraction over the two.
So how would you guys go about handling this? And i'd love to know your approaches to abstracting the Vulkan/D3D12 binding model in general.
↧