To make things short: I am trying to bind and use a depth buffer in D3D12, but it is not working. The depth buffer gets created and bound properly (I can see it in nsight graphics) but does only take either 0.0f or 1.0f (Clear value). I first thought that it might be a problem with my projection matrix so I played around with the near and far Z but I didn't get any improvements.
The following code was used to create the depth buffer:
// === Create DSV descriptor heap
D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc;
ZeroMemory(&dsvHeapDesc, sizeof(D3D12_DESCRIPTOR_HEAP_DESC));
dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
dsvHeapDesc.NumDescriptors = 1;
dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
dsvHeapDesc.NodeMask = NULL;
ptrDevice->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_ptrDsvDescriptorHeap))
// === Create depth buffer resource
// Describe heap
D3D12_HEAP_PROPERTIES dsHeapProperties;
ZeroMemory(&dsHeapProperties, sizeof(&dsHeapProperties));
dsHeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
dsHeapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
dsHeapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
dsHeapProperties.CreationNodeMask = NULL;
dsHeapProperties.VisibleNodeMask = NULL;
// Describe resource
D3D12_RESOURCE_DESC dsResDesc;
ZeroMemory(&dsResDesc, sizeof(D3D12_RESOURCE_DESC));
dsResDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
dsResDesc.Alignment = 0;
dsResDesc.Width = width;
dsResDesc.Height = height;
dsResDesc.DepthOrArraySize = 1;
dsResDesc.MipLevels = 1;
dsResDesc.Format = DXGI_FORMAT_D32_FLOAT;
dsResDesc.SampleDesc.Count = 1;
dsResDesc.SampleDesc.Quality = 0;
dsResDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
dsResDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
// Describe clear value
D3D12_CLEAR_VALUE clearValueDs;
ZeroMemory(&clearValueDs, sizeof(D3D12_CLEAR_VALUE));
clearValueDs.Format = DXGI_FORMAT_D32_FLOAT;
clearValueDs.DepthStencil.Depth = 1.0f;
clearValueDs.DepthStencil.Stencil = 0;
ptrDevice->CreateCommittedResource(
&dsHeapProperties,
D3D12_HEAP_FLAG_NONE,
&dsResDesc,
D3D12_RESOURCE_STATE_DEPTH_WRITE,
&clearValueDs,
IID_PPV_ARGS(&m_ptrDepthStencil)
);
// === Create view description
D3D12_DEPTH_STENCIL_VIEW_DESC dsViewDesk;
ZeroMemory(&dsViewDesk, sizeof(D3D12_DEPTH_STENCIL_VIEW_DESC));
dsViewDesk.Format = DXGI_FORMAT_D32_FLOAT;
dsViewDesk.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
dsViewDesk.Flags = D3D12_DSV_FLAG_NONE;
dsViewDesk.Texture2D.MipSlice = 0;
D3D12_CPU_DESCRIPTOR_HANDLE heapHandleDsv = m_ptrDsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
ptrDevice->CreateDepthStencilView(m_ptrDepthStencil, &dsViewDesk, heapHandleDsv);
In my frame begin method the following code is executed
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = m_ptrDsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
ptrCmdList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle); // RTV Handle works
ptrCmdList->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, NULL);
The D3D12_DEPTH_STENCIL_DESC
descriptor of my pipline state is set as follows
D3D12_DEPTH_STENCIL_DESC depthDesc;
ZeroMemory(&depthDesc, sizeof(D3D12_DEPTH_STENCIL_DESC));
depthDesc.DepthEnable = TRUE;
depthDesc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
depthDesc.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;
depthDesc.StencilEnable = FALSE;
The DSV format in also set psoDesk.DSVFormat = DXGI_FORMAT_D32_FLOAT;
The viewport also has the correct min and max depth values set.
My Projection matrix is generated statically and uploaded once with the following code:
DirectX::XMStoreFloat4x4(&m_constBuffer.getPointer()->matView, DirectX::XMMatrixPerspectiveFovLH(DirectX::XM_PIDIV2, (FLOAT)width / (FLOAT)height, 0.5f, 400.0f));
The m_constBuffer
is an instance of a template class witch is capable of uploading any kind of c++ class members to the GPU as buffer (Here: DirectX::XMFLOAT4X4
)
My vertex shader just multiplies the model matrix and projection matrix (Currently I have no view matrix!)
#include "RootSignature.hlsl"
struct camerCbuf{
float4x4 matProject;
};
struct modellCbuf{
float4x4 matModell;
};
struct sOut{
float4 pos : SV_Position;
float2 tex : TEXCOORD;
};
ConstantBuffer<camerCbuf> constBufferView : register(b0);
ConstantBuffer<modellCbuf> constBufferModell : register(b1);
[RootSignature(ROOTSIG)]
void main(float3 pos : POSITION, float4 tex : TEXCOORD, out sOut outData){
outData.pos = mul(float4(pos.xyz, 1.0f) , constBufferModell.matModell);
outData.pos = mul(outData.pos , constBufferView.matProject);
outData.tex = tex;
}
Currently I have no clue why my depth buffer is not working. Thanks for your answers in advance!