diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2020-08-15 22:42:13 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-08-15 22:42:13 +0000 |
| commit | df3a2c7c744eae194c79187a59914c6662f69b52 (patch) | |
| tree | 6f67919092b671b4a0fb637db26f75293f849886 /Graphics/GraphicsEngineD3D12 | |
| parent | Fixed Visual Studio 16.7 build error (diff) | |
| parent | Vk backend: not setting render pass in SetPipelineState (diff) | |
| download | DiligentCore-df3a2c7c744eae194c79187a59914c6662f69b52.tar.gz DiligentCore-df3a2c7c744eae194c79187a59914c6662f69b52.zip | |
Added render passes to the API (fixed https://github.com/DiligentGraphics/DiligentCore/issues/9)
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
15 files changed, 633 insertions, 14 deletions
diff --git a/Graphics/GraphicsEngineD3D12/CMakeLists.txt b/Graphics/GraphicsEngineD3D12/CMakeLists.txt index 0c878103..99501a4e 100644 --- a/Graphics/GraphicsEngineD3D12/CMakeLists.txt +++ b/Graphics/GraphicsEngineD3D12/CMakeLists.txt @@ -18,12 +18,14 @@ set(INCLUDE include/DeviceContextD3D12Impl.hpp include/D3D12DynamicHeap.hpp include/FenceD3D12Impl.hpp + include/FramebufferD3D12Impl.hpp include/GenerateMips.hpp include/pch.h include/PipelineStateD3D12Impl.hpp include/QueryD3D12Impl.hpp include/QueryManagerD3D12.hpp include/RenderDeviceD3D12Impl.hpp + include/RenderPassD3D12Impl.hpp include/RootSignature.hpp include/SamplerD3D12Impl.hpp include/ShaderD3D12Impl.hpp @@ -69,11 +71,13 @@ set(SRC src/D3D12DynamicHeap.cpp src/EngineFactoryD3D12.cpp src/FenceD3D12Impl.cpp + src/FramebufferD3D12Impl.cpp src/GenerateMips.cpp src/PipelineStateD3D12Impl.cpp src/QueryD3D12Impl.cpp src/QueryManagerD3D12.cpp src/RenderDeviceD3D12Impl.cpp + src/RenderPassD3D12Impl.cpp src/RootSignature.cpp src/SamplerD3D12Impl.cpp src/ShaderD3D12Impl.cpp diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp index a8211db6..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) @@ -339,6 +344,20 @@ public: FlushResourceBarriers(); m_pCommandList->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); } + + void BeginRenderPass(UINT NumRenderTargets, + const D3D12_RENDER_PASS_RENDER_TARGET_DESC* pRenderTargets, + const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC* pDepthStencil, + D3D12_RENDER_PASS_FLAGS Flags) + { + FlushResourceBarriers(); + static_cast<ID3D12GraphicsCommandList4*>(m_pCommandList.p)->BeginRenderPass(NumRenderTargets, pRenderTargets, pDepthStencil, Flags); + } + + void EndRenderPass() + { + static_cast<ID3D12GraphicsCommandList4*>(m_pCommandList.p)->EndRenderPass(); + } }; class ComputeContext : public CommandContext diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp index bdaa3f5e..89e52955 100644 --- a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp +++ b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp @@ -31,6 +31,7 @@ /// Type conversion routines #include "GraphicsTypes.h" +#include "RenderPass.h" namespace Diligent { @@ -71,4 +72,7 @@ RESOURCE_STATE D3D12ResourceStatesToResourceStateFlags(D3D12_RESOURCE D3D12_QUERY_HEAP_TYPE QueryTypeToD3D12QueryHeapType(QUERY_TYPE QueryType); D3D12_QUERY_TYPE QueryTypeToD3D12QueryType(QUERY_TYPE QueryType); +D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE AttachmentLoadOpToD3D12BeginningAccessType(ATTACHMENT_LOAD_OP LoadOp); +D3D12_RENDER_PASS_ENDING_ACCESS_TYPE AttachmentStoreOpToD3D12EndingAccessType(ATTACHMENT_STORE_OP StoreOp); + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp index 5c6912b6..09d9419b 100644 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp @@ -31,20 +31,21 @@ /// Declaration of Diligent::DeviceContextD3D12Impl class #include <unordered_map> +#include <vector> #include "DeviceContextD3D12.h" #include "DeviceContextNextGenBase.hpp" #include "BufferD3D12Impl.hpp" #include "TextureD3D12Impl.hpp" #include "QueryD3D12Impl.hpp" +#include "FramebufferD3D12Impl.hpp" +#include "RenderPassD3D12Impl.hpp" #include "PipelineStateD3D12Impl.hpp" #include "D3D12DynamicHeap.hpp" namespace Diligent { -class RenderDeviceD3D12Impl; - struct DeviceContextD3D12ImplTraits { using BufferType = BufferD3D12Impl; @@ -53,6 +54,8 @@ struct DeviceContextD3D12ImplTraits using DeviceType = RenderDeviceD3D12Impl; using ICommandQueueType = ICommandQueueD3D12; using QueryType = QueryD3D12Impl; + using FramebufferType = FramebufferD3D12Impl; + using RenderPassType = RenderPassD3D12Impl; }; /// Device context implementation in Direct3D12 backend. @@ -122,6 +125,15 @@ public: ITextureView* pDepthStencil, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + /// Implementation of IDeviceContext::BeginRenderPass() in Direct3D11 backend. + virtual void DILIGENT_CALL_TYPE BeginRenderPass(const BeginRenderPassAttribs& Attribs) override final; + + /// Implementation of IDeviceContext::NextSubpass() in Direct3D11 backend. + virtual void DILIGENT_CALL_TYPE NextSubpass() override final; + + /// Implementation of IDeviceContext::EndRenderPass() in Direct3D11 backend. + virtual void DILIGENT_CALL_TYPE EndRenderPass() override final; + // clang-format off /// Implementation of IDeviceContext::Draw() in Direct3D12 backend. virtual void DILIGENT_CALL_TYPE Draw (const DrawAttribs& Attribs) override final; @@ -307,6 +319,8 @@ private: void CommitRenderTargets(RESOURCE_STATE_TRANSITION_MODE StateTransitionMode); void CommitViewports(); void CommitScissorRects(class GraphicsContext& GraphCtx, bool ScissorEnable); + void TransitionSubpassAttachments(Uint32 NextSubpass); + void CommitSubpassRenderTargets(); void Flush(bool RequestNewCmdCtx); __forceinline void RequestCommandContext(RenderDeviceD3D12Impl* pDeviceD3D12Impl); @@ -414,6 +428,10 @@ private: std::unordered_map<MappedTextureKey, TextureUploadSpace, MappedTextureKey::Hasher> m_MappedTextures; Int32 m_ActiveQueriesCounter = 0; + + std::vector<OptimizedClearValue> m_AttachmentClearValues; + + std::vector<D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS> m_AttachmentResolveInfo; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/FramebufferD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/FramebufferD3D12Impl.hpp new file mode 100644 index 00000000..59642660 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/FramebufferD3D12Impl.hpp @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::FramebufferD3D12Impl class + +#include "RenderDeviceD3D12.h" +#include "FramebufferBase.hpp" +#include "RenderDeviceD3D12Impl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Render pass implementation in Direct3D11 backend. +class FramebufferD3D12Impl final : public FramebufferBase<IFramebuffer, RenderDeviceD3D12Impl> +{ +public: + using TFramebufferBase = FramebufferBase<IFramebuffer, RenderDeviceD3D12Impl>; + + FramebufferD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDevice, + const FramebufferDesc& Desc); + ~FramebufferD3D12Impl(); +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp index 303f8bfb..ddcc4f14 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -92,6 +92,14 @@ public: /// Implementation of IRenderDevice::CreateQuery() in Direct3D12 backend. virtual void DILIGENT_CALL_TYPE CreateQuery(const QueryDesc& Desc, IQuery** ppQuery) override final; + /// Implementation of IRenderDevice::CreateRenderPass() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE CreateRenderPass(const RenderPassDesc& Desc, + IRenderPass** ppRenderPass) override final; + + /// Implementation of IRenderDevice::CreateFramebuffer() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE CreateFramebuffer(const FramebufferDesc& Desc, + IFramebuffer** ppFramebuffer) override final; + /// Implementation of IRenderDeviceD3D12::GetD3D12Device(). virtual ID3D12Device* DILIGENT_CALL_TYPE GetD3D12Device() override final { return m_pd3d12Device; } diff --git a/Graphics/GraphicsEngineD3D12/include/RenderPassD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderPassD3D12Impl.hpp new file mode 100644 index 00000000..501e62df --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/RenderPassD3D12Impl.hpp @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::RenderPassD3D12Impl class + +#include "RenderDeviceD3D12.h" +#include "RenderPassBase.hpp" +#include "RenderDeviceD3D12Impl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Render pass implementation in Direct3D11 backend. +class RenderPassD3D12Impl final : public RenderPassBase<IRenderPass, RenderDeviceD3D12Impl> +{ +public: + using TRenderPassBase = RenderPassBase<IRenderPass, RenderDeviceD3D12Impl>; + + RenderPassD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDevice, + const RenderPassDesc& Desc); + ~RenderPassD3D12Impl(); +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp b/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp index f1099ac7..c4d6e1b5 100644 --- a/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp +++ b/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp @@ -50,7 +50,7 @@ void CommandListManager::CreateNewCommandList(ID3D12GraphicsCommandList** List, { RequestAllocator(Allocator); auto* pd3d12Device = m_DeviceD3D12Impl.GetD3D12Device(); - auto hr = pd3d12Device->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, *Allocator, nullptr, __uuidof(*List), reinterpret_cast<void**>(List)); + auto hr = pd3d12Device->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, *Allocator, nullptr, __uuidof(ID3D12GraphicsCommandList4), reinterpret_cast<void**>(List)); VERIFY(SUCCEEDED(hr), "Failed to create command list"); (*List)->SetName(L"CommandList"); } diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index 124201ff..1759663f 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -329,7 +329,7 @@ D3D12_STATIC_BORDER_COLOR BorderColorToD3D12StaticBorderColor(const Float32 Bord static D3D12_RESOURCE_STATES ResourceStateFlagToD3D12ResourceState(RESOURCE_STATE StateFlag) { - static_assert(RESOURCE_STATE_MAX_BIT == 0x8000, "This function must be updated to handle new resource state flag"); + static_assert(RESOURCE_STATE_MAX_BIT == 0x10000, "This function must be updated to handle new resource state flag"); VERIFY((StateFlag & (StateFlag - 1)) == 0, "Only single bit must be set"); switch (StateFlag) { @@ -349,6 +349,7 @@ static D3D12_RESOURCE_STATES ResourceStateFlagToD3D12ResourceState(RESOURCE_STAT case RESOURCE_STATE_COPY_SOURCE: return D3D12_RESOURCE_STATE_COPY_SOURCE; case RESOURCE_STATE_RESOLVE_DEST: return D3D12_RESOURCE_STATE_RESOLVE_DEST; case RESOURCE_STATE_RESOLVE_SOURCE: return D3D12_RESOURCE_STATE_RESOLVE_SOURCE; + case RESOURCE_STATE_INPUT_ATTACHMENT: return D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; case RESOURCE_STATE_PRESENT: return D3D12_RESOURCE_STATE_PRESENT; // clang-format on default: @@ -376,7 +377,7 @@ public: } private: - static constexpr Uint32 MaxFlagBitPos = 15; + static constexpr Uint32 MaxFlagBitPos = 16; std::array<D3D12_RESOURCE_STATES, MaxFlagBitPos + 1> FlagBitPosToResStateMap; }; @@ -398,7 +399,7 @@ D3D12_RESOURCE_STATES ResourceStateFlagsToD3D12ResourceStates(RESOURCE_STATE Sta static RESOURCE_STATE D3D12ResourceStateToResourceStateFlags(D3D12_RESOURCE_STATES state) { - static_assert(RESOURCE_STATE_MAX_BIT == 0x8000, "This function must be updated to handle new resource state flag"); + static_assert(RESOURCE_STATE_MAX_BIT == 0x10000, "This function must be updated to handle new resource state flag"); VERIFY((state & (state - 1)) == 0, "Only single state must be set"); switch (state) { @@ -501,4 +502,35 @@ D3D12_QUERY_HEAP_TYPE QueryTypeToD3D12QueryHeapType(QUERY_TYPE QueryType) // clang-format on } +D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE AttachmentLoadOpToD3D12BeginningAccessType(ATTACHMENT_LOAD_OP LoadOp) +{ + // clang-format off + switch (LoadOp) + { + case ATTACHMENT_LOAD_OP_LOAD: return D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE; + case ATTACHMENT_LOAD_OP_CLEAR: return D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR; + case ATTACHMENT_LOAD_OP_DISCARD: return D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD; + + default: + UNEXPECTED("Unexpected attachment load op"); + return D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE; + } + // clang-format on +} + +D3D12_RENDER_PASS_ENDING_ACCESS_TYPE AttachmentStoreOpToD3D12EndingAccessType(ATTACHMENT_STORE_OP StoreOp) +{ + // clang-format off + switch (StoreOp) + { + case ATTACHMENT_STORE_OP_STORE: return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE; + case ATTACHMENT_STORE_OP_DISCARD: return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD; + + default: + UNEXPECTED("Unexpected attachment store op"); + return D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE; + } + // clang-format on +} + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 5fa7f8e1..08b64857 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -230,7 +230,10 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState) { GraphicsCtx.SetStencilRef(m_StencilRef); GraphicsCtx.SetBlendFactor(m_BlendFactors); - CommitRenderTargets(RESOURCE_STATE_TRANSITION_MODE_VERIFY); + if (PSODesc.GraphicsPipeline.pRenderPass == nullptr) + { + CommitRenderTargets(RESOURCE_STATE_TRANSITION_MODE_VERIFY); + } CommitViewports(); } @@ -245,7 +248,12 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState) void DeviceContextD3D12Impl::TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding) { - VERIFY_EXPR(pPipelineState != nullptr); + DEV_CHECK_ERR(pPipelineState != nullptr, "Pipeline state must mot be null"); + if (m_pActiveRenderPass) + { + LOG_ERROR_MESSAGE("State transitions are not allowed inside a render pass."); + return; + } auto& Ctx = GetCmdContext(); @@ -612,6 +620,12 @@ void DeviceContextD3D12Impl::ClearDepthStencil(ITextureView* pV Uint8 Stencil, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) { + if (m_pActiveRenderPass != nullptr) + { + LOG_ERROR_MESSAGE("Direct3D12 does not allow depth-stencil clears inside a render pass"); + return; + } + if (!TDeviceContextBase::ClearDepthStencil(pView)) return; @@ -634,6 +648,12 @@ void DeviceContextD3D12Impl::ClearDepthStencil(ITextureView* pV void DeviceContextD3D12Impl::ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) { + if (m_pActiveRenderPass != nullptr) + { + LOG_ERROR_MESSAGE("Direct3D12 does not allow render target clears inside a render pass"); + return; + } + if (!TDeviceContextBase::ClearRenderTarget(pView)) return; @@ -707,6 +727,11 @@ void DeviceContextD3D12Impl::Flush() return; } + if (m_pActiveRenderPass != nullptr) + { + LOG_ERROR_MESSAGE("Flushing device context inside an active render pass."); + } + Flush(true); } @@ -748,6 +773,11 @@ void DeviceContextD3D12Impl::FinishFrame() "All queries must be ended before the frame is finished."); } + if (m_pActiveRenderPass != nullptr) + { + LOG_ERROR_MESSAGE("Finishing frame inside an active render pass."); + } + VERIFY_EXPR(m_bIsDeferred || m_SubmittedBuffersCmdQueueMask == (Uint64{1} << m_CommandQueueId)); // Released pages are returned to the global dynamic memory manager hosted by render device. @@ -905,6 +935,8 @@ void DeviceContextD3D12Impl::SetScissorRects(Uint32 NumRects, const Rect* pRects void DeviceContextD3D12Impl::CommitRenderTargets(RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) { + VERIFY(m_pActiveRenderPass == nullptr, "This method must not be called inside a render pass"); + const Uint32 MaxD3D12RTs = D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; Uint32 NumRenderTargets = m_NumBoundRenderTargets; VERIFY(NumRenderTargets <= MaxD3D12RTs, "D3D12 only allows 8 simultaneous render targets"); @@ -960,6 +992,14 @@ void DeviceContextD3D12Impl::SetRenderTargets(Uint32 Num ITextureView* pDepthStencil, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) { +#ifdef DILIGENT_DEVELOPMENT + if (m_pActiveRenderPass != nullptr) + { + LOG_ERROR_MESSAGE("Calling SetRenderTargets inside active render pass is invalid. End the render pass first"); + return; + } +#endif + if (TDeviceContextBase::SetRenderTargets(NumRenderTargets, ppRenderTargets, pDepthStencil)) { CommitRenderTargets(StateTransitionMode); @@ -969,6 +1009,257 @@ void DeviceContextD3D12Impl::SetRenderTargets(Uint32 Num } } +void DeviceContextD3D12Impl::TransitionSubpassAttachments(Uint32 NextSubpass) +{ + VERIFY_EXPR(m_pActiveRenderPass); + const auto& RPDesc = m_pActiveRenderPass->GetDesc(); + VERIFY_EXPR(m_pBoundFramebuffer); + 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<TextureViewD3D12Impl>(FBDesc.ppAttachments[att]); + if (pViewD3D12 == nullptr) + continue; + + auto* pTexD3D12 = pViewD3D12->GetTexture<TextureD3D12Impl>(); + + 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() +{ + VERIFY_EXPR(m_pActiveRenderPass); + const auto& RPDesc = m_pActiveRenderPass->GetDesc(); + VERIFY_EXPR(m_pBoundFramebuffer); + const auto& FBDesc = m_pBoundFramebuffer->GetDesc(); + VERIFY_EXPR(m_SubpassIndex < RPDesc.SubpassCount); + const auto& Subpass = RPDesc.pSubpasses[m_SubpassIndex]; + VERIFY(Subpass.RenderTargetAttachmentCount == m_NumBoundRenderTargets, + "The number of currently bound render targets (", m_NumBoundRenderTargets, + ") is not consistent with the number of redner target attachments (", Subpass.RenderTargetAttachmentCount, + ") in current subpass"); + + D3D12_RENDER_PASS_RENDER_TARGET_DESC RenderPassRTs[MAX_RENDER_TARGETS]; + for (Uint32 rt = 0; rt < m_NumBoundRenderTargets; ++rt) + { + const auto& RTRef = Subpass.pRenderTargetAttachments[rt]; + if (RTRef.AttachmentIndex != ATTACHMENT_UNUSED) + { + TextureViewD3D12Impl* pRTV = m_pBoundRenderTargets[rt]; + VERIFY(pRTV == FBDesc.ppAttachments[RTRef.AttachmentIndex], + "Render target bound in the device context at slot ", rt, " is not consistent with the corresponding framebuffer attachment"); + const auto FirstLastUse = m_pActiveRenderPass->GetAttachmentFirstLastUse(RTRef.AttachmentIndex); + const auto& RTAttachmentDesc = RPDesc.pAttachments[RTRef.AttachmentIndex]; + + auto& RPRT = RenderPassRTs[rt]; + RPRT = D3D12_RENDER_PASS_RENDER_TARGET_DESC{}; + + RPRT.cpuDescriptor = pRTV->GetCPUDescriptorHandle(); + if (FirstLastUse.first == m_SubpassIndex) + { + // This is the first use of this attachment - use LoadOp + RPRT.BeginningAccess.Type = AttachmentLoadOpToD3D12BeginningAccessType(RTAttachmentDesc.LoadOp); + } + else + { + // Preserve the attachment contents + RPRT.BeginningAccess.Type = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE; + } + + if (RPRT.BeginningAccess.Type == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR) + { + RPRT.BeginningAccess.Clear.ClearValue.Format = TexFormatToDXGI_Format(RTAttachmentDesc.Format); + + const auto ClearColor = m_AttachmentClearValues[RTRef.AttachmentIndex].Color; + for (Uint32 i = 0; i < 4; ++i) + RPRT.BeginningAccess.Clear.ClearValue.Color[i] = ClearColor[i]; + } + + if (FirstLastUse.second == m_SubpassIndex) + { + // This is the last use of this attachment - use StoreOp or resolve parameters + if (Subpass.pResolveAttachments != nullptr && Subpass.pResolveAttachments[rt].AttachmentIndex != ATTACHMENT_UNUSED) + { + VERIFY_EXPR(Subpass.pResolveAttachments[rt].AttachmentIndex < RPDesc.AttachmentCount); + auto* pDstView = FBDesc.ppAttachments[Subpass.pResolveAttachments[rt].AttachmentIndex]; + auto* pSrcTexD3D12 = pRTV->GetTexture<TextureD3D12Impl>(); + auto* pDstTexD3D12 = ValidatedCast<TextureViewD3D12Impl>(pDstView)->GetTexture<TextureD3D12Impl>(); + + const auto& SrcRTVDesc = pRTV->GetDesc(); + const auto& DstViewDesc = pDstView->GetDesc(); + const auto& SrcTexDesc = pSrcTexD3D12->GetDesc(); + const auto& DstTexDesc = pDstTexD3D12->GetDesc(); + + VERIFY_EXPR(SrcRTVDesc.NumArraySlices == 1); + Uint32 SubresourceCount = SrcRTVDesc.NumArraySlices; + m_AttachmentResolveInfo.resize(SubresourceCount); + const auto MipProps = GetMipLevelProperties(SrcTexDesc, SrcRTVDesc.MostDetailedMip); + for (Uint32 slice = 0; slice < SrcRTVDesc.NumArraySlices; ++slice) + { + auto& ARI = m_AttachmentResolveInfo[slice]; + + ARI.SrcSubresource = D3D12CalcSubresource(SrcRTVDesc.MostDetailedMip, SrcRTVDesc.FirstArraySlice + slice, 0, SrcTexDesc.MipLevels, SrcTexDesc.ArraySize); + ARI.DstSubresource = D3D12CalcSubresource(DstViewDesc.MostDetailedMip, DstViewDesc.FirstArraySlice + slice, 0, DstTexDesc.MipLevels, DstTexDesc.ArraySize); + ARI.DstX = 0; + ARI.DstY = 0; + ARI.SrcRect.left = 0; + ARI.SrcRect.top = 0; + ARI.SrcRect.right = MipProps.LogicalWidth; + ARI.SrcRect.bottom = MipProps.LogicalHeight; + } + + // The resolve source is left in its initial resource state at the time the render pass ends. + // A resolve operation submitted by a render pass doesn't implicitly change the state of any resource. + // https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_render_pass_ending_access_type + RPRT.EndingAccess.Type = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_RESOLVE; + + auto& ResolveParams = RPRT.EndingAccess.Resolve; + ResolveParams.pSrcResource = pSrcTexD3D12->GetD3D12Resource(); + ResolveParams.pDstResource = pDstTexD3D12->GetD3D12Resource(); + ResolveParams.SubresourceCount = SubresourceCount; + // This pointer is directly referenced by the command list, and the memory for this array + // must remain alive and intact until EndRenderPass is called. + ResolveParams.pSubresourceParameters = m_AttachmentResolveInfo.data(); + ResolveParams.Format = TexFormatToDXGI_Format(RTAttachmentDesc.Format); + ResolveParams.ResolveMode = D3D12_RESOLVE_MODE_AVERAGE; + ResolveParams.PreserveResolveSource = RTAttachmentDesc.StoreOp == ATTACHMENT_STORE_OP_STORE; + } + else + { + RPRT.EndingAccess.Type = AttachmentStoreOpToD3D12EndingAccessType(RTAttachmentDesc.StoreOp); + } + } + else + { + // The attachment will be used in subsequent subpasses - preserve its contents + RPRT.EndingAccess.Type = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE; + } + } + else + { + // Attachment is not used + RenderPassRTs[rt].BeginningAccess.Type = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS; + RenderPassRTs[rt].EndingAccess.Type = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS; + continue; + } + } + + D3D12_RENDER_PASS_DEPTH_STENCIL_DESC RenderPassDS; + if (m_pBoundDepthStencil) + { + RenderPassDS = D3D12_RENDER_PASS_DEPTH_STENCIL_DESC{}; + + const auto& DSAttachmentRef = *Subpass.pDepthStencilAttachment; + VERIFY_EXPR(Subpass.pDepthStencilAttachment != nullptr && DSAttachmentRef.AttachmentIndex != ATTACHMENT_UNUSED); + VERIFY(m_pBoundDepthStencil == FBDesc.ppAttachments[DSAttachmentRef.AttachmentIndex], + "Depth-stencil bufer in the device context is inconsistent with the framebuffer"); + const auto FirstLastUse = m_pActiveRenderPass->GetAttachmentFirstLastUse(DSAttachmentRef.AttachmentIndex); + const auto& DSAttachmentDesc = RPDesc.pAttachments[DSAttachmentRef.AttachmentIndex]; + + RenderPassDS.cpuDescriptor = m_pBoundDepthStencil->GetCPUDescriptorHandle(); + if (FirstLastUse.first == m_SubpassIndex) + { + RenderPassDS.DepthBeginningAccess.Type = AttachmentLoadOpToD3D12BeginningAccessType(DSAttachmentDesc.LoadOp); + RenderPassDS.StencilBeginningAccess.Type = AttachmentLoadOpToD3D12BeginningAccessType(DSAttachmentDesc.StencilLoadOp); + } + else + { + RenderPassDS.DepthBeginningAccess.Type = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE; + RenderPassDS.StencilBeginningAccess.Type = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE; + } + + if (RenderPassDS.DepthBeginningAccess.Type == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR) + { + RenderPassDS.DepthBeginningAccess.Clear.ClearValue.Format = TexFormatToDXGI_Format(DSAttachmentDesc.Format); + RenderPassDS.DepthBeginningAccess.Clear.ClearValue.DepthStencil.Depth = + m_AttachmentClearValues[DSAttachmentRef.AttachmentIndex].DepthStencil.Depth; + } + + if (RenderPassDS.StencilBeginningAccess.Type == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR) + { + RenderPassDS.StencilBeginningAccess.Clear.ClearValue.Format = TexFormatToDXGI_Format(DSAttachmentDesc.Format); + RenderPassDS.StencilBeginningAccess.Clear.ClearValue.DepthStencil.Stencil = + m_AttachmentClearValues[DSAttachmentRef.AttachmentIndex].DepthStencil.Stencil; + } + + if (FirstLastUse.second == m_SubpassIndex) + { + RenderPassDS.DepthEndingAccess.Type = AttachmentStoreOpToD3D12EndingAccessType(DSAttachmentDesc.StoreOp); + RenderPassDS.StencilEndingAccess.Type = AttachmentStoreOpToD3D12EndingAccessType(DSAttachmentDesc.StencilStoreOp); + } + else + { + RenderPassDS.DepthEndingAccess.Type = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE; + RenderPassDS.StencilEndingAccess.Type = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE; + } + } + + auto& CmdCtx = GetCmdContext(); + CmdCtx.AsGraphicsContext().BeginRenderPass( + Subpass.RenderTargetAttachmentCount, + RenderPassRTs, + m_pBoundDepthStencil ? &RenderPassDS : nullptr, + D3D12_RENDER_PASS_FLAG_NONE); + + // Set the viewport to match the framebuffer size + SetViewports(1, nullptr, 0, 0); +} + +void DeviceContextD3D12Impl::BeginRenderPass(const BeginRenderPassAttribs& Attribs) +{ + TDeviceContextBase::BeginRenderPass(Attribs); + + m_AttachmentClearValues.resize(Attribs.ClearValueCount); + for (Uint32 i = 0; i < Attribs.ClearValueCount; ++i) + m_AttachmentClearValues[i] = Attribs.pClearValues[i]; + + TransitionSubpassAttachments(m_SubpassIndex); + CommitSubpassRenderTargets(); +} + +void DeviceContextD3D12Impl::NextSubpass() +{ + auto& CmdCtx = GetCmdContext(); + CmdCtx.AsGraphicsContext().EndRenderPass(); + TDeviceContextBase::NextSubpass(); + TransitionSubpassAttachments(m_SubpassIndex); + CommitSubpassRenderTargets(); +} + +void DeviceContextD3D12Impl::EndRenderPass() +{ + auto& CmdCtx = GetCmdContext(); + CmdCtx.AsGraphicsContext().EndRenderPass(); + TransitionSubpassAttachments(m_SubpassIndex + 1); + TDeviceContextBase::EndRenderPass(); +} + D3D12DynamicAllocation DeviceContextD3D12Impl::AllocateDynamicSpace(size_t NumBytes, size_t Alignment) { return m_DynamicHeap.Allocate(NumBytes, Alignment, m_ContextFrameNumber); @@ -1652,6 +1943,8 @@ void DeviceContextD3D12Impl::GenerateMips(ITextureView* pTexView) void DeviceContextD3D12Impl::FinishCommandList(ICommandList** ppCommandList) { + VERIFY(m_pActiveRenderPass == nullptr, "Finishing command list inside an active render pass."); + CommandListD3D12Impl* pCmdListD3D12(NEW_RC_OBJ(m_CmdListAllocator, "CommandListD3D12Impl instance", CommandListD3D12Impl)(m_pDevice, this, std::move(m_CurrCmdCtx))); pCmdListD3D12->QueryInterface(IID_CommandList, reinterpret_cast<IObject**>(ppCommandList)); Flush(true); @@ -1739,6 +2032,8 @@ void DeviceContextD3D12Impl::EndQuery(IQuery* pQuery) void DeviceContextD3D12Impl::TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) { + VERIFY(m_pActiveRenderPass == nullptr, "State transitions are not allowed inside a render pass"); + auto& CmdCtx = GetCmdContext(); for (Uint32 i = 0; i < BarrierCount; ++i) { diff --git a/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp index 74a69136..65991753 100644 --- a/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp @@ -308,15 +308,26 @@ void EngineFactoryD3D12Impl::CreateDeviceAndContextsD3D12(const EngineD3D12Creat }; // Suppress individual messages by their ID - //D3D12_MESSAGE_ID DenyIds[] = {}; + D3D12_MESSAGE_ID DenyIds[] = + { + // D3D12 WARNING: ID3D12CommandList::ClearRenderTargetView: The clear values do not match those passed to resource creation. + // The clear operation is typically slower as a result; but will still clear to the desired value. + // [ EXECUTION WARNING #820: CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE] + D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE, + + // D3D12 WARNING: ID3D12CommandList::ClearDepthStencilView: The clear values do not match those passed to resource creation. + // The clear operation is typically slower as a result; but will still clear to the desired value. + // [ EXECUTION WARNING #821: CLEARDEPTHSTENCILVIEW_MISMATCHINGCLEARVALUE] + D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_MISMATCHINGCLEARVALUE // + }; D3D12_INFO_QUEUE_FILTER NewFilter = {}; //NewFilter.DenyList.NumCategories = _countof(Categories); //NewFilter.DenyList.pCategoryList = Categories; NewFilter.DenyList.NumSeverities = _countof(Severities); NewFilter.DenyList.pSeverityList = Severities; - //NewFilter.DenyList.NumIDs = _countof(DenyIds); - //NewFilter.DenyList.pIDList = DenyIds; + NewFilter.DenyList.NumIDs = _countof(DenyIds); + NewFilter.DenyList.pIDList = DenyIds; hr = pInfoQueue->PushStorageFilter(&NewFilter); VERIFY(SUCCEEDED(hr), "Failed to push storage filter"); diff --git a/Graphics/GraphicsEngineD3D12/src/FramebufferD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/FramebufferD3D12Impl.cpp new file mode 100644 index 00000000..38b8b956 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/FramebufferD3D12Impl.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "FramebufferD3D12Impl.hpp" +#include "EngineMemory.h" + +namespace Diligent +{ + +FramebufferD3D12Impl::FramebufferD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDevice, + const FramebufferDesc& Desc) : + TFramebufferBase{pRefCounters, pDevice, Desc} +{ +} + +FramebufferD3D12Impl::~FramebufferD3D12Impl() +{ +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index 0315f7f0..381ecb95 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -38,6 +38,8 @@ #include "DeviceContextD3D12Impl.hpp" #include "FenceD3D12Impl.hpp" #include "QueryD3D12Impl.hpp" +#include "RenderPassD3D12Impl.hpp" +#include "FramebufferD3D12Impl.hpp" #include "EngineMemory.h" namespace Diligent @@ -109,7 +111,9 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo sizeof(PipelineStateD3D12Impl), sizeof(ShaderResourceBindingD3D12Impl), sizeof(FenceD3D12Impl), - sizeof(QueryD3D12Impl) + sizeof(QueryD3D12Impl), + sizeof(RenderPassD3D12Impl), + sizeof(FramebufferD3D12Impl) } }, m_pd3d12Device {pd3d12Device}, @@ -522,6 +526,28 @@ void RenderDeviceD3D12Impl::CreateQuery(const QueryDesc& Desc, IQuery** ppQuery) }); } +void RenderDeviceD3D12Impl::CreateRenderPass(const RenderPassDesc& Desc, IRenderPass** ppRenderPass) +{ + CreateDeviceObject("RenderPass", Desc, ppRenderPass, + [&]() // + { + RenderPassD3D12Impl* pRenderPassD3D12(NEW_RC_OBJ(m_RenderPassAllocator, "RenderPassD3D12Impl instance", RenderPassD3D12Impl)(this, Desc)); + pRenderPassD3D12->QueryInterface(IID_RenderPass, reinterpret_cast<IObject**>(ppRenderPass)); + OnCreateDeviceObject(pRenderPassD3D12); + }); +} + +void RenderDeviceD3D12Impl::CreateFramebuffer(const FramebufferDesc& Desc, IFramebuffer** ppFramebuffer) +{ + CreateDeviceObject("Framebuffer", Desc, ppFramebuffer, + [&]() // + { + FramebufferD3D12Impl* pFramebufferD3D12(NEW_RC_OBJ(m_FramebufferAllocator, "FramebufferD3D12Impl instance", FramebufferD3D12Impl)(this, Desc)); + pFramebufferD3D12->QueryInterface(IID_Framebuffer, reinterpret_cast<IObject**>(ppFramebuffer)); + OnCreateDeviceObject(pFramebufferD3D12); + }); +} + DescriptorHeapAllocation RenderDeviceD3D12Impl::AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count /*= 1*/) { VERIFY(Type >= D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV && Type < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES, "Invalid heap type"); diff --git a/Graphics/GraphicsEngineD3D12/src/RenderPassD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderPassD3D12Impl.cpp new file mode 100644 index 00000000..88d4fad2 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/RenderPassD3D12Impl.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "RenderPassD3D12Impl.hpp" +#include "EngineMemory.h" + +namespace Diligent +{ + +RenderPassD3D12Impl::RenderPassD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDevice, + const RenderPassDesc& Desc) : + TRenderPassBase{pRefCounters, pDevice, Desc} +{ +} + +RenderPassD3D12Impl::~RenderPassD3D12Impl() +{ +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index 958df523..418aa8d8 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -745,7 +745,7 @@ __forceinline void TransitionResource(CommandContext& Ctx, VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type"); auto* pTexViewD3D12 = Res.pObject.RawPtr<TextureViewD3D12Impl>(); auto* pTexToTransition = pTexViewD3D12->GetTexture<TextureD3D12Impl>(); - if (pTexToTransition->IsInKnownState() && !pTexToTransition->CheckState(RESOURCE_STATE_SHADER_RESOURCE)) + if (pTexToTransition->IsInKnownState() && !pTexToTransition->CheckAnyState(RESOURCE_STATE_SHADER_RESOURCE | RESOURCE_STATE_INPUT_ATTACHMENT)) Ctx.TransitionResource(pTexToTransition, RESOURCE_STATE_SHADER_RESOURCE); } break; @@ -835,7 +835,7 @@ void RootSignature::DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resou VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type"); const auto* pTexViewD3D12 = Res.pObject.RawPtr<const TextureViewD3D12Impl>(); const auto* pTexD3D12 = pTexViewD3D12->GetTexture<TextureD3D12Impl>(); - if (pTexD3D12->IsInKnownState() && !pTexD3D12->CheckState(RESOURCE_STATE_SHADER_RESOURCE)) + if (pTexD3D12->IsInKnownState() && !pTexD3D12->CheckAnyState(RESOURCE_STATE_SHADER_RESOURCE | RESOURCE_STATE_INPUT_ATTACHMENT)) { LOG_ERROR_MESSAGE("Texture '", pTexD3D12->GetDesc().Name, "' must be in RESOURCE_STATE_SHADER_RESOURCE state. Actual state: ", GetResourceStateString(pTexD3D12->GetState()), |
