I am learning DirectX12 programming. And one thing that has me confused is in all the tutorials I read, they only create a single depth/stencil buffer even when triple/double buffering is used with the swap chain. Wouldn't you need a depth/stencil buffer for each frame?
Code in question:
D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
dsvHeapDesc.NumDescriptors = 1; //why only 1?
dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
if(FAILED(device->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&dsDescriptorHeap))))
{
MessageBoxW(NULL, L"Failed to create depth buffer descriptor heap!", L"Error", MB_OK | MB_ICONERROR);
return -1;
}
D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {};
depthStencilDesc.Format = DXGI_FORMAT_D32_FLOAT;
depthStencilDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
depthStencilDesc.Flags = D3D12_DSV_FLAG_NONE;
D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
depthOptimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT;
depthOptimizedClearValue.DepthStencil.Depth = 1.0f;
depthOptimizedClearValue.DepthStencil.Stencil = 0;
device->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D32_FLOAT, width, height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL), D3D12_RESOURCE_STATE_DEPTH_WRITE, &depthOptimizedClearValue, IID_PPV_ARGS(&depthStencilBuffer));
depthStencilBuffer->SetName(L"Depth/Stencil Resource Heap");
device->CreateDepthStencilView(depthStencilBuffer, &depthStencilDesc, dsDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
Tutorials in question:
Generally speaking, "intermediate resources" (such as depth stencils and intermediate render targets) are not presented on the screen.
So when one swapchain is ready to present (and you start recording next frame commands), those resources can be safely overridden, since the content is ready within the swap chain.
The only exception for those resources are generally buffers that are uploaded from cpu, for them it is needed to have one per frame (since you will start to copy data while another command list is still executing).