Objects in depth buffer are always black (0.0) My problem is exactly what titles and screenshot below says - rendered object depth value is 0.0 in depth buffer. I'm using DirectX 12.

Matrices:

// VS code
PixelInputType main(VertexInputType input)
{
    PixelInputType output;
    
    float4 position = float4(input.position, 1.0f);
    position = mul(position, g_worldMatrix);
    position = mul(position, g_viewMatrix);
    position = mul(position, g_projMatrix);
    output.position = position;

    return output;
}
// PS code
float4 main(PixelInputType input) : SV_TARGET
{
    return float4(g_texture.Sample(g_sampler, input.uv).rgb, 1.0f);
}

I am rendering single object for now, so world matrix is just identity matrix.
Regarding view/proj matrix - they're updated each frame and saved to the CB:
void Renderer::CreateViewAndPerspective()
{
    const DirectX::XMVECTOR up = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.f);
    constexpr float conv{ 0.0174532925f };

    // Create the rotation matrix from the yaw, pitch, and roll values.
    const XMMATRIX rotationMatrix = XMMatrixRotationRollPitchYaw(m_cameraRotation.x * conv, m_cameraRotation.y * conv, m_cameraRotation.z * conv);

    const DirectX::XMVECTOR eye = DirectX::XMVectorSet(m_cameraPosition.x, m_cameraPosition.y, m_cameraPosition.z, 0.0f);

    //Setup target (look at object position)
    XMVECTOR target = XMVector3TransformCoord(DirectX::XMVECTOR{ 0, 0, 1, 0 }, rotationMatrix);
    target = XMVector3Normalize(target);
    target = { m_cameraPosition.x + target.m128_f32[0], m_cameraPosition.y + target.m128_f32[1], m_cameraPosition.z + target.m128_f32[2], 0.0f };  

    //Create view matrix
    m_constantBuffer.value.view = DirectX::XMMatrixTranspose(DirectX::XMMatrixLookAtLH(eye, target, up));

    //Create perspective matrix
    constexpr float FOV = 3.14f / 4.0f;
    float aspectRatio = m_windowSize.x / m_windowSize.y /* 1280 x 720 */;
    m_constantBuffer.value.projection = DirectX::XMMatrixTranspose(DirectX::XMMatrixPerspectiveFovLH(FOV, aspectRatio, Z_NEAR /* 0.5f */, Z_FAR /* 100.0f */));
}


Edit: Depth buffer implementation details below (full code - https://github.com/komilll/YARE/blob/main/YARE/Renderer.cpp#L131 ):
// Create DSV
D3D12_DESCRIPTOR_HEAP_DESC desc{};
desc.NumDescriptors = 1;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
device-&gt;CreateDescriptorHeap(&amp;desc, IID_PPV_ARGS(&amp;heap));

// Create Depth Stencil
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;

ThrowIfFailed(device-&gt;CreateCommittedResource(
    &amp;CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
    D3D12_HEAP_FLAG_NONE,
    &amp;CD3DX12_RESOURCE_DESC::Tex2D(format, width, height, 1, 0, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL),
    D3D12_RESOURCE_STATE_DEPTH_WRITE,
    &amp;depthOptimizedClearValue,
    IID_PPV_ARGS(&amp;depthStencil)
));

device-&gt;CreateDepthStencilView(depthStencil.Get(), &amp;depthStencilDesc, dsvHeap-&gt;GetCPUDescriptorHandleForHeapStart());

/* ... */
// Usage of DSV
const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f };
m_commandList-&gt;ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
m_commandList-&gt;ClearDepthStencilView(m_dsvHeap-&gt;GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);
m_commandList-&gt;IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_commandList-&gt;IASetVertexBuffers(0, 1, &amp;m_modelSphere-&gt;GetVertexBufferView());
m_commandList-&gt;DrawInstanced(m_modelSphere-&gt;GetIndicesCount(), 1, 0, 0);
That's how I used to initialize viewport (CD3DX12_VIEWPORT). But I didn't realize that there are two additional fields minDepth and maxDepth. Therefore, I have min/max depth set to 0.0 and objects rendered to depth buffer are always black:
m_viewport.TopLeftY = 0.0f;
m_viewport.TopLeftX = 0.0f;
m_viewport.Width = static_cast&lt;float&gt;(m_windowSize.x);
m_viewport.Height = static_cast&lt;float&gt;(m_windowSize.y);

Fixed that by simply using constructor which default minDepth to 0.0 and maxDepth to 1.0:
m_viewport = CD3DX12_VIEWPORT{ 0.0f, 0.0f, static_cast&lt;float&gt;(m_windowSize.x), static_cast&lt;float&gt;(m_windowSize.y) };