From fd070e679f723413cb18980e49d85e08831a04d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Fri, 18 Sep 2026 19:16:27 -0700 Subject: [PATCH] D3D12: Fixed depth-stencil plane states. (#3990) --- src/renderer_d3d12.cpp | 91 +++++++++++++++++++++++++++++++++++------- src/renderer_d3d12.h | 2 + 2 files changed, 79 insertions(+), 14 deletions(-) diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 19f4d1c72..4702c5fb6 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -3505,11 +3505,16 @@ namespace bgfx { namespace d3d12 { TextureD3D12& texture = m_textures[frameBuffer.m_depth.idx]; - texture.setState(m_commandList - , hasReadOnlyDepth(frameBuffer.m_attachment, frameBuffer.m_numTh) + const D3D12_RESOURCE_STATES depthState = hasReadOnlyDepth(frameBuffer.m_attachment, frameBuffer.m_numTh) ? D3D12_RESOURCE_STATE_DEPTH_READ|D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE : D3D12_RESOURCE_STATE_DEPTH_WRITE - ); + ; + const D3D12_RESOURCE_STATES stencilState = hasReadOnlyStencil(frameBuffer.m_attachment, frameBuffer.m_numTh) + ? D3D12_RESOURCE_STATE_DEPTH_READ|D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE + : D3D12_RESOURCE_STATE_DEPTH_WRITE + ; + + texture.setPlaneStates(m_commandList, depthState, stencilState); } } @@ -7421,9 +7426,20 @@ namespace bgfx { namespace d3d12 ; } + uint32_t TextureD3D12::getNumPlanes() const + { + return false + || TextureFormat::D24S8 == m_textureFormat + || TextureFormat::D32FS8 == m_textureFormat + || TextureFormat::D0S8 == m_textureFormat + ? 2 + : 1 + ; + } + uint32_t TextureD3D12::getNumSubresources() const { - return getNumPtrMips() * getNumSlices(); + return getNumPtrMips() * getNumSlices() * getNumPlanes(); } DXGI_FORMAT TextureD3D12::getSrvFormat(SrgbSelect::Enum _srgb) const @@ -7510,21 +7526,60 @@ namespace bgfx { namespace d3d12 } } - for (uint32_t slice = firstSlice, sliceEnd = firstSlice + numSlices; slice < sliceEnd; ++slice) - { - for (uint32_t mip = firstMip, mipEnd = firstMip + numMips; mip < mipEnd; ++mip) - { - const uint32_t subresource = mip + slice*mipCount; + const uint32_t numPlanes = getNumPlanes(); - if (m_subStates[subresource] != _state) + for (uint32_t plane = 0; plane < numPlanes; ++plane) + { + for (uint32_t slice = firstSlice, sliceEnd = firstSlice + numSlices; slice < sliceEnd; ++slice) + { + for (uint32_t mip = firstMip, mipEnd = firstMip + numMips; mip < mipEnd; ++mip) { - setResourceBarrier(_commandList, m_ptr, m_subStates[subresource], _state, subresource); - m_subStates[subresource] = _state; + const uint32_t subresource = mip + slice*mipCount + plane*mipCount*sliceCount; + + if (m_subStates[subresource] != _state) + { + setResourceBarrier(_commandList, m_ptr, m_subStates[subresource], _state, subresource); + m_subStates[subresource] = _state; + } } } } } + void TextureD3D12::setPlaneStates(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _depthState, D3D12_RESOURCE_STATES _stencilState) + { + if (_depthState == _stencilState + || 2 != getNumPlanes() ) + { + setState(_commandList, _depthState); + return; + } + + const uint32_t numSubresources = getNumSubresources(); + const uint32_t planeSize = numSubresources / 2; + + if (NULL == m_subStates) + { + m_subStates = (D3D12_RESOURCE_STATES*)bx::alloc(g_allocator, numSubresources*sizeof(D3D12_RESOURCE_STATES) ); + + for (uint32_t ii = 0; ii < numSubresources; ++ii) + { + m_subStates[ii] = m_state; + } + } + + for (uint32_t ii = 0; ii < numSubresources; ++ii) + { + const D3D12_RESOURCE_STATES state = ii < planeSize ? _depthState : _stencilState; + + if (m_subStates[ii] != state) + { + setResourceBarrier(_commandList, m_ptr, m_subStates[ii], state, ii); + m_subStates[ii] = state; + } + } + } + void RendererContextD3D12::generateMips(ID3D12GraphicsCommandList* _commandList, TextureD3D12& _texture) { if (NULL == m_mipGen @@ -9689,7 +9744,11 @@ namespace bgfx { namespace d3d12 ? bind.m_samplerFlags : uint32_t(texture.m_flags) ; - texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ, bind.m_firstMip, bind.m_numMips, bind.m_firstLayer, bind.m_numLayers); + const bool isDepthAttach = isValid(m_fbh) && NULL == m_frameBuffers[m_fbh.idx].m_swapChain && m_frameBuffers[m_fbh.idx].m_depth.idx == bind.m_idx; + if (!isDepthAttach) + { + texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ, bind.m_firstMip, bind.m_numMips, bind.m_firstLayer, bind.m_numLayers); + } scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_firstLayer, bind.m_numLayers, bind.m_firstMip, bind.m_numMips , 0 != (resolvedFlags & BGFX_SAMPLER_SAMPLE_STENCIL) , program.getTextureDimension(uint8_t(stage) ) @@ -10067,7 +10126,11 @@ namespace bgfx { namespace d3d12 ? bind.m_samplerFlags : uint32_t(texture.m_flags) ; - texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ, bind.m_firstMip, bind.m_numMips, bind.m_firstLayer, bind.m_numLayers); + const bool isDepthAttach = isValid(m_fbh) && NULL == m_frameBuffers[m_fbh.idx].m_swapChain && m_frameBuffers[m_fbh.idx].m_depth.idx == bind.m_idx; + if (!isDepthAttach) + { + texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ, bind.m_firstMip, bind.m_numMips, bind.m_firstLayer, bind.m_numLayers); + } scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_firstLayer, bind.m_numLayers, bind.m_firstMip, bind.m_numMips , 0 != (resolvedFlags & BGFX_SAMPLER_SAMPLE_STENCIL) , program.getTextureDimension(uint8_t(stage) ) diff --git a/src/renderer_d3d12.h b/src/renderer_d3d12.h index 6bda20b90..d2f637958 100644 --- a/src/renderer_d3d12.h +++ b/src/renderer_d3d12.h @@ -468,9 +468,11 @@ namespace bgfx { namespace d3d12 D3D12_RESOURCE_STATES setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state); void setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state, uint16_t _firstMip, uint16_t _numMips, uint16_t _firstSlice, uint16_t _numSlices); + void setPlaneStates(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _depthState, D3D12_RESOURCE_STATES _stencilState); uint32_t getNumSlices() const; uint32_t getNumPtrMips() const; + uint32_t getNumPlanes() const; uint32_t getNumSubresources() const; bool isMsaaSurface() const;