0
\$\begingroup\$

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!

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

You should check that matrix.

The DirectXMath function XMMatrixPerspectiveFovLH returns 'row-major' memory order, but HLSL defaults to 'column-major' unless you specifically specify otherwise. See Microsoft Docs

Try:

XMMATRIX proj = DirectX::XMMatrixPerspectiveFovLH(DirectX::XM_PIDIV2, (FLOAT)width / (FLOAT)height, 0.5f, 400.0f);
DirectX::XMStoreFloat4x4(&m_constBuffer.getPointer()->matView, XMMatrixTranspose(proj));

Note that you may find using SimpleMath a little easier. It's part of DirectX Tool Kit for DX11 and DX12.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you! you are right! I did created my resource with the layout D3D12_TEXTURE_LAYOUT_ROW_MAJOR and thought this would be sufficient but it looks like it wasn't! When I did tried the transpose I got wrong near and far planes... I forgot to check it later on :facepalm: \$\endgroup\$
    – Ohjurot
    Commented Aug 16, 2020 at 14:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .