summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D12
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-08-15 22:42:13 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-08-15 22:42:13 +0000
commitdf3a2c7c744eae194c79187a59914c6662f69b52 (patch)
tree6f67919092b671b4a0fb637db26f75293f849886 /Graphics/GraphicsEngineD3D12
parentFixed Visual Studio 16.7 build error (diff)
parentVk backend: not setting render pass in SetPipelineState (diff)
downloadDiligentCore-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')
-rw-r--r--Graphics/GraphicsEngineD3D12/CMakeLists.txt4
-rw-r--r--Graphics/GraphicsEngineD3D12/include/CommandContext.hpp19
-rw-r--r--Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp4
-rw-r--r--Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp22
-rw-r--r--Graphics/GraphicsEngineD3D12/include/FramebufferD3D12Impl.hpp54
-rw-r--r--Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp8
-rw-r--r--Graphics/GraphicsEngineD3D12/include/RenderPassD3D12Impl.hpp54
-rw-r--r--Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp2
-rw-r--r--Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp38
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp299
-rw-r--r--Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp17
-rw-r--r--Graphics/GraphicsEngineD3D12/src/FramebufferD3D12Impl.cpp47
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp28
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RenderPassD3D12Impl.cpp47
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RootSignature.cpp4
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()),