From d04e840486b08bc8356d6e7275a8e7f4d54f68e3 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 8 Aug 2020 15:40:24 -0700 Subject: D3D12 backend: implemented render pass attachment state transitons --- .../GraphicsEngineD3D12/include/CommandContext.hpp | 6 +++ .../include/DeviceContextD3D12Impl.hpp | 2 +- .../src/DeviceContextD3D12Impl.cpp | 48 ++++++++++++++++++---- 3 files changed, 48 insertions(+), 8 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp index 2ef40103..6fd7c63f 100644 --- a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp +++ b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp @@ -166,6 +166,11 @@ public: return m_DynamicGPUDescriptorAllocators[Type].Allocate(Count); } + void ResourceBarrier(const D3D12_RESOURCE_BARRIER& Barrier) + { + m_PendingResourceBarriers.emplace_back(Barrier); + } + void InsertUAVBarrier(ID3D12Resource* pd3d12Resource); void SetPipelineState(ID3D12PipelineState* pPSO) @@ -345,6 +350,7 @@ public: const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC* pDepthStencil, D3D12_RENDER_PASS_FLAGS Flags) { + FlushResourceBarriers(); static_cast(m_pCommandList.p)->BeginRenderPass(NumRenderTargets, pRenderTargets, pDepthStencil, Flags); } diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp index 0aae73af..dddf159e 100644 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp @@ -319,7 +319,7 @@ private: void CommitRenderTargets(RESOURCE_STATE_TRANSITION_MODE StateTransitionMode); void CommitViewports(); void CommitScissorRects(class GraphicsContext& GraphCtx, bool ScissorEnable); - void TransitionSubpassAttachments(); + void TransitionSubpassAttachments(Uint32 NextSubpass); void CommitSubpassRenderTargets(); void Flush(bool RequestNewCmdCtx); diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 2c8eb45e..25c0bba9 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -1004,12 +1004,47 @@ void DeviceContextD3D12Impl::SetRenderTargets(Uint32 Num } } -void DeviceContextD3D12Impl::TransitionSubpassAttachments() +void DeviceContextD3D12Impl::TransitionSubpassAttachments(Uint32 NextSubpass) { VERIFY_EXPR(m_pActiveRenderPass); - //const auto& RPDesc = m_pActiveRenderPass->GetDesc(); + const auto& RPDesc = m_pActiveRenderPass->GetDesc(); VERIFY_EXPR(m_pBoundFramebuffer); - //const auto& FBDesc = m_pBoundFramebuffer->GetDesc(); + const auto& FBDesc = m_pBoundFramebuffer->GetDesc(); + VERIFY_EXPR(RPDesc.AttachmentCount == FBDesc.AttachmentCount); + for (Uint32 att = 0; att < RPDesc.AttachmentCount; ++att) + { + const auto& AttDesc = RPDesc.pAttachments[att]; + auto OldState = NextSubpass > 0 ? m_pActiveRenderPass->GetAttachmentState(NextSubpass - 1, att) : AttDesc.InitialState; + auto NewState = NextSubpass < RPDesc.SubpassCount ? m_pActiveRenderPass->GetAttachmentState(NextSubpass, att) : AttDesc.FinalState; + if (OldState != NewState) + { + auto& CmdCtx = GetCmdContext(); + + auto* pViewD3D12 = ValidatedCast(FBDesc.ppAttachments[att]); + if (pViewD3D12 == nullptr) + continue; + + auto* pTexD3D12 = pViewD3D12->GetTexture(); + + const auto& ViewDesc = pViewD3D12->GetDesc(); + const auto& TexDesc = pTexD3D12->GetDesc(); + + D3D12_RESOURCE_BARRIER BarrierDesc; + BarrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + BarrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + BarrierDesc.Transition.pResource = pTexD3D12->GetD3D12Resource(); + BarrierDesc.Transition.StateBefore = ResourceStateFlagsToD3D12ResourceStates(OldState); + BarrierDesc.Transition.StateAfter = ResourceStateFlagsToD3D12ResourceStates(NewState); + for (Uint32 mip = ViewDesc.MostDetailedMip; mip < ViewDesc.MostDetailedMip + ViewDesc.NumDepthSlices; ++mip) + { + for (Uint32 slice = ViewDesc.FirstArraySlice; slice < ViewDesc.FirstArraySlice + ViewDesc.NumArraySlices; ++slice) + { + BarrierDesc.Transition.Subresource = D3D12CalcSubresource(mip, slice, 0, TexDesc.MipLevels, TexDesc.ArraySize); + CmdCtx.ResourceBarrier(BarrierDesc); + } + } + } + } } void DeviceContextD3D12Impl::CommitSubpassRenderTargets() @@ -1190,7 +1225,7 @@ void DeviceContextD3D12Impl::BeginRenderPass(const BeginRenderPassAttribs& Attri for (Uint32 i = 0; i < Attribs.ClearValueCount; ++i) m_AttachmentClearValues[i] = Attribs.pClearValues[i]; - TransitionSubpassAttachments(); + TransitionSubpassAttachments(m_SubpassIndex); CommitSubpassRenderTargets(); } @@ -1199,17 +1234,16 @@ void DeviceContextD3D12Impl::NextSubpass() auto& CmdCtx = GetCmdContext(); CmdCtx.AsGraphicsContext().EndRenderPass(); TDeviceContextBase::NextSubpass(); - TransitionSubpassAttachments(); + TransitionSubpassAttachments(m_SubpassIndex); CommitSubpassRenderTargets(); - //auto& CmdCtx = GetCmdContext(); } void DeviceContextD3D12Impl::EndRenderPass(bool UpdateResourceStates) { auto& CmdCtx = GetCmdContext(); CmdCtx.AsGraphicsContext().EndRenderPass(); + TransitionSubpassAttachments(m_SubpassIndex + 1); TDeviceContextBase::EndRenderPass(UpdateResourceStates); - TransitionSubpassAttachments(); } D3D12DynamicAllocation DeviceContextD3D12Impl::AllocateDynamicSpace(size_t NumBytes, size_t Alignment) -- cgit v1.2.3