summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D11
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2021-03-09 23:33:41 +0000
committerassiduous <assiduous@diligentgraphics.com>2021-03-19 00:38:21 +0000
commit9411711453738341acc10dec8be88675fafd3155 (patch)
treeb61c05f63ba5d0efe2dea1fac323575fb68da6d6 /Graphics/GraphicsEngineD3D11
parentReworked combined and immutable sampler validation in resource signature (diff)
downloadDiligentCore-9411711453738341acc10dec8be88675fafd3155.tar.gz
DiligentCore-9411711453738341acc10dec8be88675fafd3155.zip
Direct3D11: added resource signature
Diffstat (limited to 'Graphics/GraphicsEngineD3D11')
-rw-r--r--Graphics/GraphicsEngineD3D11/CMakeLists.txt7
-rw-r--r--Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.hpp6
-rw-r--r--Graphics/GraphicsEngineD3D11/include/BufferViewD3D11Impl.hpp6
-rw-r--r--Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp140
-rw-r--r--Graphics/GraphicsEngineD3D11/include/EngineD3D11ImplTraits.hpp120
-rw-r--r--Graphics/GraphicsEngineD3D11/include/FenceD3D11Impl.hpp6
-rw-r--r--Graphics/GraphicsEngineD3D11/include/FramebufferD3D11Impl.hpp4
-rw-r--r--Graphics/GraphicsEngineD3D11/include/PipelineResourceAttribsD3D11.hpp115
-rw-r--r--Graphics/GraphicsEngineD3D11/include/PipelineResourceSignatureD3D11Impl.hpp160
-rw-r--r--Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp145
-rw-r--r--Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.hpp4
-rw-r--r--Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.hpp14
-rw-r--r--Graphics/GraphicsEngineD3D11/include/RenderPassD3D11Impl.hpp4
-rw-r--r--Graphics/GraphicsEngineD3D11/include/SamplerD3D11Impl.hpp4
-rw-r--r--Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.hpp7
-rw-r--r--Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.hpp76
-rw-r--r--Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.hpp376
-rw-r--r--Graphics/GraphicsEngineD3D11/include/ShaderVariableManagerD3D11.hpp (renamed from Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.hpp)332
-rw-r--r--Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.hpp4
-rw-r--r--Graphics/GraphicsEngineD3D11/include/TextureViewD3D11Impl.hpp4
-rw-r--r--Graphics/GraphicsEngineD3D11/src/BufferViewD3D11Impl.cpp3
-rwxr-xr-xGraphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp1051
-rw-r--r--Graphics/GraphicsEngineD3D11/src/PipelineResourceSignatureD3D11Impl.cpp489
-rw-r--r--Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp774
-rw-r--r--Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp147
-rw-r--r--Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp4
-rw-r--r--Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp209
-rwxr-xr-xGraphics/GraphicsEngineD3D11/src/ShaderResourceCacheD3D11.cpp642
-rwxr-xr-xGraphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp1022
-rwxr-xr-xGraphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp28
-rw-r--r--Graphics/GraphicsEngineD3D11/src/ShaderVariableManagerD3D11.cpp857
31 files changed, 3799 insertions, 2961 deletions
diff --git a/Graphics/GraphicsEngineD3D11/CMakeLists.txt b/Graphics/GraphicsEngineD3D11/CMakeLists.txt
index 05715440..cd903d79 100644
--- a/Graphics/GraphicsEngineD3D11/CMakeLists.txt
+++ b/Graphics/GraphicsEngineD3D11/CMakeLists.txt
@@ -16,6 +16,8 @@ set(INCLUDE
include/FenceD3D11Impl.hpp
include/FramebufferD3D11Impl.hpp
include/PipelineStateD3D11Impl.hpp
+ include/PipelineResourceAttribsD3D11.hpp
+ include/PipelineResourceSignatureD3D11Impl.hpp
include/QueryD3D11Impl.hpp
include/RenderDeviceD3D11Impl.hpp
include/RenderPassD3D11Impl.hpp
@@ -23,7 +25,7 @@ set(INCLUDE
include/ShaderD3D11Impl.hpp
include/ShaderResourceBindingD3D11Impl.hpp
include/ShaderResourceCacheD3D11.hpp
- include/ShaderResourceLayoutD3D11.hpp
+ include/ShaderVariableManagerD3D11.hpp
include/ShaderResourcesD3D11.hpp
include/SwapChainD3D11Impl.hpp
include/targetver.h
@@ -63,6 +65,7 @@ set(SRC
src/FramebufferD3D11Impl.cpp
src/GUIDDef.cpp
src/PipelineStateD3D11Impl.cpp
+ src/PipelineResourceSignatureD3D11Impl.cpp
src/QueryD3D11Impl.cpp
src/RenderDeviceD3D11Impl.cpp
src/RenderPassD3D11Impl.cpp
@@ -70,7 +73,7 @@ set(SRC
src/ShaderD3D11Impl.cpp
src/ShaderResourceBindingD3D11Impl.cpp
src/ShaderResourceCacheD3D11.cpp
- src/ShaderResourceLayoutD3D11.cpp
+ src/ShaderVariableManagerD3D11.cpp
src/ShaderResourcesD3D11.cpp
src/SwapChainD3D11Impl.cpp
src/Texture1D_D3D11.cpp
diff --git a/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.hpp
index 4d82cd39..2f523ea5 100644
--- a/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.hpp
@@ -39,13 +39,11 @@
namespace Diligent
{
-class FixedBlockMemoryAllocator;
-
/// Buffer object implementation in Direct3D11 backend.
-class BufferD3D11Impl final : public BufferBase<IBufferD3D11, RenderDeviceD3D11Impl, BufferViewD3D11Impl, FixedBlockMemoryAllocator>
+class BufferD3D11Impl final : public BufferBase<EngineD3D11ImplTraits>
{
public:
- using TBufferBase = BufferBase<IBufferD3D11, RenderDeviceD3D11Impl, BufferViewD3D11Impl, FixedBlockMemoryAllocator>;
+ using TBufferBase = BufferBase<EngineD3D11ImplTraits>;
BufferD3D11Impl(IReferenceCounters* pRefCounters,
FixedBlockMemoryAllocator& BuffViewObjMemAllocator,
diff --git a/Graphics/GraphicsEngineD3D11/include/BufferViewD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/BufferViewD3D11Impl.hpp
index 0f9ee914..44121a4a 100644
--- a/Graphics/GraphicsEngineD3D11/include/BufferViewD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/BufferViewD3D11Impl.hpp
@@ -41,15 +41,15 @@ namespace Diligent
class FixedBlockMemoryAllocator;
/// Buffer view implementation in Direct3D11 backend.
-class BufferViewD3D11Impl final : public BufferViewBase<IBufferViewD3D11, RenderDeviceD3D11Impl>
+class BufferViewD3D11Impl final : public BufferViewBase<EngineD3D11ImplTraits>
{
public:
- using TBufferViewBase = BufferViewBase<IBufferViewD3D11, RenderDeviceD3D11Impl>;
+ using TBufferViewBase = BufferViewBase<EngineD3D11ImplTraits>;
BufferViewD3D11Impl(IReferenceCounters* pRefCounters,
RenderDeviceD3D11Impl* pDevice,
const BufferViewDesc& ViewDesc,
- IBuffer* pBuffer,
+ BufferD3D11Impl* pBuffer,
ID3D11View* pD3D11View,
bool bIsDefaultView);
diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp
index 3c7bf09c..5c72ed1f 100644
--- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp
@@ -43,32 +43,20 @@
#include "DisjointQueryPool.hpp"
#include "BottomLevelASBase.hpp"
#include "TopLevelASBase.hpp"
+#include "ShaderResourceBindingD3D11Impl.hpp"
-#ifdef DILIGENT_DEBUG
+#ifdef DILIGENT_DEVELOPMENT
# define VERIFY_CONTEXT_BINDINGS
#endif
namespace Diligent
{
-struct DeviceContextD3D11ImplTraits
-{
- using BufferType = BufferD3D11Impl;
- using TextureType = TextureBaseD3D11;
- using PipelineStateType = PipelineStateD3D11Impl;
- using DeviceType = RenderDeviceD3D11Impl;
- using QueryType = QueryD3D11Impl;
- using FramebufferType = FramebufferD3D11Impl;
- using RenderPassType = RenderPassD3D11Impl;
- using BottomLevelASType = BottomLevelASBase<IBottomLevelAS, RenderDeviceD3D11Impl>;
- using TopLevelASType = TopLevelASBase<ITopLevelAS, BottomLevelASType, RenderDeviceD3D11Impl>;
-};
-
/// Device context implementation in Direct3D11 backend.
-class DeviceContextD3D11Impl final : public DeviceContextBase<IDeviceContextD3D11, DeviceContextD3D11ImplTraits>
+class DeviceContextD3D11Impl final : public DeviceContextBase<EngineD3D11ImplTraits>
{
public:
- using TDeviceContextBase = DeviceContextBase<IDeviceContextD3D11, DeviceContextD3D11ImplTraits>;
+ using TDeviceContextBase = DeviceContextBase<EngineD3D11ImplTraits>;
DeviceContextD3D11Impl(IReferenceCounters* pRefCounters,
IMemoryAllocator& Allocator,
@@ -288,8 +276,8 @@ public:
/// Unbinds all render targets. Used when resizing the swap chain.
virtual void ResetRenderTargets() override final;
- /// Number of different shader types (Vertex, Pixel, Geometry, Domain, Hull, Compute)
- static constexpr int NumShaderTypes = 6;
+ void TransitionResource(TextureBaseD3D11* pTexture, RESOURCE_STATE NewState, RESOURCE_STATE OldState = RESOURCE_STATE_UNKNOWN, bool UpdateResourceState = true);
+ void TransitionResource(BufferD3D11Impl* pBuffer, RESOURCE_STATE NewState, RESOURCE_STATE OldState = RESOURCE_STATE_UNKNOWN, bool UpdateResourceState = true);
private:
/// Commits d3d11 index buffer to d3d11 device context.
@@ -341,54 +329,53 @@ private:
/// Ends current subpass
void EndSubpass();
- template <bool TransitionResources,
- bool CommitResources>
- void TransitionAndCommitShaderResources(IPipelineState* pPSO, IShaderResourceBinding* pShaderResourceBinding, bool VerifyStates);
-
void ClearStateCache();
+ void BindShaderResources();
+
+ using TBindingsPerStage = PipelineResourceSignatureD3D11Impl::TBindingsPerStage;
+ using TCommittedResources = ShaderResourceCacheD3D11::TCommittedResources;
+ using TMinMaxSlotPerStage = ShaderResourceCacheD3D11::TMinMaxSlotPerStage;
+
+ static constexpr auto NumShaderTypes = PipelineResourceSignatureD3D11Impl::NumShaderTypes;
+
+#ifdef DILIGENT_DEVELOPMENT
+ void DvpValidateCommittedShaderResources();
+#endif
+
std::shared_ptr<DisjointQueryPool::DisjointQueryWrapper> BeginDisjointQuery();
CComPtr<ID3D11DeviceContext> m_pd3d11DeviceContext; ///< D3D11 device context
- // clang-format off
-
- /// An array of D3D11 constant buffers committed to D3D11 device context,
- /// for each shader type. The context addref's all bound resources, so we do
- /// not need to keep strong references.
- ID3D11Buffer* m_CommittedD3D11CBs [NumShaderTypes][D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {};
-
- /// An array of D3D11 shader resource views committed to D3D11 device context,
- /// for each shader type. The context addref's all bound resources, so we do
- /// not need to keep strong references.
- ID3D11ShaderResourceView* m_CommittedD3D11SRVs [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
-
- /// An array of D3D11 samplers committed to D3D11 device context,
- /// for each shader type. The context addref's all bound resources, so we do
- /// not need to keep strong references.
- ID3D11SamplerState* m_CommittedD3D11Samplers[NumShaderTypes][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {};
-
- /// An array of D3D11 UAVs committed to D3D11 device context,
- /// for each shader type. The context addref's all bound resources, so we do
- /// not need to keep strong references.
- ID3D11UnorderedAccessView* m_CommittedD3D11UAVs [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
-
- /// An array of D3D11 resources commited as SRV to D3D11 device context,
- /// for each shader type. The context addref's all bound resources, so we do
- /// not need to keep strong references.
- ID3D11Resource* m_CommittedD3D11SRVResources [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
-
- /// An array of D3D11 resources commited as UAV to D3D11 device context,
- /// for each shader type. The context addref's all bound resources, so we do
- /// not need to keep strong references.
- ID3D11Resource* m_CommittedD3D11UAVResources [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
-
- Uint8 m_NumCommittedCBs [NumShaderTypes] = {};
- Uint8 m_NumCommittedSRVs [NumShaderTypes] = {};
- Uint8 m_NumCommittedSamplers[NumShaderTypes] = {};
- Uint8 m_NumCommittedUAVs [NumShaderTypes] = {};
-
- // clang-format on
+ struct SRBState
+ {
+ // Do not use strong references!
+ std::array<ShaderResourceBindingD3D11Impl*, MAX_RESOURCE_SIGNATURES> SRBs = {};
+
+ using Bitfield = Uint8;
+ static_assert(sizeof(Bitfield) * 8 >= MAX_RESOURCE_SIGNATURES, "not enought space to store MAX_RESOURCE_SIGNATURES bits");
+
+ Bitfield ActiveSRBMask = 0; // Indicates which SRBs are active in current PSO
+ Bitfield StaleSRBMask = 0; // Indicates stale SRBs that have descriptor sets that need to be bound
+
+ SHADER_TYPE ActiveStages = SHADER_TYPE_UNKNOWN;
+
+#ifdef DILIGENT_DEVELOPMENT
+ bool CommittedResourcesValidated = false;
+
+ // Binding offsets that was used at last BindProgramResources() call.
+ std::array<TBindingsPerStage, MAX_RESOURCE_SIGNATURES> BoundResOffsets = {};
+#endif
+
+ SRBState()
+ {}
+
+ void SetStaleSRBBit(Uint32 Index) { StaleSRBMask |= static_cast<Bitfield>(1u << Index); }
+ void ClearStaleSRBBit(Uint32 Index) { StaleSRBMask &= static_cast<Bitfield>(~(1u << Index)); }
+
+ } m_BindInfo;
+
+ TCommittedResources m_CommittedRes;
/// An array of D3D11 vertex buffers committed to D3D device context.
/// There is no need to keep strong references because D3D11 device context
@@ -438,60 +425,51 @@ private:
/// Helper template function used to facilitate context verification
template <UINT MaxResources, typename TD3D11ResourceType, typename TGetD3D11ResourcesType>
- void dbgVerifyCommittedResources(TD3D11ResourceType CommittedD3D11ResourcesArr[][MaxResources],
+ void DvpVerifyCommittedResources(TD3D11ResourceType CommittedD3D11ResourcesArr[][MaxResources],
Uint8 NumCommittedResourcesArr[],
TGetD3D11ResourcesType GetD3D11ResMethods[],
const Char* ResourceName,
- SHADER_TYPE ShaderType);
+ SHADER_TYPE ShaderStages);
/// Helper template function used to facilitate validation of SRV and UAV consistency with D3D11 resources
template <UINT MaxResources, typename TD3D11ViewType>
- void dbgVerifyViewConsistency(TD3D11ViewType CommittedD3D11ViewArr[][MaxResources],
+ void DvpVerifyViewConsistency(TD3D11ViewType CommittedD3D11ViewArr[][MaxResources],
ID3D11Resource* CommittedD3D11ResourcesArr[][MaxResources],
Uint8 NumCommittedResourcesArr[],
const Char* ResourceName,
- SHADER_TYPE ShaderType);
+ SHADER_TYPE ShaderStages);
/// Debug function that verifies that SRVs cached in m_CommittedD3D11SRVs
/// array comply with resources actually committed to D3D11 device context
- void dbgVerifyCommittedSRVs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN);
+ void DvpVerifyCommittedSRVs(SHADER_TYPE ShaderStages);
/// Debug function that verifies that UAVs cached in m_CommittedD3D11UAVs
/// array comply with resources actually committed to D3D11 device context
- void dbgVerifyCommittedUAVs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN);
+ void DvpVerifyCommittedUAVs(SHADER_TYPE ShaderStages);
/// Debug function that verifies that samplers cached in m_CommittedD3D11Samplers
/// array comply with resources actually committed to D3D11 device context
- void dbgVerifyCommittedSamplers(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN);
+ void DvpVerifyCommittedSamplers(SHADER_TYPE ShaderStages);
/// Debug function that verifies that constant buffers cached in m_CommittedD3D11CBs
/// array comply with buffers actually committed to D3D11 device context
- void dbgVerifyCommittedCBs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN);
+ void DvpVerifyCommittedCBs(SHADER_TYPE ShaderStages);
/// Debug function that verifies that index buffer cached in
/// m_CommittedD3D11IndexBuffer is the buffer actually committed to D3D11
/// device context
- void dbgVerifyCommittedIndexBuffer();
+ void DvpVerifyCommittedIndexBuffer();
/// Debug function that verifies that vertex buffers cached in
/// m_CommittedD3D11VertexBuffers are the buffers actually committed to D3D11
/// device context
- void dbgVerifyCommittedVertexBuffers();
+ void DvpVerifyCommittedVertexBuffers();
/// Debug function that verifies that shaders cached in
/// m_CommittedD3DShaders are the shaders actually committed to D3D11
/// device context
- void dbgVerifyCommittedShaders();
-
-#else
-# define dbgVerifyRenderTargetFormats(...)
-# define dbgVerifyCommittedSRVs(...)
-# define dbgVerifyCommittedUAVs(...)
-# define dbgVerifyCommittedSamplers(...)
-# define dbgVerifyCommittedCBs(...)
-# define dbgVerifyCommittedIndexBuffer(...)
-# define dbgVerifyCommittedVertexBuffers(...)
-# define dbgVerifyCommittedShaders(...)
+ void DvpVerifyCommittedShaders();
+
#endif // VERIFY_CONTEXT_BINDINGS
};
diff --git a/Graphics/GraphicsEngineD3D11/include/EngineD3D11ImplTraits.hpp b/Graphics/GraphicsEngineD3D11/include/EngineD3D11ImplTraits.hpp
new file mode 100644
index 00000000..87e3e0cb
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D11/include/EngineD3D11ImplTraits.hpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2019-2021 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::EngineD3D11ImplTraits struct
+
+#include "RenderDeviceD3D11.h"
+#include "PipelineStateD3D11.h"
+#include "ShaderResourceBindingD3D11.h"
+#include "BufferD3D11.h"
+#include "BufferViewD3D11.h"
+#include "TextureD3D11.h"
+#include "TextureViewD3D11.h"
+#include "ShaderD3D11.h"
+#include "SamplerD3D11.h"
+#include "FenceD3D11.h"
+#include "QueryD3D11.h"
+#include "RenderPass.h"
+#include "Framebuffer.h"
+#include "PipelineResourceSignature.h"
+#include "DeviceContextD3D11.h"
+
+namespace Diligent
+{
+
+class RenderDeviceD3D11Impl;
+class DeviceContextD3D11Impl;
+class PipelineStateD3D11Impl;
+class ShaderResourceBindingD3D11Impl;
+class BufferD3D11Impl;
+class BufferViewD3D11Impl;
+class TextureBaseD3D11;
+class TextureViewD3D11Impl;
+class ShaderD3D11Impl;
+class SamplerD3D11Impl;
+class FenceD3D11Impl;
+class QueryD3D11Impl;
+class RenderPassD3D11Impl;
+class FramebufferD3D11Impl;
+class BottomLevelASD3D11Impl;
+class TopLevelASD3D11Impl;
+class ShaderBindingTableD3D11Impl;
+class PipelineResourceSignatureD3D11Impl;
+
+class FixedBlockMemoryAllocator;
+
+class ShaderResourceCacheD3D11;
+class ShaderVariableManagerD3D11;
+
+struct EngineD3D11ImplTraits
+{
+ using RenderDeviceInterface = IRenderDeviceD3D11;
+ using DeviceContextInterface = IDeviceContextD3D11;
+ using PipelineStateInterface = IPipelineStateD3D11;
+ using ShaderResourceBindingInterface = IShaderResourceBindingD3D11;
+ using BufferInterface = IBufferD3D11;
+ using BufferViewInterface = IBufferViewD3D11;
+ using TextureInterface = ITextureD3D11;
+ using TextureViewInterface = ITextureViewD3D11;
+ using ShaderInterface = IShaderD3D11;
+ using SamplerInterface = ISamplerD3D11;
+ using FenceInterface = IFenceD3D11;
+ using QueryInterface = IQueryD3D11;
+ using RenderPassInterface = IRenderPass;
+ using FramebufferInterface = IFramebuffer;
+ using PipelineResourceSignatureInterface = IPipelineResourceSignature;
+
+ using RenderDeviceImplType = RenderDeviceD3D11Impl;
+ using DeviceContextImplType = DeviceContextD3D11Impl;
+ using PipelineStateImplType = PipelineStateD3D11Impl;
+ using ShaderResourceBindingImplType = ShaderResourceBindingD3D11Impl;
+ using BufferImplType = BufferD3D11Impl;
+ using BufferViewImplType = BufferViewD3D11Impl;
+ using TextureImplType = TextureBaseD3D11;
+ using TextureViewImplType = TextureViewD3D11Impl;
+ using ShaderImplType = ShaderD3D11Impl;
+ using SamplerImplType = SamplerD3D11Impl;
+ using FenceImplType = FenceD3D11Impl;
+ using QueryImplType = QueryD3D11Impl;
+ using RenderPassImplType = RenderPassD3D11Impl;
+ using FramebufferImplType = FramebufferD3D11Impl;
+ using BottomLevelASImplType = BottomLevelASD3D11Impl;
+ using TopLevelASImplType = TopLevelASD3D11Impl;
+ using ShaderBindingTableImplType = ShaderBindingTableD3D11Impl;
+ using PipelineResourceSignatureImplType = PipelineResourceSignatureD3D11Impl;
+
+ using BuffViewObjAllocatorType = FixedBlockMemoryAllocator;
+ using TexViewObjAllocatorType = FixedBlockMemoryAllocator;
+
+ using ShaderResourceCacheImplType = ShaderResourceCacheD3D11;
+ using ShaderVariableManagerImplType = ShaderVariableManagerD3D11;
+};
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/include/FenceD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/FenceD3D11Impl.hpp
index f1e0e87a..9385d3c4 100644
--- a/Graphics/GraphicsEngineD3D11/include/FenceD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/FenceD3D11Impl.hpp
@@ -39,13 +39,11 @@
namespace Diligent
{
-class FixedBlockMemoryAllocator;
-
/// Fence implementation in Direct3D11 backend.
-class FenceD3D11Impl final : public FenceBase<IFenceD3D11, RenderDeviceD3D11Impl>
+class FenceD3D11Impl final : public FenceBase<EngineD3D11ImplTraits>
{
public:
- using TFenceBase = FenceBase<IFenceD3D11, RenderDeviceD3D11Impl>;
+ using TFenceBase = FenceBase<EngineD3D11ImplTraits>;
FenceD3D11Impl(IReferenceCounters* pRefCounters,
RenderDeviceD3D11Impl* pDevice,
diff --git a/Graphics/GraphicsEngineD3D11/include/FramebufferD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/FramebufferD3D11Impl.hpp
index 39ca46e9..1cd1654a 100644
--- a/Graphics/GraphicsEngineD3D11/include/FramebufferD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/FramebufferD3D11Impl.hpp
@@ -40,10 +40,10 @@ namespace Diligent
class FixedBlockMemoryAllocator;
/// Render pass implementation in Direct3D11 backend.
-class FramebufferD3D11Impl final : public FramebufferBase<IFramebuffer, RenderDeviceD3D11Impl>
+class FramebufferD3D11Impl final : public FramebufferBase<EngineD3D11ImplTraits>
{
public:
- using TFramebufferBase = FramebufferBase<IFramebuffer, RenderDeviceD3D11Impl>;
+ using TFramebufferBase = FramebufferBase<EngineD3D11ImplTraits>;
FramebufferD3D11Impl(IReferenceCounters* pRefCounters,
RenderDeviceD3D11Impl* pDevice,
diff --git a/Graphics/GraphicsEngineD3D11/include/PipelineResourceAttribsD3D11.hpp b/Graphics/GraphicsEngineD3D11/include/PipelineResourceAttribsD3D11.hpp
new file mode 100644
index 00000000..ad5ae8c1
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D11/include/PipelineResourceAttribsD3D11.hpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2019-2021 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::PipelineResourceAttribsD3D11 struct
+
+#include <array>
+
+#include "BasicTypes.h"
+#include "DebugUtilities.hpp"
+
+namespace Diligent
+{
+
+enum DESCRIPTOR_RANGE : Uint32
+{
+ DESCRIPTOR_RANGE_CBV = 0,
+ DESCRIPTOR_RANGE_SRV,
+ DESCRIPTOR_RANGE_SAMPLER,
+ DESCRIPTOR_RANGE_UAV,
+ DESCRIPTOR_RANGE_COUNT,
+ DESCRIPTOR_RANGE_UNKNOWN = ~0u
+};
+DESCRIPTOR_RANGE ShaderResourceToDescriptorRange(SHADER_RESOURCE_TYPE Type);
+
+// sizeof(PipelineResourceAttribsD3D11) == 4, x64
+struct PipelineResourceAttribsD3D11
+{
+private:
+ static constexpr Uint32 _CacheOffsetBits = 10;
+ static constexpr Uint32 _SamplerIndBits = 10;
+ static constexpr Uint32 _SamplerAssignedBits = 1;
+
+public:
+ static constexpr Uint32 InvalidCacheOffset = (1u << _CacheOffsetBits) - 1;
+ static constexpr Uint32 InvalidSamplerInd = (1u << _SamplerIndBits) - 1;
+
+ /// Number of different shader types (Vertex, Pixel, Geometry, Domain, Hull, Compute)
+ static constexpr Uint32 NumShaderTypes = 6;
+
+ using TBindPoints = std::array<Uint8, NumShaderTypes>;
+ static constexpr Uint8 InvalidBindPoint = 0xFF;
+ static constexpr TBindPoints InvalidBindPoints = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+ // clang-format off
+ const Uint32 CacheOffset : _CacheOffsetBits; // SRB and Signature has the same cache offsets for static resources.
+ const Uint32 SamplerInd : _SamplerIndBits; // Index of the assigned sampler in m_Desc.Resources.
+ const Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; // Immutable sampler flag.
+ TBindPoints BindPoints = InvalidBindPoints;
+ // clang-format on
+
+ PipelineResourceAttribsD3D11(Uint32 _CacheOffset,
+ Uint32 _SamplerInd,
+ bool _ImtblSamplerAssigned) noexcept :
+ // clang-format off
+ CacheOffset {_CacheOffset },
+ SamplerInd {_SamplerInd },
+ ImtblSamplerAssigned{_ImtblSamplerAssigned ? 1u : 0u}
+ // clang-format on
+ {
+ VERIFY(CacheOffset == _CacheOffset, "Cache offset (", _CacheOffset, ") exceeds maximum representable value");
+ VERIFY(SamplerInd == _SamplerInd, "Sampler index (", _SamplerInd, ") exceeds maximum representable value");
+ }
+
+ bool IsSamplerAssigned() const { return SamplerInd != InvalidSamplerInd; }
+ bool IsImmutableSamplerAssigned() const { return ImtblSamplerAssigned != 0; }
+
+ bool IsCompatibleWith(const PipelineResourceAttribsD3D11& rhs) const
+ {
+ // Ignore sampler index.
+ // clang-format off
+ return CacheOffset == rhs.CacheOffset &&
+ IsImmutableSamplerAssigned() == rhs.IsImmutableSamplerAssigned() &&
+ BindPoints == rhs.BindPoints;
+ // clang-format on
+ }
+
+ size_t GetHash() const
+ {
+ Uint64 h = 0;
+ for (Uint32 i = 0; i < NumShaderTypes; ++i)
+ {
+ h |= (BindPoints[i] << (i * 8));
+ }
+ return ComputeHash(h);
+ }
+};
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/include/PipelineResourceSignatureD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/PipelineResourceSignatureD3D11Impl.hpp
new file mode 100644
index 00000000..fc6233be
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D11/include/PipelineResourceSignatureD3D11Impl.hpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2019-2021 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::PipelineResourceSignatureD3D11Impl class
+
+#include <array>
+
+#include "ResourceBindingMap.hpp"
+
+#include "EngineD3D11ImplTraits.hpp"
+#include "PipelineResourceSignatureBase.hpp"
+#include "PipelineResourceAttribsD3D11.hpp"
+
+// ShaderVariableManagerD3D11, ShaderResourceCacheD3D11, and ShaderResourceBindingD3D11Impl
+// are required by PipelineResourceSignatureBase
+#include "ShaderVariableManagerD3D11.hpp"
+#include "ShaderResourceBindingD3D11Impl.hpp"
+#include "ShaderResourceCacheD3D11.hpp"
+
+namespace Diligent
+{
+
+/// Implementation of the Diligent::PipelineResourceSignatureD3D11Impl class
+class PipelineResourceSignatureD3D11Impl final : public PipelineResourceSignatureBase<EngineD3D11ImplTraits>
+{
+public:
+ using TPipelineResourceSignatureBase = PipelineResourceSignatureBase<EngineD3D11ImplTraits>;
+
+ PipelineResourceSignatureD3D11Impl(IReferenceCounters* pRefCounters,
+ RenderDeviceD3D11Impl* pDevice,
+ const PipelineResourceSignatureDesc& Desc,
+ bool bIsDeviceInternal = false);
+ ~PipelineResourceSignatureD3D11Impl();
+
+ using ResourceAttribs = PipelineResourceAttribsD3D11;
+ using TBindPoints = PipelineResourceAttribsD3D11::TBindPoints;
+
+ static constexpr auto NumShaderTypes = ResourceAttribs::NumShaderTypes;
+ static constexpr auto InvalidBindPoint = ResourceAttribs::InvalidBindPoint;
+ static constexpr auto InvalidBindPoints = ResourceAttribs::InvalidBindPoints;
+
+ const ResourceAttribs& GetResourceAttribs(Uint32 ResIndex) const
+ {
+ VERIFY_EXPR(ResIndex < m_Desc.NumResources);
+ return m_pResourceAttribs[ResIndex];
+ }
+
+ // sizeof(ImmutableSamplerAttribs) == 16, x64
+ struct ImmutableSamplerAttribs
+ {
+ private:
+ static constexpr Uint32 _CacheOffsetBits = 10;
+ static constexpr Uint32 _ArraySizeBits = 22;
+
+ public:
+ static constexpr Uint32 InvalidCacheOffset = (1u << _CacheOffsetBits) - 1;
+ static_assert(InvalidCacheOffset == ResourceAttribs::InvalidCacheOffset,
+ "InvalidCacheOffset value mismatch between ResourceAttribs and ImmutableSamplerAttribs");
+
+ // clang-format off
+ RefCntAutoPtr<ISampler> pSampler;
+ TBindPoints BindPoints = InvalidBindPoints;
+ TBindPoints LastBindPoints = InvalidBindPoints; // array size for each stage may be different
+ Uint32 CacheOffset : _CacheOffsetBits;
+ Uint32 ArraySize : _ArraySizeBits;
+ // clang-format on
+
+ ImmutableSamplerAttribs() :
+ CacheOffset{InvalidCacheOffset},
+ ArraySize{0}
+ {}
+
+ bool IsAllocated() const { return CacheOffset != InvalidCacheOffset; }
+ SamplerD3D11Impl* GetSamplerD3D11() const { return ValidatedCast<SamplerD3D11Impl>(pSampler.RawPtr<ISampler>()); }
+ };
+
+ const ImmutableSamplerAttribs& GetImmutableSamplerAttribs(Uint32 SampIndex) const
+ {
+ VERIFY_EXPR(SampIndex < m_Desc.NumImmutableSamplers);
+ return m_ImmutableSamplers[SampIndex];
+ }
+
+ using TBindings = ShaderResourceCacheD3D11::TResourceCount;
+ using TBindingsPerStage = ShaderResourceCacheD3D11::TBindingsPerStage;
+
+ void AddBindings(TBindingsPerStage& Bindings) const;
+
+ void InitSRBResourceCache(ShaderResourceCacheD3D11& ResourceCache);
+
+ void UpdateShaderResourceBindingMap(ResourceBinding::TMap& ResourceMap, SHADER_TYPE ShaderStage, const TBindingsPerStage& BaseBindings) const;
+
+ // Copies static resources from the static resource cache to the destination cache
+ void CopyStaticResources(ShaderResourceCacheD3D11& ResourceCache) const;
+
+#ifdef DILIGENT_DEVELOPMENT
+ /// Verifies committed resource attribs using the SPIRV resource attributes from the PSO.
+ bool DvpValidateCommittedResource(const D3DShaderResourceAttribs& D3DAttribs,
+ RESOURCE_DIMENSION ResourceDim,
+ bool IsMultisample,
+ Uint32 ResIndex,
+ const ShaderResourceCacheD3D11& ResourceCache,
+ const char* ShaderName,
+ const char* PSOName) const;
+#endif
+
+private:
+ void CreateLayout();
+
+ void Destruct();
+
+private:
+ TBindings m_ResourceCount = {};
+ TBindingsPerStage m_BindingCountPerStage = {};
+
+ ResourceAttribs* m_pResourceAttribs = nullptr; // [m_Desc.NumResources]
+ ImmutableSamplerAttribs* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers]
+};
+
+
+__forceinline void PipelineResourceSignatureD3D11Impl::AddBindings(TBindingsPerStage& Bindings) const
+{
+ for (Uint32 s = 0; s < Bindings.size(); ++s)
+ {
+ for (Uint32 i = 0; i < Bindings[s].size(); ++i)
+ {
+ Uint32 Count = Bindings[s][i] + m_BindingCountPerStage[s][i];
+ VERIFY_EXPR(Count < std::numeric_limits<Uint8>::max());
+ Bindings[s][i] = static_cast<Uint8>(Count);
+ }
+ }
+}
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp
index 9b1a9330..f473416f 100644
--- a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp
@@ -33,21 +33,18 @@
#include "PipelineStateD3D11.h"
#include "RenderDeviceD3D11.h"
#include "PipelineStateBase.hpp"
-#include "ShaderResourceLayoutD3D11.hpp"
-#include "SRBMemoryAllocator.hpp"
-#include "RenderDeviceD3D11Impl.hpp"
+
+#include "PipelineResourceSignatureD3D11Impl.hpp" // Required by PipelineStateBase
#include "ShaderD3D11Impl.hpp"
namespace Diligent
{
-class FixedBlockMemoryAllocator;
-
/// Pipeline state object implementation in Direct3D11 backend.
-class PipelineStateD3D11Impl final : public PipelineStateBase<IPipelineStateD3D11, RenderDeviceD3D11Impl>
+class PipelineStateD3D11Impl final : public PipelineStateBase<EngineD3D11ImplTraits>
{
public:
- using TPipelineStateBase = PipelineStateBase<IPipelineStateD3D11, RenderDeviceD3D11Impl>;
+ using TPipelineStateBase = PipelineStateBase<EngineD3D11ImplTraits>;
PipelineStateD3D11Impl(IReferenceCounters* pRefCounters,
class RenderDeviceD3D11Impl* pDeviceD3D11,
@@ -59,130 +56,88 @@ public:
virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
- /// Implementation of IPipelineState::BindStaticResources() in Direct3D11 backend.
- virtual void DILIGENT_CALL_TYPE BindStaticResources(Uint32 ShaderFlags,
- IResourceMapping* pResourceMapping,
- Uint32 Flags) override final;
-
- /// Implementation of IPipelineState::GetStaticVariableCount() in Direct3D11 backend.
- virtual Uint32 DILIGENT_CALL_TYPE GetStaticVariableCount(SHADER_TYPE ShaderType) const override final;
-
- /// Implementation of IPipelineState::GetStaticVariableByName() in Direct3D11 backend.
- virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetStaticVariableByName(SHADER_TYPE ShaderType,
- const Char* Name) override final;
-
- /// Implementation of IPipelineState::GetStaticVariableByIndex() in Direct3D11 backend.
- virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetStaticVariableByIndex(SHADER_TYPE ShaderType,
- Uint32 Index) override final;
-
- /// Implementation of IPipelineState::CreateShaderResourceBinding() in Direct3D11 backend.
- virtual void DILIGENT_CALL_TYPE CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding,
- bool InitStaticResources) override final;
-
/// Implementation of IPipelineState::IsCompatibleWith() in Direct3D11 backend.
virtual bool DILIGENT_CALL_TYPE IsCompatibleWith(const IPipelineState* pPSO) const override final;
-
/// Implementation of IPipelineStateD3D11::GetD3D11BlendState() method.
- virtual ID3D11BlendState* DILIGENT_CALL_TYPE GetD3D11BlendState() override final;
+ virtual ID3D11BlendState* DILIGENT_CALL_TYPE GetD3D11BlendState() override final { return m_pd3d11BlendState; }
/// Implementation of IPipelineStateD3D11::GetD3D11RasterizerState() method.
- virtual ID3D11RasterizerState* DILIGENT_CALL_TYPE GetD3D11RasterizerState() override final;
+ virtual ID3D11RasterizerState* DILIGENT_CALL_TYPE GetD3D11RasterizerState() override final { return m_pd3d11RasterizerState; }
/// Implementation of IPipelineStateD3D11::GetD3D11DepthStencilState() method.
- virtual ID3D11DepthStencilState* DILIGENT_CALL_TYPE GetD3D11DepthStencilState() override final;
+ virtual ID3D11DepthStencilState* DILIGENT_CALL_TYPE GetD3D11DepthStencilState() override final { return m_pd3d11DepthStencilState; }
/// Implementation of IPipelineStateD3D11::GetD3D11InputLayout() method.
- virtual ID3D11InputLayout* DILIGENT_CALL_TYPE GetD3D11InputLayout() override final;
+ virtual ID3D11InputLayout* DILIGENT_CALL_TYPE GetD3D11InputLayout() override final { return m_pd3d11InputLayout; }
/// Implementation of IPipelineStateD3D11::GetD3D11VertexShader() method.
- virtual ID3D11VertexShader* DILIGENT_CALL_TYPE GetD3D11VertexShader() override final;
+ virtual ID3D11VertexShader* DILIGENT_CALL_TYPE GetD3D11VertexShader() override final { return m_pVS; }
/// Implementation of IPipelineStateD3D11::GetD3D11PixelShader() method.
- virtual ID3D11PixelShader* DILIGENT_CALL_TYPE GetD3D11PixelShader() override final;
+ virtual ID3D11PixelShader* DILIGENT_CALL_TYPE GetD3D11PixelShader() override final { return m_pPS; }
/// Implementation of IPipelineStateD3D11::GetD3D11GeometryShader() method.
- virtual ID3D11GeometryShader* DILIGENT_CALL_TYPE GetD3D11GeometryShader() override final;
+ virtual ID3D11GeometryShader* DILIGENT_CALL_TYPE GetD3D11GeometryShader() override final { return m_pGS; }
/// Implementation of IPipelineStateD3D11::GetD3D11DomainShader() method.
- virtual ID3D11DomainShader* DILIGENT_CALL_TYPE GetD3D11DomainShader() override final;
+ virtual ID3D11DomainShader* DILIGENT_CALL_TYPE GetD3D11DomainShader() override final { return m_pDS; }
/// Implementation of IPipelineStateD3D11::GetD3D11HullShader() method.
- virtual ID3D11HullShader* DILIGENT_CALL_TYPE GetD3D11HullShader() override final;
+ virtual ID3D11HullShader* DILIGENT_CALL_TYPE GetD3D11HullShader() override final { return m_pHS; }
/// Implementation of IPipelineStateD3D11::GetD3D11ComputeShader() method.
- virtual ID3D11ComputeShader* DILIGENT_CALL_TYPE GetD3D11ComputeShader() override final;
+ virtual ID3D11ComputeShader* DILIGENT_CALL_TYPE GetD3D11ComputeShader() override final { return m_pCS; }
+ Uint32 GetNumShaders() const { return m_NumShaders; }
+ SHADER_TYPE GetShaderStageType(Uint32 Index) const;
- SRBMemoryAllocator& GetSRBMemoryAllocator()
- {
- return m_SRBMemAllocator;
- }
+private:
+ template <typename PSOCreateInfoType>
+ void InitInternalObjects(const PSOCreateInfoType& CreateInfo,
+ std::vector<CComPtr<ID3DBlob>>& ByteCodes);
- const ShaderResourceLayoutD3D11& GetStaticResourceLayout(Uint32 s) const
- {
- VERIFY_EXPR(s < GetNumShaderStages());
- return m_pStaticResourceLayouts[s];
- }
+ void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
+ const std::vector<ShaderD3D11Impl*>& Shaders,
+ std::vector<CComPtr<ID3DBlob>>& ByteCodes);
- ShaderResourceCacheD3D11& GetStaticResourceCache(Uint32 s)
- {
- VERIFY_EXPR(s < GetNumShaderStages());
- return m_pStaticResourceCaches[s];
- }
+ RefCntAutoPtr<PipelineResourceSignatureD3D11Impl> CreateDefaultResourceSignature(
+ const PipelineStateCreateInfo& CreateInfo,
+ const std::vector<ShaderD3D11Impl*>& Shaders);
- const ShaderD3D11Impl* GetShaderByType(SHADER_TYPE ShaderType) const;
- const ShaderD3D11Impl* GetShader(Uint32 Index) const;
+ void Destruct();
- void SetImmutableSamplers(ShaderResourceCacheD3D11& ResourceCache, Uint32 ShaderInd) const;
+ void ValidateShaderResources(const ShaderD3D11Impl* pShader);
private:
- template <typename PSOCreateInfoType>
- void InitInternalObjects(const PSOCreateInfoType& CreateInfo);
+ using SignaturePtr = RefCntAutoPtr<PipelineResourceSignatureD3D11Impl>;
- void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
- const std::vector<ShaderD3D11Impl*>& Shaders);
-
- void Destruct();
+ std::array<Uint8, 5> m_ShaderTypes = {};
+ Uint8 m_NumShaders = 0;
CComPtr<ID3D11BlendState> m_pd3d11BlendState;
CComPtr<ID3D11RasterizerState> m_pd3d11RasterizerState;
CComPtr<ID3D11DepthStencilState> m_pd3d11DepthStencilState;
CComPtr<ID3D11InputLayout> m_pd3d11InputLayout;
-
- RefCntAutoPtr<ShaderD3D11Impl> m_pVS;
- RefCntAutoPtr<ShaderD3D11Impl> m_pPS;
- RefCntAutoPtr<ShaderD3D11Impl> m_pGS;
- RefCntAutoPtr<ShaderD3D11Impl> m_pDS;
- RefCntAutoPtr<ShaderD3D11Impl> m_pHS;
- RefCntAutoPtr<ShaderD3D11Impl> m_pCS;
-
- // The caches are indexed by the shader order in the PSO, not shader index
- ShaderResourceCacheD3D11* m_pStaticResourceCaches = nullptr; // [m_NumShaderStages]
- ShaderResourceLayoutD3D11* m_pStaticResourceLayouts = nullptr; // [m_NumShaderStages]
-
- // SRB memory allocator must be defined before the default shader res binding
- SRBMemoryAllocator m_SRBMemAllocator;
-
- // Resource layout index in m_pStaticResourceLayouts array for every shader stage,
- // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
- std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
- static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above");
-
- std::array<Uint16, MAX_SHADERS_IN_PIPELINE + 1> m_ImmutableSamplerOffsets = {};
- struct ImmutableSamplerInfo
- {
- const D3DShaderResourceAttribs& Attribs;
- RefCntAutoPtr<ISampler> pSampler;
- ImmutableSamplerInfo(const D3DShaderResourceAttribs& _Attribs,
- RefCntAutoPtr<ISampler> _pSampler) :
- // clang-format off
- Attribs {_Attribs},
- pSampler {std::move(_pSampler)}
- // clang-format on
- {}
- };
- std::vector<ImmutableSamplerInfo, STDAllocatorRawMem<ImmutableSamplerInfo>> m_ImmutableSamplers;
+ CComPtr<ID3D11VertexShader> m_pVS;
+ CComPtr<ID3D11PixelShader> m_pPS;
+ CComPtr<ID3D11GeometryShader> m_pGS;
+ CComPtr<ID3D11DomainShader> m_pDS;
+ CComPtr<ID3D11HullShader> m_pHS;
+ CComPtr<ID3D11ComputeShader> m_pCS;
+
+#ifdef DILIGENT_DEVELOPMENT
+ // Shader resources for all shaders in all shader stages in the pipeline.
+ std::vector<std::shared_ptr<const ShaderResourcesD3D11>> m_ShaderResources;
+
+ // Shader resource attributions for every resource in m_ShaderResources, in the same order.
+ std::vector<ResourceAttribution> m_ResourceAttibutions;
+#endif
};
+__forceinline SHADER_TYPE GetShaderStageType(const ShaderD3D11Impl* pShader)
+{
+ return pShader->GetDesc().ShaderType;
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.hpp
index c7052d4f..6d011c5d 100644
--- a/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.hpp
@@ -43,10 +43,10 @@ namespace Diligent
class FixedBlockMemoryAllocator;
/// Query implementation in Direct3D11 backend.
-class QueryD3D11Impl final : public QueryBase<IQueryD3D11, RenderDeviceD3D11Impl>
+class QueryD3D11Impl final : public QueryBase<EngineD3D11ImplTraits>
{
public:
- using TQueryBase = QueryBase<IQueryD3D11, RenderDeviceD3D11Impl>;
+ using TQueryBase = QueryBase<EngineD3D11ImplTraits>;
QueryD3D11Impl(IReferenceCounters* pRefCounters,
RenderDeviceD3D11Impl* pDevice,
diff --git a/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.hpp
index 0d5d4187..bd9cf2f9 100644
--- a/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.hpp
@@ -30,7 +30,7 @@
/// \file
/// Declaration of Diligent::RenderDeviceD3D11Impl class
-#include "RenderDeviceD3D11.h"
+#include "EngineD3D11ImplTraits.hpp"
#include "RenderDeviceD3DBase.hpp"
#include "DeviceContextD3D11.h"
@@ -38,10 +38,10 @@ namespace Diligent
{
/// Render device implementation in Direct3D11 backend.
-class RenderDeviceD3D11Impl final : public RenderDeviceD3DBase<IRenderDeviceD3D11>
+class RenderDeviceD3D11Impl final : public RenderDeviceD3DBase<EngineD3D11ImplTraits>
{
public:
- using TRenderDeviceBase = RenderDeviceD3DBase<IRenderDeviceD3D11>;
+ using TRenderDeviceBase = RenderDeviceD3DBase<EngineD3D11ImplTraits>;
RenderDeviceD3D11Impl(IReferenceCounters* pRefCounters,
IMemoryAllocator& RawMemAllocator,
@@ -109,6 +109,14 @@ public:
virtual void DILIGENT_CALL_TYPE CreateSBT(const ShaderBindingTableDesc& Desc,
IShaderBindingTable** ppSBT) override final;
+ /// Implementation of IRenderDevice::CreatePipelineResourceSignature() in Direct3D11 backend.
+ virtual void DILIGENT_CALL_TYPE CreatePipelineResourceSignature(const PipelineResourceSignatureDesc& Desc,
+ IPipelineResourceSignature** ppSignature) override final;
+
+ void CreatePipelineResourceSignature(const PipelineResourceSignatureDesc& Desc,
+ IPipelineResourceSignature** ppSignature,
+ bool IsDeviceInternal);
+
/// Implementation of IRenderDeviceD3D11::GetD3D11Device() in Direct3D11 backend.
ID3D11Device* DILIGENT_CALL_TYPE GetD3D11Device() override final { return m_pd3d11Device; }
diff --git a/Graphics/GraphicsEngineD3D11/include/RenderPassD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/RenderPassD3D11Impl.hpp
index 2ac99a15..82a5d290 100644
--- a/Graphics/GraphicsEngineD3D11/include/RenderPassD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/RenderPassD3D11Impl.hpp
@@ -40,10 +40,10 @@ namespace Diligent
class FixedBlockMemoryAllocator;
/// Render pass implementation in Direct3D11 backend.
-class RenderPassD3D11Impl final : public RenderPassBase<IRenderPass, RenderDeviceD3D11Impl>
+class RenderPassD3D11Impl final : public RenderPassBase<EngineD3D11ImplTraits>
{
public:
- using TRenderPassBase = RenderPassBase<IRenderPass, RenderDeviceD3D11Impl>;
+ using TRenderPassBase = RenderPassBase<EngineD3D11ImplTraits>;
RenderPassD3D11Impl(IReferenceCounters* pRefCounters,
RenderDeviceD3D11Impl* pDevice,
diff --git a/Graphics/GraphicsEngineD3D11/include/SamplerD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/SamplerD3D11Impl.hpp
index f30427e0..415b8b69 100644
--- a/Graphics/GraphicsEngineD3D11/include/SamplerD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/SamplerD3D11Impl.hpp
@@ -41,10 +41,10 @@ namespace Diligent
class FixedBlockMemoryAllocator;
/// Sampler implementation in Direct3D11 backend.
-class SamplerD3D11Impl final : public SamplerBase<ISamplerD3D11, RenderDeviceD3D11Impl>
+class SamplerD3D11Impl final : public SamplerBase<EngineD3D11ImplTraits>
{
public:
- using TSamplerBase = SamplerBase<ISamplerD3D11, RenderDeviceD3D11Impl>;
+ using TSamplerBase = SamplerBase<EngineD3D11ImplTraits>;
SamplerD3D11Impl(IReferenceCounters* pRefCounters,
class RenderDeviceD3D11Impl* pRenderDeviceD3D11,
diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.hpp
index 257286bf..b17e473d 100644
--- a/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.hpp
@@ -34,7 +34,6 @@
#include "RenderDeviceD3D11.h"
#include "ShaderBase.hpp"
#include "ShaderD3DBase.hpp"
-#include "ShaderResourceLayoutD3D11.hpp"
#include "ShaderResourceCacheD3D11.hpp"
#include "EngineD3D11Defines.h"
#include "ShaderResourcesD3D11.hpp"
@@ -47,10 +46,10 @@ class FixedBlockMemoryAllocator;
class ResourceMapping;
/// Shader implementation in Direct3D11 backend.
-class ShaderD3D11Impl final : public ShaderBase<IShaderD3D11, RenderDeviceD3D11Impl>, public ShaderD3DBase
+class ShaderD3D11Impl final : public ShaderBase<EngineD3D11ImplTraits>, public ShaderD3DBase
{
public:
- using TShaderBase = ShaderBase<IShaderD3D11, RenderDeviceD3D11Impl>;
+ using TShaderBase = ShaderBase<EngineD3D11ImplTraits>;
ShaderD3D11Impl(IReferenceCounters* pRefCounters,
class RenderDeviceD3D11Impl* pRenderDeviceD3D11,
@@ -85,7 +84,7 @@ public:
ID3DBlob* GetBytecode() { return m_pShaderByteCode; }
- const std::shared_ptr<const ShaderResourcesD3D11>& GetD3D11Resources() const { return m_pShaderResources; }
+ const std::shared_ptr<const ShaderResourcesD3D11>& GetShaderResources() const { return m_pShaderResources; }
private:
/// D3D11 shader
diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.hpp
index 5beeb027..36be84cc 100644
--- a/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.hpp
@@ -35,87 +35,25 @@
#include "ShaderResourceBindingD3D11.h"
#include "RenderDeviceD3D11.h"
#include "ShaderResourceBindingBase.hpp"
+
+// ShaderResourceCacheD3D11 and ShaderVariableManagerD3D11 are required by ShaderResourceBindingBase
#include "ShaderResourceCacheD3D11.hpp"
-#include "ShaderResourceLayoutD3D11.hpp"
-#include "STDAllocator.hpp"
+#include "ShaderVariableManagerD3D11.hpp"
namespace Diligent
{
-class PipelineStateD3D11Impl;
-
/// Implementation of shader resource binding object in Direct3D11 backend.
-class ShaderResourceBindingD3D11Impl final : public ShaderResourceBindingBase<IShaderResourceBindingD3D11, PipelineStateD3D11Impl>
+class ShaderResourceBindingD3D11Impl final : public ShaderResourceBindingBase<EngineD3D11ImplTraits>
{
public:
- using TBase = ShaderResourceBindingBase<IShaderResourceBindingD3D11, PipelineStateD3D11Impl>;
+ using TBase = ShaderResourceBindingBase<EngineD3D11ImplTraits>;
- ShaderResourceBindingD3D11Impl(IReferenceCounters* pRefCounters,
- PipelineStateD3D11Impl* pPSO,
- bool IsInternal);
+ ShaderResourceBindingD3D11Impl(IReferenceCounters* pRefCounters,
+ PipelineResourceSignatureD3D11Impl* pPRS);
~ShaderResourceBindingD3D11Impl();
virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
-
- /// Implementation of IShaderResourceBinding::BindResources() in Direct3D11 backend.
- virtual void DILIGENT_CALL_TYPE BindResources(Uint32 ShaderFlags,
- IResourceMapping* pResMapping,
- Uint32 Flags) override final;
-
- /// Implementation of IShaderResourceBinding::GetVariableByName() in Direct3D11 backend.
- virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetVariableByName(SHADER_TYPE ShaderType, const char* Name) override final;
-
- /// Implementation of IShaderResourceBinding::GetVariableCount() in Direct3D11 backend.
- virtual Uint32 DILIGENT_CALL_TYPE GetVariableCount(SHADER_TYPE ShaderType) const override final;
-
- /// Implementation of IShaderResourceBinding::GetVariableByIndex() in Direct3D11 backend.
- virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final;
-
- /// Implementation of IShaderResourceBinding::InitializeStaticResources() in Direct3D11 backend.
- virtual void DILIGENT_CALL_TYPE InitializeStaticResources(const IPipelineState* pPipelineState) override final;
-
- ShaderResourceCacheD3D11& GetResourceCache(Uint32 Ind)
- {
- VERIFY_EXPR(Ind < m_NumActiveShaders);
- return m_pBoundResourceCaches[Ind];
- }
-
- ShaderResourceLayoutD3D11& GetResourceLayout(Uint32 Ind)
- {
- VERIFY_EXPR(Ind < m_NumActiveShaders);
- return m_pResourceLayouts[Ind];
- }
-
- inline bool IsStaticResourcesBound() const { return m_bIsStaticResourcesBound; }
-
- Uint32 GetNumActiveShaders() const
- {
- return Uint32{m_NumActiveShaders};
- }
-
- SHADER_TYPE GetActiveShaderType(Uint32 s) const
- {
- VERIFY_EXPR(s < m_NumActiveShaders);
- return m_ShaderTypes[s];
- }
-
-private:
- void Destruct();
-
- // The caches are indexed by the shader order in the PSO, not shader index
- ShaderResourceCacheD3D11* m_pBoundResourceCaches = nullptr;
- ShaderResourceLayoutD3D11* m_pResourceLayouts = nullptr;
-
- std::array<SHADER_TYPE, MAX_SHADERS_IN_PIPELINE> m_ShaderTypes = {};
-
- // Resource layout index in m_pResourceLayouts array for every shader stage,
- // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
- std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
- static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above");
-
- Uint8 m_NumActiveShaders = 0;
-
- bool m_bIsStaticResourcesBound = false;
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.hpp b/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.hpp
index 321a758a..7f208182 100644
--- a/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.hpp
@@ -31,9 +31,11 @@
/// Declaration of Diligent::ShaderResourceCacheD3D11 class
#include "MemoryAllocator.h"
+#include "ShaderResourceCacheCommon.hpp"
#include "TextureBaseD3D11.hpp"
#include "BufferD3D11Impl.hpp"
#include "SamplerD3D11Impl.hpp"
+#include "PipelineResourceAttribsD3D11.hpp"
namespace Diligent
{
@@ -51,7 +53,8 @@ namespace Diligent
class ShaderResourceCacheD3D11
{
public:
- ShaderResourceCacheD3D11() noexcept
+ explicit ShaderResourceCacheD3D11(ResourceCacheContentType ContentType) noexcept :
+ m_ContentType{ContentType}
{}
~ShaderResourceCacheD3D11();
@@ -63,12 +66,81 @@ public:
ShaderResourceCacheD3D11& operator = (ShaderResourceCacheD3D11&&) = delete;
// clang-format on
+ enum class StateTransitionMode
+ {
+ Transition,
+ Verify
+ };
+ // Transitions all resources in the cache
+ void TransitionResourceStates(DeviceContextD3D11Impl& Ctx, StateTransitionMode Mode);
+
+
+ static constexpr int NumShaderTypes = PipelineResourceAttribsD3D11::NumShaderTypes;
+
+ struct TCommittedResources
+ {
+ // clang-format off
+
+ /// An array of D3D11 constant buffers committed to D3D11 device context,
+ /// for each shader type. The context addref's all bound resources, so we do
+ /// not need to keep strong references.
+ ID3D11Buffer* D3D11CBs [NumShaderTypes][D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {};
+
+ /// An array of D3D11 shader resource views committed to D3D11 device context,
+ /// for each shader type. The context addref's all bound resources, so we do
+ /// not need to keep strong references.
+ ID3D11ShaderResourceView* D3D11SRVs [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
+
+ /// An array of D3D11 samplers committed to D3D11 device context,
+ /// for each shader type. The context addref's all bound resources, so we do
+ /// not need to keep strong references.
+ ID3D11SamplerState* D3D11Samplers[NumShaderTypes][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {};
+
+ /// An array of D3D11 UAVs committed to D3D11 device context,
+ /// for each shader type. The context addref's all bound resources, so we do
+ /// not need to keep strong references.
+ ID3D11UnorderedAccessView* D3D11UAVs [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
+
+ /// An array of D3D11 resources commited as SRV to D3D11 device context,
+ /// for each shader type. The context addref's all bound resources, so we do
+ /// not need to keep strong references.
+ ID3D11Resource* D3D11SRVResources [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
+
+ /// An array of D3D11 resources commited as UAV to D3D11 device context,
+ /// for each shader type. The context addref's all bound resources, so we do
+ /// not need to keep strong references.
+ ID3D11Resource* D3D11UAVResources [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
+
+ Uint8 NumCBs [NumShaderTypes] = {};
+ Uint8 NumSRVs [NumShaderTypes] = {};
+ Uint8 NumSamplers[NumShaderTypes] = {};
+ Uint8 NumUAVs [NumShaderTypes] = {};
+
+ // clang-format on
+
+ void Clear();
+ };
+
+ struct MinMaxSlot
+ {
+ UINT MinSlot = UINT_MAX;
+ UINT MaxSlot = 0;
+ };
+ using TMinMaxSlotPerStage = std::array<std::array<MinMaxSlot, DESCRIPTOR_RANGE_COUNT>, NumShaderTypes>;
+ using TResourceCount = std::array<Uint8, DESCRIPTOR_RANGE_COUNT>;
+ using TBindingsPerStage = std::array<TResourceCount, NumShaderTypes>;
+
+ void BindResources(DeviceContextD3D11Impl& Ctx, const TBindingsPerStage& BaseBindings, TMinMaxSlotPerStage& MinMaxSlot, TCommittedResources& CommittedRes, SHADER_TYPE ActiveStages) const;
+
+
/// Describes a resource associated with a cached constant buffer
struct CachedCB
{
/// Strong reference to the buffer
RefCntAutoPtr<BufferD3D11Impl> pBuff;
+ private:
+ friend class ShaderResourceCacheD3D11;
__forceinline void Set(RefCntAutoPtr<BufferD3D11Impl>&& _pBuff)
{
pBuff = std::move(_pBuff);
@@ -81,6 +153,8 @@ public:
/// Strong reference to the sampler
RefCntAutoPtr<class SamplerD3D11Impl> pSampler;
+ private:
+ friend class ShaderResourceCacheD3D11;
__forceinline void Set(SamplerD3D11Impl* pSam)
{
pSampler = pSam;
@@ -106,6 +180,8 @@ public:
CachedResource() noexcept {}
+ private:
+ friend class ShaderResourceCacheD3D11;
__forceinline void Set(RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView)
{
pBuffer = nullptr;
@@ -125,211 +201,325 @@ public:
}
};
- static size_t GetRequriedMemorySize(const class ShaderResourcesD3D11& Resources);
+ static size_t GetRequriedMemorySize(const TResourceCount& ResCount);
+
+ void Initialize(const TResourceCount& ResCount, IMemoryAllocator& MemAllocator);
- void Initialize(const class ShaderResourcesD3D11& Resources, IMemoryAllocator& MemAllocator);
- void Initialize(Uint32 CBCount, Uint32 SRVCount, Uint32 SamplerCount, Uint32 UAVCount, IMemoryAllocator& MemAllocator);
- void Destroy(IMemoryAllocator& MemAllocator);
+ using TBindPoints = PipelineResourceAttribsD3D11::TBindPoints;
+ using TBindPointsAndActiveBits = std::array<Uint8, NumShaderTypes + 1>; // ActiveBits [0], TBindPoints [1..6]
+ static constexpr auto InvalidBindPoint = PipelineResourceAttribsD3D11::InvalidBindPoint;
- __forceinline void SetCB(Uint32 Slot, RefCntAutoPtr<BufferD3D11Impl>&& pBuffD3D11Impl)
+ __forceinline void SetCB(Uint32 CacheOffset, Uint32 ArrayIndex, TBindPoints BindPoints, RefCntAutoPtr<BufferD3D11Impl>&& pBuffD3D11Impl)
{
auto* pd3d11Buff = pBuffD3D11Impl ? pBuffD3D11Impl->BufferD3D11Impl::GetD3D11Buffer() : nullptr;
- SetD3D11ResourceInternal<CachedCB>(Slot, GetCBCount(), &ShaderResourceCacheD3D11::GetCBArrays, std::move(pBuffD3D11Impl), pd3d11Buff);
+ SetD3D11ResourceInternal<CachedCB>(CacheOffset, ArrayIndex, GetCBCount(), BindPoints, &ShaderResourceCacheD3D11::GetCBArrays, std::move(pBuffD3D11Impl), pd3d11Buff);
}
- __forceinline void SetTexSRV(Uint32 Slot, RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView)
+ __forceinline void SetTexSRV(Uint32 CacheOffset, Uint32 ArrayIndex, TBindPoints BindPoints, RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView)
{
auto* pd3d11SRV = pTexView ? static_cast<ID3D11ShaderResourceView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr;
- SetD3D11ResourceInternal<CachedResource>(Slot, GetSRVCount(), &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pTexView), pd3d11SRV);
+ SetD3D11ResourceInternal<CachedResource>(CacheOffset, ArrayIndex, GetSRVCount(), BindPoints, &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pTexView), pd3d11SRV);
}
- __forceinline void SetBufSRV(Uint32 Slot, RefCntAutoPtr<BufferViewD3D11Impl>&& pBuffView)
+ __forceinline void SetBufSRV(Uint32 CacheOffset, Uint32 ArrayIndex, TBindPoints BindPoints, RefCntAutoPtr<BufferViewD3D11Impl>&& pBuffView)
{
auto* pd3d11SRV = pBuffView ? static_cast<ID3D11ShaderResourceView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr;
- SetD3D11ResourceInternal<CachedResource>(Slot, GetSRVCount(), &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pBuffView), pd3d11SRV);
+ SetD3D11ResourceInternal<CachedResource>(CacheOffset, ArrayIndex, GetSRVCount(), BindPoints, &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pBuffView), pd3d11SRV);
}
- __forceinline void SetTexUAV(Uint32 Slot, RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView)
+ __forceinline void SetTexUAV(Uint32 CacheOffset, Uint32 ArrayIndex, TBindPoints BindPoints, RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView)
{
auto* pd3d11UAV = pTexView ? static_cast<ID3D11UnorderedAccessView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr;
- SetD3D11ResourceInternal<CachedResource>(Slot, GetUAVCount(), &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pTexView), pd3d11UAV);
+ SetD3D11ResourceInternal<CachedResource>(CacheOffset, ArrayIndex, GetUAVCount(), BindPoints, &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pTexView), pd3d11UAV);
}
- __forceinline void SetBufUAV(Uint32 Slot, RefCntAutoPtr<BufferViewD3D11Impl>&& pBuffView)
+ __forceinline void SetBufUAV(Uint32 CacheOffset, Uint32 ArrayIndex, TBindPoints BindPoints, RefCntAutoPtr<BufferViewD3D11Impl>&& pBuffView)
{
auto* pd3d11UAV = pBuffView ? static_cast<ID3D11UnorderedAccessView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr;
- SetD3D11ResourceInternal<CachedResource>(Slot, GetUAVCount(), &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pBuffView), pd3d11UAV);
+ SetD3D11ResourceInternal<CachedResource>(CacheOffset, ArrayIndex, GetUAVCount(), BindPoints, &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pBuffView), pd3d11UAV);
}
- __forceinline void SetSampler(Uint32 Slot, SamplerD3D11Impl* pSampler)
+ __forceinline void SetSampler(Uint32 CacheOffset, Uint32 ArrayIndex, TBindPoints BindPoints, SamplerD3D11Impl* pSampler)
{
auto* pd3d11Sampler = pSampler ? pSampler->SamplerD3D11Impl::GetD3D11SamplerState() : nullptr;
- SetD3D11ResourceInternal<CachedSampler>(Slot, GetSamplerCount(), &ShaderResourceCacheD3D11::GetSamplerArrays, pSampler, pd3d11Sampler);
+ SetD3D11ResourceInternal<CachedSampler>(CacheOffset, ArrayIndex, GetSamplerCount(), BindPoints, &ShaderResourceCacheD3D11::GetSamplerArrays, pSampler, pd3d11Sampler);
}
-
- __forceinline CachedCB& GetCB(Uint32 Slot)
+ __forceinline CachedCB const& GetCB(Uint32 CacheOffset) const
{
- VERIFY(Slot < GetCBCount(), "CB slot is out of range");
+ VERIFY(CacheOffset < GetCBCount(), "CB slot is out of range");
ShaderResourceCacheD3D11::CachedCB* CBs;
ID3D11Buffer** pd3d11CBs;
- GetCBArrays(CBs, pd3d11CBs);
- return CBs[Slot];
+ TBindPointsAndActiveBits* bindPoints;
+ const_cast<ShaderResourceCacheD3D11*>(this)->GetCBArrays(CBs, pd3d11CBs, bindPoints);
+ return CBs[CacheOffset];
}
- __forceinline CachedResource& GetSRV(Uint32 Slot)
+ __forceinline CachedResource const& GetSRV(Uint32 CacheOffset) const
{
- VERIFY(Slot < GetSRVCount(), "SRV slot is out of range");
+ VERIFY(CacheOffset < GetSRVCount(), "SRV slot is out of range");
ShaderResourceCacheD3D11::CachedResource* SRVResources;
ID3D11ShaderResourceView** pd3d11SRVs;
- GetSRVArrays(SRVResources, pd3d11SRVs);
- return SRVResources[Slot];
+ TBindPointsAndActiveBits* bindPoints;
+ const_cast<ShaderResourceCacheD3D11*>(this)->GetSRVArrays(SRVResources, pd3d11SRVs, bindPoints);
+ return SRVResources[CacheOffset];
}
- __forceinline CachedResource& GetUAV(Uint32 Slot)
+ __forceinline CachedResource const& GetUAV(Uint32 CacheOffset) const
{
- VERIFY(Slot < GetUAVCount(), "UAV slot is out of range");
+ VERIFY(CacheOffset < GetUAVCount(), "UAV slot is out of range");
ShaderResourceCacheD3D11::CachedResource* UAVResources;
ID3D11UnorderedAccessView** pd3d11UAVs;
- GetUAVArrays(UAVResources, pd3d11UAVs);
- return UAVResources[Slot];
+ TBindPointsAndActiveBits* bindPoints;
+ const_cast<ShaderResourceCacheD3D11*>(this)->GetUAVArrays(UAVResources, pd3d11UAVs, bindPoints);
+ return UAVResources[CacheOffset];
}
- __forceinline CachedSampler& GetSampler(Uint32 Slot)
+ __forceinline CachedSampler const& GetSampler(Uint32 CacheOffset) const
{
- VERIFY(Slot < GetSamplerCount(), "Sampler slot is out of range");
+ VERIFY(CacheOffset < GetSamplerCount(), "Sampler slot is out of range");
ShaderResourceCacheD3D11::CachedSampler* Samplers;
ID3D11SamplerState** pd3d11Samplers;
- GetSamplerArrays(Samplers, pd3d11Samplers);
- return Samplers[Slot];
+ TBindPointsAndActiveBits* bindPoints;
+ const_cast<ShaderResourceCacheD3D11*>(this)->GetSamplerArrays(Samplers, pd3d11Samplers, bindPoints);
+ return Samplers[CacheOffset];
}
- __forceinline bool IsCBBound(Uint32 Slot) const
+ __forceinline bool IsCBBound(Uint32 CacheOffset) const
{
- CachedCB* CBs = nullptr;
- ID3D11Buffer** d3d11CBs = nullptr;
- const_cast<ShaderResourceCacheD3D11*>(this)->GetCBArrays(CBs, d3d11CBs);
- if (Slot < GetCBCount() && d3d11CBs[Slot] != nullptr)
+ CachedCB const* CBs;
+ ID3D11Buffer* const* d3d11CBs;
+ TBindPointsAndActiveBits const* bindPoints;
+ GetConstCBArrays(CBs, d3d11CBs, bindPoints);
+ if (CacheOffset < GetCBCount() && d3d11CBs[CacheOffset] != nullptr)
{
- VERIFY(CBs[Slot].pBuff != nullptr, "No relevant buffer resource");
+ VERIFY(CBs[CacheOffset].pBuff != nullptr, "No relevant buffer resource");
return true;
}
return false;
}
- __forceinline bool IsSRVBound(Uint32 Slot, bool dbgIsTextureView) const
+ __forceinline bool IsSRVBound(Uint32 CacheOffset, bool dbgIsTextureView) const
{
- CachedResource* SRVResources = nullptr;
- ID3D11ShaderResourceView** d3d11SRVs = nullptr;
- const_cast<ShaderResourceCacheD3D11*>(this)->GetSRVArrays(SRVResources, d3d11SRVs);
- if (Slot < GetSRVCount() && d3d11SRVs[Slot] != nullptr)
+ CachedResource const* SRVResources;
+ ID3D11ShaderResourceView* const* d3d11SRVs;
+ TBindPointsAndActiveBits const* bindPoints;
+ GetConstSRVArrays(SRVResources, d3d11SRVs, bindPoints);
+ if (CacheOffset < GetSRVCount() && d3d11SRVs[CacheOffset] != nullptr)
{
- VERIFY((dbgIsTextureView && SRVResources[Slot].pTexture != nullptr) || (!dbgIsTextureView && SRVResources[Slot].pBuffer != nullptr),
+ VERIFY((dbgIsTextureView && SRVResources[CacheOffset].pTexture != nullptr) || (!dbgIsTextureView && SRVResources[CacheOffset].pBuffer != nullptr),
"No relevant resource");
return true;
}
return false;
}
- __forceinline bool IsUAVBound(Uint32 Slot, bool dbgIsTextureView) const
+ __forceinline bool IsUAVBound(Uint32 CacheOffset, bool dbgIsTextureView) const
{
- CachedResource* UAVResources = nullptr;
- ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
- const_cast<ShaderResourceCacheD3D11*>(this)->GetUAVArrays(UAVResources, d3d11UAVs);
- if (Slot < GetUAVCount() && d3d11UAVs[Slot] != nullptr)
+ CachedResource const* UAVResources;
+ ID3D11UnorderedAccessView* const* d3d11UAVs;
+ TBindPointsAndActiveBits const* bindPoints;
+ GetConstUAVArrays(UAVResources, d3d11UAVs, bindPoints);
+ if (CacheOffset < GetUAVCount() && d3d11UAVs[CacheOffset] != nullptr)
{
- VERIFY((dbgIsTextureView && UAVResources[Slot].pTexture != nullptr) || (!dbgIsTextureView && UAVResources[Slot].pBuffer != nullptr),
+ VERIFY((dbgIsTextureView && UAVResources[CacheOffset].pTexture != nullptr) || (!dbgIsTextureView && UAVResources[CacheOffset].pBuffer != nullptr),
"No relevant resource");
return true;
}
return false;
}
- __forceinline bool IsSamplerBound(Uint32 Slot) const
+ __forceinline bool IsSamplerBound(Uint32 CacheOffset) const
{
- CachedSampler* Samplers = nullptr;
- ID3D11SamplerState** d3d11Samplers = nullptr;
- const_cast<ShaderResourceCacheD3D11*>(this)->GetSamplerArrays(Samplers, d3d11Samplers);
- if (Slot < GetSamplerCount() && d3d11Samplers[Slot] != nullptr)
+ CachedSampler const* Samplers;
+ ID3D11SamplerState* const* d3d11Samplers;
+ TBindPointsAndActiveBits const* bindPoints;
+ GetConstSamplerArrays(Samplers, d3d11Samplers, bindPoints);
+ if (CacheOffset < GetSamplerCount() && d3d11Samplers[CacheOffset] != nullptr)
{
- VERIFY(Samplers[Slot].pSampler != nullptr, "No relevant sampler");
+ VERIFY(Samplers[CacheOffset].pSampler != nullptr, "No relevant sampler");
return true;
}
return false;
}
- void dbgVerifyCacheConsistency();
+#ifdef DILIGENT_DEVELOPMENT
+ void DvpVerifyCacheConsistency();
+#endif
// clang-format off
- __forceinline Uint32 GetCBCount() const { return (m_SRVOffset - m_CBOffset) / (sizeof(CachedCB) + sizeof(ID3D11Buffer*)); }
- __forceinline Uint32 GetSRVCount() const { return (m_SamplerOffset - m_SRVOffset) / (sizeof(CachedResource) + sizeof(ID3D11ShaderResourceView*)); }
- __forceinline Uint32 GetSamplerCount() const { return (m_UAVOffset - m_SamplerOffset) / (sizeof(CachedSampler) + sizeof(ID3D11SamplerState*)); }
- __forceinline Uint32 GetUAVCount() const { return (m_MemoryEndOffset - m_UAVOffset) / (sizeof(CachedResource) + sizeof(ID3D11UnorderedAccessView*)); }
+ __forceinline Uint32 GetCBCount() const { return m_CBCount; }
+ __forceinline Uint32 GetSRVCount() const { return m_SRVCount; }
+ __forceinline Uint32 GetSamplerCount() const { return m_SamplerCount; }
+ __forceinline Uint32 GetUAVCount() const { return m_UAVCount; }
// clang-format on
- __forceinline void GetCBArrays(CachedCB*& CBs, ID3D11Buffer**& pd3d11CBs)
+ __forceinline void GetCBArrays(CachedCB*& CBs, ID3D11Buffer**& pd3d11CBs, TBindPointsAndActiveBits*& pBindPoints)
{
- CBs = reinterpret_cast<CachedCB*>(m_pResourceData + m_CBOffset);
- pd3d11CBs = reinterpret_cast<ID3D11Buffer**>(CBs + GetCBCount());
+ VERIFY(alignof(CachedCB) == alignof(ID3D11Buffer*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
+ CBs = reinterpret_cast<CachedCB*>(m_pResourceData + m_CBOffset);
+ pd3d11CBs = reinterpret_cast<ID3D11Buffer**>(CBs + GetCBCount());
+ pBindPoints = reinterpret_cast<TBindPointsAndActiveBits*>(pd3d11CBs + GetCBCount());
}
- __forceinline void GetSRVArrays(CachedResource*& SRVResources, ID3D11ShaderResourceView**& d3d11SRVs)
+ __forceinline void GetSRVArrays(CachedResource*& SRVResources, ID3D11ShaderResourceView**& d3d11SRVs, TBindPointsAndActiveBits*& pBindPoints)
{
+ VERIFY(alignof(CachedResource) == alignof(ID3D11ShaderResourceView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
SRVResources = reinterpret_cast<CachedResource*>(m_pResourceData + m_SRVOffset);
d3d11SRVs = reinterpret_cast<ID3D11ShaderResourceView**>(SRVResources + GetSRVCount());
+ pBindPoints = reinterpret_cast<TBindPointsAndActiveBits*>(d3d11SRVs + GetSRVCount());
}
- __forceinline void GetSamplerArrays(CachedSampler*& Samplers, ID3D11SamplerState**& pd3d11Samplers)
+ __forceinline void GetSamplerArrays(CachedSampler*& Samplers, ID3D11SamplerState**& pd3d11Samplers, TBindPointsAndActiveBits*& pBindPoints)
{
+ VERIFY(alignof(CachedSampler) == alignof(ID3D11SamplerState*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
Samplers = reinterpret_cast<CachedSampler*>(m_pResourceData + m_SamplerOffset);
pd3d11Samplers = reinterpret_cast<ID3D11SamplerState**>(Samplers + GetSamplerCount());
+ pBindPoints = reinterpret_cast<TBindPointsAndActiveBits*>(pd3d11Samplers + GetSamplerCount());
}
- __forceinline void GetUAVArrays(CachedResource*& UAVResources, ID3D11UnorderedAccessView**& pd3d11UAVs)
+ __forceinline void GetUAVArrays(CachedResource*& UAVResources, ID3D11UnorderedAccessView**& pd3d11UAVs, TBindPointsAndActiveBits*& pBindPoints)
{
+ VERIFY(alignof(CachedResource) == alignof(ID3D11UnorderedAccessView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
UAVResources = reinterpret_cast<CachedResource*>(m_pResourceData + m_UAVOffset);
pd3d11UAVs = reinterpret_cast<ID3D11UnorderedAccessView**>(UAVResources + GetUAVCount());
+ pBindPoints = reinterpret_cast<TBindPointsAndActiveBits*>(pd3d11UAVs + GetUAVCount());
+ }
+
+ __forceinline void GetConstCBArrays(CachedCB const*& CBs, ID3D11Buffer* const*& pd3d11CBs, TBindPointsAndActiveBits const*& pBindPoints) const
+ {
+ VERIFY(alignof(CachedCB) == alignof(ID3D11Buffer*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
+ CBs = reinterpret_cast<CachedCB const*>(m_pResourceData + m_CBOffset);
+ pd3d11CBs = reinterpret_cast<ID3D11Buffer* const*>(CBs + GetCBCount());
+ pBindPoints = reinterpret_cast<TBindPointsAndActiveBits const*>(pd3d11CBs + GetCBCount());
+ }
+
+ __forceinline void GetConstSRVArrays(CachedResource const*& SRVResources, ID3D11ShaderResourceView* const*& d3d11SRVs, TBindPointsAndActiveBits const*& pBindPoints) const
+ {
+ VERIFY(alignof(CachedResource) == alignof(ID3D11ShaderResourceView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
+ SRVResources = reinterpret_cast<CachedResource const*>(m_pResourceData + m_SRVOffset);
+ d3d11SRVs = reinterpret_cast<ID3D11ShaderResourceView* const*>(SRVResources + GetSRVCount());
+ pBindPoints = reinterpret_cast<TBindPointsAndActiveBits const*>(d3d11SRVs + GetSRVCount());
+ }
+
+ __forceinline void GetConstSamplerArrays(CachedSampler const*& Samplers, ID3D11SamplerState* const*& pd3d11Samplers, TBindPointsAndActiveBits const*& pBindPoints) const
+ {
+ VERIFY(alignof(CachedSampler) == alignof(ID3D11SamplerState*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
+ Samplers = reinterpret_cast<CachedSampler const*>(m_pResourceData + m_SamplerOffset);
+ pd3d11Samplers = reinterpret_cast<ID3D11SamplerState* const*>(Samplers + GetSamplerCount());
+ pBindPoints = reinterpret_cast<TBindPointsAndActiveBits const*>(pd3d11Samplers + GetSamplerCount());
+ }
+
+ __forceinline void GetConstUAVArrays(CachedResource const*& UAVResources, ID3D11UnorderedAccessView* const*& pd3d11UAVs, TBindPointsAndActiveBits const*& pBindPoints) const
+ {
+ VERIFY(alignof(CachedResource) == alignof(ID3D11UnorderedAccessView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
+ UAVResources = reinterpret_cast<CachedResource const*>(m_pResourceData + m_UAVOffset);
+ pd3d11UAVs = reinterpret_cast<ID3D11UnorderedAccessView* const*>(UAVResources + GetUAVCount());
+ pBindPoints = reinterpret_cast<TBindPointsAndActiveBits const*>(pd3d11UAVs + GetUAVCount());
}
__forceinline bool IsInitialized() const
{
- return m_MemoryEndOffset != InvalidResourceOffset;
+ return m_UAVOffset != InvalidResourceOffset;
}
+ ResourceCacheContentType GetContentType() const { return m_ContentType; }
+
private:
template <typename TCachedResourceType, typename TGetResourceArraysFunc, typename TSrcResourceType, typename TD3D11ResourceType>
- __forceinline void SetD3D11ResourceInternal(Uint32 Slot, Uint32 Size, TGetResourceArraysFunc GetArrays, TSrcResourceType&& pResource, TD3D11ResourceType* pd3d11Resource)
+ __forceinline void SetD3D11ResourceInternal(Uint32 CacheOffset, Uint32 ArrayIndex, Uint32 Size, TBindPoints SrcBindPoints, TGetResourceArraysFunc GetArrays, TSrcResourceType&& pResource, TD3D11ResourceType* pd3d11Resource)
{
- VERIFY(Slot < Size, "Resource cache is not big enough");
+ CacheOffset += ArrayIndex;
+
+ TBindPointsAndActiveBits BindPointsAndActiveBits;
+ auto& ActiveBits = BindPointsAndActiveBits[0];
+ auto* BindPoints = &BindPointsAndActiveBits[1];
+
+ ActiveBits = 0;
+ for (Uint32 i = 0; i < SrcBindPoints.size(); ++i)
+ {
+ if (SrcBindPoints[i] != InvalidBindPoint)
+ {
+ auto BindPoint = SrcBindPoints[i] + ArrayIndex;
+ VERIFY_EXPR(BindPoint < InvalidBindPoint);
+ BindPoints[i] = static_cast<Uint8>(BindPoint);
+ ActiveBits |= static_cast<Uint8>(1u << i);
+ }
+ else
+ {
+ BindPoints[i] = InvalidBindPoint;
+ }
+ }
+
+ VERIFY(CacheOffset < Size, "Resource cache is not big enough");
VERIFY(pResource != nullptr && pd3d11Resource != nullptr || pResource == nullptr && pd3d11Resource == nullptr,
"Resource and D3D11 resource must be set/unset atomically");
- TCachedResourceType* Resources;
- TD3D11ResourceType** d3d11ResArr;
- (this->*GetArrays)(Resources, d3d11ResArr);
- Resources[Slot].Set(std::forward<TSrcResourceType>(pResource));
- d3d11ResArr[Slot] = pd3d11Resource;
+ TCachedResourceType* Resources;
+ TD3D11ResourceType** d3d11ResArr;
+ TBindPointsAndActiveBits* bindPoints;
+ (this->*GetArrays)(Resources, d3d11ResArr, bindPoints);
+ Resources[CacheOffset].Set(std::forward<TSrcResourceType>(pResource));
+ bindPoints[CacheOffset] = BindPointsAndActiveBits;
+ d3d11ResArr[CacheOffset] = pd3d11Resource;
}
- static constexpr const Uint16 InvalidResourceOffset = 0xFFFF;
- // Resource limits in D3D11:
- // Max CB count: 14
- // Max SRV count: 128
- // Max Sampler count: 16
- // Max UAV count: 8
- static constexpr const Uint16 m_CBOffset = 0;
- Uint16 m_SRVOffset = InvalidResourceOffset;
- Uint16 m_SamplerOffset = InvalidResourceOffset;
- Uint16 m_UAVOffset = InvalidResourceOffset;
- Uint16 m_MemoryEndOffset = InvalidResourceOffset;
-
- Uint8* m_pResourceData = nullptr;
-
-#ifdef DILIGENT_DEBUG
- IMemoryAllocator* m_pdbgMemoryAllocator = nullptr;
+ template <typename THandleResource>
+ void ProcessResources(THandleResource HandleResource);
+
+ // Transitions resource to the shader resource state required by Type member.
+ __forceinline void TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedCB* CBs, ID3D11Buffer** pd3d11CBs);
+ __forceinline void TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedResource* SRVResources, ID3D11ShaderResourceView** d3d11SRVs);
+ __forceinline void TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedSampler* Samplers, ID3D11SamplerState** pd3d11Samplers);
+ __forceinline void TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedResource* UAVResources, ID3D11UnorderedAccessView** pd3d11UAVs);
+
+#ifdef DILIGENT_DEVELOPMENT
+ // Verifies that resource is in correct shader resource state required by Type member.
+ void DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedCB* CBs, ID3D11Buffer**);
+ void DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedResource* SRVResources, ID3D11ShaderResourceView**);
+ void DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedSampler* Samplers, ID3D11SamplerState**);
+ void DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedResource* UAVResources, ID3D11UnorderedAccessView**);
#endif
+
+private:
+ using OffsetType = Uint16;
+
+ static constexpr size_t MaxAlignment = std::max(std::max(std::max(alignof(CachedCB), alignof(CachedResource)),
+ std::max(alignof(CachedSampler), alignof(TBindPoints))),
+ std::max(std::max(alignof(ID3D11Buffer*), alignof(ID3D11ShaderResourceView*)),
+ std::max(alignof(ID3D11SamplerState*), alignof(ID3D11UnorderedAccessView*))));
+
+ static constexpr OffsetType InvalidResourceOffset = std::numeric_limits<OffsetType>::max();
+
+ static constexpr OffsetType m_CBOffset = 0;
+ OffsetType m_SRVOffset = InvalidResourceOffset;
+ OffsetType m_SamplerOffset = InvalidResourceOffset;
+ OffsetType m_UAVOffset = InvalidResourceOffset;
+
+ static constexpr Uint32 _CBCountBits = 7;
+ static constexpr Uint32 _SVCountBits = 10;
+ static constexpr Uint32 _SampCountBits = 7;
+ static constexpr Uint32 _UAVCountBits = 4;
+
+ // clang-format off
+ static_assert((1U << _CBCountBits) >= (D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT * NumShaderTypes), "Number of constant buffers is too small");
+ static_assert((1U << _SVCountBits) >= (D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT * NumShaderTypes), "Number of shader resources is too small");
+ static_assert((1U << _SampCountBits) >= (D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT * NumShaderTypes), "Number of samplers is too small");
+ static_assert((1U << _UAVCountBits) >= D3D11_PS_CS_UAV_REGISTER_COUNT, "Number of UAVs is too small");
+
+ Uint32 m_CBCount : _CBCountBits;
+ Uint32 m_SRVCount : _SVCountBits;
+ Uint32 m_SamplerCount : _SampCountBits;
+ Uint32 m_UAVCount : _UAVCountBits;
+ // clang-format on
+
+ // Indicates what types of resources are stored in the cache
+ const ResourceCacheContentType m_ContentType;
+
+ Uint8* m_pResourceData = nullptr;
+ IMemoryAllocator* m_pAllocator = nullptr;
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.hpp b/Graphics/GraphicsEngineD3D11/include/ShaderVariableManagerD3D11.hpp
index fcbe994c..d7febdb0 100644
--- a/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/ShaderVariableManagerD3D11.hpp
@@ -28,261 +28,319 @@
#pragma once
/// \file
-/// Declaration of Diligent::ShaderResourceLayoutD3D11 class
+/// Declaration of Diligent::ShaderVariableManagerD3D11 class
#include "ShaderResources.hpp"
#include "ShaderBase.hpp"
-#include "ShaderResourceCacheD3D11.hpp"
-#include "EngineD3D11Defines.h"
-#include "STDAllocator.hpp"
-#include "ShaderVariableD3DBase.hpp"
+#include "ShaderResourceVariableBase.hpp"
+#include "ShaderVariableD3D.hpp"
#include "ShaderResourcesD3D11.hpp"
+#include "ShaderResourceVariableD3D.h"
+#include "PipelineResourceAttribsD3D11.hpp"
+#include "ShaderResourceCacheD3D11.hpp"
namespace Diligent
{
-/// Diligent::ShaderResourceLayoutD3D11 class
-/// http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-layout/
-// sizeof(ShaderResourceLayoutD3D11) == 64 (x64)
-class ShaderResourceLayoutD3D11
+/// Diligent::ShaderVariableManagerD3D11 class
+// sizeof(ShaderVariableManagerD3D11) == AZ TODO (Release, x64)
+class ShaderVariableManagerD3D11
{
public:
- ShaderResourceLayoutD3D11(IObject& Owner,
- ShaderResourceCacheD3D11& ResourceCache) noexcept :
+ ShaderVariableManagerD3D11(IObject& Owner,
+ ShaderResourceCacheD3D11& ResourceCache) noexcept :
m_Owner{Owner},
m_ResourceCache{ResourceCache}
{
}
- void Initialize(std::shared_ptr<const ShaderResourcesD3D11> pSrcResources,
- const PipelineResourceLayoutDesc& ResourceLayout,
- const SHADER_RESOURCE_VARIABLE_TYPE* VarTypes,
- Uint32 NumVarTypes,
- IMemoryAllocator& ResCacheDataAllocator,
- IMemoryAllocator& ResLayoutDataAllocator);
- ~ShaderResourceLayoutD3D11();
+ ~ShaderVariableManagerD3D11();
+
+ void Destroy(IMemoryAllocator& Allocator);
// clang-format off
// No copies, only moves are allowed
- ShaderResourceLayoutD3D11 (const ShaderResourceLayoutD3D11&) = delete;
- ShaderResourceLayoutD3D11& operator = (const ShaderResourceLayoutD3D11&) = delete;
- ShaderResourceLayoutD3D11 ( ShaderResourceLayoutD3D11&&) = default;
- ShaderResourceLayoutD3D11& operator = ( ShaderResourceLayoutD3D11&&) = delete;
+ ShaderVariableManagerD3D11 (const ShaderVariableManagerD3D11&) = delete;
+ ShaderVariableManagerD3D11& operator = (const ShaderVariableManagerD3D11&) = delete;
+ ShaderVariableManagerD3D11 ( ShaderVariableManagerD3D11&&) = default;
+ ShaderVariableManagerD3D11& operator = ( ShaderVariableManagerD3D11&&) = delete;
// clang-format on
- static size_t GetRequiredMemorySize(const ShaderResourcesD3D11& SrcResources,
- const PipelineResourceLayoutDesc& ResourceLayout,
- const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
- Uint32 NumAllowedTypes) noexcept;
+ void Initialize(const PipelineResourceSignatureD3D11Impl& Signature,
+ IMemoryAllocator& Allocator,
+ const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
+ Uint32 NumAllowedTypes,
+ SHADER_TYPE ShaderType);
+
+ static size_t GetRequiredMemorySize(const PipelineResourceSignatureD3D11Impl& Signature,
+ const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
+ Uint32 NumAllowedTypes,
+ SHADER_TYPE ShaderType);
+
+ using ResourceAttribs = PipelineResourceAttribsD3D11;
+
+ const PipelineResourceDesc& GetResourceDesc(Uint32 Index) const;
+ const ResourceAttribs& GetAttribs(Uint32 Index) const;
+
+
+ struct ShaderVariableD3D11Base : ShaderVariableBase<ShaderVariableManagerD3D11, IShaderResourceVariableD3D>
+ {
+ public:
+ ShaderVariableD3D11Base(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
+ ShaderVariableBase<ShaderVariableManagerD3D11, IShaderResourceVariableD3D>{ParentLayout},
+ m_ResIndex{ResIndex}
+ {}
+
+ // clang-format off
+ ShaderVariableD3D11Base (const ShaderVariableD3D11Base&) = delete;
+ ShaderVariableD3D11Base ( ShaderVariableD3D11Base&&) = delete;
+ ShaderVariableD3D11Base& operator= (const ShaderVariableD3D11Base&) = delete;
+ ShaderVariableD3D11Base& operator= ( ShaderVariableD3D11Base&&) = delete;
+ // clang-format on
+
+ const PipelineResourceDesc& GetDesc() const { return m_ParentManager.GetResourceDesc(m_ResIndex); }
+ const ResourceAttribs& GetAttribs() const { return m_ParentManager.GetAttribs(m_ResIndex); }
+
+ virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final
+ {
+ if (ppInterface == nullptr)
+ return;
+
+ *ppInterface = nullptr;
+ if (IID == IID_ShaderResourceVariableD3D || IID == IID_ShaderResourceVariable || IID == IID_Unknown)
+ {
+ *ppInterface = this;
+ (*ppInterface)->AddRef();
+ }
+ }
+
+ virtual SHADER_RESOURCE_VARIABLE_TYPE DILIGENT_CALL_TYPE GetType() const override final
+ {
+ return GetDesc().VarType;
+ }
+
+ virtual void DILIGENT_CALL_TYPE GetResourceDesc(ShaderResourceDesc& ResourceDesc) const override final
+ {
+ const auto& Desc = GetDesc();
+ ResourceDesc.Name = Desc.Name;
+ ResourceDesc.Type = Desc.ResourceType;
+ ResourceDesc.ArraySize = Desc.ArraySize;
+ }
+
+ virtual Uint32 DILIGENT_CALL_TYPE GetIndex() const override final
+ {
+ return m_ParentManager.GetVariableIndex(*this);
+ }
- void CopyResources(ShaderResourceCacheD3D11& DstCache) const;
+ virtual void DILIGENT_CALL_TYPE GetHLSLResourceDesc(HLSLShaderResourceDesc& HLSLResDesc) const override final
+ {
+ // AZ TODO
+ }
- using ShaderVariableD3D11Base = ShaderVariableD3DBase<ShaderResourceLayoutD3D11>;
+ private:
+ const Uint32 m_ResIndex;
+ };
struct ConstBuffBindInfo final : ShaderVariableD3D11Base
{
- ConstBuffBindInfo(const D3DShaderResourceAttribs& ResourceAttribs,
- ShaderResourceLayoutD3D11& ParentResLayout,
- SHADER_RESOURCE_VARIABLE_TYPE VariableType) :
- ShaderVariableD3D11Base{ParentResLayout, ResourceAttribs, VariableType}
+ ConstBuffBindInfo(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
+ ShaderVariableD3D11Base{ParentLayout, ResIndex}
{}
+
// Non-virtual function
- __forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
+ __forceinline void BindResource(IDeviceObject* pObj, Uint32 ArrayIndex);
- virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); }
+ virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
+ {
+ BindResource(pObject, 0);
+ }
virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
Uint32 FirstElement,
Uint32 NumElements) override final
{
- VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.BindCount, FirstElement, NumElements);
+ const auto& Desc = GetDesc();
+ VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
for (Uint32 elem = 0; elem < NumElements; ++elem)
BindResource(ppObjects[elem], FirstElement + elem);
}
virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
{
- VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount);
- return m_ParentResLayout.m_ResourceCache.IsCBBound(m_Attribs.BindPoint + ArrayIndex);
+ VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
+ return m_ParentManager.m_ResourceCache.IsCBBound(GetAttribs().CacheOffset + ArrayIndex);
}
};
struct TexSRVBindInfo final : ShaderVariableD3D11Base
{
- TexSRVBindInfo(const D3DShaderResourceAttribs& _TextureAttribs,
- Uint32 _SamplerIndex,
- ShaderResourceLayoutD3D11& ParentResLayout,
- SHADER_RESOURCE_VARIABLE_TYPE VariableType) :
- ShaderVariableD3D11Base{ParentResLayout, _TextureAttribs, VariableType},
- SamplerIndex{_SamplerIndex}
+ TexSRVBindInfo(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
+ ShaderVariableD3D11Base{ParentLayout, ResIndex}
{}
// Non-virtual function
__forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
- virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); }
+ virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
+ {
+ BindResource(pObject, 0);
+ }
virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
Uint32 FirstElement,
Uint32 NumElements) override final
{
- VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.BindCount, FirstElement, NumElements);
+ const auto& Desc = GetDesc();
+ VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
for (Uint32 elem = 0; elem < NumElements; ++elem)
BindResource(ppObjects[elem], FirstElement + elem);
}
virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
{
- VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount);
- return m_ParentResLayout.m_ResourceCache.IsSRVBound(m_Attribs.BindPoint + ArrayIndex, true);
+ VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
+ return m_ParentManager.m_ResourceCache.IsSRVBound(GetAttribs().CacheOffset + ArrayIndex, true);
}
-
-
- bool ValidSamplerAssigned() const { return SamplerIndex != InvalidSamplerIndex; }
-
- static constexpr Uint32 InvalidSamplerIndex = static_cast<Uint32>(-1);
- const Uint32 SamplerIndex;
};
struct TexUAVBindInfo final : ShaderVariableD3D11Base
{
- TexUAVBindInfo(const D3DShaderResourceAttribs& ResourceAttribs,
- ShaderResourceLayoutD3D11& ParentResLayout,
- SHADER_RESOURCE_VARIABLE_TYPE VariableType) :
- ShaderVariableD3D11Base(ParentResLayout, ResourceAttribs, VariableType)
+ TexUAVBindInfo(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
+ ShaderVariableD3D11Base{ParentLayout, ResIndex}
{}
// Provide non-virtual function
__forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
- virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); }
+ virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
+ {
+ BindResource(pObject, 0);
+ }
virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
Uint32 FirstElement,
Uint32 NumElements) override final
{
- VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.BindCount, FirstElement, NumElements);
+ const auto& Desc = GetDesc();
+ VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
for (Uint32 elem = 0; elem < NumElements; ++elem)
BindResource(ppObjects[elem], FirstElement + elem);
}
__forceinline virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
{
- VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount);
- return m_ParentResLayout.m_ResourceCache.IsUAVBound(m_Attribs.BindPoint + ArrayIndex, true);
+ VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
+ return m_ParentManager.m_ResourceCache.IsUAVBound(GetAttribs().CacheOffset + ArrayIndex, true);
}
};
struct BuffUAVBindInfo final : ShaderVariableD3D11Base
{
- BuffUAVBindInfo(const D3DShaderResourceAttribs& ResourceAttribs,
- ShaderResourceLayoutD3D11& ParentResLayout,
- SHADER_RESOURCE_VARIABLE_TYPE VariableType) :
- ShaderVariableD3D11Base{ParentResLayout, ResourceAttribs, VariableType}
+ BuffUAVBindInfo(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
+ ShaderVariableD3D11Base{ParentLayout, ResIndex}
{}
// Non-virtual function
__forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
- virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); }
+ virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
+ {
+ BindResource(pObject, 0);
+ }
virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
Uint32 FirstElement,
Uint32 NumElements) override final
{
- VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.BindCount, FirstElement, NumElements);
+ const auto& Desc = GetDesc();
+ VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
for (Uint32 elem = 0; elem < NumElements; ++elem)
BindResource(ppObjects[elem], FirstElement + elem);
}
virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
{
- VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount);
- return m_ParentResLayout.m_ResourceCache.IsUAVBound(m_Attribs.BindPoint + ArrayIndex, false);
+ VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
+ return m_ParentManager.m_ResourceCache.IsUAVBound(GetAttribs().CacheOffset + ArrayIndex, false);
}
};
struct BuffSRVBindInfo final : ShaderVariableD3D11Base
{
- BuffSRVBindInfo(const D3DShaderResourceAttribs& ResourceAttribs,
- ShaderResourceLayoutD3D11& ParentResLayout,
- SHADER_RESOURCE_VARIABLE_TYPE VariableType) :
- ShaderVariableD3D11Base{ParentResLayout, ResourceAttribs, VariableType}
+ BuffSRVBindInfo(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
+ ShaderVariableD3D11Base{ParentLayout, ResIndex}
{}
// Non-virtual function
__forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
- virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); }
+ virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
+ {
+ BindResource(pObject, 0);
+ }
virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
Uint32 FirstElement,
Uint32 NumElements) override final
{
- VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.BindCount, FirstElement, NumElements);
+ const auto& Desc = GetDesc();
+ VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
for (Uint32 elem = 0; elem < NumElements; ++elem)
BindResource(ppObjects[elem], FirstElement + elem);
}
virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
{
- VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount);
- return m_ParentResLayout.m_ResourceCache.IsSRVBound(m_Attribs.BindPoint + ArrayIndex, false);
+ VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
+ return m_ParentManager.m_ResourceCache.IsSRVBound(GetAttribs().CacheOffset + ArrayIndex, false);
}
};
struct SamplerBindInfo final : ShaderVariableD3D11Base
{
- SamplerBindInfo(const D3DShaderResourceAttribs& ResourceAttribs,
- ShaderResourceLayoutD3D11& ParentResLayout,
- SHADER_RESOURCE_VARIABLE_TYPE VariableType) :
- ShaderVariableD3D11Base{ParentResLayout, ResourceAttribs, VariableType}
+ SamplerBindInfo(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
+ ShaderVariableD3D11Base{ParentLayout, ResIndex}
{}
// Non-virtual function
__forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
- virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); }
+ virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
+ {
+ BindResource(pObject, 0);
+ }
virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
Uint32 FirstElement,
Uint32 NumElements) override final
{
- VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.BindCount, FirstElement, NumElements);
+ const auto& Desc = GetDesc();
+ VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
for (Uint32 elem = 0; elem < NumElements; ++elem)
BindResource(ppObjects[elem], FirstElement + elem);
}
virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
{
- VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount);
- return m_ParentResLayout.m_ResourceCache.IsSamplerBound(m_Attribs.BindPoint + ArrayIndex);
+ VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
+ return m_ParentManager.m_ResourceCache.IsSamplerBound(GetAttribs().CacheOffset + ArrayIndex);
}
};
- // dbgResourceCache is only used for sanity check and as a remainder that the resource cache must be alive
- // while Layout is alive
- void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags, const ShaderResourceCacheD3D11& dbgResourceCache);
+ void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags);
#ifdef DILIGENT_DEVELOPMENT
bool dvpVerifyBindings() const;
#endif
- IShaderResourceVariable* GetShaderVariable(const Char* Name);
- IShaderResourceVariable* GetShaderVariable(Uint32 Index);
- __forceinline SHADER_TYPE GetShaderType() const { return m_pResources->GetShaderType(); }
+ IShaderResourceVariable* GetVariable(const Char* Name) const;
+ IShaderResourceVariable* GetVariable(Uint32 Index) const;
IObject& GetOwner() { return m_Owner; }
+ Uint32 GetVariableCount() const;
+
Uint32 GetVariableIndex(const ShaderVariableD3D11Base& Variable) const;
- Uint32 GetTotalResourceCount() const
- {
- auto ResourceCount = GetNumCBs() + GetNumTexSRVs() + GetNumTexUAVs() + GetNumBufUAVs() + GetNumBufSRVs();
- // Do not expose sampler variables when using combined texture samplers
- if (!m_pResources->IsUsingCombinedTextureSamplers())
- ResourceCount += GetNumSamplers();
- return ResourceCount;
- }
// clang-format off
Uint32 GetNumCBs() const { return (m_TexSRVsOffset - 0 ) / sizeof(ConstBuffBindInfo);}
@@ -301,35 +359,22 @@ public:
template<> Uint32 GetNumResources<SamplerBindInfo> () const { return GetNumSamplers(); }
// clang-format on
- const Char* GetShaderName() const
- {
- return m_pResources->GetShaderName();
- }
-
private:
- // clang-format off
-
-/* 0 */ IObject& m_Owner;
-/* 8 */ std::shared_ptr<const ShaderResourcesD3D11> m_pResources;
-
- // No need to use shared pointer, as the resource cache is either part of the same
- // ShaderD3D11Impl object, or ShaderResourceBindingD3D11Impl object
-/*24*/ ShaderResourceCacheD3D11& m_ResourceCache;
-
-/*32*/ std::unique_ptr<void, STDDeleterRawMem<void> > m_ResourceBuffer;
-
- // Offsets in bytes
- using OffsetType = Uint16;
-/*48*/ OffsetType m_TexSRVsOffset = 0;
-/*50*/ OffsetType m_TexUAVsOffset = 0;
-/*52*/ OffsetType m_BuffSRVsOffset = 0;
-/*54*/ OffsetType m_BuffUAVsOffset = 0;
-/*56*/ OffsetType m_SamplerOffset = 0;
-/*58*/ OffsetType m_MemorySize = 0;
-/*60 - 64*/
-/*64*/ // End of data
-
+ static void CountResources(const PipelineResourceSignatureD3D11Impl& Signature,
+ const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
+ Uint32 NumAllowedTypes,
+ SHADER_TYPE ShaderType,
+ D3DShaderResourceCounters& Counters);
+
+ template <typename HandlerType>
+ static void ProcessSignatureResources(const PipelineResourceSignatureD3D11Impl& Signature,
+ const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
+ Uint32 NumAllowedTypes,
+ SHADER_TYPE ShaderType,
+ HandlerType Handler);
+ // clang-format off
+ using OffsetType = Uint16;
template<typename ResourceType> OffsetType GetResourceOffset()const;
template<> OffsetType GetResourceOffset<ConstBuffBindInfo>() const { return 0; }
template<> OffsetType GetResourceOffset<TexSRVBindInfo> () const { return m_TexSRVsOffset; }
@@ -337,27 +382,26 @@ private:
template<> OffsetType GetResourceOffset<BuffSRVBindInfo> () const { return m_BuffSRVsOffset; }
template<> OffsetType GetResourceOffset<BuffUAVBindInfo> () const { return m_BuffUAVsOffset; }
template<> OffsetType GetResourceOffset<SamplerBindInfo> () const { return m_SamplerOffset; }
-
// clang-format on
template <typename ResourceType>
- ResourceType& GetResource(Uint32 ResIndex)
+ ResourceType& GetResource(Uint32 ResIndex) const
{
- VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources<ResourceType>() - 1, ")");
+ VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") must be less than (", GetNumResources<ResourceType>(), ")");
auto Offset = GetResourceOffset<ResourceType>();
- return reinterpret_cast<ResourceType*>(reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + Offset)[ResIndex];
+ return reinterpret_cast<ResourceType*>(reinterpret_cast<Uint8*>(m_ResourceBuffer) + Offset)[ResIndex];
}
template <typename ResourceType>
const ResourceType& GetConstResource(Uint32 ResIndex) const
{
- VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources<ResourceType>() - 1, ")");
+ VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") must be less than (", GetNumResources<ResourceType>(), ")");
auto Offset = GetResourceOffset<ResourceType>();
- return reinterpret_cast<const ResourceType*>(reinterpret_cast<const Uint8*>(m_ResourceBuffer.get()) + Offset)[ResIndex];
+ return reinterpret_cast<const ResourceType*>(reinterpret_cast<const Uint8*>(m_ResourceBuffer) + Offset)[ResIndex];
}
template <typename ResourceType>
- IShaderResourceVariable* GetResourceByName(const Char* Name);
+ IShaderResourceVariable* GetResourceByName(const Char* Name) const;
template <typename THandleCB,
typename THandleTexSRV,
@@ -425,6 +469,28 @@ private:
friend class ShaderVariableIndexLocator;
friend class ShaderVariableLocator;
+
+private:
+ PipelineResourceSignatureD3D11Impl const* m_pSignature = nullptr;
+
+ IObject& m_Owner;
+
+ // No need to use shared pointer, as the resource cache is either part of the same
+ // ShaderD3D11Impl object, or ShaderResourceBindingD3D11Impl object
+ ShaderResourceCacheD3D11& m_ResourceCache;
+ void* m_ResourceBuffer = nullptr;
+
+ // Offsets in bytes
+ OffsetType m_TexSRVsOffset = 0;
+ OffsetType m_TexUAVsOffset = 0;
+ OffsetType m_BuffSRVsOffset = 0;
+ OffsetType m_BuffUAVsOffset = 0;
+ OffsetType m_SamplerOffset = 0;
+ OffsetType m_MemorySize = 0;
+
+#ifdef DILIGENT_DEBUG
+ IMemoryAllocator* m_pDbgAllocator = nullptr;
+#endif
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.hpp b/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.hpp
index d1d882c2..54cc7031 100644
--- a/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.hpp
@@ -42,10 +42,10 @@ namespace Diligent
class FixedBlockMemoryAllocator;
/// Base implementation of a texture object in Direct3D11 backend.
-class TextureBaseD3D11 : public TextureBase<ITextureD3D11, RenderDeviceD3D11Impl, TextureViewD3D11Impl, FixedBlockMemoryAllocator>
+class TextureBaseD3D11 : public TextureBase<EngineD3D11ImplTraits>
{
public:
- using TTextureBase = TextureBase<ITextureD3D11, RenderDeviceD3D11Impl, TextureViewD3D11Impl, FixedBlockMemoryAllocator>;
+ using TTextureBase = TextureBase<EngineD3D11ImplTraits>;
using ViewImplType = TextureViewD3D11Impl;
TextureBaseD3D11(IReferenceCounters* pRefCounters,
diff --git a/Graphics/GraphicsEngineD3D11/include/TextureViewD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/TextureViewD3D11Impl.hpp
index bfb2e73e..4bb89268 100644
--- a/Graphics/GraphicsEngineD3D11/include/TextureViewD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/TextureViewD3D11Impl.hpp
@@ -41,10 +41,10 @@ namespace Diligent
class FixedBlockMemoryAllocator;
/// Texture view implementation in Direct3D11 backend.
-class TextureViewD3D11Impl final : public TextureViewBase<ITextureViewD3D11, RenderDeviceD3D11Impl>
+class TextureViewD3D11Impl final : public TextureViewBase<EngineD3D11ImplTraits>
{
public:
- using TTextureViewBase = TextureViewBase<ITextureViewD3D11, RenderDeviceD3D11Impl>;
+ using TTextureViewBase = TextureViewBase<EngineD3D11ImplTraits>;
TextureViewD3D11Impl(IReferenceCounters* pRefCounters,
RenderDeviceD3D11Impl* pDevice,
diff --git a/Graphics/GraphicsEngineD3D11/src/BufferViewD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/BufferViewD3D11Impl.cpp
index 361dfc6d..8844b8d8 100644
--- a/Graphics/GraphicsEngineD3D11/src/BufferViewD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/BufferViewD3D11Impl.cpp
@@ -27,6 +27,7 @@
#include "pch.h"
#include "BufferViewD3D11Impl.hpp"
+#include "BufferD3D11Impl.hpp"
namespace Diligent
{
@@ -34,7 +35,7 @@ namespace Diligent
BufferViewD3D11Impl::BufferViewD3D11Impl(IReferenceCounters* pRefCounters,
RenderDeviceD3D11Impl* pDevice,
const BufferViewDesc& ViewDesc,
- IBuffer* pBuffer,
+ BufferD3D11Impl* pBuffer,
ID3D11View* pD3D11View,
bool bIsDefaultView) :
// clang-format off
diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
index 7c1ae564..a517a59e 100755
--- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
@@ -133,6 +133,58 @@ void DeviceContextD3D11Impl::SetPipelineState(IPipelineState* pPipelineState)
{
UNEXPECTED(GetPipelineTypeString(Desc.PipelineType), " pipelines '", Desc.Name, "' are not supported in OpenGL");
}
+
+ const auto SignCount = m_pPipelineState->GetResourceSignatureCount();
+ const auto ActiveStages = m_pPipelineState->GetActiveShaderStages();
+
+ m_BindInfo.ActiveSRBMask = 0;
+ for (Uint32 s = 0; s < SignCount; ++s)
+ {
+ const auto* pLayoutSign = m_pPipelineState->GetResourceSignature(s);
+ if (pLayoutSign == nullptr || pLayoutSign->GetTotalResourceCount() == 0)
+ continue;
+
+ m_BindInfo.ActiveSRBMask |= (1u << s);
+ }
+
+ // Reset states if new pipeline have new shader stages.
+ if ((m_BindInfo.ActiveStages & ActiveStages) != ActiveStages)
+ {
+ m_BindInfo.ActiveStages = ActiveStages;
+ m_BindInfo.StaleSRBMask = 0xFF;
+ }
+
+#ifdef DILIGENT_DEVELOPMENT
+ // Find the first incompatible shader resource bindings
+ Uint32 sign = 0;
+ for (; sign < SignCount; ++sign)
+ {
+ const auto* pLayoutSign = m_pPipelineState->GetResourceSignature(sign);
+ const auto* pSRBSign = m_BindInfo.SRBs[sign] != nullptr ? m_BindInfo.SRBs[sign]->GetSignature() : nullptr;
+
+ if ((pLayoutSign == nullptr || pLayoutSign->GetTotalResourceCount() == 0) != (pSRBSign == nullptr || pSRBSign->GetTotalResourceCount() == 0))
+ {
+ // One signature is null or empty while the other is not - SRB is not compatible with the layout.
+ break;
+ }
+
+ if (pLayoutSign != nullptr && pSRBSign != nullptr && pLayoutSign->IsIncompatibleWith(*pSRBSign))
+ {
+ // Signatures are incompatible
+ break;
+ }
+ }
+
+ // Unbind incompatible SRB and SRB with a higher binding index.
+ // This is the same behavior that used in Vulkan backend.
+ for (; sign < SignCount; ++sign)
+ {
+ m_BindInfo.SRBs[sign] = nullptr;
+ m_BindInfo.ClearStaleSRBBit(sign);
+ }
+
+ m_BindInfo.CommittedResourcesValidated = false;
+#endif
}
// clang-format off
@@ -168,493 +220,239 @@ void DeviceContextD3D11Impl::SetPipelineState(IPipelineState* pPipelineState)
// clang-format on
-// http://diligentgraphics.com/diligent-engine/architecture/d3d11/committing-shader-resources-to-the-gpu-pipeline/
-template <bool TransitionResources, bool CommitResources>
-void DeviceContextD3D11Impl::TransitionAndCommitShaderResources(IPipelineState* pPSO, IShaderResourceBinding* pShaderResourceBinding, bool VerifyStates)
+void DeviceContextD3D11Impl::TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding)
{
- VERIFY_EXPR(pPSO != nullptr);
- static_assert(TransitionResources || CommitResources, "At least one of TransitionResources or CommitResources flags is expected to be true");
-
- auto* pPipelineStateD3D11 = ValidatedCast<PipelineStateD3D11Impl>(pPSO);
-
- if (pShaderResourceBinding == nullptr)
+ DEV_CHECK_ERR(pPipelineState != nullptr, "Pipeline state must not be null");
+ DEV_CHECK_ERR(pShaderResourceBinding != nullptr, "Shader resource binding must not be null");
+ if (m_pActiveRenderPass)
{
-#ifdef DILIGENT_DEVELOPMENT
- bool ResourcesPresent = false;
- for (Uint32 s = 0; s < pPipelineStateD3D11->GetNumShaderStages(); ++s)
- {
- auto* pShaderD3D11 = pPipelineStateD3D11->GetShader(s);
- if (pShaderD3D11->GetD3D11Resources()->GetTotalResources() > 0)
- ResourcesPresent = true;
- }
-
- if (ResourcesPresent)
- {
- LOG_ERROR_MESSAGE("Pipeline state '", pPSO->GetDesc().Name, "' requires shader resource binding object to ",
- (CommitResources ? "commit" : "transition"), " resources, but none is provided.");
- }
-#endif
+ LOG_ERROR_MESSAGE("State transitions are not allowed inside a render pass.");
return;
}
+ auto* pShaderResBindingD3D11 = ValidatedCast<ShaderResourceBindingD3D11Impl>(pShaderResourceBinding);
+ auto& ResourceCache = pShaderResBindingD3D11->GetResourceCache();
- auto pShaderResBindingD3D11 = ValidatedCast<ShaderResourceBindingD3D11Impl>(pShaderResourceBinding);
-#ifdef DILIGENT_DEVELOPMENT
- if (pPipelineStateD3D11->IsIncompatibleWith(pShaderResourceBinding->GetPipelineState()))
- {
- LOG_ERROR_MESSAGE("Shader resource binding does not match Pipeline State");
+ ResourceCache.TransitionResourceStates(*this, ShaderResourceCacheD3D11::StateTransitionMode::Transition);
+}
+
+void DeviceContextD3D11Impl::CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)
+{
+ if (!DeviceContextBase::CommitShaderResources(pShaderResourceBinding, StateTransitionMode, 0 /*Dummy*/))
return;
- }
-#endif
- auto NumShaders = pShaderResBindingD3D11->GetNumActiveShaders();
- VERIFY(NumShaders == pPipelineStateD3D11->GetNumShaderStages(), "Number of active shaders in shader resource binding is not consistent with the number of shaders in the pipeline state");
+ auto* pShaderResBindingD3D11 = ValidatedCast<ShaderResourceBindingD3D11Impl>(pShaderResourceBinding);
+ const auto SRBIndex = pShaderResBindingD3D11->GetBindingIndex();
+ auto& ResourceCache = pShaderResBindingD3D11->GetResourceCache();
+
+ m_BindInfo.SRBs[SRBIndex] = pShaderResBindingD3D11;
+ m_BindInfo.SetStaleSRBBit(SRBIndex);
#ifdef DILIGENT_DEVELOPMENT
- {
- bool StaticResourcesPresent = false;
- for (Uint32 s = 0; s < NumShaders; ++s)
- {
- const auto& StaticResLayout = pPipelineStateD3D11->GetStaticResourceLayout(s);
- if (StaticResLayout.GetTotalResourceCount() > 0)
- StaticResourcesPresent = true;
- }
- // Static resource bindings are verified in BindStaticShaderResources()
- if (StaticResourcesPresent && !pShaderResBindingD3D11->IsStaticResourcesBound())
- {
- LOG_ERROR_MESSAGE("Static resources have not been initialized in the shader resource binding object being committed for PSO '", pPSO->GetDesc().Name, "'. Please call IShaderResourceBinding::InitializeStaticResources().");
- }
- }
+ m_BindInfo.CommittedResourcesValidated = false;
#endif
- bool ClearPixelShaderUAVs = m_NumCommittedUAVs[PSInd] > 0;
- // First, commit all UAVs for all shader stages. This will unbind them from input
- for (Uint32 s = 0; s < NumShaders; ++s)
+ if (StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION)
{
- const auto ShaderType = pShaderResBindingD3D11->GetActiveShaderType(s);
- const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType);
-
+ ResourceCache.TransitionResourceStates(*this, ShaderResourceCacheD3D11::StateTransitionMode::Transition);
+ }
#ifdef DILIGENT_DEVELOPMENT
- auto* pShaderD3D11 = pPipelineStateD3D11->GetShader(s);
- VERIFY_EXPR(ShaderType == pShaderD3D11->GetDesc().ShaderType);
+ else if (StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY)
+ {
+ ResourceCache.TransitionResourceStates(*this, ShaderResourceCacheD3D11::StateTransitionMode::Verify);
+ }
#endif
+}
- auto& Cache = pShaderResBindingD3D11->GetResourceCache(s);
- auto NumUAVs = Cache.GetUAVCount();
- if (NumUAVs)
- {
- ShaderResourceCacheD3D11::CachedResource* CachedUAVResources;
- ID3D11UnorderedAccessView** d3d11UAVs;
- Cache.GetUAVArrays(CachedUAVResources, d3d11UAVs);
-
- auto* CommittedD3D11UAVs = m_CommittedD3D11UAVs[ShaderTypeInd];
- auto* CommittedD3D11UAVRes = m_CommittedD3D11UAVResources[ShaderTypeInd];
+void DeviceContextD3D11Impl::BindShaderResources()
+{
+ if ((m_BindInfo.StaleSRBMask & m_BindInfo.ActiveSRBMask) == 0)
+ return;
- if (ShaderTypeInd == PSInd)
- ClearPixelShaderUAVs = false;
+ TBindingsPerStage Bindings = {};
+ TMinMaxSlotPerStage MinMaxSlot = {};
+ const auto ActiveStages = m_BindInfo.ActiveStages;
- UINT MinSlot = UINT_MAX;
- UINT MaxSlot = 0;
+ if (m_pPipelineState->GetDesc().IsAnyGraphicsPipeline())
+ Bindings[GetShaderTypeIndex(SHADER_TYPE_PIXEL)][DESCRIPTOR_RANGE_UAV] = static_cast<Uint8>(m_pPipelineState->GetGraphicsPipelineDesc().NumRenderTargets);
- for (Uint32 uav = 0; uav < NumUAVs; ++uav)
- {
- VERIFY_EXPR(uav < Cache.GetUAVCount());
- auto& UAVRes = CachedUAVResources[uav];
- // WARNING! This code is not thread-safe. It is up to the application to make
- // sure that multiple threads do not modify the texture state simultaneously.
- if (TransitionResources)
- {
- if (auto* pTexture = ValidatedCast<TextureBaseD3D11>(UAVRes.pTexture))
- {
- if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
- {
- if (pTexture->CheckAnyState(RESOURCE_STATE_SHADER_RESOURCE | RESOURCE_STATE_INPUT_ATTACHMENT))
- UnbindTextureFromInput(pTexture, UAVRes.pd3d11Resource);
- pTexture->SetState(RESOURCE_STATE_UNORDERED_ACCESS);
- }
- }
- else if (auto* pBuffer = ValidatedCast<BufferD3D11Impl>(UAVRes.pBuffer))
- {
- if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
- {
- if ((pBuffer->GetState() & RESOURCE_STATE_GENERIC_READ) != 0)
- UnbindBufferFromInput(pBuffer, UAVRes.pd3d11Resource);
- pBuffer->SetState(RESOURCE_STATE_UNORDERED_ACCESS);
- }
- }
- }
-#ifdef DILIGENT_DEVELOPMENT
- else if (VerifyStates)
- {
- if (const auto* pTexture = ValidatedCast<TextureBaseD3D11>(UAVRes.pTexture))
- {
- if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
- {
- LOG_ERROR_MESSAGE("Texture '", pTexture->GetDesc().Name, "' has not been transitioned to Unordered Access state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the texture to required state.");
- }
- }
- else if (const auto* pBuffer = ValidatedCast<BufferD3D11Impl>(UAVRes.pBuffer))
- {
- if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
- {
- LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name, "' has not been transitioned to Unordered Access state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
- }
- }
- }
-#endif
- if (CommitResources)
- {
- bool IsNewUAV = CommittedD3D11UAVs[uav] != d3d11UAVs[uav];
- MinSlot = IsNewUAV ? std::min(MinSlot, uav) : MinSlot;
- MaxSlot = IsNewUAV ? uav : MaxSlot;
+ auto ActiveSRBMask = Uint32{m_BindInfo.ActiveSRBMask};
+ while (ActiveSRBMask != 0)
+ {
+ Uint32 sign = PlatformMisc::GetLSB(ActiveSRBMask);
+ Uint32 SigBit = (1u << sign);
+ VERIFY_EXPR(sign < m_pPipelineState->GetResourceSignatureCount());
- CommittedD3D11UAVRes[uav] = UAVRes.pd3d11Resource;
- CommittedD3D11UAVs[uav] = d3d11UAVs[uav];
- }
- }
+ ActiveSRBMask &= ~SigBit;
- if (CommitResources)
- {
- if (MinSlot != UINT_MAX || ShaderTypeInd == PSInd && m_NumCommittedUAVs[PSInd] != NumUAVs)
- {
- // Something has changed
- if (ShaderTypeInd == PSInd)
- {
- // Pixel shader UAVs cannot be set independently; they all need to be set at the same time.
- // https://docs.microsoft.com/en-us/windows/desktop/api/d3d11/nf-d3d11-id3d11devicecontext-omsetrendertargetsandunorderedaccessviews#remarks
- auto StartUAVSlot = m_NumBoundRenderTargets;
- VERIFY(NumUAVs > StartUAVSlot, "Number of UAVs must be greater than the render target count");
- m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(
- D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr,
- StartUAVSlot, NumUAVs - StartUAVSlot, CommittedD3D11UAVs + StartUAVSlot, nullptr);
- // Clear previously bound UAVs, but do not clear lower slots as if
- // render target count reduces, we will bind these UAVs in CommitRenderTargets()
- for (Uint32 uav = NumUAVs; uav < m_NumCommittedUAVs[ShaderTypeInd]; ++uav)
- {
- CommittedD3D11UAVRes[uav] = nullptr;
- CommittedD3D11UAVs[uav] = nullptr;
- }
- m_NumCommittedUAVs[ShaderTypeInd] = static_cast<Uint8>(NumUAVs);
- }
- else
- {
- // This can only be CS
- auto SetUAVMethod = SetUAVMethods[ShaderTypeInd];
- (m_pd3d11DeviceContext->*SetUAVMethod)(MinSlot, MaxSlot - MinSlot + 1, CommittedD3D11UAVs + MinSlot, nullptr);
- m_NumCommittedUAVs[ShaderTypeInd] = std::max(m_NumCommittedUAVs[ShaderTypeInd], static_cast<Uint8>(NumUAVs));
- }
- }
+ auto* pSRB = m_BindInfo.SRBs[sign];
+ VERIFY_EXPR(pSRB);
+ if (m_BindInfo.StaleSRBMask & SigBit)
+ {
#ifdef DILIGENT_DEVELOPMENT
- if ((m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE) != 0 && ShaderTypeInd == CSInd)
- {
- dbgVerifyCommittedUAVs(pShaderD3D11->GetDesc().ShaderType);
- }
+ m_BindInfo.BoundResOffsets[sign] = Bindings;
#endif
- }
+ pSRB->GetResourceCache().BindResources(*this, Bindings, MinMaxSlot, m_CommittedRes, ActiveStages);
}
+ pSRB->GetSignature()->AddBindings(Bindings);
}
- if (ClearPixelShaderUAVs)
- {
- // If pixel shader stage is inactive or does not use UAVs, unbind all committed UAVs.
- // This is important as UnbindPixelShaderUAV<> function may need to rebind
- // existing UAVs and the UAVs pointed to by CommittedD3D11UAVRes must be alive
- // (we do not keep strong references to d3d11 UAVs)
- auto* CommittedD3D11UAVs = m_CommittedD3D11UAVs[PSInd];
- auto* CommittedD3D11UAVRes = m_CommittedD3D11UAVResources[PSInd];
- auto& NumCommittedPixelShaderUAVs = m_NumCommittedUAVs[PSInd];
- for (Uint32 uav = 0; uav < NumCommittedPixelShaderUAVs; ++uav)
- {
- CommittedD3D11UAVRes[uav] = nullptr;
- CommittedD3D11UAVs[uav] = nullptr;
- }
- m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(
- D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr,
- 0, 0, nullptr, nullptr);
- NumCommittedPixelShaderUAVs = 0;
- }
+ m_BindInfo.StaleSRBMask &= ~m_BindInfo.ActiveSRBMask;
+ bool ClearPixelShaderUAVs = m_CommittedRes.NumUAVs[PSInd] > 0;
- // Commit input resources (CBs, SRVs and Samplers)
- for (Uint32 s = 0; s < NumShaders; ++s)
+ for (Uint32 s = 0, ShaderCount = m_pPipelineState->GetNumShaders(); s < ShaderCount; ++s)
{
- const auto ShaderType = pShaderResBindingD3D11->GetActiveShaderType(s);
- const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType);
+ const auto ShaderType = m_pPipelineState->GetShaderStageType(s);
+ const Uint32 ShaderInd = GetShaderTypeIndex(ShaderType);
-#ifdef DILIGENT_DEVELOPMENT
- auto* pShaderD3D11 = pPipelineStateD3D11->GetShader(s);
- VERIFY_EXPR(ShaderType == pShaderD3D11->GetDesc().ShaderType);
-#endif
-
- auto& Cache = pShaderResBindingD3D11->GetResourceCache(s);
-
- // Transition and commit Constant Buffers
- auto NumCBs = Cache.GetCBCount();
- if (NumCBs)
+ // CBV
{
- ShaderResourceCacheD3D11::CachedCB* CachedCBs;
- ID3D11Buffer** d3d11CBs;
- Cache.GetCBArrays(CachedCBs, d3d11CBs);
-
- auto* CommittedD3D11CBs = m_CommittedD3D11CBs[ShaderTypeInd];
- UINT MinSlot = UINT_MAX;
- UINT MaxSlot = 0;
- for (Uint32 cb = 0; cb < NumCBs; ++cb)
+ const auto Range = DESCRIPTOR_RANGE_CBV;
+ const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
+ const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
+ if (MinSlot != UINT_MAX)
{
- VERIFY_EXPR(cb < Cache.GetCBCount());
-
- if (TransitionResources)
- {
- auto& CB = CachedCBs[cb];
- if (auto* pBuff = CB.pBuff.RawPtr<BufferD3D11Impl>())
- {
- // WARNING! This code is not thread-safe. It is up to the application to make
- // sure that multiple threads do not modify the buffer state simultaneously.
- if (pBuff->IsInKnownState() && !pBuff->CheckState(RESOURCE_STATE_CONSTANT_BUFFER))
- {
- if (pBuff->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
- {
- // Even though we have unbound resources from UAV, we only checked shader
- // stages active in current PSO, so we still may need to unbind the resource
- // from UAV (for instance, unbind resource from CS UAV when running draw command).
- UnbindResourceFromUAV(pBuff, d3d11CBs[cb]);
- pBuff->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
- }
- pBuff->AddState(RESOURCE_STATE_CONSTANT_BUFFER);
- }
- }
- }
-#ifdef DILIGENT_DEVELOPMENT
- else if (VerifyStates)
- {
- VERIFY_EXPR(CommitResources);
- const auto& CB = CachedCBs[cb];
- if (auto* pBuff = CB.pBuff.RawPtr<const BufferD3D11Impl>())
- {
- if (pBuff->IsInKnownState() && !pBuff->CheckState(RESOURCE_STATE_CONSTANT_BUFFER))
- {
- LOG_ERROR_MESSAGE("Buffer '", pBuff->GetDesc().Name, "' has not been transitioned to Constant Buffer state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
- }
- }
- }
-#endif
-
- if (CommitResources)
- {
- bool IsNewCB = CommittedD3D11CBs[cb] != d3d11CBs[cb];
- MinSlot = IsNewCB ? std::min(MinSlot, cb) : MinSlot;
- MaxSlot = IsNewCB ? cb : MaxSlot;
- CommittedD3D11CBs[cb] = d3d11CBs[cb];
- }
+ auto SetCBMethod = SetCBMethods[ShaderInd];
+ (m_pd3d11DeviceContext->*SetCBMethod)(MinSlot, MaxSlot - MinSlot + 1, m_CommittedRes.D3D11CBs[ShaderInd] + MinSlot);
+ m_CommittedRes.NumCBs[ShaderInd] = std::max(m_CommittedRes.NumCBs[ShaderInd], Bindings[ShaderInd][Range]);
+ VERIFY_EXPR(MaxSlot < Bindings[ShaderInd][Range]);
}
-
- if (CommitResources)
+#ifdef VERIFY_CONTEXT_BINDINGS
+ if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
{
- if (MinSlot != UINT_MAX)
- {
- auto SetCBMethod = SetCBMethods[ShaderTypeInd];
- (m_pd3d11DeviceContext->*SetCBMethod)(MinSlot, MaxSlot - MinSlot + 1, CommittedD3D11CBs + MinSlot);
- m_NumCommittedCBs[ShaderTypeInd] = std::max(m_NumCommittedCBs[ShaderTypeInd], static_cast<Uint8>(NumCBs));
- }
-#ifdef DILIGENT_DEVELOPMENT
- if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
- {
- dbgVerifyCommittedCBs(pShaderD3D11->GetDesc().ShaderType);
- }
-#endif
+ DvpVerifyCommittedCBs(ShaderType);
}
+#endif
}
-
- // Transition and commit Shader Resource Views
- auto NumSRVs = Cache.GetSRVCount();
- if (NumSRVs)
+ // SRV
{
- ShaderResourceCacheD3D11::CachedResource* CachedSRVResources;
- ID3D11ShaderResourceView** d3d11SRVs;
- Cache.GetSRVArrays(CachedSRVResources, d3d11SRVs);
-
- auto* CommittedD3D11SRVs = m_CommittedD3D11SRVs[ShaderTypeInd];
- auto* CommittedD3D11SRVRes = m_CommittedD3D11SRVResources[ShaderTypeInd];
-
- UINT MinSlot = UINT_MAX;
- UINT MaxSlot = 0;
-
- for (Uint32 srv = 0; srv < NumSRVs; ++srv)
+ const auto Range = DESCRIPTOR_RANGE_SRV;
+ const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
+ const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
+ if (MinSlot != UINT_MAX)
{
- VERIFY_EXPR(srv < Cache.GetSRVCount());
- auto& SRVRes = CachedSRVResources[srv];
- // WARNING! This code is not thread-safe. It is up to the application to make
- // sure that multiple threads do not modify the texture state simultaneously.
- if (TransitionResources)
- {
- if (auto* pTexture = ValidatedCast<TextureBaseD3D11>(SRVRes.pTexture))
- {
- if (pTexture->IsInKnownState() && !pTexture->CheckAnyState(RESOURCE_STATE_SHADER_RESOURCE | RESOURCE_STATE_INPUT_ATTACHMENT))
- {
- if (pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
- {
- // Even though we have unbound resources from UAV, we only checked shader
- // stages active in current PSO, so we still may need to unbind the resource
- // from UAV (for instance, unbind resource from CS UAV when running draw command).
- UnbindResourceFromUAV(pTexture, SRVRes.pd3d11Resource);
- pTexture->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
- }
-
- if (pTexture->CheckState(RESOURCE_STATE_RENDER_TARGET))
- UnbindTextureFromRenderTarget(pTexture);
-
- if (pTexture->CheckState(RESOURCE_STATE_DEPTH_WRITE))
- UnbindTextureFromDepthStencil(pTexture);
-
- pTexture->SetState(RESOURCE_STATE_SHADER_RESOURCE);
- }
- }
- else if (auto* pBuffer = ValidatedCast<BufferD3D11Impl>(SRVRes.pBuffer))
- {
- if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_SHADER_RESOURCE))
- {
- if (pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
- {
- UnbindResourceFromUAV(pBuffer, SRVRes.pd3d11Resource);
- pBuffer->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
- }
- pBuffer->AddState(RESOURCE_STATE_SHADER_RESOURCE);
- }
- }
- }
-#ifdef DILIGENT_DEVELOPMENT
- else if (VerifyStates)
- {
- VERIFY_EXPR(CommitResources);
- if (const auto* pTexture = ValidatedCast<TextureBaseD3D11>(SRVRes.pTexture))
- {
- if (pTexture->IsInKnownState() &&
- !(pTexture->CheckState(RESOURCE_STATE_SHADER_RESOURCE) || m_pActiveRenderPass != nullptr && pTexture->CheckState(RESOURCE_STATE_INPUT_ATTACHMENT)))
- {
- LOG_ERROR_MESSAGE("Texture '", pTexture->GetDesc().Name, "' has not been transitioned to Shader Resource state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the texture to required state.");
- }
- }
- else if (const auto* pBuffer = ValidatedCast<BufferD3D11Impl>(SRVRes.pBuffer))
- {
- if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_SHADER_RESOURCE))
- {
- LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name, "' has not been transitioned to Shader Resource state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
- }
- }
- }
+ auto SetSRVMethod = SetSRVMethods[ShaderInd];
+ (m_pd3d11DeviceContext->*SetSRVMethod)(MinSlot, MaxSlot - MinSlot + 1, m_CommittedRes.D3D11SRVs[ShaderInd] + MinSlot);
+ m_CommittedRes.NumSRVs[ShaderInd] = std::max(m_CommittedRes.NumSRVs[ShaderInd], Bindings[ShaderInd][Range]);
+ VERIFY_EXPR(MaxSlot <= Bindings[ShaderInd][Range]);
+ }
+#ifdef VERIFY_CONTEXT_BINDINGS
+ if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
+ {
+ DvpVerifyCommittedSRVs(ShaderType);
+ }
#endif
+ }
- if (CommitResources)
- {
- bool IsNewSRV = CommittedD3D11SRVs[srv] != d3d11SRVs[srv];
- MinSlot = IsNewSRV ? std::min(MinSlot, srv) : MinSlot;
- MaxSlot = IsNewSRV ? srv : MaxSlot;
-
- CommittedD3D11SRVRes[srv] = SRVRes.pd3d11Resource;
- CommittedD3D11SRVs[srv] = d3d11SRVs[srv];
- }
+ // Sampler
+ {
+ const auto Range = DESCRIPTOR_RANGE_SAMPLER;
+ const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
+ const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
+ if (MinSlot != UINT_MAX)
+ {
+ auto SetSamplerMethod = SetSamplerMethods[ShaderInd];
+ (m_pd3d11DeviceContext->*SetSamplerMethod)(MinSlot, MaxSlot - MinSlot + 1, m_CommittedRes.D3D11Samplers[ShaderInd] + MinSlot);
+ m_CommittedRes.NumSamplers[ShaderInd] = std::max(m_CommittedRes.NumSamplers[ShaderInd], Bindings[ShaderInd][Range]);
+ VERIFY_EXPR(MaxSlot < Bindings[ShaderInd][Range]);
}
-
- if (CommitResources)
+#ifdef VERIFY_CONTEXT_BINDINGS
+ if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
{
- if (MinSlot != UINT_MAX)
- {
- auto SetSRVMethod = SetSRVMethods[ShaderTypeInd];
- (m_pd3d11DeviceContext->*SetSRVMethod)(MinSlot, MaxSlot - MinSlot + 1, CommittedD3D11SRVs + MinSlot);
- m_NumCommittedSRVs[ShaderTypeInd] = std::max(m_NumCommittedSRVs[ShaderTypeInd], static_cast<Uint8>(NumSRVs));
- }
-#ifdef DILIGENT_DEVELOPMENT
- if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
- {
- dbgVerifyCommittedSRVs(pShaderD3D11->GetDesc().ShaderType);
- }
-#endif
+ DvpVerifyCommittedSamplers(ShaderType);
}
+#endif
}
-
- // Commit samplers (no transitions for samplers)
- if (CommitResources)
+ // UAV
{
- auto NumSamplers = Cache.GetSamplerCount();
- if (NumSamplers)
+ const auto Range = DESCRIPTOR_RANGE_UAV;
+ const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
+ const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
+ if (MinSlot != UINT_MAX)
{
- ShaderResourceCacheD3D11::CachedSampler* CachedSamplers;
- ID3D11SamplerState** d3d11Samplers;
- Cache.GetSamplerArrays(CachedSamplers, d3d11Samplers);
-
- auto* CommittedD3D11Samplers = m_CommittedD3D11Samplers[ShaderTypeInd];
- UINT MinSlot = std::numeric_limits<UINT>::max();
- UINT MaxSlot = 0;
- for (Uint32 sam = 0; sam < NumSamplers; ++sam)
- {
- VERIFY_EXPR(sam < Cache.GetSamplerCount());
+ auto* CommittedD3D11UAVs = m_CommittedRes.D3D11UAVs[ShaderInd];
+ auto* CommittedD3D11UAVRes = m_CommittedRes.D3D11UAVResources[ShaderInd];
- bool IsNewSam = CommittedD3D11Samplers[sam] != d3d11Samplers[sam];
- MinSlot = IsNewSam ? std::min(MinSlot, sam) : MinSlot;
- MaxSlot = IsNewSam ? sam : MaxSlot;
+ if (ShaderInd == PSInd)
+ ClearPixelShaderUAVs = false;
- CommittedD3D11Samplers[sam] = d3d11Samplers[sam];
+ // Something has changed
+ if (ShaderInd == PSInd)
+ {
+ // Pixel shader UAVs cannot be set independently; they all need to be set at the same time.
+ // https://docs.microsoft.com/en-us/windows/desktop/api/d3d11/nf-d3d11-id3d11devicecontext-omsetrendertargetsandunorderedaccessviews#remarks
+ const auto StartUAVSlot = m_NumBoundRenderTargets;
+ const auto NumUAVSlot = Bindings[ShaderInd][Range];
+ VERIFY(NumUAVSlot > StartUAVSlot, "Number of UAVs must be greater than the render target count");
+ m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(
+ D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr,
+ StartUAVSlot, NumUAVSlot - StartUAVSlot, CommittedD3D11UAVs + StartUAVSlot, nullptr);
+ // Clear previously bound UAVs, but do not clear lower slots as if
+ // render target count reduces, we will bind these UAVs in CommitRenderTargets()
+ for (Uint32 uav = NumUAVSlot; uav < m_CommittedRes.NumUAVs[ShaderInd]; ++uav)
+ {
+ CommittedD3D11UAVRes[uav] = nullptr;
+ CommittedD3D11UAVs[uav] = nullptr;
+ }
+ m_CommittedRes.NumUAVs[ShaderInd] = NumUAVSlot;
}
-
- if (MinSlot != UINT_MAX)
+ else if (ShaderInd == CSInd)
{
- auto SetSamplerMethod = SetSamplerMethods[ShaderTypeInd];
- (m_pd3d11DeviceContext->*SetSamplerMethod)(MinSlot, MaxSlot - MinSlot + 1, CommittedD3D11Samplers + MinSlot);
- m_NumCommittedSamplers[ShaderTypeInd] = std::max(m_NumCommittedSamplers[ShaderTypeInd], static_cast<Uint8>(NumSamplers));
+ // This can only be CS
+ auto SetUAVMethod = SetUAVMethods[ShaderInd];
+ (m_pd3d11DeviceContext->*SetUAVMethod)(MinSlot, MaxSlot - MinSlot + 1, CommittedD3D11UAVs + MinSlot, nullptr);
+ m_CommittedRes.NumUAVs[ShaderInd] = std::max(m_CommittedRes.NumUAVs[ShaderInd], Bindings[ShaderInd][Range]);
+ VERIFY_EXPR(MaxSlot < Bindings[ShaderInd][Range]);
}
-#ifdef DILIGENT_DEVELOPMENT
- if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
+ else
{
- dbgVerifyCommittedSamplers(pShaderD3D11->GetDesc().ShaderType);
+ UNEXPECTED("UAV is not supported in shader that is not pixel or compute");
}
-#endif
}
- }
-
-
-
-#ifdef DILIGENT_DEVELOPMENT
- if (CommitResources && (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_SHADER_RESOURCES) != 0)
- {
- // Use full resource layout to verify that all required resources are committed
- pShaderD3D11->GetD3D11Resources()->dvpVerifyCommittedResources(
- m_CommittedD3D11CBs[ShaderTypeInd],
- m_CommittedD3D11SRVs[ShaderTypeInd],
- m_CommittedD3D11SRVResources[ShaderTypeInd],
- m_CommittedD3D11Samplers[ShaderTypeInd],
- m_CommittedD3D11UAVs[ShaderTypeInd],
- m_CommittedD3D11UAVResources[ShaderTypeInd],
- Cache);
- }
+#ifdef VERIFY_CONTEXT_BINDINGS
+ if ((m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE) != 0 && ShaderInd == CSInd)
+ {
+ DvpVerifyCommittedUAVs(ShaderType);
+ }
#endif
+ }
}
-}
-void DeviceContextD3D11Impl::TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding)
-{
- DEV_CHECK_ERR(pPipelineState != nullptr, "Pipeline state must not be null");
- DEV_CHECK_ERR(pShaderResourceBinding != nullptr, "Shader resource binding must not be null");
- if (m_pActiveRenderPass)
+ if (ClearPixelShaderUAVs)
{
- LOG_ERROR_MESSAGE("State transitions are not allowed inside a render pass.");
- return;
+ // If pixel shader stage is inactive or does not use UAVs, unbind all committed UAVs.
+ // This is important as UnbindPixelShaderUAV<> function may need to rebind
+ // existing UAVs and the UAVs pointed to by CommittedD3D11UAVRes must be alive
+ // (we do not keep strong references to d3d11 UAVs)
+ auto* CommittedD3D11UAVs = m_CommittedRes.D3D11UAVs[PSInd];
+ auto* CommittedD3D11UAVRes = m_CommittedRes.D3D11UAVResources[PSInd];
+ auto& NumCommittedPixelShaderUAVs = m_CommittedRes.NumUAVs[PSInd];
+ for (Uint32 uav = 0; uav < NumCommittedPixelShaderUAVs; ++uav)
+ {
+ CommittedD3D11UAVRes[uav] = nullptr;
+ CommittedD3D11UAVs[uav] = nullptr;
+ }
+ m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(
+ D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr,
+ 0, 0, nullptr, nullptr);
+ NumCommittedPixelShaderUAVs = 0;
}
-
- TransitionAndCommitShaderResources<true, false>(pPipelineState, pShaderResourceBinding, false);
}
-void DeviceContextD3D11Impl::CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)
+#ifdef DILIGENT_DEVELOPMENT
+void DeviceContextD3D11Impl::DvpValidateCommittedShaderResources()
{
- if (!DeviceContextBase::CommitShaderResources(pShaderResourceBinding, StateTransitionMode, 0 /*Dummy*/))
+ if (m_BindInfo.CommittedResourcesValidated)
return;
- if (StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION)
- TransitionAndCommitShaderResources<true, true>(m_pPipelineState, pShaderResourceBinding, false);
- else
- TransitionAndCommitShaderResources<false, true>(m_pPipelineState, pShaderResourceBinding, StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY);
+ // AZ TODO
+ //m_pPipelineState->DvpVerifySRBResources(m_BindInfo.SRBs.data(), m_BindInfo.BoundResOffsets.data(), static_cast<Uint32>(m_BindInfo.SRBs.size()));
+ m_BindInfo.CommittedResourcesValidated = true;
}
+#endif
void DeviceContextD3D11Impl::SetStencilRef(Uint32 StencilRef)
{
@@ -780,7 +578,9 @@ void DeviceContextD3D11Impl::PrepareForDraw(DRAW_FLAGS Flags)
CommitD3D11VertexBuffers(m_pPipelineState);
}
-#ifdef DILIGENT_DEVELOPMENT
+ BindShaderResources();
+
+#ifdef VERIFY_CONTEXT_BINDINGS
if ((Flags & DRAW_FLAG_VERIFY_STATES) != 0)
{
for (UINT Slot = 0; Slot < m_NumVertexStreams; ++Slot)
@@ -798,13 +598,13 @@ void DeviceContextD3D11Impl::PrepareForDraw(DRAW_FLAGS Flags)
if ((m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE) != 0)
{
// Verify bindings after all resources are set
- dbgVerifyCommittedSRVs();
- dbgVerifyCommittedUAVs(SHADER_TYPE_COMPUTE);
- dbgVerifyCommittedSamplers();
- dbgVerifyCommittedCBs();
- dbgVerifyCommittedVertexBuffers();
- dbgVerifyCommittedIndexBuffer();
- dbgVerifyCommittedShaders();
+ const auto ActiveStages = m_pPipelineState->GetActiveShaderStages();
+ DvpVerifyCommittedSRVs(ActiveStages);
+ DvpVerifyCommittedSamplers(ActiveStages);
+ DvpVerifyCommittedCBs(ActiveStages);
+ DvpVerifyCommittedVertexBuffers();
+ DvpVerifyCommittedIndexBuffer();
+ DvpVerifyCommittedShaders();
}
}
#endif
@@ -900,15 +700,17 @@ void DeviceContextD3D11Impl::DispatchCompute(const DispatchComputeAttribs& Attri
if (!DvpVerifyDispatchArguments(Attribs))
return;
-#ifdef DILIGENT_DEVELOPMENT
+ BindShaderResources();
+
+#ifdef VERIFY_CONTEXT_BINDINGS
if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
{
// Verify bindings
- dbgVerifyCommittedSRVs();
- dbgVerifyCommittedUAVs(SHADER_TYPE_COMPUTE);
- dbgVerifyCommittedSamplers();
- dbgVerifyCommittedCBs();
- dbgVerifyCommittedShaders();
+ DvpVerifyCommittedSRVs(SHADER_TYPE_COMPUTE);
+ DvpVerifyCommittedUAVs(SHADER_TYPE_COMPUTE);
+ DvpVerifyCommittedSamplers(SHADER_TYPE_COMPUTE);
+ DvpVerifyCommittedCBs(SHADER_TYPE_COMPUTE);
+ DvpVerifyCommittedShaders();
}
#endif
@@ -920,15 +722,17 @@ void DeviceContextD3D11Impl::DispatchComputeIndirect(const DispatchComputeIndire
if (!DvpVerifyDispatchIndirectArguments(Attribs, pAttribsBuffer))
return;
-#ifdef DILIGENT_DEVELOPMENT
+ BindShaderResources();
+
+#ifdef VERIFY_CONTEXT_BINDINGS
if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
{
// Verify bindings
- dbgVerifyCommittedSRVs();
- dbgVerifyCommittedUAVs(SHADER_TYPE_COMPUTE);
- dbgVerifyCommittedSamplers();
- dbgVerifyCommittedCBs();
- dbgVerifyCommittedShaders();
+ DvpVerifyCommittedSRVs(SHADER_TYPE_COMPUTE);
+ DvpVerifyCommittedUAVs(SHADER_TYPE_COMPUTE);
+ DvpVerifyCommittedSamplers(SHADER_TYPE_COMPUTE);
+ DvpVerifyCommittedCBs(SHADER_TYPE_COMPUTE);
+ DvpVerifyCommittedShaders();
}
#endif
@@ -1320,14 +1124,14 @@ void DeviceContextD3D11Impl::CommitRenderTargets()
pd3d11DSV = static_cast<ID3D11DepthStencilView*>(m_pBoundDepthStencil->GetD3D11View());
}
- auto& NumCommittedPixelShaderUAVs = m_NumCommittedUAVs[PSInd];
+ auto& NumCommittedPixelShaderUAVs = m_CommittedRes.NumUAVs[PSInd];
if (NumCommittedPixelShaderUAVs > 0)
{
m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(NumRenderTargets, NumRenderTargets > 0 ? pd3d11RTs : nullptr, pd3d11DSV,
0, D3D11_KEEP_UNORDERED_ACCESS_VIEWS, nullptr, nullptr);
- auto CommittedD3D11UAVs = m_CommittedD3D11UAVs[PSInd];
- auto CommittedD3D11UAVRes = m_CommittedD3D11UAVResources[PSInd];
+ auto CommittedD3D11UAVs = m_CommittedRes.D3D11UAVs[PSInd];
+ auto CommittedD3D11UAVRes = m_CommittedRes.D3D11UAVResources[PSInd];
for (Uint32 slot = 0; slot < NumRenderTargets; ++slot)
{
CommittedD3D11UAVs[slot] = nullptr;
@@ -1450,7 +1254,7 @@ void DeviceContextD3D11Impl::UnbindTextureFromInput(TextureBaseD3D11* pTexture,
VERIFY(pTexture, "Null texture provided");
if (!pTexture) return;
- UnbindResourceView(m_CommittedD3D11SRVs, m_CommittedD3D11SRVResources, m_NumCommittedSRVs, pd3d11Resource, SetSRVMethods);
+ UnbindResourceView(m_CommittedRes.D3D11SRVs, m_CommittedRes.D3D11SRVResources, m_CommittedRes.NumSRVs, pd3d11Resource, SetSRVMethods);
pTexture->ClearState(RESOURCE_STATE_SHADER_RESOURCE | RESOURCE_STATE_INPUT_ATTACHMENT);
}
@@ -1461,7 +1265,7 @@ void DeviceContextD3D11Impl::UnbindBufferFromInput(BufferD3D11Impl* pBuffer, ID3
if (pBuffer->CheckState(RESOURCE_STATE_SHADER_RESOURCE))
{
- UnbindResourceView(m_CommittedD3D11SRVs, m_CommittedD3D11SRVResources, m_NumCommittedSRVs, pd3d11Buffer, SetSRVMethods);
+ UnbindResourceView(m_CommittedRes.D3D11SRVs, m_CommittedRes.D3D11SRVResources, m_CommittedRes.NumSRVs, pd3d11Buffer, SetSRVMethods);
pBuffer->ClearState(RESOURCE_STATE_SHADER_RESOURCE);
}
@@ -1478,12 +1282,6 @@ void DeviceContextD3D11Impl::UnbindBufferFromInput(BufferD3D11Impl* pBuffer, ID3
m_bCommittedD3D11IBUpToDate = false;
m_pd3d11DeviceContext->IASetIndexBuffer(nullptr, DXGI_FORMAT_R32_UINT, m_CommittedD3D11IndexDataStartOffset);
}
-#ifdef DILIGENT_DEVELOPMENT
- if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
- {
- dbgVerifyCommittedIndexBuffer();
- }
-#endif
pBuffer->ClearState(RESOURCE_STATE_INDEX_BUFFER);
}
@@ -1506,12 +1304,6 @@ void DeviceContextD3D11Impl::UnbindBufferFromInput(BufferD3D11Impl* pBuffer, ID3
m_pd3d11DeviceContext->IASetVertexBuffers(Slot, _countof(ppNullBuffer), ppNullBuffer, Zero, Zero);
}
}
-#ifdef DILIGENT_DEVELOPMENT
- if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
- {
- dbgVerifyCommittedVertexBuffers();
- }
-#endif
pBuffer->ClearState(RESOURCE_STATE_VERTEX_BUFFER);
}
@@ -1519,8 +1311,8 @@ void DeviceContextD3D11Impl::UnbindBufferFromInput(BufferD3D11Impl* pBuffer, ID3
{
for (Int32 ShaderTypeInd = 0; ShaderTypeInd < NumShaderTypes; ++ShaderTypeInd)
{
- auto* CommittedD3D11CBs = m_CommittedD3D11CBs[ShaderTypeInd];
- auto NumSlots = m_NumCommittedCBs[ShaderTypeInd];
+ auto* CommittedD3D11CBs = m_CommittedRes.D3D11CBs[ShaderTypeInd];
+ auto NumSlots = m_CommittedRes.NumCBs[ShaderTypeInd];
for (Uint32 Slot = 0; Slot < NumSlots; ++Slot)
{
if (CommittedD3D11CBs[Slot] == pd3d11Buffer)
@@ -1532,12 +1324,6 @@ void DeviceContextD3D11Impl::UnbindBufferFromInput(BufferD3D11Impl* pBuffer, ID3
}
}
}
-#ifdef DILIGENT_DEVELOPMENT
- if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
- {
- dbgVerifyCommittedCBs();
- }
-#endif
pBuffer->ClearState(RESOURCE_STATE_CONSTANT_BUFFER);
}
}
@@ -1547,7 +1333,7 @@ void DeviceContextD3D11Impl::UnbindResourceFromUAV(IDeviceObject* pResource, ID3
VERIFY(pResource, "Null resource provided");
if (!pResource) return;
- UnbindResourceView(m_CommittedD3D11UAVs, m_CommittedD3D11UAVResources, m_NumCommittedUAVs, pd3d11Resource, SetUAVMethods);
+ UnbindResourceView(m_CommittedRes.D3D11UAVs, m_CommittedRes.D3D11UAVResources, m_CommittedRes.NumUAVs, pd3d11Resource, SetUAVMethods);
}
void DeviceContextD3D11Impl::UnbindTextureFromRenderTarget(TextureBaseD3D11* pTexture)
@@ -1677,7 +1463,7 @@ void DeviceContextD3D11Impl::BeginSubpass()
if (auto* pTexView = FBDesc.ppAttachments[AttachmentRef.AttachmentIndex])
{
auto* pTexD3D11 = ValidatedCast<TextureBaseD3D11>(pTexView->GetTexture());
- UnbindResourceView(m_CommittedD3D11SRVs, m_CommittedD3D11SRVResources, m_NumCommittedSRVs, pTexD3D11->GetD3D11Texture(), SetSRVMethods);
+ UnbindResourceView(m_CommittedRes.D3D11SRVs, m_CommittedRes.D3D11SRVResources, m_CommittedRes.NumSRVs, pTexD3D11->GetD3D11Texture(), SetSRVMethods);
}
}
};
@@ -1854,34 +1640,37 @@ void ReleaseCommittedPSUAVs(ID3D11UnorderedAccessView* CommittedD3D11UAVs[],
void DeviceContextD3D11Impl::ReleaseCommittedShaderResources()
{
+ m_BindInfo = {};
+
for (int ShaderType = 0; ShaderType < NumShaderTypes; ++ShaderType)
{
// clang-format off
- ReleaseCommittedShaderResourcesHelper(m_CommittedD3D11CBs[ShaderType], m_NumCommittedCBs[ShaderType], SetCBMethods[ShaderType], m_pd3d11DeviceContext);
- ReleaseCommittedShaderResourcesHelper(m_CommittedD3D11SRVs[ShaderType], m_NumCommittedSRVs[ShaderType], SetSRVMethods[ShaderType], m_pd3d11DeviceContext);
- ReleaseCommittedShaderResourcesHelper(m_CommittedD3D11Samplers[ShaderType], m_NumCommittedSamplers[ShaderType], SetSamplerMethods[ShaderType], m_pd3d11DeviceContext);
+ ReleaseCommittedShaderResourcesHelper(m_CommittedRes.D3D11CBs[ShaderType], m_CommittedRes.NumCBs[ShaderType], SetCBMethods[ShaderType], m_pd3d11DeviceContext);
+ ReleaseCommittedShaderResourcesHelper(m_CommittedRes.D3D11SRVs[ShaderType], m_CommittedRes.NumSRVs[ShaderType], SetSRVMethods[ShaderType], m_pd3d11DeviceContext);
+ ReleaseCommittedShaderResourcesHelper(m_CommittedRes.D3D11Samplers[ShaderType], m_CommittedRes.NumSamplers[ShaderType], SetSamplerMethods[ShaderType], m_pd3d11DeviceContext);
// clang-format on
if (ShaderType == PSInd)
- ReleaseCommittedPSUAVs(m_CommittedD3D11UAVs[ShaderType], m_NumCommittedUAVs[ShaderType], m_pd3d11DeviceContext);
+ ReleaseCommittedPSUAVs(m_CommittedRes.D3D11UAVs[ShaderType], m_CommittedRes.NumUAVs[ShaderType], m_pd3d11DeviceContext);
else
- ReleaseCommittedShaderResourcesHelper(m_CommittedD3D11UAVs[ShaderType], m_NumCommittedUAVs[ShaderType], SetUAVMethods[ShaderType], m_pd3d11DeviceContext);
+ ReleaseCommittedShaderResourcesHelper(m_CommittedRes.D3D11UAVs[ShaderType], m_CommittedRes.NumUAVs[ShaderType], SetUAVMethods[ShaderType], m_pd3d11DeviceContext);
- memset(m_CommittedD3D11SRVResources[ShaderType], 0, sizeof(m_CommittedD3D11SRVResources[ShaderType][0]) * m_NumCommittedSRVs[ShaderType]);
- memset(m_CommittedD3D11UAVResources[ShaderType], 0, sizeof(m_CommittedD3D11UAVResources[ShaderType][0]) * m_NumCommittedUAVs[ShaderType]);
- m_NumCommittedCBs[ShaderType] = 0;
- m_NumCommittedSRVs[ShaderType] = 0;
- m_NumCommittedSamplers[ShaderType] = 0;
- m_NumCommittedUAVs[ShaderType] = 0;
+ memset(m_CommittedRes.D3D11SRVResources[ShaderType], 0, sizeof(m_CommittedRes.D3D11SRVResources[ShaderType][0]) * m_CommittedRes.NumSRVs[ShaderType]);
+ memset(m_CommittedRes.D3D11UAVResources[ShaderType], 0, sizeof(m_CommittedRes.D3D11UAVResources[ShaderType][0]) * m_CommittedRes.NumUAVs[ShaderType]);
+ m_CommittedRes.NumCBs[ShaderType] = 0;
+ m_CommittedRes.NumSRVs[ShaderType] = 0;
+ m_CommittedRes.NumSamplers[ShaderType] = 0;
+ m_CommittedRes.NumUAVs[ShaderType] = 0;
}
-#ifdef DILIGENT_DEVELOPMENT
+#ifdef VERIFY_CONTEXT_BINDINGS
if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
{
- dbgVerifyCommittedSRVs();
- dbgVerifyCommittedUAVs(SHADER_TYPE_COMPUTE);
- dbgVerifyCommittedSamplers();
- dbgVerifyCommittedCBs();
+ constexpr auto AllStages = SHADER_TYPE_ALL_GRAPHICS | SHADER_TYPE_COMPUTE;
+ DvpVerifyCommittedSRVs(AllStages);
+ DvpVerifyCommittedUAVs(SHADER_TYPE_COMPUTE);
+ DvpVerifyCommittedSamplers(AllStages);
+ DvpVerifyCommittedCBs(AllStages);
}
#endif
// We do not unbind vertex buffers and index buffer as this can explicitly
@@ -1910,17 +1699,18 @@ void DeviceContextD3D11Impl::FinishCommandList(ICommandList** ppCommandList)
// Device context is now in default state
InvalidateState();
-#ifdef DILIGENT_DEVELOPMENT
+#ifdef VERIFY_CONTEXT_BINDINGS
if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
{
// Verify bindings
- dbgVerifyCommittedSRVs();
- dbgVerifyCommittedUAVs(SHADER_TYPE_COMPUTE);
- dbgVerifyCommittedSamplers();
- dbgVerifyCommittedCBs();
- dbgVerifyCommittedVertexBuffers();
- dbgVerifyCommittedIndexBuffer();
- dbgVerifyCommittedShaders();
+ constexpr auto AllStages = SHADER_TYPE_ALL_GRAPHICS | SHADER_TYPE_COMPUTE;
+ DvpVerifyCommittedSRVs(AllStages);
+ DvpVerifyCommittedUAVs(SHADER_TYPE_COMPUTE);
+ DvpVerifyCommittedSamplers(AllStages);
+ DvpVerifyCommittedCBs(AllStages);
+ DvpVerifyCommittedVertexBuffers();
+ DvpVerifyCommittedIndexBuffer();
+ DvpVerifyCommittedShaders();
}
#endif
}
@@ -1955,17 +1745,18 @@ void DeviceContextD3D11Impl::ExecuteCommandLists(Uint32 NumCommand
// Device context is now in default state
InvalidateState();
-#ifdef DILIGENT_DEVELOPMENT
+#ifdef VERIFY_CONTEXT_BINDINGS
if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
{
// Verify bindings
- dbgVerifyCommittedSRVs();
- dbgVerifyCommittedUAVs(SHADER_TYPE_COMPUTE);
- dbgVerifyCommittedSamplers();
- dbgVerifyCommittedCBs();
- dbgVerifyCommittedVertexBuffers();
- dbgVerifyCommittedIndexBuffer();
- dbgVerifyCommittedShaders();
+ constexpr auto AllStages = SHADER_TYPE_ALL_GRAPHICS | SHADER_TYPE_COMPUTE;
+ DvpVerifyCommittedSRVs(AllStages);
+ DvpVerifyCommittedUAVs(SHADER_TYPE_COMPUTE);
+ DvpVerifyCommittedSamplers(AllStages);
+ DvpVerifyCommittedCBs(AllStages);
+ DvpVerifyCommittedVertexBuffers();
+ DvpVerifyCommittedIndexBuffer();
+ DvpVerifyCommittedShaders();
}
#endif
}
@@ -2068,22 +1859,10 @@ void DeviceContextD3D11Impl::ClearStateCache()
{
TDeviceContextBase::ClearStateCache();
+ m_CommittedRes.Clear();
+
for (int ShaderType = 0; ShaderType < NumShaderTypes; ++ShaderType)
{
- // clang-format off
- memset(m_CommittedD3D11CBs[ShaderType], 0, sizeof(m_CommittedD3D11CBs[ShaderType][0]) * m_NumCommittedCBs[ShaderType]);
- memset(m_CommittedD3D11SRVs[ShaderType], 0, sizeof(m_CommittedD3D11SRVs[ShaderType][0]) * m_NumCommittedSRVs[ShaderType]);
- memset(m_CommittedD3D11Samplers[ShaderType], 0, sizeof(m_CommittedD3D11Samplers[ShaderType][0]) * m_NumCommittedSamplers[ShaderType]);
- memset(m_CommittedD3D11UAVs[ShaderType], 0, sizeof(m_CommittedD3D11UAVs[ShaderType][0]) * m_NumCommittedUAVs[ShaderType]);
- memset(m_CommittedD3D11SRVResources[ShaderType], 0, sizeof(m_CommittedD3D11SRVResources[ShaderType][0]) * m_NumCommittedSRVs[ShaderType]);
- memset(m_CommittedD3D11UAVResources[ShaderType], 0, sizeof(m_CommittedD3D11UAVResources[ShaderType][0]) * m_NumCommittedUAVs[ShaderType]);
- // clang-format on
-
- m_NumCommittedCBs[ShaderType] = 0;
- m_NumCommittedSRVs[ShaderType] = 0;
- m_NumCommittedSamplers[ShaderType] = 0;
- m_NumCommittedUAVs[ShaderType] = 0;
-
m_CommittedD3DShaders[ShaderType].Release();
}
@@ -2179,101 +1958,109 @@ void DeviceContextD3D11Impl::TransitionResourceStates(Uint32 BarrierCount, State
if (RefCntAutoPtr<TextureBaseD3D11> pTexture{Barrier.pResource, IID_TextureD3D11})
{
- auto OldState = Barrier.OldState;
- if (OldState == RESOURCE_STATE_UNKNOWN)
- {
- if (pTexture->IsInKnownState())
- {
- OldState = pTexture->GetState();
- }
- else
- {
- LOG_ERROR_MESSAGE("Failed to transition the state of texture '", pTexture->GetDesc().Name, "' because the buffer state is unknown and is not explicitly specified");
- continue;
- }
- }
- else
- {
- if (pTexture->IsInKnownState() && pTexture->GetState() != OldState)
- {
- LOG_ERROR_MESSAGE("The state ", GetResourceStateString(pTexture->GetState()), " of texture '",
- pTexture->GetDesc().Name, "' does not match the old state ", GetResourceStateString(OldState),
- " specified by the barrier");
- }
- }
+ TransitionResource(pTexture, Barrier.NewState, Barrier.OldState);
+ }
+ else if (RefCntAutoPtr<BufferD3D11Impl> pBuffer{Barrier.pResource, IID_BufferD3D11})
+ {
+ TransitionResource(pBuffer, Barrier.NewState, Barrier.OldState);
+ }
+ else
+ {
+ UNEXPECTED("The type of resource '", Barrier.pResource->GetDesc().Name, "' is not support in D3D11");
+ }
+ }
+}
- if ((Barrier.NewState & RESOURCE_STATE_UNORDERED_ACCESS) != 0)
- {
- DEV_CHECK_ERR((Barrier.NewState & (RESOURCE_STATE_GENERIC_READ | RESOURCE_STATE_INPUT_ATTACHMENT)) == 0, "Unordered access state is not compatible with any input state");
- UnbindTextureFromInput(pTexture, pTexture->GetD3D11Texture());
- }
+void DeviceContextD3D11Impl::TransitionResource(TextureBaseD3D11* pTexture, RESOURCE_STATE NewState, RESOURCE_STATE OldState, bool UpdateResourceState)
+{
+ if (OldState == RESOURCE_STATE_UNKNOWN)
+ {
+ if (pTexture->IsInKnownState())
+ {
+ OldState = pTexture->GetState();
+ }
+ else
+ {
+ LOG_ERROR_MESSAGE("Failed to transition the state of texture '", pTexture->GetDesc().Name, "' because the buffer state is unknown and is not explicitly specified");
+ return;
+ }
+ }
+ else
+ {
+ if (pTexture->IsInKnownState() && pTexture->GetState() != OldState)
+ {
+ LOG_ERROR_MESSAGE("The state ", GetResourceStateString(pTexture->GetState()), " of texture '",
+ pTexture->GetDesc().Name, "' does not match the old state ", GetResourceStateString(OldState),
+ " specified by the barrier");
+ }
+ }
- if ((Barrier.NewState & (RESOURCE_STATE_GENERIC_READ | RESOURCE_STATE_INPUT_ATTACHMENT)) != 0)
- {
- if ((OldState & RESOURCE_STATE_RENDER_TARGET) != 0)
- UnbindTextureFromRenderTarget(pTexture);
+ if ((NewState & RESOURCE_STATE_UNORDERED_ACCESS) != 0)
+ {
+ DEV_CHECK_ERR((NewState & (RESOURCE_STATE_GENERIC_READ | RESOURCE_STATE_INPUT_ATTACHMENT)) == 0, "Unordered access state is not compatible with any input state");
+ UnbindTextureFromInput(pTexture, pTexture->GetD3D11Texture());
+ }
- if ((OldState & RESOURCE_STATE_DEPTH_WRITE) != 0)
- UnbindTextureFromDepthStencil(pTexture);
+ if ((NewState & (RESOURCE_STATE_GENERIC_READ | RESOURCE_STATE_INPUT_ATTACHMENT)) != 0)
+ {
+ if ((OldState & RESOURCE_STATE_RENDER_TARGET) != 0)
+ UnbindTextureFromRenderTarget(pTexture);
- if ((OldState & RESOURCE_STATE_UNORDERED_ACCESS) != 0)
- {
- UnbindResourceFromUAV(pTexture, pTexture->GetD3D11Texture());
- pTexture->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
- }
- }
+ if ((OldState & RESOURCE_STATE_DEPTH_WRITE) != 0)
+ UnbindTextureFromDepthStencil(pTexture);
- if (Barrier.UpdateResourceState)
- {
- pTexture->SetState(Barrier.NewState);
- }
- }
- else if (RefCntAutoPtr<BufferD3D11Impl> pBuffer{Barrier.pResource, IID_BufferD3D11})
+ if ((OldState & RESOURCE_STATE_UNORDERED_ACCESS) != 0)
{
- auto OldState = Barrier.OldState;
- if (OldState == RESOURCE_STATE_UNKNOWN)
- {
- if (pBuffer->IsInKnownState())
- {
- OldState = pBuffer->GetState();
- }
- else
- {
- LOG_ERROR_MESSAGE("Failed to transition the state of buffer '", pBuffer->GetDesc().Name, "' because the buffer state is unknown and is not explicitly specified");
- continue;
- }
- }
- else
- {
- if (pBuffer->IsInKnownState() && pBuffer->GetState() != OldState)
- {
- LOG_ERROR_MESSAGE("The state ", GetResourceStateString(pBuffer->GetState()), " of buffer '",
- pBuffer->GetDesc().Name, "' does not match the old state ", GetResourceStateString(OldState),
- " specified by the barrier");
- }
- }
-
- if ((Barrier.NewState & RESOURCE_STATE_UNORDERED_ACCESS) != 0)
- {
- DEV_CHECK_ERR((Barrier.NewState & RESOURCE_STATE_GENERIC_READ) == 0, "Unordered access state is not compatible with any input state");
- UnbindBufferFromInput(pBuffer, pBuffer->m_pd3d11Buffer);
- }
+ UnbindResourceFromUAV(pTexture, pTexture->GetD3D11Texture());
+ pTexture->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
+ }
+ }
- if ((Barrier.NewState & RESOURCE_STATE_GENERIC_READ) != 0)
- {
- UnbindResourceFromUAV(pBuffer, pBuffer->m_pd3d11Buffer);
- }
+ if (UpdateResourceState)
+ {
+ pTexture->SetState(NewState);
+ }
+}
- if (Barrier.UpdateResourceState)
- {
- pBuffer->SetState(Barrier.NewState);
- }
+void DeviceContextD3D11Impl::TransitionResource(BufferD3D11Impl* pBuffer, RESOURCE_STATE NewState, RESOURCE_STATE OldState, bool UpdateResourceState)
+{
+ if (OldState == RESOURCE_STATE_UNKNOWN)
+ {
+ if (pBuffer->IsInKnownState())
+ {
+ OldState = pBuffer->GetState();
}
else
{
- UNEXPECTED("The type of resource '", Barrier.pResource->GetDesc().Name, "' is not support in D3D11");
+ LOG_ERROR_MESSAGE("Failed to transition the state of buffer '", pBuffer->GetDesc().Name, "' because the buffer state is unknown and is not explicitly specified");
+ return;
}
}
+ else
+ {
+ if (pBuffer->IsInKnownState() && pBuffer->GetState() != OldState)
+ {
+ LOG_ERROR_MESSAGE("The state ", GetResourceStateString(pBuffer->GetState()), " of buffer '",
+ pBuffer->GetDesc().Name, "' does not match the old state ", GetResourceStateString(OldState),
+ " specified by the barrier");
+ }
+ }
+
+ if ((NewState & RESOURCE_STATE_UNORDERED_ACCESS) != 0)
+ {
+ DEV_CHECK_ERR((NewState & RESOURCE_STATE_GENERIC_READ) == 0, "Unordered access state is not compatible with any input state");
+ UnbindBufferFromInput(pBuffer, pBuffer->m_pd3d11Buffer);
+ }
+
+ if ((NewState & RESOURCE_STATE_GENERIC_READ) != 0)
+ {
+ UnbindResourceFromUAV(pBuffer, pBuffer->m_pd3d11Buffer);
+ }
+
+ if (UpdateResourceState)
+ {
+ pBuffer->SetState(NewState);
+ }
}
void DeviceContextD3D11Impl::ResolveTextureSubresource(ITexture* pSrcTexture,
@@ -2377,29 +2164,25 @@ void DeviceContextD3D11Impl::TraceRays(const TraceRaysAttribs& Attribs)
template <UINT MaxResources,
typename TD3D11ResourceType,
typename TGetD3D11ResourcesType>
-void DeviceContextD3D11Impl::dbgVerifyCommittedResources(TD3D11ResourceType CommittedD3D11ResourcesArr[][MaxResources],
+void DeviceContextD3D11Impl::DvpVerifyCommittedResources(TD3D11ResourceType CommittedD3D11ResourcesArr[][MaxResources],
Uint8 NumCommittedResourcesArr[],
TGetD3D11ResourcesType GetD3D11ResMethods[],
const Char* ResourceName,
- SHADER_TYPE ShaderType)
+ SHADER_TYPE ShaderStages)
{
- int iStartInd = 0, iEndInd = NumShaderTypes;
- if (ShaderType != SHADER_TYPE_UNKNOWN)
- {
- iStartInd = GetShaderTypeIndex(ShaderType);
- iEndInd = iStartInd + 1;
- }
- for (int iShaderTypeInd = iStartInd; iShaderTypeInd < iEndInd; ++iShaderTypeInd)
+ while (ShaderStages != 0)
{
- const auto ShaderName = GetShaderTypeLiteralName(GetShaderTypeFromIndex(iShaderTypeInd));
+ const auto Stage = ExtractLSB(ShaderStages);
+ const auto ShaderInd = GetShaderTypeIndex(Stage);
+ const auto ShaderName = GetShaderTypeLiteralName(GetShaderTypeFromIndex(ShaderInd));
TD3D11ResourceType pctxResources[MaxResources] = {};
- auto GetResMethod = GetD3D11ResMethods[iShaderTypeInd];
+ auto GetResMethod = GetD3D11ResMethods[ShaderInd];
if (GetResMethod)
{
(m_pd3d11DeviceContext->*GetResMethod)(0, _countof(pctxResources), pctxResources);
}
- const auto* CommittedResources = CommittedD3D11ResourcesArr[iShaderTypeInd];
- auto NumCommittedResources = NumCommittedResourcesArr[iShaderTypeInd];
+ const auto* CommittedResources = CommittedD3D11ResourcesArr[ShaderInd];
+ auto NumCommittedResources = NumCommittedResourcesArr[ShaderInd];
for (Uint32 Slot = 0; Slot < _countof(pctxResources); ++Slot)
{
if (Slot < NumCommittedResources)
@@ -2419,24 +2202,20 @@ void DeviceContextD3D11Impl::dbgVerifyCommittedResources(TD3D11ResourceType
}
template <UINT MaxResources, typename TD3D11ViewType>
-void DeviceContextD3D11Impl::dbgVerifyViewConsistency(TD3D11ViewType CommittedD3D11ViewArr[][MaxResources],
+void DeviceContextD3D11Impl::DvpVerifyViewConsistency(TD3D11ViewType CommittedD3D11ViewArr[][MaxResources],
ID3D11Resource* CommittedD3D11ResourcesArr[][MaxResources],
Uint8 NumCommittedResourcesArr[],
const Char* ResourceName,
- SHADER_TYPE ShaderType)
+ SHADER_TYPE ShaderStages)
{
- int iStartInd = 0, iEndInd = NumShaderTypes;
- if (ShaderType != SHADER_TYPE_UNKNOWN)
- {
- iStartInd = GetShaderTypeIndex(ShaderType);
- iEndInd = iStartInd + 1;
- }
- for (int iShaderTypeInd = iStartInd; iShaderTypeInd < iEndInd; ++iShaderTypeInd)
+ while (ShaderStages != 0)
{
- const auto ShaderName = GetShaderTypeLiteralName(GetShaderTypeFromIndex(iShaderTypeInd));
- auto* Views = CommittedD3D11ViewArr[iShaderTypeInd];
- auto* Resources = CommittedD3D11ResourcesArr[iShaderTypeInd];
- auto NumCommittedResources = NumCommittedResourcesArr[iShaderTypeInd];
+ const auto Stage = ExtractLSB(ShaderStages);
+ const auto ShaderInd = GetShaderTypeIndex(Stage);
+ const auto ShaderName = GetShaderTypeLiteralName(GetShaderTypeFromIndex(ShaderInd));
+ auto* Views = CommittedD3D11ViewArr[ShaderInd];
+ auto* Resources = CommittedD3D11ResourcesArr[ShaderInd];
+ auto NumCommittedResources = NumCommittedResourcesArr[ShaderInd];
for (Uint32 Slot = 0; Slot < NumCommittedResources; ++Slot)
{
if (Views[Slot] != nullptr)
@@ -2449,29 +2228,29 @@ void DeviceContextD3D11Impl::dbgVerifyViewConsistency(TD3D11ViewType CommittedD
}
}
-void DeviceContextD3D11Impl::dbgVerifyCommittedSRVs(SHADER_TYPE ShaderType)
+void DeviceContextD3D11Impl::DvpVerifyCommittedSRVs(SHADER_TYPE ShaderStages)
{
- dbgVerifyCommittedResources<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT>(m_CommittedD3D11SRVs, m_NumCommittedSRVs, GetSRVMethods, "SRV", ShaderType);
- dbgVerifyViewConsistency<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT>(m_CommittedD3D11SRVs, m_CommittedD3D11SRVResources, m_NumCommittedSRVs, "SRV", ShaderType);
+ DvpVerifyCommittedResources<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT>(m_CommittedRes.D3D11SRVs, m_CommittedRes.NumSRVs, GetSRVMethods, "SRV", ShaderStages);
+ DvpVerifyViewConsistency<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT>(m_CommittedRes.D3D11SRVs, m_CommittedRes.D3D11SRVResources, m_CommittedRes.NumSRVs, "SRV", ShaderStages);
}
-void DeviceContextD3D11Impl::dbgVerifyCommittedUAVs(SHADER_TYPE ShaderType)
+void DeviceContextD3D11Impl::DvpVerifyCommittedUAVs(SHADER_TYPE ShaderStages)
{
- dbgVerifyCommittedResources<D3D11_PS_CS_UAV_REGISTER_COUNT>(m_CommittedD3D11UAVs, m_NumCommittedUAVs, GetUAVMethods, "UAV", ShaderType);
- dbgVerifyViewConsistency<D3D11_PS_CS_UAV_REGISTER_COUNT>(m_CommittedD3D11UAVs, m_CommittedD3D11UAVResources, m_NumCommittedUAVs, "UAV", ShaderType);
+ DvpVerifyCommittedResources<D3D11_PS_CS_UAV_REGISTER_COUNT>(m_CommittedRes.D3D11UAVs, m_CommittedRes.NumUAVs, GetUAVMethods, "UAV", ShaderStages);
+ DvpVerifyViewConsistency<D3D11_PS_CS_UAV_REGISTER_COUNT>(m_CommittedRes.D3D11UAVs, m_CommittedRes.D3D11UAVResources, m_CommittedRes.NumUAVs, "UAV", ShaderStages);
}
-void DeviceContextD3D11Impl::dbgVerifyCommittedSamplers(SHADER_TYPE ShaderType)
+void DeviceContextD3D11Impl::DvpVerifyCommittedSamplers(SHADER_TYPE ShaderStages)
{
- dbgVerifyCommittedResources<D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>(m_CommittedD3D11Samplers, m_NumCommittedSamplers, GetSamplerMethods, "Sampler", ShaderType);
+ DvpVerifyCommittedResources<D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>(m_CommittedRes.D3D11Samplers, m_CommittedRes.NumSamplers, GetSamplerMethods, "Sampler", ShaderStages);
}
-void DeviceContextD3D11Impl::dbgVerifyCommittedCBs(SHADER_TYPE ShaderType)
+void DeviceContextD3D11Impl::DvpVerifyCommittedCBs(SHADER_TYPE ShaderStages)
{
- dbgVerifyCommittedResources<D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT>(m_CommittedD3D11CBs, m_NumCommittedCBs, GetCBMethods, "Constant buffer", ShaderType);
+ DvpVerifyCommittedResources<D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT>(m_CommittedRes.D3D11CBs, m_CommittedRes.NumCBs, GetCBMethods, "Constant buffer", ShaderStages);
}
-void DeviceContextD3D11Impl::dbgVerifyCommittedIndexBuffer()
+void DeviceContextD3D11Impl::DvpVerifyCommittedIndexBuffer()
{
RefCntAutoPtr<ID3D11Buffer> pctxIndexBuffer;
DXGI_FORMAT Fmt = DXGI_FORMAT_UNKNOWN;
@@ -2497,7 +2276,7 @@ void DeviceContextD3D11Impl::dbgVerifyCommittedIndexBuffer()
}
}
-void DeviceContextD3D11Impl::dbgVerifyCommittedVertexBuffers()
+void DeviceContextD3D11Impl::DvpVerifyCommittedVertexBuffers()
{
CComPtr<ID3D11InputLayout> pInputLayout;
m_pd3d11DeviceContext->IAGetInputLayout(&pInputLayout);
@@ -2538,7 +2317,7 @@ void DeviceContextD3D11Impl::dbgVerifyCommittedVertexBuffers()
}
template <typename TD3D11ShaderType, typename TGetShaderMethodType>
-void dbgVerifyCommittedShadersHelper(SHADER_TYPE ShaderType,
+void DvpVerifyCommittedShadersHelper(SHADER_TYPE ShaderType,
const CComPtr<ID3D11DeviceChild> BoundD3DShaders[],
ID3D11DeviceContext* pCtx,
TGetShaderMethodType GetShaderMethod)
@@ -2548,9 +2327,9 @@ void dbgVerifyCommittedShadersHelper(SHADER_TYPE ShaderType
const auto& BoundShader = BoundD3DShaders[GetShaderTypeIndex(ShaderType)];
VERIFY(BoundShader == pctxShader, GetShaderTypeLiteralName(ShaderType), " binding mismatch detected");
}
-void DeviceContextD3D11Impl::dbgVerifyCommittedShaders()
+void DeviceContextD3D11Impl::DvpVerifyCommittedShaders()
{
-# define VERIFY_SHADER(NAME, Name, N) dbgVerifyCommittedShadersHelper<ID3D11##Name##Shader>(SHADER_TYPE_##NAME, m_CommittedD3DShaders, m_pd3d11DeviceContext, &ID3D11DeviceContext::N##SGetShader)
+# define VERIFY_SHADER(NAME, Name, N) DvpVerifyCommittedShadersHelper<ID3D11##Name##Shader>(SHADER_TYPE_##NAME, m_CommittedD3DShaders, m_pd3d11DeviceContext, &ID3D11DeviceContext::N##SGetShader)
// These shaders which are not set will be unbound from the D3D11 device context
VERIFY_SHADER(VERTEX, Vertex, V);
VERIFY_SHADER(PIXEL, Pixel, P);
diff --git a/Graphics/GraphicsEngineD3D11/src/PipelineResourceSignatureD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/PipelineResourceSignatureD3D11Impl.cpp
new file mode 100644
index 00000000..aab59266
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D11/src/PipelineResourceSignatureD3D11Impl.cpp
@@ -0,0 +1,489 @@
+/*
+ * Copyright 2019-2021 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 "PipelineResourceSignatureD3D11Impl.hpp"
+#include "RenderDeviceD3D11Impl.hpp"
+
+namespace Diligent
+{
+
+DESCRIPTOR_RANGE ShaderResourceToDescriptorRange(SHADER_RESOURCE_TYPE Type)
+{
+ static_assert(SHADER_RESOURCE_TYPE_LAST == 8, "Please update the switch below to handle the new shader resource type");
+ switch (Type)
+ {
+ // clang-format off
+ case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER: return DESCRIPTOR_RANGE_CBV;
+ case SHADER_RESOURCE_TYPE_TEXTURE_SRV: return DESCRIPTOR_RANGE_SRV;
+ case SHADER_RESOURCE_TYPE_BUFFER_SRV: return DESCRIPTOR_RANGE_SRV;
+ case SHADER_RESOURCE_TYPE_TEXTURE_UAV: return DESCRIPTOR_RANGE_UAV;
+ case SHADER_RESOURCE_TYPE_BUFFER_UAV: return DESCRIPTOR_RANGE_UAV;
+ case SHADER_RESOURCE_TYPE_SAMPLER: return DESCRIPTOR_RANGE_SAMPLER;
+ case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT: return DESCRIPTOR_RANGE_SRV;
+ // clang-format on
+ default:
+ UNEXPECTED("Unsupported resource type");
+ return DESCRIPTOR_RANGE_UNKNOWN;
+ }
+}
+
+
+PipelineResourceSignatureD3D11Impl::PipelineResourceSignatureD3D11Impl(IReferenceCounters* pRefCounters,
+ RenderDeviceD3D11Impl* pDeviceD3D11,
+ const PipelineResourceSignatureDesc& Desc,
+ bool bIsDeviceInternal) :
+ TPipelineResourceSignatureBase{pRefCounters, pDeviceD3D11, Desc, bIsDeviceInternal}
+{
+ try
+ {
+ auto& RawAllocator{GetRawAllocator()};
+ auto MemPool = AllocateInternalObjects(RawAllocator, Desc,
+ [&Desc](FixedLinearAllocator& MemPool) //
+ {
+ MemPool.AddSpace<ResourceAttribs>(Desc.NumResources);
+ MemPool.AddSpace<ImmutableSamplerAttribs>(Desc.NumImmutableSamplers);
+ });
+
+ static_assert(std::is_trivially_destructible<ResourceAttribs>::value,
+ "ResourceAttribs objects must be constructed to be properly destructed in case an excpetion is thrown");
+ m_pResourceAttribs = MemPool.Allocate<ResourceAttribs>(m_Desc.NumResources);
+ m_ImmutableSamplers = MemPool.ConstructArray<ImmutableSamplerAttribs>(m_Desc.NumImmutableSamplers);
+
+ CreateLayout();
+
+ const auto NumStaticResStages = GetNumStaticResStages();
+ if (NumStaticResStages > 0)
+ {
+ constexpr SHADER_RESOURCE_VARIABLE_TYPE AllowedVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC};
+ for (Uint32 i = 0; i < m_StaticResStageIndex.size(); ++i)
+ {
+ Int8 Idx = m_StaticResStageIndex[i];
+ if (Idx >= 0)
+ {
+ VERIFY_EXPR(static_cast<Uint32>(Idx) < NumStaticResStages);
+ const auto ShaderType = GetShaderTypeFromPipelineIndex(i, GetPipelineType());
+ m_StaticVarsMgrs[Idx].Initialize(*this, GetRawAllocator(), AllowedVarTypes, _countof(AllowedVarTypes), ShaderType);
+ }
+ }
+ }
+
+ if (m_Desc.SRBAllocationGranularity > 1)
+ {
+ std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderVariableDataSizes = {};
+ for (Uint32 s = 0; s < GetNumActiveShaderStages(); ++s)
+ {
+ constexpr SHADER_RESOURCE_VARIABLE_TYPE AllowedVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC};
+
+ ShaderVariableDataSizes[s] = ShaderVariableManagerD3D11::GetRequiredMemorySize(*this, AllowedVarTypes, _countof(AllowedVarTypes), GetActiveShaderStageType(s));
+ }
+
+ const size_t CacheMemorySize = ShaderResourceCacheD3D11::GetRequriedMemorySize(m_ResourceCount);
+ m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumActiveShaderStages(), ShaderVariableDataSizes.data(), 1, &CacheMemorySize);
+ }
+
+ CalculateHash();
+ }
+ catch (...)
+ {
+ Destruct();
+ throw;
+ }
+}
+
+void PipelineResourceSignatureD3D11Impl::CreateLayout()
+{
+ using TBindings32 = std::array<Uint32, DESCRIPTOR_RANGE_COUNT>;
+ using TBindingsPerStage32 = std::array<TBindings32, NumShaderTypes>;
+
+ if (m_pStaticResCache)
+ {
+ TBindings32 StaticCounter32 = {};
+ const auto ResIdxRange = GetResourceIndexRange(SHADER_RESOURCE_VARIABLE_TYPE_STATIC);
+ for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r)
+ {
+ const auto& ResDesc = m_Desc.Resources[r];
+ const auto Range = ShaderResourceToDescriptorRange(ResDesc.ResourceType);
+ StaticCounter32[Range] += ResDesc.ArraySize;
+ }
+
+ TBindings StaticCounter8 = {};
+ for (Uint32 i = 0; i < StaticCounter8.size(); ++i)
+ {
+ VERIFY_EXPR(StaticCounter8[i] < std::numeric_limits<Uint8>::max());
+ StaticCounter8[i] = static_cast<Uint8>(StaticCounter32[i]);
+ }
+
+ m_pStaticResCache->Initialize(StaticCounter8, GetRawAllocator());
+ }
+
+ // Index of the assigned sampler, for every texture SRV in m_Desc.Resources, or InvalidSamplerInd.
+ std::vector<Uint32> TextureSrvToAssignedSamplerInd(m_Desc.NumResources, ResourceAttribs::InvalidSamplerInd);
+ // Index of the immutable sampler for every sampler or texture in m_Desc.Resources, or InvalidImmutableSamplerIndex.
+ std::vector<Uint32> ResourceToImmutableSamplerInd(m_Desc.NumResources, InvalidImmutableSamplerIndex);
+ for (Uint32 i = 0; i < m_Desc.NumResources; ++i)
+ {
+ const auto& ResDesc = m_Desc.Resources[i];
+
+ if (ResDesc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER ||
+ ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV)
+ {
+ const char* SamplerSuffix = ResDesc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER ? GetCombinedSamplerSuffix() : nullptr;
+ const auto SrcImmutableSamplerInd = Diligent::FindImmutableSampler(m_Desc.ImmutableSamplers, m_Desc.NumImmutableSamplers, ResDesc.ShaderStages, ResDesc.Name, SamplerSuffix);
+ if (SrcImmutableSamplerInd != InvalidImmutableSamplerIndex)
+ {
+ ResourceToImmutableSamplerInd[i] = SrcImmutableSamplerInd;
+ // Set the immutable sampler array size to match the resource array size
+ auto& DstImtblSampAttribs = m_ImmutableSamplers[SrcImmutableSamplerInd];
+ // One immutable sampler may be used by different arrays in different shader stages - use the maximum array size
+ const auto ImtblSampArraySize = std::max(DstImtblSampAttribs.ArraySize, ResDesc.ArraySize);
+ DstImtblSampAttribs.ArraySize = ImtblSampArraySize;
+ VERIFY(DstImtblSampAttribs.ArraySize == ImtblSampArraySize, "Immutable sampler array size exceeds maximum representable value");
+ }
+ }
+
+ if (ResourceToImmutableSamplerInd[i] == InvalidImmutableSamplerIndex &&
+ ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV)
+ {
+ TextureSrvToAssignedSamplerInd[i] = FindAssignedSampler(ResDesc, ResourceAttribs::InvalidSamplerInd);
+ }
+ }
+
+ TBindings32 ResourceCount = {};
+ TBindingsPerStage32 BindingPerStage = {};
+ const auto AllocBindPoints = [&BindingPerStage](TBindPoints& BindPoints, SHADER_TYPE ShaderStages, Uint32 ArraySize, DESCRIPTOR_RANGE Range) //
+ {
+ while (ShaderStages != 0)
+ {
+ auto Stage = ExtractLSB(ShaderStages);
+ Uint32 ShaderInd = GetShaderTypeIndex(Stage);
+
+ BindPoints[ShaderInd] = static_cast<Uint8>(BindingPerStage[ShaderInd][Range]);
+ VERIFY_EXPR(BindPoints[ShaderInd] == BindingPerStage[ShaderInd][Range]);
+ BindingPerStage[ShaderInd][Range] += ArraySize;
+ }
+ };
+
+ for (Uint32 i = 0; i < m_Desc.NumResources; ++i)
+ {
+ const auto& ResDesc = m_Desc.Resources[i];
+ const auto Range = ShaderResourceToDescriptorRange(ResDesc.ResourceType);
+ VERIFY(i == 0 || ResDesc.VarType >= m_Desc.Resources[i - 1].VarType, "Resources must be sorted by variable type");
+
+ auto AssignedSamplerInd = TextureSrvToAssignedSamplerInd[i];
+ auto SrcImmutableSamplerInd = ResourceToImmutableSamplerInd[i];
+ if (AssignedSamplerInd != ResourceAttribs::InvalidSamplerInd)
+ {
+ VERIFY_EXPR(ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV);
+ SrcImmutableSamplerInd = ResourceToImmutableSamplerInd[AssignedSamplerInd];
+ }
+
+ constexpr SHADER_TYPE UAVStages = SHADER_TYPE_PIXEL | SHADER_TYPE_COMPUTE;
+ if (Range == DESCRIPTOR_RANGE_UAV && (ResDesc.ShaderStages & ~UAVStages) != 0)
+ {
+ LOG_ERROR_AND_THROW("Description of a pipeline resource signature '", m_Desc.Name, "' is invalid: ",
+ "Desc.Resources[", i, "].ResourceType (", GetShaderResourceTypeLiteralName(ResDesc.ResourceType),
+ ") - UAV resource is not supported in shader stages ", GetShaderStagesString(ResDesc.ShaderStages & ~UAVStages));
+ }
+
+ // Allocate space for immutable sampler which is assigned to sampler or texture resource.
+ if (SrcImmutableSamplerInd != InvalidImmutableSamplerIndex)
+ {
+ const auto& ImtblSamp = GetImmutableSamplerDesc(SrcImmutableSamplerInd);
+ auto& ImtblSampAttribs = m_ImmutableSamplers[SrcImmutableSamplerInd];
+ VERIFY_EXPR(ResDesc.ArraySize <= ImtblSampAttribs.ArraySize);
+
+ if (!ImtblSampAttribs.IsAllocated())
+ {
+ ImtblSampAttribs.CacheOffset = ResourceCount[DESCRIPTOR_RANGE_SAMPLER];
+ AllocBindPoints(ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, DESCRIPTOR_RANGE_SAMPLER);
+ ResourceCount[DESCRIPTOR_RANGE_SAMPLER] += ImtblSampAttribs.ArraySize;
+ }
+ }
+
+ if (!(ResDesc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER && SrcImmutableSamplerInd != InvalidImmutableSamplerIndex))
+ {
+ auto* pAttrib = new (m_pResourceAttribs + i) ResourceAttribs //
+ {
+ ResourceCount[Range],
+ AssignedSamplerInd,
+ SrcImmutableSamplerInd != InvalidImmutableSamplerIndex //
+ };
+ AllocBindPoints(pAttrib->BindPoints, ResDesc.ShaderStages, ResDesc.ArraySize, Range);
+ ResourceCount[Range] += ResDesc.ArraySize;
+ }
+ else
+ {
+ VERIFY_EXPR(AssignedSamplerInd == ResourceAttribs::InvalidSamplerInd);
+
+ auto& ImtblSampAttribs = m_ImmutableSamplers[SrcImmutableSamplerInd];
+ auto* pAttrib = new (m_pResourceAttribs + i) ResourceAttribs //
+ {
+ ImtblSampAttribs.CacheOffset,
+ ResourceAttribs::InvalidSamplerInd,
+ SrcImmutableSamplerInd != InvalidImmutableSamplerIndex //
+ };
+ pAttrib->BindPoints = ImtblSampAttribs.BindPoints;
+ }
+ }
+
+ // Add bindings for immutable samplers that is not assigned to texture or separate sampler.
+ for (Uint32 i = 0; i < m_Desc.NumImmutableSamplers; ++i)
+ {
+ const auto Range = DESCRIPTOR_RANGE_SAMPLER;
+ const auto& ImtblSamp = GetImmutableSamplerDesc(i);
+ auto& ImtblSampAttribs = m_ImmutableSamplers[i];
+
+ if (IsUsingCombinedSamplers() && !ImtblSampAttribs.IsAllocated())
+ continue;
+
+ GetDevice()->CreateSampler(ImtblSamp.Desc, &ImtblSampAttribs.pSampler);
+
+ // Add as separate sampler.
+ if (!ImtblSampAttribs.IsAllocated())
+ {
+ ImtblSampAttribs.ArraySize = 1;
+ ImtblSampAttribs.CacheOffset = ResourceCount[Range];
+ ResourceCount[Range] += ImtblSampAttribs.ArraySize;
+ AllocBindPoints(ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, Range);
+ }
+ }
+
+ for (Uint32 i = 0; i < ResourceCount.size(); ++i)
+ {
+ using T = std::remove_reference<decltype(m_ResourceCount[i])>::type;
+ VERIFY_EXPR(ResourceCount[i] < std::numeric_limits<T>::max());
+ m_ResourceCount[i] = static_cast<T>(ResourceCount[i]);
+ }
+
+ for (Uint32 s = 0; s < BindingPerStage.size(); ++s)
+ {
+ for (Uint32 i = 0; i < BindingPerStage[s].size(); ++i)
+ {
+ using T = std::remove_reference<decltype(m_BindingCountPerStage[s][i])>::type;
+ VERIFY_EXPR(BindingPerStage[s][i] < std::numeric_limits<T>::max());
+ m_BindingCountPerStage[s][i] = static_cast<T>(BindingPerStage[s][i]);
+ }
+ }
+}
+
+PipelineResourceSignatureD3D11Impl::~PipelineResourceSignatureD3D11Impl()
+{
+ Destruct();
+}
+
+void PipelineResourceSignatureD3D11Impl::Destruct()
+{
+ if (m_ImmutableSamplers != nullptr)
+ {
+ for (Uint32 s = 0; s < m_Desc.NumImmutableSamplers; ++s)
+ m_ImmutableSamplers[s].~ImmutableSamplerAttribs();
+
+ m_ImmutableSamplers = nullptr;
+ }
+
+ m_pResourceAttribs = nullptr;
+
+ TPipelineResourceSignatureBase::Destruct();
+}
+
+void PipelineResourceSignatureD3D11Impl::CopyStaticResources(ShaderResourceCacheD3D11& DstResourceCache) const
+{
+ if (m_pStaticResCache == nullptr)
+ return;
+
+ // SrcResourceCache contains only static resources.
+ // DstResourceCache contains static, mutable and dynamic resources.
+ const auto& SrcResourceCache = *m_pStaticResCache;
+ const auto ResIdxRange = GetResourceIndexRange(SHADER_RESOURCE_VARIABLE_TYPE_STATIC);
+
+ VERIFY_EXPR(SrcResourceCache.GetContentType() == ResourceCacheContentType::Signature);
+ VERIFY_EXPR(DstResourceCache.GetContentType() == ResourceCacheContentType::SRB);
+
+ for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r)
+ {
+ const auto& ResDesc = GetResourceDesc(r);
+ const auto& ResAttr = GetResourceAttribs(r);
+ VERIFY_EXPR(ResDesc.VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC);
+
+ static_assert(DESCRIPTOR_RANGE_COUNT == 4, "Please update the switch below to handle the new descriptor range");
+ switch (ShaderResourceToDescriptorRange(ResDesc.ResourceType))
+ {
+ case DESCRIPTOR_RANGE_CBV:
+ for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
+ {
+ const auto& SrcCachedRes = SrcResourceCache.GetCB(ResAttr.CacheOffset + ArrInd);
+ if (!SrcCachedRes.pBuff)
+ LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetShaderResourcePrintName(ResDesc, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'.");
+
+ DstResourceCache.SetCB(ResAttr.CacheOffset, ArrInd, ResAttr.BindPoints, RefCntAutoPtr<BufferD3D11Impl>{SrcCachedRes.pBuff});
+ }
+ break;
+ case DESCRIPTOR_RANGE_SRV:
+ for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
+ {
+ const auto& SrcCachedRes = SrcResourceCache.GetSRV(ResAttr.CacheOffset + ArrInd);
+ if (!SrcCachedRes.pBuffer && !SrcCachedRes.pTexture)
+ LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetShaderResourcePrintName(ResDesc, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'.");
+
+ if (SrcCachedRes.pTexture)
+ DstResourceCache.SetTexSRV(ResAttr.CacheOffset, ArrInd, ResAttr.BindPoints, RefCntAutoPtr<TextureViewD3D11Impl>{SrcCachedRes.pView.RawPtr<TextureViewD3D11Impl>()});
+ else
+ DstResourceCache.SetBufSRV(ResAttr.CacheOffset, ArrInd, ResAttr.BindPoints, RefCntAutoPtr<BufferViewD3D11Impl>{SrcCachedRes.pView.RawPtr<BufferViewD3D11Impl>()});
+ }
+ break;
+ case DESCRIPTOR_RANGE_SAMPLER:
+ // Immutable samplers will be copied in InitSRBResourceCache().
+ if (!ResAttr.IsImmutableSamplerAssigned())
+ {
+ for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
+ {
+ const auto& SrcCachedRes = SrcResourceCache.GetSampler(ResAttr.CacheOffset + ArrInd);
+ if (!SrcCachedRes.pSampler)
+ LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetShaderResourcePrintName(ResDesc, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'.");
+
+ DstResourceCache.SetSampler(ResAttr.CacheOffset, ArrInd, ResAttr.BindPoints, RefCntAutoPtr<SamplerD3D11Impl>{SrcCachedRes.pSampler});
+ }
+ }
+ break;
+ case DESCRIPTOR_RANGE_UAV:
+ for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
+ {
+ const auto& SrcCachedRes = SrcResourceCache.GetUAV(ResAttr.CacheOffset + ArrInd);
+ if (!SrcCachedRes.pBuffer && !SrcCachedRes.pTexture)
+ LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetShaderResourcePrintName(ResDesc, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'.");
+
+ if (SrcCachedRes.pTexture)
+ DstResourceCache.SetTexUAV(ResAttr.CacheOffset, ArrInd, ResAttr.BindPoints, RefCntAutoPtr<TextureViewD3D11Impl>{SrcCachedRes.pView.RawPtr<TextureViewD3D11Impl>()});
+ else
+ DstResourceCache.SetBufUAV(ResAttr.CacheOffset, ArrInd, ResAttr.BindPoints, RefCntAutoPtr<BufferViewD3D11Impl>{SrcCachedRes.pView.RawPtr<BufferViewD3D11Impl>()});
+ }
+ break;
+ default:
+ UNEXPECTED("Unsupported descriptor range type.");
+ }
+ }
+}
+
+void PipelineResourceSignatureD3D11Impl::InitSRBResourceCache(ShaderResourceCacheD3D11& ResourceCache)
+{
+ ResourceCache.Initialize(m_ResourceCount, m_SRBMemAllocator.GetResourceCacheDataAllocator(0));
+
+ // Copy immutable samplers.
+ for (Uint32 i = 0; i < m_Desc.NumImmutableSamplers; ++i)
+ {
+ const auto& ImtblSampAttr = GetImmutableSamplerAttribs(i);
+
+ if (ImtblSampAttr.IsAllocated())
+ {
+ SamplerD3D11Impl* pSampler = ImtblSampAttr.GetSamplerD3D11();
+ VERIFY_EXPR(pSampler != nullptr);
+ VERIFY_EXPR(ImtblSampAttr.ArraySize > 0);
+
+ for (Uint32 ArrInd = 0; ArrInd < ImtblSampAttr.ArraySize; ++ArrInd)
+ ResourceCache.SetSampler(ImtblSampAttr.CacheOffset, ArrInd, ImtblSampAttr.BindPoints, pSampler);
+ }
+ }
+}
+
+void PipelineResourceSignatureD3D11Impl::UpdateShaderResourceBindingMap(ResourceBinding::TMap& ResourceMap, SHADER_TYPE ShaderStage, const TBindingsPerStage& BaseBindings) const
+{
+ VERIFY(ShaderStage != SHADER_TYPE_UNKNOWN && IsPowerOfTwo(ShaderStage), "Only single shader stage must be provided.");
+ const auto ShaderInd = GetShaderTypeIndex(ShaderStage);
+
+ for (Uint32 r = 0, ResCount = GetTotalResourceCount(); r < ResCount; ++r)
+ {
+ const auto& ResDesc = GetResourceDesc(r);
+ const auto& ResAttr = GetResourceAttribs(r);
+ const auto Range = ShaderResourceToDescriptorRange(ResDesc.ResourceType);
+
+ if ((ResDesc.ShaderStages & ShaderStage) != 0)
+ {
+ VERIFY_EXPR(ResAttr.BindPoints[ShaderInd] != InvalidBindPoint);
+ ResourceBinding::BindInfo BindInfo //
+ {
+ Uint32{BaseBindings[ShaderInd][Range]} + ResAttr.BindPoints[ShaderInd],
+ 0u, // register space is not supported
+ ResDesc.ArraySize,
+ ResDesc.ResourceType //
+ };
+ auto IsUnique = ResourceMap.emplace(HashMapStringKey{ResDesc.Name}, BindInfo).second;
+ VERIFY(IsUnique, "Shader resource '", ResDesc.Name,
+ "' already present in the binding map. Every shader resource in PSO must be unambiguously defined by "
+ "only one resource signature. This error should've been caught by ValidatePipelineResourceSignatures().");
+ }
+ }
+
+ for (Uint32 samp = 0, SampCount = GetImmutableSamplerCount(); samp < SampCount; ++samp)
+ {
+ const auto& ImtblSam = GetImmutableSamplerDesc(samp);
+ const auto& SampAttr = GetImmutableSamplerAttribs(samp);
+ const auto Range = DESCRIPTOR_RANGE_SAMPLER;
+
+ if ((ImtblSam.ShaderStages & ShaderStage) != 0 && SampAttr.IsAllocated())
+ {
+ VERIFY_EXPR(SampAttr.BindPoints[ShaderInd] != InvalidBindPoint);
+
+ String SampName{ImtblSam.SamplerOrTextureName};
+ if (IsUsingCombinedSamplers())
+ SampName += GetCombinedSamplerSuffix();
+
+ ResourceBinding::BindInfo BindInfo //
+ {
+ Uint32{BaseBindings[ShaderInd][Range]} + SampAttr.BindPoints[ShaderInd],
+ 0u, // register space is not supported
+ SampAttr.ArraySize,
+ SHADER_RESOURCE_TYPE_SAMPLER //
+ };
+
+ auto it_inserted = ResourceMap.emplace(HashMapStringKey{SampName}, BindInfo);
+#ifdef DILIGENT_DEBUG
+ if (!it_inserted.second)
+ {
+ const auto& ExistingBindInfo = it_inserted.first->second;
+ VERIFY(ExistingBindInfo.BindPoint == BindInfo.BindPoint,
+ "Bind point defined by the immutable sampler attribs is inconsistent with the bind point defined by the sampler resource.");
+ }
+#endif
+ }
+ }
+}
+
+// AZ TODO
+#if 0 //def DILIGENT_DEVELOPMENT
+bool PipelineResourceSignatureGLImpl::DvpValidateCommittedResource(const D3DShaderResourceAttribs& D3DAttribs,
+ RESOURCE_DIMENSION ResourceDim,
+ bool IsMultisample,
+ Uint32 ResIndex,
+ const ShaderResourceCacheD3D11& ResourceCache,
+ const char* ShaderName,
+ const char* PSOName) const
+{
+}
+#endif // DILIGENT_DEVELOPMENT
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp
index 933e2978..2cedc96a 100644
--- a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp
@@ -27,100 +27,360 @@
#include "pch.h"
#include <array>
+#include <d3dcompiler.h>
+
#include "PipelineStateD3D11Impl.hpp"
#include "RenderDeviceD3D11Impl.hpp"
#include "ShaderResourceBindingD3D11Impl.hpp"
#include "EngineMemory.h"
+#include "DXBCUtils.hpp"
namespace Diligent
{
+namespace
+{
+void GetShaderResourceTypeAndFlags(const D3DShaderResourceAttribs& Attribs,
+ SHADER_RESOURCE_TYPE& OutType,
+ PIPELINE_RESOURCE_FLAGS& OutFlags)
+{
+ OutFlags = PIPELINE_RESOURCE_FLAG_UNKNOWN;
-template <typename PSOCreateInfoType>
-void PipelineStateD3D11Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo)
+ switch (int{Attribs.GetInputType()})
+ {
+ case D3D_SIT_CBUFFER:
+ OutType = SHADER_RESOURCE_TYPE_CONSTANT_BUFFER;
+ break;
+ case D3D_SIT_TBUFFER:
+ UNSUPPORTED("TBuffers are not supported");
+ OutType = SHADER_RESOURCE_TYPE_TEXTURE_SRV;
+ break;
+ case D3D_SIT_TEXTURE:
+ if (Attribs.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER)
+ {
+ OutType = SHADER_RESOURCE_TYPE_BUFFER_SRV;
+ OutFlags = PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER;
+ }
+ else
+ OutType = SHADER_RESOURCE_TYPE_TEXTURE_SRV;
+ break;
+ case D3D_SIT_SAMPLER:
+ OutType = SHADER_RESOURCE_TYPE_SAMPLER;
+ break;
+ case D3D_SIT_UAV_RWTYPED:
+ if (Attribs.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER)
+ {
+ OutType = SHADER_RESOURCE_TYPE_BUFFER_UAV;
+ OutFlags = PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER;
+ }
+ else
+ OutType = SHADER_RESOURCE_TYPE_TEXTURE_UAV;
+ break;
+ case D3D_SIT_STRUCTURED:
+ case D3D_SIT_BYTEADDRESS:
+ OutType = SHADER_RESOURCE_TYPE_BUFFER_SRV;
+ break;
+ case D3D_SIT_UAV_RWSTRUCTURED:
+ case D3D_SIT_UAV_RWBYTEADDRESS:
+ case D3D_SIT_UAV_APPEND_STRUCTURED:
+ case D3D_SIT_UAV_CONSUME_STRUCTURED:
+ case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
+ OutType = SHADER_RESOURCE_TYPE_BUFFER_UAV;
+ break;
+ default:
+ UNEXPECTED("Unknown HLSL resource type");
+ OutType = SHADER_RESOURCE_TYPE_UNKNOWN;
+ break;
+ }
+}
+
+void VerifyResourceMerge(const PipelineStateDesc& PSODesc,
+ const D3DShaderResourceAttribs& ExistingRes,
+ const D3DShaderResourceAttribs& NewResAttribs)
+{
+#define LOG_RESOURCE_MERGE_ERROR_AND_THROW(PropertyName) \
+ LOG_ERROR_AND_THROW("Shader variable '", NewResAttribs.Name, \
+ "' is shared between multiple shaders in pipeline '", (PSODesc.Name ? PSODesc.Name : ""), \
+ "', but its " PropertyName " varies. A variable shared between multiple shaders " \
+ "must be defined identically in all shaders. Either use separate variables for " \
+ "different shader stages, change resource name or make sure that " PropertyName " is consistent.");
+
+ if (ExistingRes.GetInputType() != NewResAttribs.GetInputType())
+ LOG_RESOURCE_MERGE_ERROR_AND_THROW("input type");
+
+ if (ExistingRes.GetSRVDimension() != NewResAttribs.GetSRVDimension())
+ LOG_RESOURCE_MERGE_ERROR_AND_THROW("resource dimension");
+
+ if (ExistingRes.BindCount != NewResAttribs.BindCount)
+ LOG_RESOURCE_MERGE_ERROR_AND_THROW("array size");
+
+ if (ExistingRes.IsMultisample() != NewResAttribs.IsMultisample())
+ LOG_RESOURCE_MERGE_ERROR_AND_THROW("mutlisample state");
+#undef LOG_RESOURCE_MERGE_ERROR_AND_THROW
+}
+
+} // namespace
+
+
+RefCntAutoPtr<PipelineResourceSignatureD3D11Impl> PipelineStateD3D11Impl::CreateDefaultResourceSignature(
+ const PipelineStateCreateInfo& CreateInfo,
+ const std::vector<ShaderD3D11Impl*>& Shaders)
{
- m_ResourceLayoutIndex.fill(-1);
+ const auto& LayoutDesc = CreateInfo.PSODesc.ResourceLayout;
+
+ struct UniqueResource
+ {
+ const D3DShaderResourceAttribs& Attribs;
+ const SHADER_TYPE ShaderStages;
+
+ bool operator==(const UniqueResource& Res) const
+ {
+ return strcmp(Attribs.Name, Res.Attribs.Name) == 0 && ShaderStages == Res.ShaderStages;
+ }
+
+ struct Hasher
+ {
+ size_t operator()(const UniqueResource& Res) const
+ {
+ return ComputeHash(CStringHash<Char>{}(Res.Attribs.Name), Uint32{Res.ShaderStages});
+ }
+ };
+ };
+ std::unordered_set<UniqueResource, UniqueResource::Hasher> UniqueResources;
+
+ std::vector<PipelineResourceDesc> Resources;
+ const char* pCombinedSamplerSuffix = nullptr;
+
+ for (auto* pShader : Shaders)
+ {
+ const auto& ShaderResources = *pShader->GetShaderResources();
+
+ ShaderResources.ProcessResources(
+ [&](const D3DShaderResourceAttribs& Attribs, Uint32) //
+ {
+ const char* const SamplerSuffix =
+ (ShaderResources.IsUsingCombinedTextureSamplers() && Attribs.GetInputType() == D3D_SIT_SAMPLER) ?
+ ShaderResources.GetCombinedSamplerSuffix() :
+ nullptr;
+
+ // Use default variable type and current shader stages
+ auto ShaderStages = pShader->GetDesc().ShaderType;
+ auto VarType = LayoutDesc.DefaultVariableType;
+
+ const auto VarIndex = FindPipelineResourceLayoutVariable(LayoutDesc, Attribs.Name, ShaderStages, SamplerSuffix);
+ if (VarIndex != InvalidPipelineResourceLayoutVariableIndex)
+ {
+ const auto& Var = LayoutDesc.Variables[VarIndex];
+ // Use shader stages and variable type from the variable desc
+ ShaderStages = Var.ShaderStages;
+ VarType = Var.Type;
+ }
+
+ auto IterAndAssigned = UniqueResources.emplace(UniqueResource{Attribs, ShaderStages});
+ if (IterAndAssigned.second)
+ {
+ SHADER_RESOURCE_TYPE ResType = SHADER_RESOURCE_TYPE_UNKNOWN;
+ PIPELINE_RESOURCE_FLAGS Flags = PIPELINE_RESOURCE_FLAG_UNKNOWN;
+ GetShaderResourceTypeAndFlags(Attribs, ResType, Flags);
+
+ if (Attribs.BindCount == 0)
+ {
+ LOG_ERROR_AND_THROW("Resource '", Attribs.Name, "' in shader '", pShader->GetDesc().Name, "' is a runtime-sized array. ",
+ "Use explicit resource signature to specify the array size.");
+ }
+
+ Resources.emplace_back(ShaderStages, Attribs.Name, Attribs.BindCount, ResType, VarType, Flags);
+ }
+ else
+ {
+ VerifyResourceMerge(CreateInfo.PSODesc, IterAndAssigned.first->Attribs, Attribs);
+ }
+ } //
+ );
+
+ // merge combined sampler suffixes
+ if (ShaderResources.IsUsingCombinedTextureSamplers() && ShaderResources.GetNumSamplers() > 0)
+ {
+ if (pCombinedSamplerSuffix != nullptr)
+ {
+ if (strcmp(pCombinedSamplerSuffix, ShaderResources.GetCombinedSamplerSuffix()) != 0)
+ LOG_ERROR_AND_THROW("CombinedSamplerSuffix is not compatible between shaders");
+ }
+ else
+ {
+ pCombinedSamplerSuffix = ShaderResources.GetCombinedSamplerSuffix();
+ }
+ }
+ }
+
+ RefCntAutoPtr<PipelineResourceSignatureD3D11Impl> pSignature;
+ if (Resources.size())
+ {
+ PipelineResourceSignatureDesc ResSignDesc;
+ ResSignDesc.Resources = Resources.data();
+ ResSignDesc.NumResources = static_cast<Uint32>(Resources.size());
+ ResSignDesc.ImmutableSamplers = LayoutDesc.ImmutableSamplers;
+ ResSignDesc.NumImmutableSamplers = LayoutDesc.NumImmutableSamplers;
+ ResSignDesc.BindingIndex = 0;
+ ResSignDesc.SRBAllocationGranularity = CreateInfo.PSODesc.SRBAllocationGranularity;
+ ResSignDesc.UseCombinedTextureSamplers = pCombinedSamplerSuffix != nullptr;
+ ResSignDesc.CombinedSamplerSuffix = pCombinedSamplerSuffix;
+
+ constexpr bool bIsDeviceInternal = true;
+ GetDevice()->CreatePipelineResourceSignature(ResSignDesc, pSignature.DblPtr<IPipelineResourceSignature>(), bIsDeviceInternal);
+
+ if (!pSignature)
+ LOG_ERROR_AND_THROW("Failed to create implicit resource signature for pipeline state '", (CreateInfo.PSODesc.Name ? CreateInfo.PSODesc.Name : ""), "'.");
+ }
+
+ return pSignature;
+}
+
+void PipelineStateD3D11Impl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
+ const std::vector<ShaderD3D11Impl*>& Shaders,
+ std::vector<CComPtr<ID3DBlob>>& ByteCodes)
+{
+ if (m_UsingImplicitSignature)
+ {
+ VERIFY_EXPR(m_SignatureCount == 1);
+ m_Signatures[0] = CreateDefaultResourceSignature(CreateInfo, Shaders);
+ VERIFY_EXPR(!m_Signatures[0] || m_Signatures[0]->GetDesc().BindingIndex == 0);
+ }
+ // Verify that pipeline layout is compatible with shader resources and remap resource bindings.
+ ByteCodes.resize(Shaders.size());
+ for (size_t s = 0; s < Shaders.size(); ++s)
+ {
+ const auto* const pShader = Shaders[s];
+ const auto ShaderType = pShader->GetDesc().ShaderType;
+ auto* pBytecode = Shaders[s]->GetBytecode();
+
+ PipelineResourceSignatureD3D11Impl::TBindingsPerStage BindingsPerStage = {};
+ if (m_Desc.IsAnyGraphicsPipeline())
+ BindingsPerStage[PSInd][DESCRIPTOR_RANGE_UAV] = GetGraphicsPipelineDesc().NumRenderTargets;
+
+ ResourceBinding::TMap ResourceMap;
+ for (Uint32 sign = 0; sign < m_SignatureCount; ++sign)
+ {
+ const PipelineResourceSignatureD3D11Impl* const pSignature = m_Signatures[sign];
+ if (pSignature == nullptr)
+ continue;
+
+ VERIFY_EXPR(pSignature->GetDesc().BindingIndex == sign);
+ pSignature->UpdateShaderResourceBindingMap(ResourceMap, ShaderType, BindingsPerStage);
+ pSignature->AddBindings(BindingsPerStage);
+ }
+
+ ValidateShaderResources(pShader);
+
+ CComPtr<ID3DBlob> pBlob;
+ D3DCreateBlob(pBytecode->GetBufferSize(), &pBlob);
+ memcpy(pBlob->GetBufferPointer(), pBytecode->GetBufferPointer(), pBytecode->GetBufferSize());
+
+ if (!DXBCUtils::RemapResourceBindings(ResourceMap, pBlob->GetBufferPointer(), pBlob->GetBufferSize()))
+ LOG_ERROR_AND_THROW("Failed to remap resource bindings in shader '", pShader->GetDesc().Name, "'.");
+
+ ByteCodes[s] = pBlob;
+ }
+
+#ifdef DILIGENT_DEVELOPMENT
+ PipelineResourceSignatureD3D11Impl::TBindingsPerStage BindingsPerStage = {};
+
+ if (m_Desc.IsAnyGraphicsPipeline())
+ BindingsPerStage[PSInd][DESCRIPTOR_RANGE_UAV] = GetGraphicsPipelineDesc().NumRenderTargets;
+
+ for (Uint32 sign = 0; sign < m_SignatureCount; ++sign)
+ {
+ const auto& pSignature = m_Signatures[sign];
+ if (pSignature != nullptr)
+ pSignature->AddBindings(BindingsPerStage);
+ }
+
+ for (Uint32 s = 0; s < BindingsPerStage.size(); ++s)
+ {
+ const auto& BindCount = BindingsPerStage[s];
+
+ DEV_CHECK_ERR(BindCount[DESCRIPTOR_RANGE_CBV] <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT,
+ "Constant buffer count ", Uint32{BindCount[DESCRIPTOR_RANGE_CBV]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
+ DEV_CHECK_ERR(BindCount[DESCRIPTOR_RANGE_SRV] <= D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT,
+ "SRV count ", Uint32{BindCount[DESCRIPTOR_RANGE_SRV]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
+ DEV_CHECK_ERR(BindCount[DESCRIPTOR_RANGE_SAMPLER] <= D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT,
+ "Sampler count ", Uint32{BindCount[DESCRIPTOR_RANGE_SAMPLER]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT);
+ DEV_CHECK_ERR(BindCount[DESCRIPTOR_RANGE_UAV] <= D3D11_PS_CS_UAV_REGISTER_COUNT,
+ "UAV count ", Uint32{BindCount[DESCRIPTOR_RANGE_UAV]}, " exceeds D3D11 limit ", D3D11_PS_CS_UAV_REGISTER_COUNT);
+ }
+#endif
+}
+
+template <typename PSOCreateInfoType>
+void PipelineStateD3D11Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo,
+ std::vector<CComPtr<ID3DBlob>>& ByteCodes)
+{
std::vector<ShaderD3D11Impl*> Shaders;
ExtractShaders<ShaderD3D11Impl>(CreateInfo, Shaders);
- const auto NumShaderStages = GetNumShaderStages();
- VERIFY_EXPR(NumShaderStages > 0 && NumShaderStages == Shaders.size());
+ m_NumShaders = static_cast<Uint8>(Shaders.size());
- FixedLinearAllocator MemPool{GetRawAllocator()};
+ for (Uint32 s = 0; s < Shaders.size(); ++s)
+ {
+ auto ShaderType = Shaders[s]->GetDesc().ShaderType;
+ m_ShaderTypes[s] = static_cast<Uint8>(GetShaderTypeIndex(ShaderType));
+ VERIFY_EXPR(ShaderType == GetShaderTypeFromIndex(m_ShaderTypes[s]));
+ }
- MemPool.AddSpace<ShaderResourceCacheD3D11>(NumShaderStages);
- MemPool.AddSpace<ShaderResourceLayoutD3D11>(NumShaderStages);
+ FixedLinearAllocator MemPool{GetRawAllocator()};
ReserveSpaceForPipelineDesc(CreateInfo, MemPool);
MemPool.Reserve();
- m_pStaticResourceCaches = MemPool.ConstructArray<ShaderResourceCacheD3D11>(NumShaderStages);
-
- // The memory is now owned by PipelineStateD3D11Impl and will be freed by Destruct().
- auto* Ptr = MemPool.ReleaseOwnership();
- VERIFY_EXPR(Ptr == m_pStaticResourceCaches);
- (void)Ptr;
-
- m_pStaticResourceLayouts = MemPool.Allocate<ShaderResourceLayoutD3D11>(NumShaderStages);
- for (Uint32 i = 0; i < NumShaderStages; ++i)
- new (m_pStaticResourceLayouts + i) ShaderResourceLayoutD3D11{*this, m_pStaticResourceCaches[i]}; // noexcept
-
InitializePipelineDesc(CreateInfo, MemPool);
- // It is important to construct all objects before initializing them because if an exception is thrown,
- // destructors will be called for all objects
+ InitResourceLayouts(CreateInfo, Shaders, ByteCodes);
- InitResourceLayouts(CreateInfo, Shaders);
+ auto* pDeviceD3D11 = GetDevice()->GetD3D11Device();
+ for (Uint32 s = 0; s < Shaders.size(); ++s)
+ {
+ auto ShaderType = Shaders[s]->GetDesc().ShaderType;
+ const auto& pByteCode = ByteCodes[s];
+ switch (ShaderType)
+ {
+#define CREATE_SHADER(SHADER_NAME, ShaderName, pShader) \
+ case SHADER_TYPE_##SHADER_NAME: \
+ { \
+ HRESULT hr = pDeviceD3D11->Create##ShaderName##Shader(pByteCode->GetBufferPointer(), pByteCode->GetBufferSize(), NULL, &pShader); \
+ CHECK_D3D_RESULT_THROW(hr, "Failed to create D3D11 shader"); \
+ break; \
+ }
+ // clang-format off
+ CREATE_SHADER(VERTEX, Vertex, m_pVS)
+ CREATE_SHADER(PIXEL, Pixel, m_pPS)
+ CREATE_SHADER(GEOMETRY, Geometry, m_pGS)
+ CREATE_SHADER(DOMAIN, Domain, m_pDS)
+ CREATE_SHADER(HULL, Hull, m_pHS)
+ CREATE_SHADER(COMPUTE, Compute, m_pCS)
+ // clang-format on
+ default: LOG_ERROR_AND_THROW("Unknown shader type");
+ }
+#undef CREATE_SHADER
+ }
}
PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCounters,
RenderDeviceD3D11Impl* pRenderDeviceD3D11,
const GraphicsPipelineStateCreateInfo& CreateInfo) :
- // clang-format off
- TPipelineStateBase
- {
- pRefCounters,
- pRenderDeviceD3D11,
- CreateInfo
- },
- m_SRBMemAllocator{GetRawAllocator()},
- m_ImmutableSamplers (STD_ALLOCATOR_RAW_MEM(ImmutableSamplerInfo, GetRawAllocator(), "Allocator for vector<ImmutableSamplerInfo>"))
-// clang-format on
+ TPipelineStateBase{pRefCounters, pRenderDeviceD3D11, CreateInfo}
{
try
{
- InitInternalObjects(CreateInfo);
-
- auto& GraphicsPipeline = GetGraphicsPipelineDesc();
-
-#define INIT_SHADER(ShortName, ExpectedType) \
- do \
- { \
- auto* pShader = ValidatedCast<ShaderD3D11Impl>(CreateInfo.p##ShortName); \
- m_p##ShortName = pShader; \
- if (m_p##ShortName && m_p##ShortName->GetDesc().ShaderType != ExpectedType) \
- { \
- LOG_ERROR_AND_THROW(GetShaderTypeLiteralName(ExpectedType), " shader is expeceted while ", GetShaderTypeLiteralName(m_p##ShortName->GetDesc().ShaderType), " provided"); \
- } \
- if (pShader != nullptr) \
- HashCombine(m_ShaderResourceLayoutHash, pShader->GetD3D11Resources()->GetHash()); \
- } while (false)
-
- INIT_SHADER(VS, SHADER_TYPE_VERTEX);
- INIT_SHADER(PS, SHADER_TYPE_PIXEL);
- INIT_SHADER(GS, SHADER_TYPE_GEOMETRY);
- INIT_SHADER(DS, SHADER_TYPE_DOMAIN);
- INIT_SHADER(HS, SHADER_TYPE_HULL);
-#undef INIT_SHADER
+ std::vector<CComPtr<ID3DBlob>> ByteCodes;
+ InitInternalObjects(CreateInfo, ByteCodes);
if (m_pVS == nullptr)
- {
LOG_ERROR_AND_THROW("Vertex shader is null");
- }
- auto* pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device();
+ auto& GraphicsPipeline = GetGraphicsPipelineDesc();
+ auto* pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device();
D3D11_BLEND_DESC D3D11BSDesc = {};
BlendStateDesc_To_D3D11_BLEND_DESC(GraphicsPipeline.BlendDesc, D3D11BSDesc);
@@ -144,10 +404,7 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters*
std::vector<D3D11_INPUT_ELEMENT_DESC, STDAllocatorRawMem<D3D11_INPUT_ELEMENT_DESC>> d311InputElements(STD_ALLOCATOR_RAW_MEM(D3D11_INPUT_ELEMENT_DESC, GetRawAllocator(), "Allocator for vector<D3D11_INPUT_ELEMENT_DESC>"));
LayoutElements_To_D3D11_INPUT_ELEMENT_DESCs(InputLayout, d311InputElements);
- ID3DBlob* pVSByteCode = m_pVS.RawPtr<ShaderD3D11Impl>()->GetBytecode();
- if (!pVSByteCode)
- LOG_ERROR_AND_THROW("Vertex Shader byte code does not exist");
-
+ ID3DBlob* pVSByteCode = ByteCodes.front();
CHECK_D3D_RESULT_THROW(pDeviceD3D11->CreateInputLayout(d311InputElements.data(), static_cast<UINT>(d311InputElements.size()), pVSByteCode->GetBufferPointer(), pVSByteCode->GetBufferSize(), &m_pd3d11InputLayout),
"Failed to create the Direct3D11 input layout");
}
@@ -162,32 +419,12 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters*
PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCounters,
RenderDeviceD3D11Impl* pRenderDeviceD3D11,
const ComputePipelineStateCreateInfo& CreateInfo) :
- // clang-format off
- TPipelineStateBase
- {
- pRefCounters,
- pRenderDeviceD3D11,
- CreateInfo
- },
- m_SRBMemAllocator{GetRawAllocator()},
- m_ImmutableSamplers(STD_ALLOCATOR_RAW_MEM(ImmutableSamplerInfo, GetRawAllocator(), "Allocator for vector<ImmutableSamplerInfo>"))
-// clang-format on
+ TPipelineStateBase{pRefCounters, pRenderDeviceD3D11, CreateInfo}
{
try
{
- InitInternalObjects(CreateInfo);
-
- m_pCS = ValidatedCast<ShaderD3D11Impl>(CreateInfo.pCS);
- if (m_pCS == nullptr)
- {
- LOG_ERROR_AND_THROW("Compute shader is null");
- }
-
- if (m_pCS->GetDesc().ShaderType != SHADER_TYPE_COMPUTE)
- {
- LOG_ERROR_AND_THROW(GetShaderTypeLiteralName(SHADER_TYPE_COMPUTE), " shader is expeceted while ", GetShaderTypeLiteralName(m_pCS->GetDesc().ShaderType), " provided");
- }
- m_ShaderResourceLayoutHash = m_pCS->GetD3D11Resources()->GetHash();
+ std::vector<CComPtr<ID3DBlob>> ByteCodes;
+ InitInternalObjects(CreateInfo, ByteCodes);
}
catch (...)
{
@@ -203,26 +440,19 @@ PipelineStateD3D11Impl::~PipelineStateD3D11Impl()
void PipelineStateD3D11Impl::Destruct()
{
- if (m_pStaticResourceLayouts != nullptr)
- {
- for (Uint32 l = 0; l < GetNumShaderStages(); ++l)
- {
- m_pStaticResourceLayouts[l].~ShaderResourceLayoutD3D11();
- }
- }
-
- if (m_pStaticResourceCaches != nullptr)
- {
- for (Uint32 s = 0; s < GetNumShaderStages(); ++s)
- {
- m_pStaticResourceCaches[s].Destroy(GetRawAllocator());
- m_pStaticResourceCaches[s].~ShaderResourceCacheD3D11();
- }
- }
-
- // All subobjects are allocated in contiguous chunks of memory.
- if (auto* pRawMem = m_pStaticResourceCaches)
- GetRawAllocator().Free(pRawMem);
+ m_ShaderTypes = {};
+ m_NumShaders = 0;
+
+ m_pd3d11BlendState = nullptr;
+ m_pd3d11RasterizerState = nullptr;
+ m_pd3d11DepthStencilState = nullptr;
+ m_pd3d11InputLayout = nullptr;
+ m_pVS = nullptr;
+ m_pPS = nullptr;
+ m_pGS = nullptr;
+ m_pDS = nullptr;
+ m_pHS = nullptr;
+ m_pCS = nullptr;
TPipelineStateBase::Destruct();
}
@@ -230,275 +460,115 @@ void PipelineStateD3D11Impl::Destruct()
IMPLEMENT_QUERY_INTERFACE(PipelineStateD3D11Impl, IID_PipelineStateD3D11, TPipelineStateBase)
-void PipelineStateD3D11Impl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
- const std::vector<ShaderD3D11Impl*>& Shaders)
-{
- const auto& ResourceLayout = m_Desc.ResourceLayout;
-
-#ifdef DILIGENT_DEVELOPMENT
- {
- const ShaderResources* pResources[MAX_SHADERS_IN_PIPELINE] = {};
- for (Uint32 s = 0; s < Shaders.size(); ++s)
- {
- pResources[s] = Shaders[s]->GetD3D11Resources().get();
- }
- ShaderResources::DvpVerifyResourceLayout(ResourceLayout, pResources, GetNumShaderStages(),
- (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_VARIABLES) == 0,
- (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_IMMUTABLE_SAMPLERS) == 0);
- }
-#endif
-
- decltype(m_ImmutableSamplers) ImmutableSamplers{STD_ALLOCATOR_RAW_MEM(ImmutableSamplerInfo, GetRawAllocator(), "Allocator for vector<ImmutableSamplerInfo>")};
-
- std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderResLayoutDataSizes = {};
- std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderResCacheDataSizes = {};
- for (Uint32 s = 0; s < Shaders.size(); ++s)
- {
- const auto* pShader = Shaders[s];
- const auto& ShaderDesc = pShader->GetDesc();
- const auto& Resources = *pShader->GetD3D11Resources();
- VERIFY_EXPR(ShaderDesc.ShaderType == Resources.GetShaderType());
-
- // The cache will be initialized by the resource layout
-
- // Shader resource layout will only contain dynamic and mutable variables
- const SHADER_RESOURCE_VARIABLE_TYPE StaticVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC};
- m_pStaticResourceLayouts[s].Initialize(
- pShader->GetD3D11Resources(),
- m_Desc.ResourceLayout,
- StaticVarTypes,
- _countof(StaticVarTypes),
- GetRawAllocator(),
- GetRawAllocator() //
- );
-
- // Initialize immutable samplers
- for (Uint32 sam = 0; sam < Resources.GetNumSamplers(); ++sam)
- {
- const auto& SamplerAttribs = Resources.GetSampler(sam);
- constexpr bool LogImtblSamplerArrayError = true;
- auto SrcImtblSamplerInd = Resources.FindImmutableSampler(SamplerAttribs, ResourceLayout, LogImtblSamplerArrayError);
- if (SrcImtblSamplerInd >= 0)
- {
- const auto& SrcImtblSamplerInfo = ResourceLayout.ImmutableSamplers[SrcImtblSamplerInd];
-
- RefCntAutoPtr<ISampler> pImbtlSampler;
- GetDevice()->CreateSampler(SrcImtblSamplerInfo.Desc, &pImbtlSampler);
- ImmutableSamplers.emplace_back(SamplerAttribs, std::move(pImbtlSampler));
- }
- }
- m_ImmutableSamplerOffsets[s + 1] = static_cast<Uint16>(ImmutableSamplers.size());
-
- if (m_Desc.SRBAllocationGranularity > 1)
- {
- const SHADER_RESOURCE_VARIABLE_TYPE SRBVarTypes[] = //
- {
- SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE,
- SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC //
- };
- ShaderResLayoutDataSizes[s] = ShaderResourceLayoutD3D11::GetRequiredMemorySize(Resources, ResourceLayout, SRBVarTypes, _countof(SRBVarTypes));
- ShaderResCacheDataSizes[s] = ShaderResourceCacheD3D11::GetRequriedMemorySize(Resources);
- }
-
- auto ShaderInd = GetShaderTypePipelineIndex(ShaderDesc.ShaderType, m_Desc.PipelineType);
- m_ResourceLayoutIndex[ShaderInd] = static_cast<Int8>(s);
- }
-
- if (m_Desc.SRBAllocationGranularity > 1)
- {
- m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderStages(), ShaderResLayoutDataSizes.data(), GetNumShaderStages(), ShaderResCacheDataSizes.data());
- }
-
- m_ImmutableSamplers.reserve(ImmutableSamplers.size());
- for (auto& ImtblSam : ImmutableSamplers)
- m_ImmutableSamplers.emplace_back(std::move(ImtblSam));
-
- for (Uint32 s = 0; s < GetNumShaderStages(); ++s)
- {
- // Initialize immutable samplers in the static resource cache to avoid warning messages
- SetImmutableSamplers(m_pStaticResourceCaches[s], s);
- }
-}
-
-ID3D11BlendState* PipelineStateD3D11Impl::GetD3D11BlendState()
-{
- return m_pd3d11BlendState;
-}
-
-ID3D11RasterizerState* PipelineStateD3D11Impl::GetD3D11RasterizerState()
-{
- return m_pd3d11RasterizerState;
-}
-
-ID3D11DepthStencilState* PipelineStateD3D11Impl::GetD3D11DepthStencilState()
-{
- return m_pd3d11DepthStencilState;
-}
-
-ID3D11InputLayout* PipelineStateD3D11Impl::GetD3D11InputLayout()
-{
- return m_pd3d11InputLayout;
-}
-
-void PipelineStateD3D11Impl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources)
-{
- auto& SRBAllocator = GetDevice()->GetSRBAllocator();
- auto pShaderResBinding = NEW_RC_OBJ(SRBAllocator, "ShaderResourceBindingD3D11Impl instance", ShaderResourceBindingD3D11Impl)(this, false);
- if (InitStaticResources)
- pShaderResBinding->InitializeStaticResources(nullptr);
- pShaderResBinding->QueryInterface(IID_ShaderResourceBinding, reinterpret_cast<IObject**>(static_cast<IShaderResourceBinding**>(ppShaderResourceBinding)));
-}
-
bool PipelineStateD3D11Impl::IsCompatibleWith(const IPipelineState* pPSO) const
{
- VERIFY_EXPR(pPSO != nullptr);
-
- if (pPSO == this)
- return true;
-
- const PipelineStateD3D11Impl* pPSOD3D11 = ValidatedCast<const PipelineStateD3D11Impl>(pPSO);
- if (m_ShaderResourceLayoutHash != pPSOD3D11->m_ShaderResourceLayoutHash)
+ if (!TPipelineStateBase::IsCompatibleWith(pPSO))
return false;
- if (GetNumShaderStages() != pPSOD3D11->GetNumShaderStages())
+ const auto& rhs = *ValidatedCast<const PipelineStateD3D11Impl>(pPSO);
+ if (m_NumShaders != rhs.m_NumShaders || m_ShaderTypes != rhs.m_ShaderTypes)
return false;
- for (Uint32 s = 0; s < GetNumShaderStages(); ++s)
- {
- auto* pShader0 = GetShader(s);
- auto* pShader1 = pPSOD3D11->GetShader(s);
- if (pShader0->GetDesc().ShaderType != pShader1->GetDesc().ShaderType)
- return false;
- const auto& Res0 = *pShader0->GetD3D11Resources();
- const auto& Res1 = *pShader1->GetD3D11Resources();
- if (!Res0.IsCompatibleWith(Res1))
- return false;
- }
-
return true;
}
-ID3D11VertexShader* PipelineStateD3D11Impl::GetD3D11VertexShader()
-{
- if (!m_pVS) return nullptr;
- auto* pVSD3D11 = m_pVS.RawPtr<ShaderD3D11Impl>();
- return static_cast<ID3D11VertexShader*>(pVSD3D11->GetD3D11Shader());
-}
-
-ID3D11PixelShader* PipelineStateD3D11Impl::GetD3D11PixelShader()
+SHADER_TYPE PipelineStateD3D11Impl::GetShaderStageType(Uint32 Index) const
{
- if (!m_pPS) return nullptr;
- auto* pPSD3D11 = m_pPS.RawPtr<ShaderD3D11Impl>();
- return static_cast<ID3D11PixelShader*>(pPSD3D11->GetD3D11Shader());
+ return GetShaderTypeFromIndex(m_ShaderTypes[Index]);
}
-ID3D11GeometryShader* PipelineStateD3D11Impl::GetD3D11GeometryShader()
+void PipelineStateD3D11Impl::ValidateShaderResources(const ShaderD3D11Impl* pShader)
{
- if (!m_pGS) return nullptr;
- auto* pGSD3D11 = m_pGS.RawPtr<ShaderD3D11Impl>();
- return static_cast<ID3D11GeometryShader*>(pGSD3D11->GetD3D11Shader());
-}
+ const auto& pShaderResources = pShader->GetShaderResources();
+ const auto ShaderType = pShader->GetDesc().ShaderType;
-ID3D11DomainShader* PipelineStateD3D11Impl::GetD3D11DomainShader()
-{
- if (!m_pDS) return nullptr;
- auto* pDSD3D11 = m_pDS.RawPtr<ShaderD3D11Impl>();
- return static_cast<ID3D11DomainShader*>(pDSD3D11->GetD3D11Shader());
-}
-
-ID3D11HullShader* PipelineStateD3D11Impl::GetD3D11HullShader()
-{
- if (!m_pHS) return nullptr;
- auto* pHSD3D11 = m_pHS.RawPtr<ShaderD3D11Impl>();
- return static_cast<ID3D11HullShader*>(pHSD3D11->GetD3D11Shader());
-}
-
-ID3D11ComputeShader* PipelineStateD3D11Impl::GetD3D11ComputeShader()
-{
- if (!m_pCS) return nullptr;
- auto* pCSD3D11 = m_pCS.RawPtr<ShaderD3D11Impl>();
- return static_cast<ID3D11ComputeShader*>(pCSD3D11->GetD3D11Shader());
-}
-
-
-void PipelineStateD3D11Impl::BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags)
-{
- for (Uint32 s = 0; s < GetNumShaderStages(); ++s)
- {
- auto& StaticResLayout = m_pStaticResourceLayouts[s];
- if ((ShaderFlags & StaticResLayout.GetShaderType()) != 0)
- StaticResLayout.BindResources(pResourceMapping, Flags, m_pStaticResourceCaches[s]);
- }
-}
-
-Uint32 PipelineStateD3D11Impl::GetStaticVariableCount(SHADER_TYPE ShaderType) const
-{
- const auto LayoutInd = GetStaticVariableCountHelper(ShaderType, m_ResourceLayoutIndex);
- if (LayoutInd < 0)
- return 0;
-
- VERIFY_EXPR(static_cast<Uint32>(LayoutInd) <= GetNumShaderStages());
- return m_pStaticResourceLayouts[LayoutInd].GetTotalResourceCount();
-}
+#ifdef DILIGENT_DEVELOPMENT
+ m_ShaderResources.emplace_back(pShaderResources);
+#endif
-IShaderResourceVariable* PipelineStateD3D11Impl::GetStaticVariableByName(SHADER_TYPE ShaderType, const Char* Name)
-{
- const auto LayoutInd = GetStaticVariableByNameHelper(ShaderType, Name, m_ResourceLayoutIndex);
- if (LayoutInd < 0)
- return nullptr;
+ // Check compatibility between shader resources and resource signature.
+ pShaderResources->ProcessResources(
+ [&](const D3DShaderResourceAttribs& Attribs, Uint32) //
+ {
+#ifdef DILIGENT_DEVELOPMENT
+ m_ResourceAttibutions.emplace_back();
+#endif
- VERIFY_EXPR(static_cast<Uint32>(LayoutInd) <= GetNumShaderStages());
- return m_pStaticResourceLayouts[LayoutInd].GetShaderVariable(Name);
-}
+ const auto IsSampler = Attribs.GetInputType() == D3D_SIT_SAMPLER;
+ if (IsSampler && pShaderResources->IsUsingCombinedTextureSamplers())
+ return;
-IShaderResourceVariable* PipelineStateD3D11Impl::GetStaticVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index)
-{
- const auto LayoutInd = GetStaticVariableByIndexHelper(ShaderType, Index, m_ResourceLayoutIndex);
- if (LayoutInd < 0)
- return nullptr;
+#ifdef DILIGENT_DEVELOPMENT
+ auto& ResAttribution = m_ResourceAttibutions.back();
+#else
+ ResourceAttribution ResAttribution;
+#endif
+ ResAttribution = GetResourceAttribution(Attribs.Name, ShaderType);
+ if (!ResAttribution)
+ {
+ LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource '", Attribs.Name,
+ "' that is not present in any pipeline resource signature used to create pipeline state '",
+ m_Desc.Name, "'.");
+ }
- VERIFY_EXPR(static_cast<Uint32>(LayoutInd) <= GetNumShaderStages());
- return m_pStaticResourceLayouts[LayoutInd].GetShaderVariable(Index);
-}
+ SHADER_RESOURCE_TYPE Type = SHADER_RESOURCE_TYPE_UNKNOWN;
+ PIPELINE_RESOURCE_FLAGS Flags = PIPELINE_RESOURCE_FLAG_UNKNOWN;
+ GetShaderResourceTypeAndFlags(Attribs, Type, Flags);
-void PipelineStateD3D11Impl::SetImmutableSamplers(ShaderResourceCacheD3D11& ResourceCache, Uint32 ShaderInd) const
-{
- auto NumCachedSamplers = ResourceCache.GetSamplerCount();
- for (Uint32 s = m_ImmutableSamplerOffsets[ShaderInd]; s < m_ImmutableSamplerOffsets[ShaderInd + 1]; ++s)
- {
- auto& SamplerInfo = m_ImmutableSamplers[s];
- const auto& SamAttribs = SamplerInfo.Attribs;
- auto* pSamplerD3D11Impl = SamplerInfo.pSampler.RawPtr<SamplerD3D11Impl>();
- // Limiting EndBindPoint is required when initializing immutable samplers in a Shader's static cache
- auto EndBindPoint = std::min(static_cast<Uint32>(SamAttribs.BindPoint) + SamAttribs.BindCount, NumCachedSamplers);
- for (Uint32 BindPoint = SamAttribs.BindPoint; BindPoint < EndBindPoint; ++BindPoint)
- ResourceCache.SetSampler(BindPoint, pSamplerD3D11Impl);
- }
-}
+ const auto* const pSignature = ResAttribution.pSignature;
+ VERIFY_EXPR(pSignature != nullptr);
-const ShaderD3D11Impl* PipelineStateD3D11Impl::GetShaderByType(SHADER_TYPE ShaderType) const
-{
- switch (ShaderType)
- {
- // clang-format off
- case SHADER_TYPE_VERTEX: return m_pVS;
- case SHADER_TYPE_PIXEL: return m_pPS;
- case SHADER_TYPE_GEOMETRY: return m_pGS;
- case SHADER_TYPE_HULL: return m_pHS;
- case SHADER_TYPE_DOMAIN: return m_pDS;
- case SHADER_TYPE_COMPUTE: return m_pCS;
- default: UNEXPECTED("unsupported shader type"); return nullptr;
- // clang-format on
- }
-}
+ if (ResAttribution.ResourceIndex != ResourceAttribution::InvalidResourceIndex)
+ {
+ const auto& ResDesc = pSignature->GetResourceDesc(ResAttribution.ResourceIndex);
-const ShaderD3D11Impl* PipelineStateD3D11Impl::GetShader(Uint32 Index) const
-{
- if (Index < GetNumShaderStages())
- return GetShaderByType(GetShaderStageType(Index));
+ auto ResourceType = ResDesc.ResourceType;
+ if (ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT)
+ ResourceType = SHADER_RESOURCE_TYPE_TEXTURE_SRV;
+ if (Type != ResourceType)
+ {
+ LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource with name '", Attribs.Name,
+ "' and type '", GetShaderResourceTypeLiteralName(Type), "' that is not compatible with type '",
+ GetShaderResourceTypeLiteralName(ResDesc.ResourceType), "' in pipeline resource signature '", pSignature->GetDesc().Name, "'.");
+ }
- UNEXPECTED("Shader index is out of range");
- return nullptr;
+ if ((Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER))
+ {
+ LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource '", Attribs.Name,
+ "' that is", ((Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) ? "" : " not"),
+ " labeled as formatted buffer, while the same resource specified by the pipeline resource signature '",
+ pSignature->GetDesc().Name, "' is", ((ResDesc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) ? "" : " not"),
+ " labeled as such.");
+ }
+
+ VERIFY(Attribs.BindCount != 0,
+ "Runtime-sized array is not supported in Direct3D11, shader must not be compiled.");
+ VERIFY((ResDesc.Flags & PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY) == 0,
+ "Runtime-sized array flag is not supported in Direct3D11, this error must be handled by ValidatePipelineResourceSignatureDesc()");
+
+ if (ResDesc.ArraySize < Attribs.BindCount)
+ {
+ LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource '", Attribs.Name,
+ "' whose array size (", Attribs.BindCount, ") is greater than the array size (",
+ ResDesc.ArraySize, ") specified by the pipeline resource signature '", pSignature->GetDesc().Name, "'.");
+ }
+ }
+ else if (ResAttribution.ImmutableSamplerIndex != ResourceAttribution::InvalidResourceIndex)
+ {
+ if (Type != SHADER_RESOURCE_TYPE_SAMPLER)
+ {
+ LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource with name '", Attribs.Name,
+ "' and type '", GetShaderResourceTypeLiteralName(Type),
+ "' that is not compatible with immutable sampler defined in pipeline resource signature '",
+ pSignature->GetDesc().Name, "'.");
+ }
+ }
+ else
+ {
+ UNEXPECTED("Either immutable sampler or resource index should be valid");
+ }
+ } //
+ );
}
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp
index e8bf17ef..3523e5b4 100644
--- a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp
@@ -38,6 +38,7 @@
#include "TextureViewD3D11Impl.hpp"
#include "PipelineStateD3D11Impl.hpp"
#include "ShaderResourceBindingD3D11Impl.hpp"
+#include "PipelineResourceSignatureD3D11Impl.hpp"
#include "FenceD3D11Impl.hpp"
#include "QueryD3D11Impl.hpp"
#include "RenderPassD3D11Impl.hpp"
@@ -47,6 +48,13 @@
namespace Diligent
{
+class BottomLevelASD3D11Impl
+{};
+class TopLevelASD3D11Impl
+{};
+class ShaderBindingTableD3D11Impl
+{};
+
static CComPtr<IDXGIAdapter1> DXGIAdapterFromD3D11Device(ID3D11Device* pd3d11Device)
{
CComPtr<IDXGIDevice> pDXGIDevice;
@@ -87,32 +95,12 @@ RenderDeviceD3D11Impl::RenderDeviceD3D11Impl(IReferenceCounters* pRefCo
pRefCounters,
RawMemAllocator,
pEngineFactory,
- NumDeferredContexts,
- DeviceObjectSizes
- {
- sizeof(TextureBaseD3D11),
- sizeof(TextureViewD3D11Impl),
- sizeof(BufferD3D11Impl),
- sizeof(BufferViewD3D11Impl),
- sizeof(ShaderD3D11Impl),
- sizeof(SamplerD3D11Impl),
- sizeof(PipelineStateD3D11Impl),
- sizeof(ShaderResourceBindingD3D11Impl),
- sizeof(FenceD3D11Impl),
- sizeof(QueryD3D11Impl),
- sizeof(RenderPassD3D11Impl),
- sizeof(FramebufferD3D11Impl),
- 0,
- 0,
- 0
- }
+ NumDeferredContexts
},
m_EngineAttribs{EngineAttribs},
m_pd3d11Device {pd3d11Device }
// clang-format on
{
- static_assert(sizeof(DeviceObjectSizes) == sizeof(size_t) * 15, "Please add new objects to DeviceObjectSizes constructor");
-
m_DeviceCaps.DevType = RENDER_DEVICE_TYPE_D3D11;
auto FeatureLevel = m_pd3d11Device->GetFeatureLevel();
switch (FeatureLevel)
@@ -149,10 +137,13 @@ RenderDeviceD3D11Impl::RenderDeviceD3D11Impl(IReferenceCounters* pRefCo
// Direct3D11 only supports shader model 5.0 even if the device feature level is
// above 11.0 (for example, 11.1 or 12.0), so bindless resources are never available.
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-intro#overview-for-each-feature-level
- UNSUPPORTED_FEATURE(BindlessResources, "Bindless resources are");
+ // clang-format off
+ UNSUPPORTED_FEATURE(BindlessResources, "Bindless resources are");
UNSUPPORTED_FEATURE(VertexPipelineUAVWritesAndAtomics, "Vertex pipeline UAV writes and atomics are");
- UNSUPPORTED_FEATURE(MeshShaders, "Mesh shaders are");
- UNSUPPORTED_FEATURE(RayTracing, "Ray tracing is");
+ UNSUPPORTED_FEATURE(MeshShaders, "Mesh shaders are");
+ UNSUPPORTED_FEATURE(RayTracing, "Ray tracing is");
+ UNSUPPORTED_FEATURE(ShaderResourceRuntimeArray, "Runtime-sized array is");
+ // clang-format on
{
bool ShaderFloat16Supported = false;
@@ -182,7 +173,7 @@ RenderDeviceD3D11Impl::RenderDeviceD3D11Impl(IReferenceCounters* pRefCo
#undef UNSUPPORTED_FEATURE
#if defined(_MSC_VER) && defined(_WIN64)
- static_assert(sizeof(DeviceFeatures) == 32, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
+ static_assert(sizeof(DeviceFeatures) == 33, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
#endif
auto& TexCaps = m_DeviceCaps.TexCaps;
@@ -257,38 +248,17 @@ IMPLEMENT_QUERY_INTERFACE(RenderDeviceD3D11Impl, IID_RenderDeviceD3D11, TRenderD
void RenderDeviceD3D11Impl::CreateBufferFromD3DResource(ID3D11Buffer* pd3d11Buffer, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer)
{
- CreateDeviceObject("buffer", BuffDesc, ppBuffer,
- [&]() //
- {
- BufferD3D11Impl* pBufferD3D11{NEW_RC_OBJ(m_BufObjAllocator, "BufferD3D11Impl instance", BufferD3D11Impl)(m_BuffViewObjAllocator, this, BuffDesc, InitialState, pd3d11Buffer)};
- pBufferD3D11->QueryInterface(IID_Buffer, reinterpret_cast<IObject**>(ppBuffer));
- pBufferD3D11->CreateDefaultViews();
- OnCreateDeviceObject(pBufferD3D11);
- });
+ CreateBufferImpl(ppBuffer, BuffDesc, InitialState, pd3d11Buffer);
}
void RenderDeviceD3D11Impl::CreateBuffer(const BufferDesc& BuffDesc, const BufferData* pBuffData, IBuffer** ppBuffer)
{
- CreateDeviceObject("buffer", BuffDesc, ppBuffer,
- [&]() //
- {
- BufferD3D11Impl* pBufferD3D11{NEW_RC_OBJ(m_BufObjAllocator, "BufferD3D11Impl instance", BufferD3D11Impl)(m_BuffViewObjAllocator, this, BuffDesc, pBuffData)};
- pBufferD3D11->QueryInterface(IID_Buffer, reinterpret_cast<IObject**>(ppBuffer));
- pBufferD3D11->CreateDefaultViews();
- OnCreateDeviceObject(pBufferD3D11);
- });
+ CreateBufferImpl(ppBuffer, BuffDesc, pBuffData);
}
void RenderDeviceD3D11Impl::CreateShader(const ShaderCreateInfo& ShaderCI, IShader** ppShader)
{
- CreateDeviceObject("shader", ShaderCI.Desc, ppShader,
- [&]() //
- {
- ShaderD3D11Impl* pShaderD3D11{NEW_RC_OBJ(m_ShaderObjAllocator, "ShaderD3D11Impl instance", ShaderD3D11Impl)(this, ShaderCI)};
- pShaderD3D11->QueryInterface(IID_Shader, reinterpret_cast<IObject**>(ppShader));
-
- OnCreateDeviceObject(pShaderD3D11);
- });
+ CreateShaderImpl(ppShader, ShaderCI);
}
void RenderDeviceD3D11Impl::CreateTexture1DFromD3DResource(ID3D11Texture1D* pd3d11Texture, RESOURCE_STATE InitialState, ITexture** ppTexture)
@@ -304,7 +274,6 @@ void RenderDeviceD3D11Impl::CreateTexture1DFromD3DResource(ID3D11Texture1D* pd3d
TextureBaseD3D11* pTextureD3D11{NEW_RC_OBJ(m_TexObjAllocator, "Texture1D_D3D11 instance", Texture1D_D3D11)(m_TexViewObjAllocator, this, InitialState, pd3d11Texture)};
pTextureD3D11->QueryInterface(IID_Texture, reinterpret_cast<IObject**>(ppTexture));
pTextureD3D11->CreateDefaultViews();
- OnCreateDeviceObject(pTextureD3D11);
});
}
@@ -321,7 +290,6 @@ void RenderDeviceD3D11Impl::CreateTexture2DFromD3DResource(ID3D11Texture2D* pd3d
TextureBaseD3D11* pTextureD3D11{NEW_RC_OBJ(m_TexObjAllocator, "Texture2D_D3D11 instance", Texture2D_D3D11)(m_TexViewObjAllocator, this, InitialState, pd3d11Texture)};
pTextureD3D11->QueryInterface(IID_Texture, reinterpret_cast<IObject**>(ppTexture));
pTextureD3D11->CreateDefaultViews();
- OnCreateDeviceObject(pTextureD3D11);
});
}
@@ -338,7 +306,6 @@ void RenderDeviceD3D11Impl::CreateTexture3DFromD3DResource(ID3D11Texture3D* pd3d
TextureBaseD3D11* pTextureD3D11{NEW_RC_OBJ(m_TexObjAllocator, "Texture3D_D3D11 instance", Texture3D_D3D11)(m_TexViewObjAllocator, this, InitialState, pd3d11Texture)};
pTextureD3D11->QueryInterface(IID_Texture, reinterpret_cast<IObject**>(ppTexture));
pTextureD3D11->CreateDefaultViews();
- OnCreateDeviceObject(pTextureD3D11);
});
}
@@ -371,47 +338,22 @@ void RenderDeviceD3D11Impl::CreateTexture(const TextureDesc& TexDesc, const Text
}
pTextureD3D11->QueryInterface(IID_Texture, reinterpret_cast<IObject**>(ppTexture));
pTextureD3D11->CreateDefaultViews();
- OnCreateDeviceObject(pTextureD3D11);
});
}
void RenderDeviceD3D11Impl::CreateSampler(const SamplerDesc& SamplerDesc, ISampler** ppSampler)
{
- CreateDeviceObject("sampler", SamplerDesc, ppSampler,
- [&]() //
- {
- m_SamplersRegistry.Find(SamplerDesc, reinterpret_cast<IDeviceObject**>(ppSampler));
- if (*ppSampler == nullptr)
- {
- SamplerD3D11Impl* pSamplerD3D11{NEW_RC_OBJ(m_SamplerObjAllocator, "SamplerD3D11Impl instance", SamplerD3D11Impl)(this, SamplerDesc)};
- pSamplerD3D11->QueryInterface(IID_Sampler, reinterpret_cast<IObject**>(ppSampler));
- OnCreateDeviceObject(pSamplerD3D11);
- m_SamplersRegistry.Add(SamplerDesc, *ppSampler);
- }
- });
-}
-
-template <typename PSOCreateInfoType>
-void RenderDeviceD3D11Impl::CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState)
-{
- CreateDeviceObject("Pipeline state", PSOCreateInfo.PSODesc, ppPipelineState,
- [&]() //
- {
- PipelineStateD3D11Impl* pPipelineStateD3D11{NEW_RC_OBJ(m_PSOAllocator, "PipelineStateD3D11Impl instance", PipelineStateD3D11Impl)(this, PSOCreateInfo)};
- pPipelineStateD3D11->QueryInterface(IID_PipelineState, reinterpret_cast<IObject**>(ppPipelineState));
- OnCreateDeviceObject(pPipelineStateD3D11);
- });
+ CreateSamplerImpl(ppSampler, SamplerDesc);
}
-
void RenderDeviceD3D11Impl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState)
{
- CreatePipelineState(PSOCreateInfo, ppPipelineState);
+ CreatePipelineStateImpl(ppPipelineState, PSOCreateInfo);
}
void RenderDeviceD3D11Impl::CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState)
{
- CreatePipelineState(PSOCreateInfo, ppPipelineState);
+ CreatePipelineStateImpl(ppPipelineState, PSOCreateInfo);
}
void RenderDeviceD3D11Impl::CreateRayTracingPipelineState(const RayTracingPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState)
@@ -422,46 +364,22 @@ void RenderDeviceD3D11Impl::CreateRayTracingPipelineState(const RayTracingPipeli
void RenderDeviceD3D11Impl::CreateFence(const FenceDesc& Desc, IFence** ppFence)
{
- CreateDeviceObject("Fence", Desc, ppFence,
- [&]() //
- {
- FenceD3D11Impl* pFenceD3D11{NEW_RC_OBJ(m_FenceAllocator, "FenceD3D11Impl instance", FenceD3D11Impl)(this, Desc)};
- pFenceD3D11->QueryInterface(IID_Fence, reinterpret_cast<IObject**>(ppFence));
- OnCreateDeviceObject(pFenceD3D11);
- });
+ CreateFenceImpl(ppFence, Desc);
}
void RenderDeviceD3D11Impl::CreateQuery(const QueryDesc& Desc, IQuery** ppQuery)
{
- CreateDeviceObject("Query", Desc, ppQuery,
- [&]() //
- {
- QueryD3D11Impl* pQueryD3D11{NEW_RC_OBJ(m_QueryAllocator, "QueryD3D11Impl instance", QueryD3D11Impl)(this, Desc)};
- pQueryD3D11->QueryInterface(IID_Query, reinterpret_cast<IObject**>(ppQuery));
- OnCreateDeviceObject(pQueryD3D11);
- });
+ CreateQueryImpl(ppQuery, Desc);
}
void RenderDeviceD3D11Impl::CreateRenderPass(const RenderPassDesc& Desc, IRenderPass** ppRenderPass)
{
- CreateDeviceObject("RenderPass", Desc, ppRenderPass,
- [&]() //
- {
- RenderPassD3D11Impl* pRenderPassD3D11{NEW_RC_OBJ(m_RenderPassAllocator, "RenderPassD3D11Impl instance", RenderPassD3D11Impl)(this, Desc)};
- pRenderPassD3D11->QueryInterface(IID_RenderPass, reinterpret_cast<IObject**>(ppRenderPass));
- OnCreateDeviceObject(pRenderPassD3D11);
- });
+ CreateRenderPassImpl(ppRenderPass, Desc);
}
void RenderDeviceD3D11Impl::CreateFramebuffer(const FramebufferDesc& Desc, IFramebuffer** ppFramebuffer)
{
- CreateDeviceObject("Framebuffer", Desc, ppFramebuffer,
- [&]() //
- {
- FramebufferD3D11Impl* pFramebufferD3D11{NEW_RC_OBJ(m_FramebufferAllocator, "FramebufferD3D11Impl instance", FramebufferD3D11Impl)(this, Desc)};
- pFramebufferD3D11->QueryInterface(IID_Framebuffer, reinterpret_cast<IObject**>(ppFramebuffer));
- OnCreateDeviceObject(pFramebufferD3D11);
- });
+ CreateFramebufferImpl(ppFramebuffer, Desc);
}
void RenderDeviceD3D11Impl::CreateBLAS(const BottomLevelASDesc& Desc,
@@ -485,6 +403,19 @@ void RenderDeviceD3D11Impl::CreateSBT(const ShaderBindingTableDesc& Desc,
*ppSBT = nullptr;
}
+void RenderDeviceD3D11Impl::CreatePipelineResourceSignature(const PipelineResourceSignatureDesc& Desc,
+ IPipelineResourceSignature** ppSignature)
+{
+ CreatePipelineResourceSignature(Desc, ppSignature, false);
+}
+
+void RenderDeviceD3D11Impl::CreatePipelineResourceSignature(const PipelineResourceSignatureDesc& Desc,
+ IPipelineResourceSignature** ppSignature,
+ bool IsDeviceInternal)
+{
+ CreatePipelineResourceSignatureImpl(ppSignature, Desc, IsDeviceInternal);
+}
+
void RenderDeviceD3D11Impl::IdleGPU()
{
if (auto pImmediateCtx = m_wpImmediateContext.Lock())
diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp
index 05ece281..9191c9ce 100644
--- a/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp
@@ -140,10 +140,6 @@ ShaderD3D11Impl::ShaderD3D11Impl(IReferenceCounters* pRefCounters,
auto* pRawMem = ALLOCATE(Allocator, "Allocator for ShaderResources", ShaderResourcesD3D11, 1);
auto* pResources = new (pRawMem) ShaderResourcesD3D11(pRenderDeviceD3D11, m_pShaderByteCode, m_Desc, ShaderCI.UseCombinedTextureSamplers ? ShaderCI.CombinedSamplerSuffix : nullptr);
m_pShaderResources.reset(pResources, STDDeleterRawMem<ShaderResourcesD3D11>(Allocator));
-
- // Byte code is only required for the vertex shader to create input layout
- if (ShaderCI.Desc.ShaderType != SHADER_TYPE_VERTEX)
- m_pShaderByteCode.Release();
}
ShaderD3D11Impl::~ShaderD3D11Impl()
diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp
index 59c9072b..8bf8f59a 100644
--- a/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp
@@ -26,222 +26,25 @@
*/
#include "pch.h"
+
#include "ShaderResourceBindingD3D11Impl.hpp"
-#include "PipelineStateD3D11Impl.hpp"
-#include "DeviceContextD3D11Impl.hpp"
+
#include "RenderDeviceD3D11Impl.hpp"
-#include "ShaderD3D11Impl.hpp"
-#include "FixedLinearAllocator.hpp"
+#include "PipelineResourceSignatureD3D11Impl.hpp"
namespace Diligent
{
-
-ShaderResourceBindingD3D11Impl::ShaderResourceBindingD3D11Impl(IReferenceCounters* pRefCounters,
- PipelineStateD3D11Impl* pPSO,
- bool IsInternal) :
- // clang-format off
- TBase
- {
- pRefCounters,
- pPSO,
- IsInternal
- },
- m_bIsStaticResourcesBound{false}
-// clang-format on
+ShaderResourceBindingD3D11Impl::ShaderResourceBindingD3D11Impl(IReferenceCounters* pRefCounters,
+ PipelineResourceSignatureD3D11Impl* pPRS) :
+ TBase{pRefCounters, pPRS}
{
- try
- {
- m_ResourceLayoutIndex.fill(-1);
- m_NumActiveShaders = static_cast<Uint8>(pPSO->GetNumShaderStages());
-
- FixedLinearAllocator MemPool{GetRawAllocator()};
- MemPool.AddSpace<ShaderResourceCacheD3D11>(m_NumActiveShaders);
- MemPool.AddSpace<ShaderResourceLayoutD3D11>(m_NumActiveShaders);
-
- MemPool.Reserve();
-
- m_pBoundResourceCaches = MemPool.ConstructArray<ShaderResourceCacheD3D11>(m_NumActiveShaders);
-
- // The memory is now owned by ShaderResourceBindingD3D11Impl and will be freed by Destruct().
- auto* Ptr = MemPool.ReleaseOwnership();
- VERIFY_EXPR(Ptr == m_pBoundResourceCaches);
- (void)Ptr;
-
- m_pResourceLayouts = MemPool.Allocate<ShaderResourceLayoutD3D11>(m_NumActiveShaders);
- for (Uint8 s = 0; s < m_NumActiveShaders; ++s)
- new (m_pResourceLayouts + s) ShaderResourceLayoutD3D11{*this, m_pBoundResourceCaches[s]}; // noexcept
-
- // It is important to construct all objects before initializing them because if an exception is thrown,
- // destructors will be called for all objects
-
- const auto& PSODesc = pPSO->GetDesc();
-
- // Reserve memory for resource layouts
- for (Uint8 s = 0; s < m_NumActiveShaders; ++s)
- {
- auto* pShaderD3D11 = pPSO->GetShader(s);
-
- auto& SRBMemAllocator = pPSO->GetSRBMemoryAllocator();
- auto& ResCacheDataAllocator = SRBMemAllocator.GetResourceCacheDataAllocator(s);
- auto& ResLayoutDataAllocator = SRBMemAllocator.GetShaderVariableDataAllocator(s);
-
- // Initialize resource cache to have enough space to contain all shader resources, including static ones
- // Static resources are copied before resources are committed
- const auto& Resources = *pShaderD3D11->GetD3D11Resources();
- m_pBoundResourceCaches[s].Initialize(Resources, ResCacheDataAllocator);
-
- // Shader resource layout will only contain dynamic and mutable variables
- // http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-cache#Shader-Resource-Cache-Initialization
- SHADER_RESOURCE_VARIABLE_TYPE VarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC};
- m_pResourceLayouts[s].Initialize(
- pShaderD3D11->GetD3D11Resources(),
- PSODesc.ResourceLayout,
- VarTypes,
- _countof(VarTypes),
- ResCacheDataAllocator,
- ResLayoutDataAllocator //
- );
-
- const auto ShaderType = pShaderD3D11->GetDesc().ShaderType;
- const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PSODesc.PipelineType);
- VERIFY_EXPR(ShaderType == m_pResourceLayouts[s].GetShaderType());
- m_ShaderTypes[s] = ShaderType;
-
- m_ResourceLayoutIndex[ShaderInd] = s;
- }
- }
- catch (...)
- {
- Destruct();
- throw;
- }
}
ShaderResourceBindingD3D11Impl::~ShaderResourceBindingD3D11Impl()
{
- Destruct();
-}
-
-void ShaderResourceBindingD3D11Impl::Destruct()
-{
- if (m_pResourceLayouts != nullptr)
- {
- for (Int32 l = 0; l < m_NumActiveShaders; ++l)
- {
- m_pResourceLayouts[l].~ShaderResourceLayoutD3D11();
- }
- }
-
- if (m_pBoundResourceCaches != nullptr)
- {
- auto& SRBMemAllocator = m_pPSO->GetSRBMemoryAllocator();
- for (Uint32 s = 0; s < m_NumActiveShaders; ++s)
- {
- auto& Allocator = SRBMemAllocator.GetResourceCacheDataAllocator(s);
- m_pBoundResourceCaches[s].Destroy(Allocator);
- m_pBoundResourceCaches[s].~ShaderResourceCacheD3D11();
- }
- }
-
- if (void* pRawMem = m_pBoundResourceCaches)
- {
- GetRawAllocator().Free(pRawMem);
- }
}
IMPLEMENT_QUERY_INTERFACE(ShaderResourceBindingD3D11Impl, IID_ShaderResourceBindingD3D11, TBase)
-void ShaderResourceBindingD3D11Impl::BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags)
-{
- for (Uint32 ResLayoutInd = 0; ResLayoutInd < m_NumActiveShaders; ++ResLayoutInd)
- {
- auto& ResLayout = m_pResourceLayouts[ResLayoutInd];
- if (ShaderFlags & ResLayout.GetShaderType())
- {
- ResLayout.BindResources(pResMapping, Flags, m_pBoundResourceCaches[ResLayoutInd]);
- }
- }
-}
-
-void ShaderResourceBindingD3D11Impl::InitializeStaticResources(const IPipelineState* pPipelineState)
-{
- if (m_bIsStaticResourcesBound)
- {
- LOG_WARNING_MESSAGE("Static resources have already been initialized in this shader resource binding object. The operation will be ignored.");
- return;
- }
-
- if (pPipelineState == nullptr)
- {
- pPipelineState = GetPipelineState();
- }
- else
- {
- DEV_CHECK_ERR(pPipelineState->IsCompatibleWith(GetPipelineState()), "The pipeline state is not compatible with this SRB");
- }
-
- const auto* pPSOD3D11 = ValidatedCast<const PipelineStateD3D11Impl>(pPipelineState);
- auto NumShaders = pPSOD3D11->GetNumShaderStages();
- VERIFY_EXPR(NumShaders == m_NumActiveShaders);
-
- for (Uint32 shader = 0; shader < NumShaders; ++shader)
- {
- const auto& StaticResLayout = pPSOD3D11->GetStaticResourceLayout(shader);
- auto* pShaderD3D11 = pPSOD3D11->GetShader(shader);
-#ifdef DILIGENT_DEVELOPMENT
- if (!StaticResLayout.dvpVerifyBindings())
- {
- LOG_ERROR_MESSAGE("Static resources in SRB of PSO '", pPSOD3D11->GetDesc().Name,
- "' will not be successfully initialized because not all static resource bindings in shader '",
- pShaderD3D11->GetDesc().Name,
- "' are valid. Please make sure you bind all static resources to PSO before calling InitializeStaticResources() "
- "directly or indirectly by passing InitStaticResources=true to CreateShaderResourceBinding() method.");
- }
-#endif
-
-#ifdef DILIGENT_DEBUG
- {
- auto ShaderTypeInd = GetShaderTypePipelineIndex(pShaderD3D11->GetDesc().ShaderType, pPSOD3D11->GetDesc().PipelineType);
- auto ResourceLayoutInd = m_ResourceLayoutIndex[ShaderTypeInd];
- VERIFY_EXPR(ResourceLayoutInd == static_cast<Int8>(shader));
- }
-#endif
- StaticResLayout.CopyResources(m_pBoundResourceCaches[shader]);
- pPSOD3D11->SetImmutableSamplers(m_pBoundResourceCaches[shader], shader);
- }
-
- m_bIsStaticResourcesBound = true;
-}
-
-IShaderResourceVariable* ShaderResourceBindingD3D11Impl::GetVariableByName(SHADER_TYPE ShaderType, const char* Name)
-{
- auto ResLayoutInd = GetVariableByNameHelper(ShaderType, Name, m_ResourceLayoutIndex);
- if (ResLayoutInd < 0)
- return nullptr;
-
- VERIFY_EXPR(static_cast<Uint32>(ResLayoutInd) < Uint32{m_NumActiveShaders});
- return m_pResourceLayouts[ResLayoutInd].GetShaderVariable(Name);
-}
-
-Uint32 ShaderResourceBindingD3D11Impl::GetVariableCount(SHADER_TYPE ShaderType) const
-{
- auto ResLayoutInd = GetVariableCountHelper(ShaderType, m_ResourceLayoutIndex);
- if (ResLayoutInd < 0)
- return 0;
-
- VERIFY_EXPR(static_cast<Uint32>(ResLayoutInd) < Uint32{m_NumActiveShaders});
- return m_pResourceLayouts[ResLayoutInd].GetTotalResourceCount();
-}
-
-IShaderResourceVariable* ShaderResourceBindingD3D11Impl::GetVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index)
-{
- auto ResLayoutInd = GetVariableByIndexHelper(ShaderType, Index, m_ResourceLayoutIndex);
- if (ResLayoutInd < 0)
- return nullptr;
-
- VERIFY_EXPR(static_cast<Uint32>(ResLayoutInd) < Uint32{m_NumActiveShaders});
- return m_pResourceLayouts[ResLayoutInd].GetShaderVariable(Index);
-}
-
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceCacheD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceCacheD3D11.cpp
index 9a7a21ba..9985c56d 100755
--- a/Graphics/GraphicsEngineD3D11/src/ShaderResourceCacheD3D11.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceCacheD3D11.cpp
@@ -28,42 +28,33 @@
#include "pch.h"
#include "ShaderResourceCacheD3D11.hpp"
-#include "ShaderResourceLayoutD3D11.hpp"
#include "TextureBaseD3D11.hpp"
#include "BufferD3D11Impl.hpp"
#include "SamplerD3D11Impl.hpp"
+#include "DeviceContextD3D11Impl.hpp"
#include "MemoryAllocator.h"
+#include "Align.hpp"
namespace Diligent
{
-size_t ShaderResourceCacheD3D11::GetRequriedMemorySize(const ShaderResourcesD3D11& Resources)
+size_t ShaderResourceCacheD3D11::GetRequriedMemorySize(const TResourceCount& ResCount)
{
// clang-format off
- auto CBCount = Resources.GetMaxCBBindPoint() + 1;
- auto SRVCount = Resources.GetMaxSRVBindPoint() + 1;
- auto SamplerCount = Resources.GetMaxSamplerBindPoint()+ 1;
- auto UAVCount = Resources.GetMaxUAVBindPoint() + 1;
- auto MemSize =
- (sizeof(CachedCB) + sizeof(ID3D11Buffer*)) * CBCount +
- (sizeof(CachedResource) + sizeof(ID3D11ShaderResourceView*)) * SRVCount +
- (sizeof(CachedSampler) + sizeof(ID3D11SamplerState*)) * SamplerCount +
- (sizeof(CachedResource) + sizeof(ID3D11UnorderedAccessView*)) * UAVCount;
+ auto CBCount = ResCount[DESCRIPTOR_RANGE_CBV];
+ auto SRVCount = ResCount[DESCRIPTOR_RANGE_SRV];
+ auto SamplerCount = ResCount[DESCRIPTOR_RANGE_SAMPLER];
+ auto UAVCount = ResCount[DESCRIPTOR_RANGE_UAV];
+ size_t MemSize = 0;
+ MemSize = Align(MemSize + (sizeof(CachedCB) + sizeof(TBindPointsAndActiveBits) + sizeof(ID3D11Buffer*)) * CBCount, MaxAlignment);
+ MemSize = Align(MemSize + (sizeof(CachedResource) + sizeof(TBindPointsAndActiveBits) + sizeof(ID3D11ShaderResourceView*)) * SRVCount, MaxAlignment);
+ MemSize = Align(MemSize + (sizeof(CachedSampler) + sizeof(TBindPointsAndActiveBits) + sizeof(ID3D11SamplerState*)) * SamplerCount, MaxAlignment);
+ MemSize = Align(MemSize + (sizeof(CachedResource) + sizeof(TBindPointsAndActiveBits) + sizeof(ID3D11UnorderedAccessView*)) * UAVCount, MaxAlignment);
// clang-format on
+ VERIFY(MemSize < InvalidResourceOffset, "Memory size exeed the maximum allowed size.");
return MemSize;
}
-void ShaderResourceCacheD3D11::Initialize(const ShaderResourcesD3D11& Resources, IMemoryAllocator& MemAllocator)
-{
- // clang-format off
- auto CBCount = Resources.GetMaxCBBindPoint() + 1;
- auto SRVCount = Resources.GetMaxSRVBindPoint() + 1;
- auto SamplerCount = Resources.GetMaxSamplerBindPoint()+ 1;
- auto UAVCount = Resources.GetMaxUAVBindPoint() + 1;
- // clang-format on
- Initialize(CBCount, SRVCount, SamplerCount, UAVCount, MemAllocator);
-}
-
-void ShaderResourceCacheD3D11::Initialize(Uint32 CBCount, Uint32 SRVCount, Uint32 SamplerCount, Uint32 UAVCount, IMemoryAllocator& MemAllocator)
+void ShaderResourceCacheD3D11::Initialize(const TResourceCount& ResCount, IMemoryAllocator& MemAllocator)
{
// http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-cache/
if (IsInitialized())
@@ -72,144 +63,164 @@ void ShaderResourceCacheD3D11::Initialize(Uint32 CBCount, Uint32 SRVCount, Uint3
return;
}
+ const Uint32 CBCount = ResCount[DESCRIPTOR_RANGE_CBV];
+ const Uint32 SRVCount = ResCount[DESCRIPTOR_RANGE_SRV];
+ const Uint32 SamplerCount = ResCount[DESCRIPTOR_RANGE_SAMPLER];
+ const Uint32 UAVCount = ResCount[DESCRIPTOR_RANGE_UAV];
+
// clang-format off
- VERIFY(CBCount <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, "Constant buffer count ", CBCount, " exceeds D3D11 limit ", D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT );
- VERIFY(SRVCount <= D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, "SRV count ", SRVCount, " exceeds D3D11 limit ", D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT );
- VERIFY(SamplerCount <= D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, "Sampler count ", SamplerCount, " exceeds D3D11 limit ", D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT );
- VERIFY(UAVCount <= D3D11_PS_CS_UAV_REGISTER_COUNT, "UAV count ", UAVCount, " exceeds D3D11 limit ", D3D11_PS_CS_UAV_REGISTER_COUNT );
+ m_CBCount = static_cast<decltype(m_CBCount )>(CBCount);
+ m_SRVCount = static_cast<decltype(m_SRVCount )>(SRVCount);
+ m_SamplerCount = static_cast<decltype(m_SamplerCount)>(SamplerCount);
+ m_UAVCount = static_cast<decltype(m_UAVCount )>(UAVCount);
- // m_CBOffset = 0
- m_SRVOffset = static_cast<Uint16>(m_CBOffset + CBCount * (sizeof(CachedCB) + sizeof(ID3D11Buffer*)));
- m_SamplerOffset = static_cast<Uint16>(m_SRVOffset + SRVCount * (sizeof(CachedResource) + sizeof(ID3D11ShaderResourceView*)));
- m_UAVOffset = static_cast<Uint16>(m_SamplerOffset + SamplerCount * (sizeof(CachedSampler) + sizeof(ID3D11SamplerState*)));
- m_MemoryEndOffset = static_cast<Uint16>(m_UAVOffset + UAVCount * (sizeof(CachedResource) + sizeof(ID3D11UnorderedAccessView*)));
+ VERIFY(CBCount == m_CBCount, "Constant buffer count (", CBCount, ") exceeds maximum representable value");
+ VERIFY(SRVCount == m_SRVCount, "Shader resources count (", SRVCount, ") exceeds maximum representable value");
+ VERIFY(SamplerCount == m_SamplerCount, "Sampler count (", SamplerCount, ") exceeds maximum representable value");
+ VERIFY(UAVCount == m_UAVCount, "UAVs count (", UAVCount, ") exceeds maximum representable value");
- VERIFY_EXPR(GetCBCount() == static_cast<Uint32>(CBCount));
- VERIFY_EXPR(GetSRVCount() == static_cast<Uint32>(SRVCount));
- VERIFY_EXPR(GetSamplerCount() == static_cast<Uint32>(SamplerCount));
- VERIFY_EXPR(GetUAVCount() == static_cast<Uint32>(UAVCount));
+ // m_CBOffset = 0
+ m_SRVOffset = static_cast<OffsetType>(Align(m_CBOffset + (sizeof(CachedCB) + sizeof(TBindPointsAndActiveBits) + sizeof(ID3D11Buffer*)) * CBCount, MaxAlignment));
+ m_SamplerOffset = static_cast<OffsetType>(Align(m_SRVOffset + (sizeof(CachedResource) + sizeof(TBindPointsAndActiveBits) + sizeof(ID3D11ShaderResourceView*)) * SRVCount, MaxAlignment));
+ m_UAVOffset = static_cast<OffsetType>(Align(m_SamplerOffset + (sizeof(CachedSampler) + sizeof(TBindPointsAndActiveBits) + sizeof(ID3D11SamplerState*)) * SamplerCount, MaxAlignment));
+ size_t BufferSize = static_cast<OffsetType>(Align(m_UAVOffset + (sizeof(CachedResource) + sizeof(TBindPointsAndActiveBits) + sizeof(ID3D11UnorderedAccessView*)) * UAVCount, MaxAlignment));
+ // clang-format on
VERIFY_EXPR(m_pResourceData == nullptr);
- size_t BufferSize = m_MemoryEndOffset;
-
- VERIFY_EXPR( BufferSize ==
- (sizeof(CachedCB) + sizeof(ID3D11Buffer*)) * CBCount +
- (sizeof(CachedResource) + sizeof(ID3D11ShaderResourceView*)) * SRVCount +
- (sizeof(CachedSampler) + sizeof(ID3D11SamplerState*)) * SamplerCount +
- (sizeof(CachedResource) + sizeof(ID3D11UnorderedAccessView*)) * UAVCount );
- // clang-format on
+ VERIFY_EXPR(BufferSize == GetRequriedMemorySize(ResCount));
-#ifdef DILIGENT_DEBUG
- m_pdbgMemoryAllocator = &MemAllocator;
-#endif
if (BufferSize > 0)
{
m_pResourceData = ALLOCATE(MemAllocator, "Shader resource cache data buffer", Uint8, BufferSize);
memset(m_pResourceData, 0, BufferSize);
+ m_pAllocator = &MemAllocator;
}
+ const TBindPointsAndActiveBits InvalidBindPoints = {0, InvalidBindPoint, InvalidBindPoint, InvalidBindPoint, InvalidBindPoint, InvalidBindPoint, InvalidBindPoint};
+
// Explicitly construct all objects
if (CBCount != 0)
{
- CachedCB* CBs = nullptr;
- ID3D11Buffer** d3d11CBs = nullptr;
- GetCBArrays(CBs, d3d11CBs);
+ CachedCB* CBs = nullptr;
+ ID3D11Buffer** d3d11CBs = nullptr;
+ TBindPointsAndActiveBits* bindPoints = nullptr;
+ GetCBArrays(CBs, d3d11CBs, bindPoints);
for (Uint32 cb = 0; cb < CBCount; ++cb)
- new (CBs + cb) CachedCB;
+ {
+ new (CBs + cb) CachedCB{};
+ bindPoints[cb] = InvalidBindPoints;
+ }
}
if (SRVCount != 0)
{
CachedResource* SRVResources = nullptr;
ID3D11ShaderResourceView** d3d11SRVs = nullptr;
- GetSRVArrays(SRVResources, d3d11SRVs);
+ TBindPointsAndActiveBits* bindPoints = nullptr;
+ GetSRVArrays(SRVResources, d3d11SRVs, bindPoints);
for (Uint32 srv = 0; srv < SRVCount; ++srv)
- new (SRVResources + srv) CachedResource;
+ {
+ new (SRVResources + srv) CachedResource{};
+ bindPoints[srv] = InvalidBindPoints;
+ }
}
if (SamplerCount != 0)
{
- CachedSampler* Samplers = nullptr;
- ID3D11SamplerState** d3d11Samplers = nullptr;
- GetSamplerArrays(Samplers, d3d11Samplers);
+ CachedSampler* Samplers = nullptr;
+ ID3D11SamplerState** d3d11Samplers = nullptr;
+ TBindPointsAndActiveBits* bindPoints = nullptr;
+ GetSamplerArrays(Samplers, d3d11Samplers, bindPoints);
for (Uint32 sam = 0; sam < SamplerCount; ++sam)
- new (Samplers + sam) CachedSampler;
+ {
+ new (Samplers + sam) CachedSampler{};
+ bindPoints[sam] = InvalidBindPoints;
+ }
}
if (UAVCount != 0)
{
CachedResource* UAVResources = nullptr;
ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
- GetUAVArrays(UAVResources, d3d11UAVs);
+ TBindPointsAndActiveBits* bindPoints = nullptr;
+ GetUAVArrays(UAVResources, d3d11UAVs, bindPoints);
for (Uint32 uav = 0; uav < UAVCount; ++uav)
- new (UAVResources + uav) CachedResource;
+ {
+ new (UAVResources + uav) CachedResource{};
+ bindPoints[uav] = InvalidBindPoints;
+ }
}
}
-void ShaderResourceCacheD3D11::Destroy(IMemoryAllocator& MemAllocator)
+ShaderResourceCacheD3D11::~ShaderResourceCacheD3D11()
{
- if (!IsInitialized())
- return;
-
- VERIFY(m_pdbgMemoryAllocator == &MemAllocator, "The allocator does not match the one used to create resources");
-
- // Explicitly destory all objects
- auto CBCount = GetCBCount();
- if (CBCount != 0)
+ if (IsInitialized())
{
- CachedCB* CBs = nullptr;
- ID3D11Buffer** d3d11CBs = nullptr;
- GetCBArrays(CBs, d3d11CBs);
- for (size_t cb = 0; cb < CBCount; ++cb)
- CBs[cb].~CachedCB();
- }
+ // Explicitly destory all objects
+ auto CBCount = GetCBCount();
+ if (CBCount != 0)
+ {
+ CachedCB* CBs = nullptr;
+ ID3D11Buffer** d3d11CBs = nullptr;
+ TBindPointsAndActiveBits* bindPoints = nullptr;
+ GetCBArrays(CBs, d3d11CBs, bindPoints);
+ for (size_t cb = 0; cb < CBCount; ++cb)
+ CBs[cb].~CachedCB();
+ }
- auto SRVCount = GetSRVCount();
- if (SRVCount != 0)
- {
- CachedResource* SRVResources = nullptr;
- ID3D11ShaderResourceView** d3d11SRVs = nullptr;
- GetSRVArrays(SRVResources, d3d11SRVs);
- for (size_t srv = 0; srv < SRVCount; ++srv)
- SRVResources[srv].~CachedResource();
- }
+ auto SRVCount = GetSRVCount();
+ if (SRVCount != 0)
+ {
+ CachedResource* SRVResources = nullptr;
+ ID3D11ShaderResourceView** d3d11SRVs = nullptr;
+ TBindPointsAndActiveBits* bindPoints = nullptr;
+ GetSRVArrays(SRVResources, d3d11SRVs, bindPoints);
+ for (size_t srv = 0; srv < SRVCount; ++srv)
+ SRVResources[srv].~CachedResource();
+ }
- auto SamplerCount = GetSamplerCount();
- if (SamplerCount != 0)
- {
- CachedSampler* Samplers = nullptr;
- ID3D11SamplerState** d3d11Samplers = nullptr;
- GetSamplerArrays(Samplers, d3d11Samplers);
- for (size_t sam = 0; sam < SamplerCount; ++sam)
- Samplers[sam].~CachedSampler();
- }
+ auto SamplerCount = GetSamplerCount();
+ if (SamplerCount != 0)
+ {
+ CachedSampler* Samplers = nullptr;
+ ID3D11SamplerState** d3d11Samplers = nullptr;
+ TBindPointsAndActiveBits* bindPoints = nullptr;
+ GetSamplerArrays(Samplers, d3d11Samplers, bindPoints);
+ for (size_t sam = 0; sam < SamplerCount; ++sam)
+ Samplers[sam].~CachedSampler();
+ }
- auto UAVCount = GetUAVCount();
- if (UAVCount != 0)
- {
- CachedResource* UAVResources = nullptr;
- ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
- GetUAVArrays(UAVResources, d3d11UAVs);
- for (size_t uav = 0; uav < UAVCount; ++uav)
- UAVResources[uav].~CachedResource();
- }
+ auto UAVCount = GetUAVCount();
+ if (UAVCount != 0)
+ {
+ CachedResource* UAVResources = nullptr;
+ ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
+ TBindPointsAndActiveBits* bindPoints = nullptr;
+ GetUAVArrays(UAVResources, d3d11UAVs, bindPoints);
+ for (size_t uav = 0; uav < UAVCount; ++uav)
+ UAVResources[uav].~CachedResource();
+ }
- m_SRVOffset = InvalidResourceOffset;
- m_SamplerOffset = InvalidResourceOffset;
- m_UAVOffset = InvalidResourceOffset;
- m_MemoryEndOffset = InvalidResourceOffset;
+ m_SRVOffset = InvalidResourceOffset;
+ m_SamplerOffset = InvalidResourceOffset;
+ m_UAVOffset = InvalidResourceOffset;
+ m_CBCount = 0;
+ m_SRVCount = 0;
+ m_SamplerCount = 0;
+ m_UAVCount = 0;
- if (m_pResourceData != nullptr)
- MemAllocator.Free(m_pResourceData);
- m_pResourceData = nullptr;
-}
+ if (m_pResourceData != nullptr)
+ m_pAllocator->Free(m_pResourceData);
-ShaderResourceCacheD3D11::~ShaderResourceCacheD3D11()
-{
- VERIFY(!IsInitialized(), "Shader resource cache memory must be released with ShaderResourceCacheD3D11::Destroy()");
+ m_pResourceData = nullptr;
+ m_pAllocator = nullptr;
+ }
}
-void dbgVerifyResource(ShaderResourceCacheD3D11::CachedResource& Res, ID3D11View* pd3d11View, const char* ViewType)
+#ifdef DILIGENT_DEVELOPMENT
+namespace
+{
+void DvpVerifyResource(ShaderResourceCacheD3D11::CachedResource& Res, ID3D11View* pd3d11View, const char* ViewType)
{
if (pd3d11View != nullptr)
{
@@ -251,8 +262,9 @@ void dbgVerifyResource(ShaderResourceCacheD3D11::CachedResource& Res, ID3D11View
VERIFY(Res.pd3d11Resource == nullptr, "Unexepected D3D11 resource");
}
}
+} // namespace
-void ShaderResourceCacheD3D11::dbgVerifyCacheConsistency()
+void ShaderResourceCacheD3D11::DvpVerifyCacheConsistency()
{
VERIFY(IsInitialized(), "Cache is not initialized");
@@ -264,11 +276,12 @@ void ShaderResourceCacheD3D11::dbgVerifyCacheConsistency()
ID3D11SamplerState** d3d11Samplers = nullptr;
CachedResource* UAVResources = nullptr;
ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
+ TBindPointsAndActiveBits* bindPoints = nullptr;
- GetCBArrays(CBs, d3d11CBs);
- GetSRVArrays(SRVResources, d3d11SRVs);
- GetSamplerArrays(Samplers, d3d11Samplers);
- GetUAVArrays(UAVResources, d3d11UAVs);
+ GetCBArrays(CBs, d3d11CBs, bindPoints);
+ GetSRVArrays(SRVResources, d3d11SRVs, bindPoints);
+ GetSamplerArrays(Samplers, d3d11Samplers, bindPoints);
+ GetUAVArrays(UAVResources, d3d11UAVs, bindPoints);
auto CBCount = GetCBCount();
for (size_t cb = 0; cb < CBCount; ++cb)
@@ -287,7 +300,7 @@ void ShaderResourceCacheD3D11::dbgVerifyCacheConsistency()
{
auto& Res = SRVResources[srv];
auto* pd3d11SRV = d3d11SRVs[srv];
- dbgVerifyResource(Res, pd3d11SRV, "SRV");
+ DvpVerifyResource(Res, pd3d11SRV, "SRV");
}
auto UAVCount = GetUAVCount();
@@ -295,7 +308,7 @@ void ShaderResourceCacheD3D11::dbgVerifyCacheConsistency()
{
auto& Res = UAVResources[uav];
auto* pd3d11UAV = d3d11UAVs[uav];
- dbgVerifyResource(Res, pd3d11UAV, "UAV");
+ DvpVerifyResource(Res, pd3d11UAV, "UAV");
}
auto SamplerCount = GetSamplerCount();
@@ -310,4 +323,393 @@ void ShaderResourceCacheD3D11::dbgVerifyCacheConsistency()
}
}
}
+#endif
+
+template <typename THandleResource>
+void ShaderResourceCacheD3D11::ProcessResources(THandleResource HandleResources)
+{
+ {
+ ShaderResourceCacheD3D11::CachedCB* CachedCBs;
+ ID3D11Buffer** d3d11CBs;
+ TBindPointsAndActiveBits* bindPoints;
+ GetCBArrays(CachedCBs, d3d11CBs, bindPoints);
+ HandleResources(GetCBCount(), CachedCBs, d3d11CBs);
+ }
+ {
+ ShaderResourceCacheD3D11::CachedResource* CachedSRVResources;
+ ID3D11ShaderResourceView** d3d11SRVs;
+ TBindPointsAndActiveBits* bindPoints;
+ GetSRVArrays(CachedSRVResources, d3d11SRVs, bindPoints);
+ HandleResources(GetSRVCount(), CachedSRVResources, d3d11SRVs);
+ }
+ {
+ ShaderResourceCacheD3D11::CachedSampler* CachedSamplers;
+ ID3D11SamplerState** d3d11Samplers;
+ TBindPointsAndActiveBits* bindPoints;
+ GetSamplerArrays(CachedSamplers, d3d11Samplers, bindPoints);
+ HandleResources(GetSamplerCount(), CachedSamplers, d3d11Samplers);
+ }
+ {
+ ShaderResourceCacheD3D11::CachedResource* CachedUAVResources;
+ ID3D11UnorderedAccessView** d3d11UAVs;
+ TBindPointsAndActiveBits* bindPoints;
+ GetUAVArrays(CachedUAVResources, d3d11UAVs, bindPoints);
+ HandleResources(GetUAVCount(), CachedUAVResources, d3d11UAVs);
+ }
+}
+
+void ShaderResourceCacheD3D11::TransitionResourceStates(DeviceContextD3D11Impl& Ctx, StateTransitionMode Mode)
+{
+ VERIFY_EXPR(IsInitialized());
+
+ switch (Mode)
+ {
+ case StateTransitionMode::Transition:
+ {
+ ProcessResources([&](Uint32 Count, auto* Resources, auto* Views) { TransitionResource(Ctx, Count, Resources, Views); });
+ break;
+ }
+ case StateTransitionMode::Verify:
+ {
+#ifdef DILIGENT_DEVELOPMENT
+ ProcessResources([&](Uint32 Count, auto* Resources, auto* Views) { DvpVerifyResourceState(Ctx, Count, Resources, Views); });
+#endif
+ break;
+ }
+ default:
+ UNEXPECTED("Unexpected mode");
+ }
+}
+
+void ShaderResourceCacheD3D11::TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedCB* CBs, ID3D11Buffer** pd3d11CBs)
+{
+ for (Uint32 i = 0; i < Count; ++i)
+ {
+ if (auto* pBuffer = CBs[i].pBuff.RawPtr<BufferD3D11Impl>())
+ {
+ if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_CONSTANT_BUFFER))
+ { /*
+ if (pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
+ {
+ // Even though we have unbound resources from UAV, we only checked shader
+ // stages active in current PSO, so we still may need to unbind the resource
+ // from UAV (for instance, unbind resource from CS UAV when running draw command).
+ Ctx.UnbindResourceFromUAV(pBuffer, pd3d11CBs[i]);
+ pBuffer->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
+ }
+ pBuffer->AddState(RESOURCE_STATE_CONSTANT_BUFFER);*/
+ Ctx.TransitionResource(pBuffer, RESOURCE_STATE_CONSTANT_BUFFER);
+ }
+ }
+ }
+}
+
+void ShaderResourceCacheD3D11::TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedResource* SRVResources, ID3D11ShaderResourceView** d3d11SRVs)
+{
+ for (Uint32 i = 0; i < Count; ++i)
+ {
+ auto& SRVRes = SRVResources[i];
+ if (auto* pTexture = SRVRes.pTexture)
+ {
+ if (pTexture->IsInKnownState() && !pTexture->CheckAnyState(RESOURCE_STATE_SHADER_RESOURCE | RESOURCE_STATE_INPUT_ATTACHMENT))
+ { /*
+ if (pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
+ {
+ // Even though we have unbound resources from UAV, we only checked shader
+ // stages active in current PSO, so we still may need to unbind the resource
+ // from UAV (for instance, unbind resource from CS UAV when running draw command).
+ Ctx.UnbindResourceFromUAV(pTexture, SRVRes.pd3d11Resource);
+ pTexture->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
+ }
+
+ if (pTexture->CheckState(RESOURCE_STATE_RENDER_TARGET))
+ Ctx.UnbindTextureFromRenderTarget(pTexture);
+
+ if (pTexture->CheckState(RESOURCE_STATE_DEPTH_WRITE))
+ Ctx.UnbindTextureFromDepthStencil(pTexture);
+
+ pTexture->SetState(RESOURCE_STATE_SHADER_RESOURCE);*/
+ Ctx.TransitionResource(pTexture, RESOURCE_STATE_SHADER_RESOURCE);
+ }
+ }
+ else if (auto* pBuffer = SRVRes.pBuffer)
+ {
+ if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_SHADER_RESOURCE))
+ { /*
+ if (pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
+ {
+ Ctx.UnbindResourceFromUAV(pBuffer, SRVRes.pd3d11Resource);
+ pBuffer->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
+ }
+ pBuffer->AddState(RESOURCE_STATE_SHADER_RESOURCE);*/
+ Ctx.TransitionResource(pBuffer, RESOURCE_STATE_SHADER_RESOURCE);
+ }
+ }
+ }
+}
+
+void ShaderResourceCacheD3D11::TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedSampler* Samplers, ID3D11SamplerState** pd3d11Samplers)
+{
+}
+
+void ShaderResourceCacheD3D11::TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedResource* UAVResources, ID3D11UnorderedAccessView** pd3d11UAVs)
+{
+ for (Uint32 i = 0; i < Count; ++i)
+ {
+ auto& UAVRes = UAVResources[i];
+ if (auto* pTexture = UAVRes.pTexture)
+ {
+ if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
+ { /*
+ if (pTexture->CheckAnyState(RESOURCE_STATE_SHADER_RESOURCE | RESOURCE_STATE_INPUT_ATTACHMENT))
+ Ctx.UnbindTextureFromInput(pTexture, UAVRes.pd3d11Resource);
+ pTexture->SetState(RESOURCE_STATE_UNORDERED_ACCESS);*/
+ Ctx.TransitionResource(pTexture, RESOURCE_STATE_UNORDERED_ACCESS);
+ }
+ }
+ else if (auto* pBuffer = UAVRes.pBuffer)
+ {
+ if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
+ { /*
+ if ((pBuffer->GetState() & RESOURCE_STATE_GENERIC_READ) != 0)
+ Ctx.UnbindBufferFromInput(pBuffer, UAVRes.pd3d11Resource);
+ pBuffer->SetState(RESOURCE_STATE_UNORDERED_ACCESS);*/
+ Ctx.TransitionResource(pBuffer, RESOURCE_STATE_UNORDERED_ACCESS);
+ }
+ }
+ }
+}
+
+#ifdef DILIGENT_DEVELOPMENT
+void ShaderResourceCacheD3D11::DvpVerifyResourceState(DeviceContextD3D11Impl&, Uint32 Count, const CachedCB* CBs, ID3D11Buffer**)
+{
+ for (Uint32 i = 0; i < Count; ++i)
+ {
+ if (const auto* pBuff = CBs[i].pBuff.RawPtr<BufferD3D11Impl>())
+ {
+ if (pBuff->IsInKnownState() && !pBuff->CheckState(RESOURCE_STATE_CONSTANT_BUFFER))
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBuff->GetDesc().Name, "' has not been transitioned to Constant Buffer state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
+ }
+ }
+ }
+}
+
+void ShaderResourceCacheD3D11::DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedResource* SRVResources, ID3D11ShaderResourceView**)
+{
+ for (Uint32 i = 0; i < Count; ++i)
+ {
+ auto& SRVRes = SRVResources[i];
+ if (const auto* pTexture = SRVRes.pTexture)
+ {
+ if (pTexture->IsInKnownState() &&
+ !(pTexture->CheckState(RESOURCE_STATE_SHADER_RESOURCE) || Ctx.HasActiveRenderPass() && pTexture->CheckState(RESOURCE_STATE_INPUT_ATTACHMENT)))
+ {
+ LOG_ERROR_MESSAGE("Texture '", pTexture->GetDesc().Name, "' has not been transitioned to Shader Resource state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the texture to required state.");
+ }
+ }
+ else if (const auto* pBuffer = SRVRes.pBuffer)
+ {
+ if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_SHADER_RESOURCE))
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name, "' has not been transitioned to Shader Resource state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
+ }
+ }
+ }
+}
+
+void ShaderResourceCacheD3D11::DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedSampler* Samplers, ID3D11SamplerState**)
+{
+}
+
+void ShaderResourceCacheD3D11::DvpVerifyResourceState(DeviceContextD3D11Impl&, Uint32 Count, const CachedResource* UAVResources, ID3D11UnorderedAccessView**)
+{
+ for (Uint32 i = 0; i < Count; ++i)
+ {
+ auto& UAVRes = UAVResources[i];
+ if (const auto* pTexture = UAVRes.pTexture)
+ {
+ if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
+ {
+ LOG_ERROR_MESSAGE("Texture '", pTexture->GetDesc().Name, "' has not been transitioned to Unordered Access state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the texture to required state.");
+ }
+ }
+ else if (const auto* pBuffer = UAVRes.pBuffer)
+ {
+ if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name, "' has not been transitioned to Unordered Access state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
+ }
+ }
+ }
+}
+#endif // DILIGENT_DEVELOPMENT
+
+void ShaderResourceCacheD3D11::BindResources(DeviceContextD3D11Impl& Ctx, const TBindingsPerStage& BaseBindings, TMinMaxSlotPerStage& MinMaxSlot, TCommittedResources& CommittedRes, SHADER_TYPE ActiveStages) const
+{
+ const auto CBCount = GetCBCount();
+ if (CBCount != 0)
+ {
+ const auto Range = DESCRIPTOR_RANGE_CBV;
+ ShaderResourceCacheD3D11::CachedCB const* CBs;
+ ID3D11Buffer* const* d3d11CBs;
+ TBindPointsAndActiveBits const* bindPoints;
+ GetConstCBArrays(CBs, d3d11CBs, bindPoints);
+
+ for (Uint32 cb = 0; cb < CBCount; ++cb)
+ {
+ Uint32 ActiveBits = bindPoints[cb][0] & ActiveStages;
+ const auto* BindPoints = &bindPoints[cb][1];
+ VERIFY(ActiveBits != 0, "resource is not initialized");
+ while (ActiveBits != 0)
+ {
+ const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
+ ActiveBits &= ~(1u << ShaderInd);
+ VERIFY_EXPR(BindPoints[ShaderInd] != InvalidBindPoint);
+
+ auto* CommittedD3D11CBs = CommittedRes.D3D11CBs[ShaderInd];
+ UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
+ UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
+ const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
+ const bool IsNewCB = CommittedD3D11CBs[Slot] != d3d11CBs[cb];
+ MinSlot = IsNewCB ? std::min(MinSlot, Slot) : MinSlot;
+ MaxSlot = IsNewCB ? Slot : MaxSlot;
+
+ VERIFY_EXPR(!IsNewCB || (Slot >= MinSlot && Slot <= MaxSlot));
+ VERIFY_EXPR(d3d11CBs[cb] != nullptr);
+ CommittedD3D11CBs[Slot] = d3d11CBs[cb];
+ }
+ }
+ }
+
+ const auto SRVCount = GetSRVCount();
+ if (SRVCount != 0)
+ {
+ const auto Range = DESCRIPTOR_RANGE_SRV;
+ ShaderResourceCacheD3D11::CachedResource const* SRVResources;
+ ID3D11ShaderResourceView* const* d3d11SRVs;
+ TBindPointsAndActiveBits const* bindPoints;
+ GetConstSRVArrays(SRVResources, d3d11SRVs, bindPoints);
+
+ for (Uint32 srv = 0; srv < SRVCount; ++srv)
+ {
+ Uint32 ActiveBits = bindPoints[srv][0] & ActiveStages;
+ const auto* BindPoints = &bindPoints[srv][1];
+ VERIFY(ActiveBits != 0, "resource is not initialized");
+ while (ActiveBits != 0)
+ {
+ const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
+ ActiveBits &= ~(1u << ShaderInd);
+ VERIFY_EXPR(BindPoints[ShaderInd] != InvalidBindPoint);
+
+ auto* CommittedD3D11SRVs = CommittedRes.D3D11SRVs[ShaderInd];
+ auto* CommittedD3D11SRVRes = CommittedRes.D3D11SRVResources[ShaderInd];
+ UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
+ UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
+ const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
+ const bool IsNewSRV = CommittedD3D11SRVs[Slot] != d3d11SRVs[srv];
+ MinSlot = IsNewSRV ? std::min(MinSlot, Slot) : MinSlot;
+ MaxSlot = IsNewSRV ? Slot : MaxSlot;
+
+ VERIFY_EXPR(!IsNewSRV || (Slot >= MinSlot && Slot <= MaxSlot));
+ VERIFY_EXPR(d3d11SRVs[srv] != nullptr);
+ CommittedD3D11SRVRes[Slot] = SRVResources[srv].pd3d11Resource;
+ CommittedD3D11SRVs[Slot] = d3d11SRVs[srv];
+ }
+ }
+ }
+
+ const auto SamplerCount = GetSamplerCount();
+ if (SamplerCount != 0)
+ {
+ const auto Range = DESCRIPTOR_RANGE_SAMPLER;
+ ShaderResourceCacheD3D11::CachedSampler const* Samplers;
+ ID3D11SamplerState* const* d3d11Samplers;
+ TBindPointsAndActiveBits const* bindPoints;
+ GetConstSamplerArrays(Samplers, d3d11Samplers, bindPoints);
+
+ for (Uint32 sam = 0; sam < SamplerCount; ++sam)
+ {
+ Uint32 ActiveBits = bindPoints[sam][0] & ActiveStages;
+ const auto* BindPoints = &bindPoints[sam][1];
+ VERIFY(ActiveBits != 0, "resource is not initialized");
+ while (ActiveBits != 0)
+ {
+ const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
+ ActiveBits &= ~(1u << ShaderInd);
+ VERIFY_EXPR(BindPoints[ShaderInd] != InvalidBindPoint);
+
+ auto* CommittedD3D11Samplers = CommittedRes.D3D11Samplers[ShaderInd];
+ UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
+ UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
+ const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
+ const bool IsNewSam = CommittedD3D11Samplers[Slot] != d3d11Samplers[sam];
+ MinSlot = IsNewSam ? std::min(MinSlot, Slot) : MinSlot;
+ MaxSlot = IsNewSam ? Slot : MaxSlot;
+
+ VERIFY_EXPR(!IsNewSam || (Slot >= MinSlot && Slot <= MaxSlot));
+ VERIFY_EXPR(d3d11Samplers[sam] != nullptr);
+ CommittedD3D11Samplers[Slot] = d3d11Samplers[sam];
+ }
+ }
+ }
+
+ const auto UAVCount = GetUAVCount();
+ if (UAVCount != 0)
+ {
+ const auto Range = DESCRIPTOR_RANGE_UAV;
+ ShaderResourceCacheD3D11::CachedResource const* UAVResources;
+ ID3D11UnorderedAccessView* const* d3d11UAVs;
+ TBindPointsAndActiveBits const* bindPoints;
+ GetConstUAVArrays(UAVResources, d3d11UAVs, bindPoints);
+
+ for (Uint32 uav = 0; uav < UAVCount; ++uav)
+ {
+ Uint32 ActiveBits = bindPoints[uav][0] & ActiveStages;
+ const auto* BindPoints = &bindPoints[uav][1];
+ VERIFY(ActiveBits != 0, "resource is not initialized");
+ while (ActiveBits != 0)
+ {
+ const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
+ ActiveBits &= ~(1u << ShaderInd);
+ VERIFY_EXPR(BindPoints[ShaderInd] != InvalidBindPoint);
+
+ auto* CommittedD3D11UAVs = CommittedRes.D3D11UAVs[ShaderInd];
+ auto* CommittedD3D11UAVRes = CommittedRes.D3D11UAVResources[ShaderInd];
+ UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
+ UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
+ const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
+ const bool IsNewUAV = CommittedD3D11UAVs[Slot] != d3d11UAVs[uav];
+ MinSlot = IsNewUAV ? std::min(MinSlot, Slot) : MinSlot;
+ MaxSlot = IsNewUAV ? Slot : MaxSlot;
+
+ VERIFY_EXPR(!IsNewUAV || (Slot >= MinSlot && Slot <= MaxSlot));
+ VERIFY_EXPR(d3d11UAVs[uav] != nullptr);
+ CommittedD3D11UAVRes[Slot] = UAVResources[uav].pd3d11Resource;
+ CommittedD3D11UAVs[Slot] = d3d11UAVs[uav];
+ }
+ }
+ }
+}
+
+void ShaderResourceCacheD3D11::TCommittedResources::Clear()
+{
+ for (int ShaderType = 0; ShaderType < NumShaderTypes; ++ShaderType)
+ {
+ // clang-format off
+ memset(D3D11CBs[ShaderType], 0, sizeof(D3D11CBs[ShaderType][0]) * NumCBs[ShaderType]);
+ memset(D3D11SRVs[ShaderType], 0, sizeof(D3D11SRVs[ShaderType][0]) * NumSRVs[ShaderType]);
+ memset(D3D11Samplers[ShaderType], 0, sizeof(D3D11Samplers[ShaderType][0]) * NumSamplers[ShaderType]);
+ memset(D3D11UAVs[ShaderType], 0, sizeof(D3D11UAVs[ShaderType][0]) * NumUAVs[ShaderType]);
+ memset(D3D11SRVResources[ShaderType], 0, sizeof(D3D11SRVResources[ShaderType][0]) * NumSRVs[ShaderType]);
+ memset(D3D11UAVResources[ShaderType], 0, sizeof(D3D11UAVResources[ShaderType][0]) * NumUAVs[ShaderType]);
+ // clang-format on
+
+ NumCBs[ShaderType] = 0;
+ NumSRVs[ShaderType] = 0;
+ NumSamplers[ShaderType] = 0;
+ NumUAVs[ShaderType] = 0;
+ }
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp
deleted file mode 100755
index 6e577314..00000000
--- a/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp
+++ /dev/null
@@ -1,1022 +0,0 @@
-/*
- * Copyright 2019-2021 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 <d3dcompiler.h>
-
-#include "ShaderResourceLayoutD3D11.hpp"
-#include "ShaderResourceCacheD3D11.hpp"
-#include "BufferD3D11Impl.hpp"
-#include "BufferViewD3D11Impl.hpp"
-#include "TextureBaseD3D11.hpp"
-#include "TextureViewD3D11.h"
-#include "SamplerD3D11Impl.hpp"
-#include "ShaderD3D11Impl.hpp"
-#include "ShaderResourceVariableBase.hpp"
-
-namespace Diligent
-{
-
-
-ShaderResourceLayoutD3D11::~ShaderResourceLayoutD3D11()
-{
- // clang-format off
- HandleResources(
- [&](ConstBuffBindInfo& cb)
- {
- cb.~ConstBuffBindInfo();
- },
-
- [&](TexSRVBindInfo& ts)
- {
- ts.~TexSRVBindInfo();
- },
-
- [&](TexUAVBindInfo& uav)
- {
- uav.~TexUAVBindInfo();
- },
-
- [&](BuffSRVBindInfo& srv)
- {
- srv.~BuffSRVBindInfo();
- },
-
- [&](BuffUAVBindInfo& uav)
- {
- uav.~BuffUAVBindInfo();
- },
-
- [&](SamplerBindInfo& sam)
- {
- sam.~SamplerBindInfo();
- }
- );
- // clang-format on
-}
-
-
-size_t ShaderResourceLayoutD3D11::GetRequiredMemorySize(const ShaderResourcesD3D11& SrcResources,
- const PipelineResourceLayoutDesc& ResourceLayout,
- const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
- Uint32 NumAllowedTypes) noexcept
-{
- // Skip immutable samplers as they are initialized directly in the resource cache by the PSO
- constexpr bool CountImtblSamplers = false;
- auto ResCounters = SrcResources.CountResources(ResourceLayout, AllowedVarTypes, NumAllowedTypes, CountImtblSamplers);
- // clang-format off
- auto MemSize = ResCounters.NumCBs * sizeof(ConstBuffBindInfo) +
- ResCounters.NumTexSRVs * sizeof(TexSRVBindInfo) +
- ResCounters.NumTexUAVs * sizeof(TexUAVBindInfo) +
- ResCounters.NumBufSRVs * sizeof(BuffSRVBindInfo) +
- ResCounters.NumBufUAVs * sizeof(BuffUAVBindInfo) +
- ResCounters.NumSamplers * sizeof(SamplerBindInfo);
- // clang-format on
- return MemSize;
-}
-
-
-void ShaderResourceLayoutD3D11::Initialize(std::shared_ptr<const ShaderResourcesD3D11> pSrcResources,
- const PipelineResourceLayoutDesc& ResourceLayout,
- const SHADER_RESOURCE_VARIABLE_TYPE* VarTypes,
- Uint32 NumVarTypes,
- IMemoryAllocator& ResCacheDataAllocator,
- IMemoryAllocator& ResLayoutDataAllocator)
-{
- m_pResources = std::move(pSrcResources);
-
- // http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-layout#Shader-Resource-Layout-Initialization
-
- const auto AllowedTypeBits = GetAllowedTypeBits(VarTypes, NumVarTypes);
-
- // Count total number of resources of allowed types
- // Skip immutable samplers as they are initialized directly in the resource cache by the PSO
- constexpr bool CountImtblSamplers = false;
- auto ResCounters = m_pResources->CountResources(ResourceLayout, VarTypes, NumVarTypes, CountImtblSamplers);
-
- // Initialize offsets
- size_t CurrentOffset = 0;
-
- auto AdvanceOffset = [&CurrentOffset](size_t NumBytes) //
- {
- constexpr size_t MaxOffset = std::numeric_limits<OffsetType>::max();
- VERIFY(CurrentOffset <= MaxOffset, "Current offser (", CurrentOffset, ") exceeds max allowed value (", MaxOffset, ")");
- auto Offset = static_cast<OffsetType>(CurrentOffset);
- CurrentOffset += NumBytes;
- return Offset;
- };
-
- // clang-format off
- auto CBOffset = AdvanceOffset(ResCounters.NumCBs * sizeof(ConstBuffBindInfo)); (void)CBOffset; // To suppress warning
- m_TexSRVsOffset = AdvanceOffset(ResCounters.NumTexSRVs * sizeof(TexSRVBindInfo) );
- m_TexUAVsOffset = AdvanceOffset(ResCounters.NumTexUAVs * sizeof(TexUAVBindInfo) );
- m_BuffSRVsOffset = AdvanceOffset(ResCounters.NumBufSRVs * sizeof(BuffSRVBindInfo) );
- m_BuffUAVsOffset = AdvanceOffset(ResCounters.NumBufUAVs * sizeof(BuffUAVBindInfo) );
- m_SamplerOffset = AdvanceOffset(ResCounters.NumSamplers * sizeof(SamplerBindInfo) );
- m_MemorySize = AdvanceOffset(0);
- // clang-format on
-
- VERIFY_EXPR(m_MemorySize == GetRequiredMemorySize(*m_pResources, ResourceLayout, VarTypes, NumVarTypes));
-
- if (m_MemorySize)
- {
- auto* pRawMem = ALLOCATE_RAW(ResLayoutDataAllocator, "Raw memory buffer for shader resource layout resources", m_MemorySize);
- m_ResourceBuffer = std::unique_ptr<void, STDDeleterRawMem<void>>(pRawMem, ResLayoutDataAllocator);
- }
-
- // clang-format off
- VERIFY_EXPR(ResCounters.NumCBs == GetNumCBs() );
- VERIFY_EXPR(ResCounters.NumTexSRVs == GetNumTexSRVs() );
- VERIFY_EXPR(ResCounters.NumTexUAVs == GetNumTexUAVs() );
- VERIFY_EXPR(ResCounters.NumBufSRVs == GetNumBufSRVs() );
- VERIFY_EXPR(ResCounters.NumBufUAVs == GetNumBufUAVs() );
- VERIFY_EXPR(ResCounters.NumSamplers== GetNumSamplers());
- // clang-format on
-
- // Current resource index for every resource type
- Uint32 cb = 0;
- Uint32 texSrv = 0;
- Uint32 texUav = 0;
- Uint32 bufSrv = 0;
- Uint32 bufUav = 0;
- Uint32 sam = 0;
-
- Uint32 NumCBSlots = 0;
- Uint32 NumSRVSlots = 0;
- Uint32 NumSamplerSlots = 0;
- Uint32 NumUAVSlots = 0;
- m_pResources->ProcessResources(
- [&](const D3DShaderResourceAttribs& CB, Uint32) //
- {
- auto VarType = m_pResources->FindVariableType(CB, ResourceLayout);
- if (IsAllowedType(VarType, AllowedTypeBits))
- {
- // Initialize current CB in place, increment CB counter
- new (&GetResource<ConstBuffBindInfo>(cb++)) ConstBuffBindInfo(CB, *this, VarType);
- NumCBSlots = std::max(NumCBSlots, Uint32{CB.BindPoint} + Uint32{CB.BindCount});
- }
- },
-
- [&](const D3DShaderResourceAttribs& Sampler, Uint32) //
- {
- auto VarType = m_pResources->FindVariableType(Sampler, ResourceLayout);
- if (IsAllowedType(VarType, AllowedTypeBits))
- {
- // Constructor of PipelineStateD3D11Impl initializes immutable samplers and will log the error, if any
- constexpr bool LogImtblSamplerArrayError = false;
- auto ImtblSamplerInd = m_pResources->FindImmutableSampler(Sampler, ResourceLayout, LogImtblSamplerArrayError);
- if (ImtblSamplerInd >= 0)
- {
- // Skip immutble samplers as they are initialized directly in the resource cache by the PSO
- return;
- }
- // Initialize current sampler in place, increment sampler counter
- new (&GetResource<SamplerBindInfo>(sam++)) SamplerBindInfo(Sampler, *this, VarType);
- NumSamplerSlots = std::max(NumSamplerSlots, Uint32{Sampler.BindPoint} + Uint32{Sampler.BindCount});
- }
- },
-
- [&](const D3DShaderResourceAttribs& TexSRV, Uint32) //
- {
- auto VarType = m_pResources->FindVariableType(TexSRV, ResourceLayout);
- if (!IsAllowedType(VarType, AllowedTypeBits))
- return;
-
- auto NumSamplers = GetNumSamplers();
- VERIFY(sam == NumSamplers, "All samplers must be initialized before texture SRVs");
-
- Uint32 AssignedSamplerIndex = TexSRVBindInfo::InvalidSamplerIndex;
- if (TexSRV.IsCombinedWithSampler())
- {
- const auto& AssignedSamplerAttribs = m_pResources->GetCombinedSampler(TexSRV);
- auto AssignedSamplerType = m_pResources->FindVariableType(AssignedSamplerAttribs, ResourceLayout);
- VERIFY(AssignedSamplerType == VarType,
- "The type (", GetShaderVariableTypeLiteralName(VarType), ") of texture SRV variable '", TexSRV.Name,
- "' is not consistent with the type (", GetShaderVariableTypeLiteralName(AssignedSamplerType),
- ") of the sampler '", AssignedSamplerAttribs.Name,
- "' that is assigned to it. This should never happen as when combined texture samplers are used, "
- "the type of the sampler is derived from the type of the texture it is assigned to SRV.");
-
- bool SamplerFound = false;
- for (AssignedSamplerIndex = 0; AssignedSamplerIndex < NumSamplers; ++AssignedSamplerIndex)
- {
- const auto& Sampler = GetResource<SamplerBindInfo>(AssignedSamplerIndex);
- SamplerFound = strcmp(Sampler.m_Attribs.Name, AssignedSamplerAttribs.Name) == 0;
- if (SamplerFound)
- break; // Otherwise AssignedSamplerIndex will be incremented
- }
-
- if (!SamplerFound)
- {
- AssignedSamplerIndex = TexSRVBindInfo::InvalidSamplerIndex;
-#ifdef DILIGENT_DEBUG
- // Shader error will be logged by the PipelineStateD3D11Impl
- constexpr bool LogImtblSamplerArrayError = false;
- if (m_pResources->FindImmutableSampler(AssignedSamplerAttribs, ResourceLayout, LogImtblSamplerArrayError) < 0)
- {
- UNEXPECTED("Unable to find non-immutable sampler assigned to texture SRV '", TexSRV.Name, "'.");
- }
-#endif
- }
- else
- {
-#ifdef DILIGENT_DEBUG
- // Shader error will be logged by the PipelineStateD3D11Impl
- constexpr bool LogImtblSamplerArrayError = false;
- if (m_pResources->FindImmutableSampler(AssignedSamplerAttribs, ResourceLayout, LogImtblSamplerArrayError) >= 0)
- {
- UNEXPECTED("Immutable sampler '", AssignedSamplerAttribs.Name, "' is assigned to texture SRV '", TexSRV.Name, "'.");
- }
-#endif
- }
- }
-
- // Initialize tex SRV in place, increment counter of tex SRVs
- new (&GetResource<TexSRVBindInfo>(texSrv++)) TexSRVBindInfo(TexSRV, AssignedSamplerIndex, *this, VarType);
- NumSRVSlots = std::max(NumSRVSlots, Uint32{TexSRV.BindPoint} + Uint32{TexSRV.BindCount});
- },
-
- [&](const D3DShaderResourceAttribs& TexUAV, Uint32) //
- {
- auto VarType = m_pResources->FindVariableType(TexUAV, ResourceLayout);
- if (IsAllowedType(VarType, AllowedTypeBits))
- {
- // Initialize tex UAV in place, increment counter of tex UAVs
- new (&GetResource<TexUAVBindInfo>(texUav++)) TexUAVBindInfo(TexUAV, *this, VarType);
- NumUAVSlots = std::max(NumUAVSlots, Uint32{TexUAV.BindPoint} + Uint32{TexUAV.BindCount});
- }
- },
-
- [&](const D3DShaderResourceAttribs& BuffSRV, Uint32) //
- {
- auto VarType = m_pResources->FindVariableType(BuffSRV, ResourceLayout);
- if (IsAllowedType(VarType, AllowedTypeBits))
- {
- // Initialize buff SRV in place, increment counter of buff SRVs
- new (&GetResource<BuffSRVBindInfo>(bufSrv++)) BuffSRVBindInfo(BuffSRV, *this, VarType);
- NumSRVSlots = std::max(NumSRVSlots, Uint32{BuffSRV.BindPoint} + Uint32{BuffSRV.BindCount});
- }
- },
-
- [&](const D3DShaderResourceAttribs& BuffUAV, Uint32) //
- {
- auto VarType = m_pResources->FindVariableType(BuffUAV, ResourceLayout);
- if (IsAllowedType(VarType, AllowedTypeBits))
- {
- // Initialize buff UAV in place, increment counter of buff UAVs
- new (&GetResource<BuffUAVBindInfo>(bufUav++)) BuffUAVBindInfo(BuffUAV, *this, VarType);
- NumUAVSlots = std::max(NumUAVSlots, Uint32{BuffUAV.BindPoint} + Uint32{BuffUAV.BindCount});
- }
- },
-
- [&](const D3DShaderResourceAttribs&, Uint32) //
- {
- UNEXPECTED("acceleration structure is not supported in DirectX 11");
- });
-
- // clang-format off
- VERIFY(cb == GetNumCBs(), "Not all CBs are initialized which will cause a crash when dtor is called");
- VERIFY(texSrv == GetNumTexSRVs(), "Not all Tex SRVs are initialized which will cause a crash when dtor is called");
- VERIFY(texUav == GetNumTexUAVs(), "Not all Tex UAVs are initialized which will cause a crash when dtor is called");
- VERIFY(bufSrv == GetNumBufSRVs(), "Not all Buf SRVs are initialized which will cause a crash when dtor is called");
- VERIFY(bufUav == GetNumBufUAVs(), "Not all Buf UAVs are initialized which will cause a crash when dtor is called");
- VERIFY(sam == GetNumSamplers(), "Not all samplers are initialized which will cause a crash when dtor is called");
- // clang-format on
-
- // Shader resource cache in the SRB is initialized by the constructor of ShaderResourceBindingD3D11Impl to
- // hold all variable types. The corresponding layout in the SRB is initialized to keep mutable and dynamic
- // variables only
- // http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-cache#Shader-Resource-Cache-Initialization
- if (!m_ResourceCache.IsInitialized())
- {
- // NOTE that here we are using max bind points required to cache only the shader variables of allowed types!
- m_ResourceCache.Initialize(NumCBSlots, NumSRVSlots, NumSamplerSlots, NumUAVSlots, ResCacheDataAllocator);
- }
-}
-
-void ShaderResourceLayoutD3D11::CopyResources(ShaderResourceCacheD3D11& DstCache) const
-{
- // clang-format off
- VERIFY( DstCache.GetCBCount() >= m_ResourceCache.GetCBCount(), "Dst cache is not large enough to contain all CBs" );
- VERIFY( DstCache.GetSRVCount() >= m_ResourceCache.GetSRVCount(), "Dst cache is not large enough to contain all SRVs" );
- VERIFY( DstCache.GetSamplerCount() >= m_ResourceCache.GetSamplerCount(), "Dst cache is not large enough to contain all samplers" );
- VERIFY( DstCache.GetUAVCount() >= m_ResourceCache.GetUAVCount(), "Dst cache is not large enough to contain all UAVs" );
- // clang-format on
-
- ShaderResourceCacheD3D11::CachedCB* CachedCBs = nullptr;
- ID3D11Buffer** d3d11CBs = nullptr;
- ShaderResourceCacheD3D11::CachedResource* CachedSRVResources = nullptr;
- ID3D11ShaderResourceView** d3d11SRVs = nullptr;
- ShaderResourceCacheD3D11::CachedSampler* CachedSamplers = nullptr;
- ID3D11SamplerState** d3d11Samplers = nullptr;
- ShaderResourceCacheD3D11::CachedResource* CachedUAVResources = nullptr;
- ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
- // clang-format off
- m_ResourceCache.GetCBArrays (CachedCBs, d3d11CBs);
- m_ResourceCache.GetSRVArrays (CachedSRVResources, d3d11SRVs);
- m_ResourceCache.GetSamplerArrays(CachedSamplers, d3d11Samplers);
- m_ResourceCache.GetUAVArrays (CachedUAVResources, d3d11UAVs);
- // clang-format on
-
-
- ShaderResourceCacheD3D11::CachedCB* DstCBs = nullptr;
- ID3D11Buffer** DstD3D11CBs = nullptr;
- ShaderResourceCacheD3D11::CachedResource* DstSRVResources = nullptr;
- ID3D11ShaderResourceView** DstD3D11SRVs = nullptr;
- ShaderResourceCacheD3D11::CachedSampler* DstSamplers = nullptr;
- ID3D11SamplerState** DstD3D11Samplers = nullptr;
- ShaderResourceCacheD3D11::CachedResource* DstUAVResources = nullptr;
- ID3D11UnorderedAccessView** DstD3D11UAVs = nullptr;
- // clang-format off
- DstCache.GetCBArrays (DstCBs, DstD3D11CBs);
- DstCache.GetSRVArrays (DstSRVResources, DstD3D11SRVs);
- DstCache.GetSamplerArrays(DstSamplers, DstD3D11Samplers);
- DstCache.GetUAVArrays (DstUAVResources, DstD3D11UAVs);
- // clang-format on
-
- HandleConstResources(
- [&](const ConstBuffBindInfo& cb) //
- {
- for (auto CBSlot = cb.m_Attribs.BindPoint; CBSlot < cb.m_Attribs.BindPoint + cb.m_Attribs.BindCount; ++CBSlot)
- {
- VERIFY_EXPR(CBSlot < m_ResourceCache.GetCBCount() && CBSlot < DstCache.GetCBCount());
- DstCBs[CBSlot] = CachedCBs[CBSlot];
- DstD3D11CBs[CBSlot] = d3d11CBs[CBSlot];
- }
- },
-
- [&](const TexSRVBindInfo& ts) //
- {
- for (auto SRVSlot = ts.m_Attribs.BindPoint; SRVSlot < ts.m_Attribs.BindPoint + ts.m_Attribs.BindCount; ++SRVSlot)
- {
- VERIFY_EXPR(SRVSlot < m_ResourceCache.GetSRVCount() && SRVSlot < DstCache.GetSRVCount());
- DstSRVResources[SRVSlot] = CachedSRVResources[SRVSlot];
- DstD3D11SRVs[SRVSlot] = d3d11SRVs[SRVSlot];
- }
- },
-
- [&](const TexUAVBindInfo& uav) //
- {
- for (auto UAVSlot = uav.m_Attribs.BindPoint; UAVSlot < uav.m_Attribs.BindPoint + uav.m_Attribs.BindCount; ++UAVSlot)
- {
- VERIFY_EXPR(UAVSlot < m_ResourceCache.GetUAVCount() && UAVSlot < DstCache.GetUAVCount());
- DstUAVResources[UAVSlot] = CachedUAVResources[UAVSlot];
- DstD3D11UAVs[UAVSlot] = d3d11UAVs[UAVSlot];
- }
- },
-
- [&](const BuffSRVBindInfo& srv) //
- {
- for (auto SRVSlot = srv.m_Attribs.BindPoint; SRVSlot < srv.m_Attribs.BindPoint + srv.m_Attribs.BindCount; ++SRVSlot)
- {
- VERIFY_EXPR(SRVSlot < m_ResourceCache.GetSRVCount() && SRVSlot < DstCache.GetSRVCount());
- DstSRVResources[SRVSlot] = CachedSRVResources[SRVSlot];
- DstD3D11SRVs[SRVSlot] = d3d11SRVs[SRVSlot];
- }
- },
-
- [&](const BuffUAVBindInfo& uav) //
- {
- for (auto UAVSlot = uav.m_Attribs.BindPoint; UAVSlot < uav.m_Attribs.BindPoint + uav.m_Attribs.BindCount; ++UAVSlot)
- {
- VERIFY_EXPR(UAVSlot < m_ResourceCache.GetUAVCount() && UAVSlot < DstCache.GetUAVCount());
- DstUAVResources[UAVSlot] = CachedUAVResources[UAVSlot];
- DstD3D11UAVs[UAVSlot] = d3d11UAVs[UAVSlot];
- }
- },
-
- [&](const SamplerBindInfo& sam) //
- {
- //VERIFY(!sam.IsImmutableSampler, "Variables are not created for immutable samplers");
- for (auto SamSlot = sam.m_Attribs.BindPoint; SamSlot < sam.m_Attribs.BindPoint + sam.m_Attribs.BindCount; ++SamSlot)
- {
- VERIFY_EXPR(SamSlot < m_ResourceCache.GetSamplerCount() && SamSlot < DstCache.GetSamplerCount());
- DstSamplers[SamSlot] = CachedSamplers[SamSlot];
- DstD3D11Samplers[SamSlot] = d3d11Samplers[SamSlot];
- }
- });
-}
-
-void ShaderResourceLayoutD3D11::ConstBuffBindInfo::BindResource(IDeviceObject* pBuffer,
- Uint32 ArrayIndex)
-{
- DEV_CHECK_ERR(ArrayIndex < m_Attribs.BindCount, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.BindCount - 1);
-
- // We cannot use ValidatedCast<> here as the resource retrieved from the
- // resource mapping can be of wrong type
- RefCntAutoPtr<BufferD3D11Impl> pBuffD3D11Impl{pBuffer, IID_BufferD3D11};
-#ifdef DILIGENT_DEVELOPMENT
- {
- auto& CachedCB = m_ParentResLayout.m_ResourceCache.GetCB(m_Attribs.BindPoint + ArrayIndex);
- VerifyConstantBufferBinding(m_Attribs, GetType(), ArrayIndex, pBuffer, pBuffD3D11Impl.RawPtr(), CachedCB.pBuff.RawPtr(), m_ParentResLayout.GetShaderName());
- }
-#endif
- m_ParentResLayout.m_ResourceCache.SetCB(m_Attribs.BindPoint + ArrayIndex, std::move(pBuffD3D11Impl));
-}
-
-
-void ShaderResourceLayoutD3D11::TexSRVBindInfo::BindResource(IDeviceObject* pView,
- Uint32 ArrayIndex)
-{
- DEV_CHECK_ERR(ArrayIndex < m_Attribs.BindCount, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.BindCount - 1);
- auto& ResourceCache = m_ParentResLayout.m_ResourceCache;
-
- // We cannot use ValidatedCast<> here as the resource retrieved from the
- // resource mapping can be of wrong type
- RefCntAutoPtr<TextureViewD3D11Impl> pViewD3D11{pView, IID_TextureViewD3D11};
-#ifdef DILIGENT_DEVELOPMENT
- {
- auto& CachedSRV = ResourceCache.GetSRV(m_Attribs.BindPoint + ArrayIndex);
- VerifyResourceViewBinding(m_Attribs, GetType(), ArrayIndex, pView, pViewD3D11.RawPtr(), {TEXTURE_VIEW_SHADER_RESOURCE},
- CachedSRV.pView.RawPtr(), m_ParentResLayout.GetShaderName());
- }
-#endif
-
- if (ValidSamplerAssigned())
- {
- auto& Sampler = m_ParentResLayout.GetResource<SamplerBindInfo>(SamplerIndex);
- //VERIFY(!Sampler.IsImmutableSampler, "Immutable samplers are not assigned to texture SRVs as they are initialized directly in the shader resource cache");
- VERIFY_EXPR(Sampler.m_Attribs.BindCount == m_Attribs.BindCount || Sampler.m_Attribs.BindCount == 1);
- auto SamplerBindPoint = Sampler.m_Attribs.BindPoint + (Sampler.m_Attribs.BindCount != 1 ? ArrayIndex : 0);
-
- SamplerD3D11Impl* pSamplerD3D11Impl = nullptr;
- if (pViewD3D11)
- {
- pSamplerD3D11Impl = ValidatedCast<SamplerD3D11Impl>(pViewD3D11->GetSampler());
-#ifdef DILIGENT_DEVELOPMENT
- if (pSamplerD3D11Impl == nullptr)
- {
- if (Sampler.m_Attribs.BindCount > 1)
- LOG_ERROR_MESSAGE("Failed to bind sampler to variable '", Sampler.m_Attribs.Name, "[", ArrayIndex, "]'. Sampler is not set in the texture view '", pViewD3D11->GetDesc().Name, "'");
- else
- LOG_ERROR_MESSAGE("Failed to bind sampler to variable '", Sampler.m_Attribs.Name, "'. Sampler is not set in the texture view '", pViewD3D11->GetDesc().Name, "'");
- }
-#endif
- }
-#ifdef DILIGENT_DEVELOPMENT
- if (Sampler.GetType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC)
- {
- auto& CachedSampler = ResourceCache.GetSampler(SamplerBindPoint);
- if (CachedSampler.pSampler != nullptr && CachedSampler.pSampler != pSamplerD3D11Impl)
- {
- auto VarTypeStr = GetShaderVariableTypeLiteralName(GetType());
- LOG_ERROR_MESSAGE("Non-null sampler is already bound to ", VarTypeStr, " shader variable '", Sampler.m_Attribs.GetPrintName(ArrayIndex), "' in shader '", m_ParentResLayout.GetShaderName(), "'. Attempting to bind another sampler or null is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic.");
- }
- }
-#endif
- ResourceCache.SetSampler(SamplerBindPoint, pSamplerD3D11Impl);
- }
-
- ResourceCache.SetTexSRV(m_Attribs.BindPoint + ArrayIndex, std::move(pViewD3D11));
-}
-
-void ShaderResourceLayoutD3D11::SamplerBindInfo::BindResource(IDeviceObject* pSampler,
- Uint32 ArrayIndex)
-{
- DEV_CHECK_ERR(ArrayIndex < m_Attribs.BindCount,
- "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name,
- "'. Max allowed index: ", m_Attribs.BindCount - 1);
- auto& ResourceCache = m_ParentResLayout.m_ResourceCache;
- //VERIFY(!IsImmutableSampler, "Cannot bind sampler to an immutable sampler");
-
- // We cannot use ValidatedCast<> here as the resource retrieved from the
- // resource mapping can be of wrong type
- RefCntAutoPtr<SamplerD3D11Impl> pSamplerD3D11{pSampler, IID_SamplerD3D11};
-
-#ifdef DILIGENT_DEVELOPMENT
- if (pSampler && !pSamplerD3D11)
- {
- LOG_ERROR_MESSAGE("Failed to bind object '", pSampler->GetDesc().Name, "' to variable '", m_Attribs.GetPrintName(ArrayIndex),
- "' in shader '", m_ParentResLayout.GetShaderName(), "'. Incorect object type: sampler is expected.");
- }
-
- if (m_Attribs.IsCombinedWithTexSRV())
- {
- auto* TexSRVName = m_ParentResLayout.m_pResources->GetCombinedTextureSRV(m_Attribs).Name;
- LOG_WARNING_MESSAGE("Texture sampler sampler '", m_Attribs.Name, "' is assigned to texture SRV '",
- TexSRVName, "' and should not be accessed directly. The sampler is initialized when texture SRV is set to '",
- TexSRVName, "' variable.");
- }
-
- if (GetType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC)
- {
- auto& CachedSampler = ResourceCache.GetSampler(m_Attribs.BindPoint + ArrayIndex);
- if (CachedSampler.pSampler != nullptr && CachedSampler.pSampler != pSamplerD3D11)
- {
- auto VarTypeStr = GetShaderVariableTypeLiteralName(GetType());
- LOG_ERROR_MESSAGE("Non-null sampler is already bound to ", VarTypeStr, " shader variable '",
- m_Attribs.GetPrintName(ArrayIndex), "' in shader '", m_ParentResLayout.GetShaderName(),
- "'. Attempting to bind another sampler or null is an error and may cause unpredicted behavior. "
- "Use another shader resource binding instance or label the variable as dynamic.");
- }
- }
-#endif
-
- ResourceCache.SetSampler(m_Attribs.BindPoint + ArrayIndex, std::move(pSamplerD3D11));
-}
-
-void ShaderResourceLayoutD3D11::BuffSRVBindInfo::BindResource(IDeviceObject* pView,
- Uint32 ArrayIndex)
-{
- DEV_CHECK_ERR(ArrayIndex < m_Attribs.BindCount, "Array index (", ArrayIndex, ") is out of range for variable '",
- m_Attribs.Name, "'. Max allowed index: ", m_Attribs.BindCount - 1);
- auto& ResourceCache = m_ParentResLayout.m_ResourceCache;
-
- // We cannot use ValidatedCast<> here as the resource retrieved from the
- // resource mapping can be of wrong type
- RefCntAutoPtr<BufferViewD3D11Impl> pViewD3D11{pView, IID_BufferViewD3D11};
-#ifdef DILIGENT_DEVELOPMENT
- {
- auto& CachedSRV = ResourceCache.GetSRV(m_Attribs.BindPoint + ArrayIndex);
- VerifyResourceViewBinding(m_Attribs, GetType(), ArrayIndex, pView, pViewD3D11.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE},
- CachedSRV.pView.RawPtr(), m_ParentResLayout.GetShaderName());
- VerifyBufferViewModeD3D(pViewD3D11.RawPtr(), m_Attribs, m_ParentResLayout.GetShaderName());
- }
-#endif
- ResourceCache.SetBufSRV(m_Attribs.BindPoint + ArrayIndex, std::move(pViewD3D11));
-}
-
-
-void ShaderResourceLayoutD3D11::TexUAVBindInfo::BindResource(IDeviceObject* pView,
- Uint32 ArrayIndex)
-{
- DEV_CHECK_ERR(ArrayIndex < m_Attribs.BindCount, "Array index (", ArrayIndex, ") is out of range for variable '",
- m_Attribs.Name, "'. Max allowed index: ", m_Attribs.BindCount - 1);
- auto& ResourceCache = m_ParentResLayout.m_ResourceCache;
-
- // We cannot use ValidatedCast<> here as the resource retrieved from the
- // resource mapping can be of wrong type
- RefCntAutoPtr<TextureViewD3D11Impl> pViewD3D11{pView, IID_TextureViewD3D11};
-#ifdef DILIGENT_DEVELOPMENT
- {
- auto& CachedUAV = ResourceCache.GetUAV(m_Attribs.BindPoint + ArrayIndex);
- VerifyResourceViewBinding(m_Attribs, GetType(), ArrayIndex, pView, pViewD3D11.RawPtr(), {TEXTURE_VIEW_UNORDERED_ACCESS},
- CachedUAV.pView.RawPtr(), m_ParentResLayout.GetShaderName());
- }
-#endif
- ResourceCache.SetTexUAV(m_Attribs.BindPoint + ArrayIndex, std::move(pViewD3D11));
-}
-
-
-void ShaderResourceLayoutD3D11::BuffUAVBindInfo::BindResource(IDeviceObject* pView,
- Uint32 ArrayIndex)
-{
- DEV_CHECK_ERR(ArrayIndex < m_Attribs.BindCount, "Array index (", ArrayIndex, ") is out of range for variable '",
- m_Attribs.Name, "'. Max allowed index: ", m_Attribs.BindCount - 1);
- auto& ResourceCache = m_ParentResLayout.m_ResourceCache;
-
- // We cannot use ValidatedCast<> here as the resource retrieved from the
- // resource mapping can be of wrong type
- RefCntAutoPtr<BufferViewD3D11Impl> pViewD3D11{pView, IID_BufferViewD3D11};
-#ifdef DILIGENT_DEVELOPMENT
- {
- auto& CachedUAV = ResourceCache.GetUAV(m_Attribs.BindPoint + ArrayIndex);
- VerifyResourceViewBinding(m_Attribs, GetType(), ArrayIndex, pView, pViewD3D11.RawPtr(), {BUFFER_VIEW_UNORDERED_ACCESS},
- CachedUAV.pView.RawPtr(), m_ParentResLayout.GetShaderName());
- VerifyBufferViewModeD3D(pViewD3D11.RawPtr(), m_Attribs, m_ParentResLayout.GetShaderName());
- }
-#endif
- ResourceCache.SetBufUAV(m_Attribs.BindPoint + ArrayIndex, std::move(pViewD3D11));
-}
-
-
-
-// Helper template class that facilitates binding CBs, SRVs, and UAVs
-class BindResourceHelper
-{
-public:
- BindResourceHelper(IResourceMapping& RM, Uint32 Fl) :
- ResourceMapping{RM},
- Flags{Fl}
- {
- }
-
- template <typename ResourceType>
- void Bind(ResourceType& Res)
- {
- if ((Flags & (1 << Res.GetType())) == 0)
- return;
-
- for (Uint16 elem = 0; elem < Res.m_Attribs.BindCount; ++elem)
- {
- if ((Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) && Res.IsBound(elem))
- continue;
-
- const auto* VarName = Res.m_Attribs.Name;
- RefCntAutoPtr<IDeviceObject> pRes;
- ResourceMapping.GetResource(VarName, &pRes, elem);
- if (pRes)
- {
- // Call non-virtual function
- Res.BindResource(pRes, elem);
- }
- else
- {
- if ((Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) && !Res.IsBound(elem))
- {
- LOG_ERROR_MESSAGE("Unable to bind resource to shader variable '", VarName,
- "': resource is not found in the resource mapping");
- }
- }
- }
- }
-
-private:
- IResourceMapping& ResourceMapping;
- const Uint32 Flags;
-};
-
-void ShaderResourceLayoutD3D11::BindResources(IResourceMapping* pResourceMapping,
- Uint32 Flags,
- const ShaderResourceCacheD3D11& dbgResourceCache)
-{
- VERIFY(&dbgResourceCache == &m_ResourceCache, "Resource cache does not match the cache provided at initialization");
-
- if (pResourceMapping == nullptr)
- {
- LOG_ERROR_MESSAGE("Failed to bind resources in shader '", GetShaderName(), "': resource mapping is null");
- return;
- }
-
- if ((Flags & BIND_SHADER_RESOURCES_UPDATE_ALL) == 0)
- Flags |= BIND_SHADER_RESOURCES_UPDATE_ALL;
-
- BindResourceHelper BindResHelper(*pResourceMapping, Flags);
-
- // clang-format off
- HandleResources(
- [&](ConstBuffBindInfo& cb)
- {
- BindResHelper.Bind(cb);
- },
-
- [&](TexSRVBindInfo& ts)
- {
- BindResHelper.Bind(ts);
- },
-
- [&](TexUAVBindInfo& uav)
- {
- BindResHelper.Bind(uav);
- },
-
- [&](BuffSRVBindInfo& srv)
- {
- BindResHelper.Bind(srv);
- },
-
- [&](BuffUAVBindInfo& uav)
- {
- BindResHelper.Bind(uav);
- },
-
- [&](SamplerBindInfo& sam)
- {
- if (!m_pResources->IsUsingCombinedTextureSamplers())
- BindResHelper.Bind(sam);
- }
- );
- // clang-format on
-}
-
-template <typename ResourceType>
-IShaderResourceVariable* ShaderResourceLayoutD3D11::GetResourceByName(const Char* Name)
-{
- auto NumResources = GetNumResources<ResourceType>();
- for (Uint32 res = 0; res < NumResources; ++res)
- {
- auto& Resource = GetResource<ResourceType>(res);
- if (strcmp(Resource.m_Attribs.Name, Name) == 0)
- return &Resource;
- }
-
- return nullptr;
-}
-
-IShaderResourceVariable* ShaderResourceLayoutD3D11::GetShaderVariable(const Char* Name)
-{
- if (auto* pCB = GetResourceByName<ConstBuffBindInfo>(Name))
- return pCB;
-
- if (auto* pTexSRV = GetResourceByName<TexSRVBindInfo>(Name))
- return pTexSRV;
-
- if (auto* pTexUAV = GetResourceByName<TexUAVBindInfo>(Name))
- return pTexUAV;
-
- if (auto* pBuffSRV = GetResourceByName<BuffSRVBindInfo>(Name))
- return pBuffSRV;
-
- if (auto* pBuffUAV = GetResourceByName<BuffUAVBindInfo>(Name))
- return pBuffUAV;
-
- if (!m_pResources->IsUsingCombinedTextureSamplers())
- {
- // Immutable samplers are never created in the resource layout
- if (auto* pSampler = GetResourceByName<SamplerBindInfo>(Name))
- return pSampler;
- }
-
- return nullptr;
-}
-
-class ShaderVariableIndexLocator
-{
-public:
- ShaderVariableIndexLocator(const ShaderResourceLayoutD3D11& _Layout, const ShaderResourceLayoutD3D11::ShaderVariableD3D11Base& Variable) :
- // clang-format off
- Layout {_Layout},
- VarOffset(reinterpret_cast<const Uint8*>(&Variable) - reinterpret_cast<const Uint8*>(_Layout.m_ResourceBuffer.get()))
- // clang-format on
- {}
-
- template <typename ResourceType>
- bool TryResource(ShaderResourceLayoutD3D11::OffsetType NextResourceTypeOffset)
- {
-#ifdef DILIGENT_DEBUG
- {
- VERIFY(Layout.GetResourceOffset<ResourceType>() >= dbgPreviousResourceOffset, "Resource types are processed out of order!");
- dbgPreviousResourceOffset = Layout.GetResourceOffset<ResourceType>();
- VERIFY_EXPR(NextResourceTypeOffset >= Layout.GetResourceOffset<ResourceType>());
- }
-#endif
- if (VarOffset < NextResourceTypeOffset)
- {
- auto RelativeOffset = VarOffset - Layout.GetResourceOffset<ResourceType>();
- DEV_CHECK_ERR(RelativeOffset % sizeof(ResourceType) == 0, "Offset is not multiple of resource type (", sizeof(ResourceType), ")");
- Index += static_cast<Uint32>(RelativeOffset / sizeof(ResourceType));
- return true;
- }
- else
- {
- Index += Layout.GetNumResources<ResourceType>();
- return false;
- }
- }
-
- Uint32 GetIndex() const { return Index; }
-
-private:
- const ShaderResourceLayoutD3D11& Layout;
- const size_t VarOffset;
- Uint32 Index = 0;
-#ifdef DILIGENT_DEBUG
- Uint32 dbgPreviousResourceOffset = 0;
-#endif
-};
-
-Uint32 ShaderResourceLayoutD3D11::GetVariableIndex(const ShaderVariableD3D11Base& Variable) const
-{
- if (!m_ResourceBuffer)
- {
- LOG_ERROR("This shader resource layout does not have resources");
- return static_cast<Uint32>(-1);
- }
-
- ShaderVariableIndexLocator IdxLocator(*this, Variable);
- if (IdxLocator.TryResource<ConstBuffBindInfo>(m_TexSRVsOffset))
- return IdxLocator.GetIndex();
-
- if (IdxLocator.TryResource<TexSRVBindInfo>(m_TexUAVsOffset))
- return IdxLocator.GetIndex();
-
- if (IdxLocator.TryResource<TexUAVBindInfo>(m_BuffSRVsOffset))
- return IdxLocator.GetIndex();
-
- if (IdxLocator.TryResource<BuffSRVBindInfo>(m_BuffUAVsOffset))
- return IdxLocator.GetIndex();
-
- if (IdxLocator.TryResource<BuffUAVBindInfo>(m_SamplerOffset))
- return IdxLocator.GetIndex();
-
- if (!m_pResources->IsUsingCombinedTextureSamplers())
- {
- if (IdxLocator.TryResource<SamplerBindInfo>(m_MemorySize))
- return IdxLocator.GetIndex();
- }
-
- LOG_ERROR("Failed to get variable index. The variable ", &Variable, " does not belong to this shader resource layout");
- return static_cast<Uint32>(-1);
-}
-
-class ShaderVariableLocator
-{
-public:
- ShaderVariableLocator(ShaderResourceLayoutD3D11& _Layout, Uint32 _Index) :
- // clang-format off
- Layout{_Layout},
- Index {_Index }
- // clang-format on
- {
- }
-
- template <typename ResourceType>
- IShaderResourceVariable* TryResource()
- {
-#ifdef DILIGENT_DEBUG
- {
- VERIFY(Layout.GetResourceOffset<ResourceType>() >= dbgPreviousResourceOffset, "Resource types are processed out of order!");
- dbgPreviousResourceOffset = Layout.GetResourceOffset<ResourceType>();
- }
-#endif
- auto NumResources = Layout.GetNumResources<ResourceType>();
- if (Index < NumResources)
- return &Layout.GetResource<ResourceType>(Index);
- else
- {
- Index -= NumResources;
- return nullptr;
- }
- }
-
-private:
- ShaderResourceLayoutD3D11& Layout;
- Uint32 Index = 0;
-#ifdef DILIGENT_DEBUG
- Uint32 dbgPreviousResourceOffset = 0;
-#endif
-};
-
-IShaderResourceVariable* ShaderResourceLayoutD3D11::GetShaderVariable(Uint32 Index)
-{
- ShaderVariableLocator VarLocator(*this, Index);
-
- if (auto* pCB = VarLocator.TryResource<ConstBuffBindInfo>())
- return pCB;
-
- if (auto* pTexSRV = VarLocator.TryResource<TexSRVBindInfo>())
- return pTexSRV;
-
- if (auto* pTexUAV = VarLocator.TryResource<TexUAVBindInfo>())
- return pTexUAV;
-
- if (auto* pBuffSRV = VarLocator.TryResource<BuffSRVBindInfo>())
- return pBuffSRV;
-
- if (auto* pBuffUAV = VarLocator.TryResource<BuffUAVBindInfo>())
- return pBuffUAV;
-
- if (!m_pResources->IsUsingCombinedTextureSamplers())
- {
- if (auto* pSampler = VarLocator.TryResource<SamplerBindInfo>())
- return pSampler;
- }
-
- auto TotalResCount = GetTotalResourceCount();
- LOG_ERROR(Index, " is not a valid variable index. Total resource count: ", TotalResCount);
- return nullptr;
-}
-
-
-#ifdef DILIGENT_DEVELOPMENT
-bool ShaderResourceLayoutD3D11::dvpVerifyBindings() const
-{
-
-# define LOG_MISSING_BINDING(VarType, Attrs, BindPt) \
- do \
- { \
- if (Attrs.BindCount == 1) \
- LOG_ERROR_MESSAGE("No resource is bound to ", VarType, " variable '", Attrs.Name, "' in shader '", GetShaderName(), "'"); \
- else \
- LOG_ERROR_MESSAGE("No resource is bound to ", VarType, " variable '", Attrs.Name, "[", BindPt - Attrs.BindPoint, "]' in shader '", GetShaderName(), "'"); \
- } while (false)
-
- m_ResourceCache.dbgVerifyCacheConsistency();
-
- bool BindingsOK = true;
- HandleConstResources(
- [&](const ConstBuffBindInfo& cb) //
- {
- for (Uint32 BindPoint = cb.m_Attribs.BindPoint; BindPoint < Uint32{cb.m_Attribs.BindPoint} + cb.m_Attribs.BindCount; ++BindPoint)
- {
- if (!m_ResourceCache.IsCBBound(BindPoint))
- {
- LOG_MISSING_BINDING("constant buffer", cb.m_Attribs, BindPoint);
- BindingsOK = false;
- }
- }
- },
-
- [&](const TexSRVBindInfo& ts) //
- {
- for (Uint32 BindPoint = ts.m_Attribs.BindPoint; BindPoint < Uint32{ts.m_Attribs.BindPoint} + ts.m_Attribs.BindCount; ++BindPoint)
- {
- if (!m_ResourceCache.IsSRVBound(BindPoint, true))
- {
- LOG_MISSING_BINDING("texture", ts.m_Attribs, BindPoint);
- BindingsOK = false;
- }
-
- if (ts.ValidSamplerAssigned())
- {
- const auto& Sampler = GetConstResource<SamplerBindInfo>(ts.SamplerIndex);
- VERIFY_EXPR(Sampler.m_Attribs.BindCount == ts.m_Attribs.BindCount || Sampler.m_Attribs.BindCount == 1);
-
- // Verify that if single sampler is used for all texture array elements, all samplers set in the resource views are consistent
- if (ts.m_Attribs.BindCount > 1 && Sampler.m_Attribs.BindCount == 1)
- {
- ShaderResourceCacheD3D11::CachedSampler* pCachedSamplers = nullptr;
- ID3D11SamplerState** ppCachedD3D11Samplers = nullptr;
- m_ResourceCache.GetSamplerArrays(pCachedSamplers, ppCachedD3D11Samplers);
- VERIFY_EXPR(Sampler.m_Attribs.BindPoint < m_ResourceCache.GetSamplerCount());
- const auto& CachedSampler = pCachedSamplers[Sampler.m_Attribs.BindPoint];
-
- ShaderResourceCacheD3D11::CachedResource* pCachedResources = nullptr;
- ID3D11ShaderResourceView** ppCachedD3D11Resources = nullptr;
- m_ResourceCache.GetSRVArrays(pCachedResources, ppCachedD3D11Resources);
- VERIFY_EXPR(BindPoint < m_ResourceCache.GetSRVCount());
- auto& CachedResource = pCachedResources[BindPoint];
- if (CachedResource.pView)
- {
- auto* pTexView = CachedResource.pView.RawPtr<ITextureView>();
- auto* pSampler = pTexView->GetSampler();
- if (pSampler != nullptr && pSampler != CachedSampler.pSampler.RawPtr())
- {
- LOG_ERROR_MESSAGE("All elements of texture array '", ts.m_Attribs.Name, "' in shader '", GetShaderName(), "' share the same sampler. However, the sampler set in view for element ", BindPoint - ts.m_Attribs.BindPoint, " does not match bound sampler. This may cause incorrect behavior on GL platform.");
- }
- }
- }
- }
- }
- },
-
- [&](const TexUAVBindInfo& uav) //
- {
- for (Uint32 BindPoint = uav.m_Attribs.BindPoint; BindPoint < Uint32{uav.m_Attribs.BindPoint} + uav.m_Attribs.BindCount; ++BindPoint)
- {
- if (!m_ResourceCache.IsUAVBound(BindPoint, true))
- {
- LOG_MISSING_BINDING("texture UAV", uav.m_Attribs, BindPoint);
- BindingsOK = false;
- }
- }
- },
-
- [&](const BuffSRVBindInfo& buf) //
- {
- for (Uint32 BindPoint = buf.m_Attribs.BindPoint; BindPoint < Uint32{buf.m_Attribs.BindPoint} + buf.m_Attribs.BindCount; ++BindPoint)
- {
- if (!m_ResourceCache.IsSRVBound(BindPoint, false))
- {
- LOG_MISSING_BINDING("buffer", buf.m_Attribs, BindPoint);
- BindingsOK = false;
- }
- }
- },
-
- [&](const BuffUAVBindInfo& uav) //
- {
- for (Uint32 BindPoint = uav.m_Attribs.BindPoint; BindPoint < Uint32{uav.m_Attribs.BindPoint} + uav.m_Attribs.BindCount; ++BindPoint)
- {
- if (!m_ResourceCache.IsUAVBound(BindPoint, false))
- {
- LOG_MISSING_BINDING("buffer UAV", uav.m_Attribs, BindPoint);
- BindingsOK = false;
- }
- }
- },
-
- [&](const SamplerBindInfo& sam) //
- {
- for (Uint32 BindPoint = sam.m_Attribs.BindPoint; BindPoint < Uint32{sam.m_Attribs.BindPoint} + sam.m_Attribs.BindCount; ++BindPoint)
- {
- if (!m_ResourceCache.IsSamplerBound(BindPoint))
- {
- LOG_MISSING_BINDING("sampler", sam.m_Attribs, BindPoint);
- BindingsOK = false;
- }
- }
- } // clang-format off
- ); // clang-format on
-# undef LOG_MISSING_BINDING
-
- return BindingsOK;
-}
-
-#endif
-} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp
index 1986eb6b..1b5f3b17 100755
--- a/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp
@@ -146,19 +146,23 @@ void ShaderResourcesD3D11::dvpVerifyCommittedResources(ID3D11Buffer*
ID3D11Resource* CommittedD3D11UAVResources[],
ShaderResourceCacheD3D11& ResourceCache) const
{
- ShaderResourceCacheD3D11::CachedCB* CachedCBs = nullptr;
- ID3D11Buffer** d3d11CBs = nullptr;
- ShaderResourceCacheD3D11::CachedResource* CachedSRVResources = nullptr;
- ID3D11ShaderResourceView** d3d11SRVs = nullptr;
- ShaderResourceCacheD3D11::CachedSampler* CachedSamplers = nullptr;
- ID3D11SamplerState** d3d11Samplers = nullptr;
- ShaderResourceCacheD3D11::CachedResource* CachedUAVResources = nullptr;
- ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
+ ShaderResourceCacheD3D11::CachedCB* CachedCBs = nullptr;
+ ID3D11Buffer** d3d11CBs = nullptr;
+ ShaderResourceCacheD3D11::CachedResource* CachedSRVResources = nullptr;
+ ID3D11ShaderResourceView** d3d11SRVs = nullptr;
+ ShaderResourceCacheD3D11::CachedSampler* CachedSamplers = nullptr;
+ ID3D11SamplerState** d3d11Samplers = nullptr;
+ ShaderResourceCacheD3D11::CachedResource* CachedUAVResources = nullptr;
+ ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
+ ShaderResourceCacheD3D11::TBindPointsAndActiveBits* CBBindPoints = nullptr;
+ ShaderResourceCacheD3D11::TBindPointsAndActiveBits* SRVBindPoints = nullptr;
+ ShaderResourceCacheD3D11::TBindPointsAndActiveBits* SampBindPoints = nullptr;
+ ShaderResourceCacheD3D11::TBindPointsAndActiveBits* UAVBindPoints = nullptr;
// clang-format off
- ResourceCache.GetCBArrays (CachedCBs, d3d11CBs);
- ResourceCache.GetSRVArrays (CachedSRVResources, d3d11SRVs);
- ResourceCache.GetSamplerArrays(CachedSamplers, d3d11Samplers);
- ResourceCache.GetUAVArrays (CachedUAVResources, d3d11UAVs);
+ ResourceCache.GetCBArrays (CachedCBs, d3d11CBs, CBBindPoints);
+ ResourceCache.GetSRVArrays (CachedSRVResources, d3d11SRVs, SRVBindPoints);
+ ResourceCache.GetSamplerArrays(CachedSamplers, d3d11Samplers, SampBindPoints);
+ ResourceCache.GetUAVArrays (CachedUAVResources, d3d11UAVs, UAVBindPoints);
// clang-format on
ProcessResources(
diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderVariableManagerD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderVariableManagerD3D11.cpp
new file mode 100644
index 00000000..79fdb94a
--- /dev/null
+++ b/Graphics/GraphicsEngineD3D11/src/ShaderVariableManagerD3D11.cpp
@@ -0,0 +1,857 @@
+/*
+ * Copyright 2019-2021 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 <d3dcompiler.h>
+
+#include "ShaderVariableManagerD3D11.hpp"
+#include "ShaderResourceCacheD3D11.hpp"
+#include "BufferD3D11Impl.hpp"
+#include "BufferViewD3D11Impl.hpp"
+#include "TextureBaseD3D11.hpp"
+#include "TextureViewD3D11.h"
+#include "SamplerD3D11Impl.hpp"
+#include "ShaderD3D11Impl.hpp"
+#include "ShaderResourceVariableBase.hpp"
+#include "PipelineResourceSignatureD3D11Impl.hpp"
+
+namespace Diligent
+{
+
+ShaderVariableManagerD3D11::~ShaderVariableManagerD3D11()
+{
+ VERIFY(m_ResourceBuffer == nullptr, "DestroyVariables() has not been called");
+}
+
+void ShaderVariableManagerD3D11::Destroy(IMemoryAllocator& Allocator)
+{
+ if (m_ResourceBuffer == nullptr)
+ return;
+
+ VERIFY(m_pDbgAllocator == &Allocator, "Incosistent alloctor");
+
+ HandleResources(
+ [&](ConstBuffBindInfo& cb) {
+ cb.~ConstBuffBindInfo();
+ },
+ [&](TexSRVBindInfo& ts) {
+ ts.~TexSRVBindInfo();
+ },
+ [&](TexUAVBindInfo& uav) {
+ uav.~TexUAVBindInfo();
+ },
+ [&](BuffSRVBindInfo& srv) {
+ srv.~BuffSRVBindInfo();
+ },
+ [&](BuffUAVBindInfo& uav) {
+ uav.~BuffUAVBindInfo();
+ },
+ [&](SamplerBindInfo& sam) {
+ sam.~SamplerBindInfo();
+ });
+
+ Allocator.Free(m_ResourceBuffer);
+
+ m_ResourceBuffer = nullptr;
+}
+
+const PipelineResourceDesc& ShaderVariableManagerD3D11::GetResourceDesc(Uint32 Index) const
+{
+ VERIFY_EXPR(m_pSignature);
+ return m_pSignature->GetResourceDesc(Index);
+}
+
+const PipelineResourceAttribsD3D11& ShaderVariableManagerD3D11::GetAttribs(Uint32 Index) const
+{
+ VERIFY_EXPR(m_pSignature);
+ return m_pSignature->GetResourceAttribs(Index);
+}
+
+void ShaderVariableManagerD3D11::CountResources(const PipelineResourceSignatureD3D11Impl& Signature,
+ const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
+ Uint32 NumAllowedTypes,
+ const SHADER_TYPE ShaderType,
+ D3DShaderResourceCounters& Counters)
+{
+ ProcessSignatureResources(
+ Signature, AllowedVarTypes, NumAllowedTypes, ShaderType,
+ [&](Uint32 Index) //
+ {
+ const auto& ResDesc = Signature.GetResourceDesc(Index);
+ static_assert(SHADER_RESOURCE_TYPE_LAST == 8, "Please update the switch below to handle the new shader resource range");
+ switch (ResDesc.ResourceType)
+ {
+ // clang-format off
+ case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER: ++Counters.NumCBs; break;
+ case SHADER_RESOURCE_TYPE_TEXTURE_SRV: ++Counters.NumTexSRVs; break;
+ case SHADER_RESOURCE_TYPE_BUFFER_SRV: ++Counters.NumBufSRVs; break;
+ case SHADER_RESOURCE_TYPE_TEXTURE_UAV: ++Counters.NumTexUAVs; break;
+ case SHADER_RESOURCE_TYPE_BUFFER_UAV: ++Counters.NumBufUAVs; break;
+ case SHADER_RESOURCE_TYPE_SAMPLER: ++Counters.NumSamplers; break;
+ case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT: ++Counters.NumTexSRVs; break;
+ // clang-format on
+ default:
+ UNEXPECTED("Unsupported resource type.");
+ }
+ });
+}
+
+template <typename HandlerType>
+void ShaderVariableManagerD3D11::ProcessSignatureResources(const PipelineResourceSignatureD3D11Impl& Signature,
+ const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
+ Uint32 NumAllowedTypes,
+ SHADER_TYPE ShaderType,
+ HandlerType Handler)
+{
+ const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes);
+ const bool UsingSeparateSamplers = Signature.IsUsingSeparateSamplers();
+
+ for (Uint32 var_type = 0; var_type < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; ++var_type)
+ {
+ const auto VarType = static_cast<SHADER_RESOURCE_VARIABLE_TYPE>(var_type);
+ if (IsAllowedType(VarType, AllowedTypeBits))
+ {
+ const auto ResIdxRange = Signature.GetResourceIndexRange(VarType);
+ for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r)
+ {
+ const auto& Res = Signature.GetResourceDesc(r);
+ const auto& Attr = Signature.GetResourceAttribs(r);
+ VERIFY_EXPR(Res.VarType == VarType);
+
+ if ((Res.ShaderStages & ShaderType) == 0)
+ continue;
+
+ // When using HLSL-style combined image samplers, we need to skip separate samplers.
+ // Also always skip immutable separate samplers.
+ if (Res.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER &&
+ (!UsingSeparateSamplers || Attr.IsImmutableSamplerAssigned()))
+ continue;
+
+ Handler(r);
+ }
+ }
+ }
+}
+
+size_t ShaderVariableManagerD3D11::GetRequiredMemorySize(const PipelineResourceSignatureD3D11Impl& Signature,
+ const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
+ Uint32 NumAllowedTypes,
+ SHADER_TYPE ShaderType)
+{
+ D3DShaderResourceCounters ResCounters;
+ CountResources(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, ResCounters);
+
+ // clang-format off
+ auto MemSize = ResCounters.NumCBs * sizeof(ConstBuffBindInfo) +
+ ResCounters.NumTexSRVs * sizeof(TexSRVBindInfo) +
+ ResCounters.NumTexUAVs * sizeof(TexUAVBindInfo) +
+ ResCounters.NumBufSRVs * sizeof(BuffSRVBindInfo) +
+ ResCounters.NumBufUAVs * sizeof(BuffUAVBindInfo) +
+ ResCounters.NumSamplers * sizeof(SamplerBindInfo);
+ // clang-format on
+ return MemSize;
+}
+
+
+void ShaderVariableManagerD3D11::Initialize(const PipelineResourceSignatureD3D11Impl& Signature,
+ IMemoryAllocator& Allocator,
+ const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
+ Uint32 NumAllowedTypes,
+ SHADER_TYPE ShaderType)
+{
+#ifdef DILIGENT_DEBUG
+ m_pDbgAllocator = &Allocator;
+#endif
+
+ D3DShaderResourceCounters ResCounters;
+ CountResources(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, ResCounters);
+
+ m_pSignature = &Signature;
+
+ // Initialize offsets
+ size_t CurrentOffset = 0;
+
+ auto AdvanceOffset = [&CurrentOffset](size_t NumBytes) //
+ {
+ constexpr size_t MaxOffset = std::numeric_limits<OffsetType>::max();
+ VERIFY(CurrentOffset <= MaxOffset, "Current offser (", CurrentOffset, ") exceeds max allowed value (", MaxOffset, ")");
+ auto Offset = static_cast<OffsetType>(CurrentOffset);
+ CurrentOffset += NumBytes;
+ return Offset;
+ };
+
+ // clang-format off
+ auto CBOffset = AdvanceOffset(ResCounters.NumCBs * sizeof(ConstBuffBindInfo)); (void)CBOffset; // To suppress warning
+ m_TexSRVsOffset = AdvanceOffset(ResCounters.NumTexSRVs * sizeof(TexSRVBindInfo) );
+ m_TexUAVsOffset = AdvanceOffset(ResCounters.NumTexUAVs * sizeof(TexUAVBindInfo) );
+ m_BuffSRVsOffset = AdvanceOffset(ResCounters.NumBufSRVs * sizeof(BuffSRVBindInfo) );
+ m_BuffUAVsOffset = AdvanceOffset(ResCounters.NumBufUAVs * sizeof(BuffUAVBindInfo) );
+ m_SamplerOffset = AdvanceOffset(ResCounters.NumSamplers * sizeof(SamplerBindInfo) );
+ m_MemorySize = AdvanceOffset(0);
+ // clang-format on
+
+ VERIFY_EXPR(m_MemorySize == GetRequiredMemorySize(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType));
+
+ if (m_MemorySize)
+ {
+ m_ResourceBuffer = ALLOCATE_RAW(Allocator, "Raw memory buffer for shader resource layout resources", m_MemorySize);
+ }
+
+ // clang-format off
+ VERIFY_EXPR(ResCounters.NumCBs == GetNumCBs() );
+ VERIFY_EXPR(ResCounters.NumTexSRVs == GetNumTexSRVs() );
+ VERIFY_EXPR(ResCounters.NumTexUAVs == GetNumTexUAVs() );
+ VERIFY_EXPR(ResCounters.NumBufSRVs == GetNumBufSRVs() );
+ VERIFY_EXPR(ResCounters.NumBufUAVs == GetNumBufUAVs() );
+ VERIFY_EXPR(ResCounters.NumSamplers== GetNumSamplers());
+ // clang-format on
+
+ // Current resource index for every resource type
+ Uint32 cb = 0;
+ Uint32 texSrv = 0;
+ Uint32 texUav = 0;
+ Uint32 bufSrv = 0;
+ Uint32 bufUav = 0;
+ Uint32 sam = 0;
+
+ Uint32 NumCBSlots = 0;
+ Uint32 NumSRVSlots = 0;
+ Uint32 NumSamplerSlots = 0;
+ Uint32 NumUAVSlots = 0;
+ ProcessSignatureResources(
+ Signature, AllowedVarTypes, NumAllowedTypes, ShaderType,
+ [&](Uint32 Index) //
+ {
+ const auto& ResDesc = Signature.GetResourceDesc(Index);
+ const auto& ResAttr = Signature.GetResourceAttribs(Index);
+ static_assert(SHADER_RESOURCE_TYPE_LAST == 8, "Please update the switch below to handle the new shader resource range");
+ switch (ResDesc.ResourceType)
+ {
+ case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER:
+ // Initialize current CB in place, increment CB counter
+ new (&GetResource<ConstBuffBindInfo>(cb++)) ConstBuffBindInfo(*this, Index);
+ NumCBSlots = std::max(NumCBSlots, ResAttr.CacheOffset + ResDesc.ArraySize);
+ break;
+
+ case SHADER_RESOURCE_TYPE_TEXTURE_SRV:
+ case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT:
+ // Initialize tex SRV in place, increment counter of tex SRVs
+ new (&GetResource<TexSRVBindInfo>(texSrv++)) TexSRVBindInfo{*this, Index};
+ NumSRVSlots = std::max(NumSRVSlots, ResAttr.CacheOffset + ResDesc.ArraySize);
+ break;
+
+ case SHADER_RESOURCE_TYPE_BUFFER_SRV:
+ // Initialize buff SRV in place, increment counter of buff SRVs
+ new (&GetResource<BuffSRVBindInfo>(bufSrv++)) BuffSRVBindInfo(*this, Index);
+ NumSRVSlots = std::max(NumSRVSlots, ResAttr.CacheOffset + ResDesc.ArraySize);
+ break;
+
+ case SHADER_RESOURCE_TYPE_TEXTURE_UAV:
+ // Initialize tex UAV in place, increment counter of tex UAVs
+ new (&GetResource<TexUAVBindInfo>(texUav++)) TexUAVBindInfo(*this, Index);
+ NumUAVSlots = std::max(NumUAVSlots, ResAttr.CacheOffset + ResDesc.ArraySize);
+ break;
+
+ case SHADER_RESOURCE_TYPE_BUFFER_UAV:
+ // Initialize buff UAV in place, increment counter of buff UAVs
+ new (&GetResource<BuffUAVBindInfo>(bufUav++)) BuffUAVBindInfo(*this, Index);
+ NumUAVSlots = std::max(NumUAVSlots, ResAttr.CacheOffset + ResDesc.ArraySize);
+ break;
+
+ case SHADER_RESOURCE_TYPE_SAMPLER:
+ // Initialize current sampler in place, increment sampler counter
+ new (&GetResource<SamplerBindInfo>(sam++)) SamplerBindInfo(*this, Index);
+ NumSamplerSlots = std::max(NumSamplerSlots, ResAttr.CacheOffset + ResDesc.ArraySize);
+ break;
+
+ default:
+ UNEXPECTED("Unsupported resource type.");
+ }
+ });
+
+ // clang-format off
+ VERIFY(cb == GetNumCBs(), "Not all CBs are initialized which will cause a crash when dtor is called");
+ VERIFY(texSrv == GetNumTexSRVs(), "Not all Tex SRVs are initialized which will cause a crash when dtor is called");
+ VERIFY(texUav == GetNumTexUAVs(), "Not all Tex UAVs are initialized which will cause a crash when dtor is called");
+ VERIFY(bufSrv == GetNumBufSRVs(), "Not all Buf SRVs are initialized which will cause a crash when dtor is called");
+ VERIFY(bufUav == GetNumBufUAVs(), "Not all Buf UAVs are initialized which will cause a crash when dtor is called");
+ VERIFY(sam == GetNumSamplers(), "Not all samplers are initialized which will cause a crash when dtor is called");
+ // clang-format on
+}
+
+void ShaderVariableManagerD3D11::ConstBuffBindInfo::BindResource(IDeviceObject* pBuffer, Uint32 ArrayIndex)
+{
+ const auto& Desc = GetDesc();
+ const auto& Attr = GetAttribs();
+ DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
+ auto& ResourceCache = m_ParentManager.m_ResourceCache;
+
+ VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER);
+
+ // We cannot use ValidatedCast<> here as the resource retrieved from the
+ // resource mapping can be of wrong type
+ RefCntAutoPtr<BufferD3D11Impl> pBuffD3D11Impl{pBuffer, IID_BufferD3D11};
+#ifdef DILIGENT_DEVELOPMENT
+ {
+ const auto& CachedCB = ResourceCache.GetCB(Attr.CacheOffset + ArrayIndex);
+ VerifyConstantBufferBinding(Desc.Name, Desc.ArraySize, Desc.VarType, Desc.Flags, ArrayIndex, pBuffer, pBuffD3D11Impl.RawPtr(), CachedCB.pBuff.RawPtr());
+ }
+#endif
+ ResourceCache.SetCB(Attr.CacheOffset, ArrayIndex, Attr.BindPoints, std::move(pBuffD3D11Impl));
+}
+
+
+void ShaderVariableManagerD3D11::TexSRVBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
+{
+ const auto& Desc = GetDesc();
+ const auto& Attr = GetAttribs();
+ DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
+ auto& ResourceCache = m_ParentManager.m_ResourceCache;
+
+ VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV ||
+ Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT);
+
+ // We cannot use ValidatedCast<> here as the resource retrieved from the
+ // resource mapping can be of wrong type
+ RefCntAutoPtr<TextureViewD3D11Impl> pViewD3D11{pView, IID_TextureViewD3D11};
+#ifdef DILIGENT_DEVELOPMENT
+ {
+ auto& CachedSRV = ResourceCache.GetSRV(Attr.CacheOffset + ArrayIndex);
+ VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
+ pView, pViewD3D11.RawPtr(), {TEXTURE_VIEW_SHADER_RESOURCE},
+ RESOURCE_DIM_UNDEFINED, false, CachedSRV.pView.RawPtr());
+ }
+#endif
+
+ if (Attr.IsSamplerAssigned() && !Attr.IsImmutableSamplerAssigned())
+ {
+ const auto& SampAttr = m_ParentManager.GetAttribs(Attr.SamplerInd);
+ const auto& SampDesc = m_ParentManager.GetResourceDesc(Attr.SamplerInd);
+ VERIFY_EXPR(SampDesc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER);
+ VERIFY_EXPR((Desc.ShaderStages & SampDesc.ShaderStages) == Desc.ShaderStages);
+ VERIFY_EXPR(SampDesc.ArraySize == Desc.ArraySize || SampDesc.ArraySize == 1);
+ const auto SampArrayIndex = (SampDesc.ArraySize != 1 ? ArrayIndex : 0);
+
+ SamplerD3D11Impl* pSamplerD3D11Impl = nullptr;
+ if (pViewD3D11)
+ {
+ pSamplerD3D11Impl = ValidatedCast<SamplerD3D11Impl>(pViewD3D11->GetSampler());
+#ifdef DILIGENT_DEVELOPMENT
+ if (pSamplerD3D11Impl == nullptr)
+ {
+ if (SampDesc.ArraySize > 1)
+ LOG_ERROR_MESSAGE("Failed to bind sampler to variable '", SampDesc.Name, "[", ArrayIndex, "]'. Sampler is not set in the texture view '", pViewD3D11->GetDesc().Name, "'");
+ else
+ LOG_ERROR_MESSAGE("Failed to bind sampler to variable '", SampDesc.Name, "'. Sampler is not set in the texture view '", pViewD3D11->GetDesc().Name, "'");
+ }
+#endif
+ }
+#ifdef DILIGENT_DEVELOPMENT
+ if (SampDesc.VarType != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC)
+ {
+ auto& CachedSampler = ResourceCache.GetSampler(SampAttr.CacheOffset + SampArrayIndex);
+ if (CachedSampler.pSampler != nullptr && CachedSampler.pSampler != pSamplerD3D11Impl)
+ {
+ auto VarTypeStr = GetShaderVariableTypeLiteralName(GetType());
+ LOG_ERROR_MESSAGE("Non-null sampler is already bound to ", VarTypeStr, " shader variable '", GetShaderResourcePrintName(SampDesc, ArrayIndex),
+ "'. Attempting to bind another sampler or null is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic.");
+ }
+ }
+#endif
+ ResourceCache.SetSampler(SampAttr.CacheOffset, SampArrayIndex, SampAttr.BindPoints, pSamplerD3D11Impl);
+ }
+ ResourceCache.SetTexSRV(Attr.CacheOffset, ArrayIndex, Attr.BindPoints, std::move(pViewD3D11));
+}
+
+void ShaderVariableManagerD3D11::SamplerBindInfo::BindResource(IDeviceObject* pSampler, Uint32 ArrayIndex)
+{
+ const auto& Desc = GetDesc();
+ const auto& Attr = GetAttribs();
+ DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
+ auto& ResourceCache = m_ParentManager.m_ResourceCache;
+
+ VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER);
+
+ // We cannot use ValidatedCast<> here as the resource retrieved from the
+ // resource mapping can be of wrong type
+ RefCntAutoPtr<SamplerD3D11Impl> pSamplerD3D11{pSampler, IID_SamplerD3D11};
+
+#ifdef DILIGENT_DEVELOPMENT
+ if (pSampler && !pSamplerD3D11)
+ {
+ LOG_ERROR_MESSAGE("Failed to bind object '", Desc.Name, "' to variable '", GetShaderResourcePrintName(Desc, ArrayIndex),
+ "''. Incorect object type: sampler is expected.");
+ }
+
+ if (Attr.IsSamplerAssigned())
+ {
+ auto* TexSRVName = m_ParentManager.GetResourceDesc(Attr.SamplerInd).Name; // AZ TODO: check
+ LOG_WARNING_MESSAGE("Texture sampler sampler '", Desc.Name, "' is assigned to texture SRV '",
+ TexSRVName, "' and should not be accessed directly. The sampler is initialized when texture SRV is set to '",
+ TexSRVName, "' variable.");
+ }
+
+ if (GetType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC)
+ {
+ auto& CachedSampler = ResourceCache.GetSampler(Attr.CacheOffset + ArrayIndex);
+ if (CachedSampler.pSampler != nullptr && CachedSampler.pSampler != pSamplerD3D11)
+ {
+ auto VarTypeStr = GetShaderVariableTypeLiteralName(GetType());
+ LOG_ERROR_MESSAGE("Non-null sampler is already bound to ", VarTypeStr, " shader variable '", GetShaderResourcePrintName(Desc, ArrayIndex),
+ "'. Attempting to bind another sampler or null is an error and may cause unpredicted behavior. "
+ "Use another shader resource binding instance or label the variable as dynamic.");
+ }
+ }
+#endif
+
+ ResourceCache.SetSampler(Attr.CacheOffset, ArrayIndex, Attr.BindPoints, std::move(pSamplerD3D11));
+}
+
+void ShaderVariableManagerD3D11::BuffSRVBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
+{
+ const auto& Desc = GetDesc();
+ const auto& Attr = GetAttribs();
+ DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
+ auto& ResourceCache = m_ParentManager.m_ResourceCache;
+
+ VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV);
+
+ // We cannot use ValidatedCast<> here as the resource retrieved from the
+ // resource mapping can be of wrong type
+ RefCntAutoPtr<BufferViewD3D11Impl> pViewD3D11{pView, IID_BufferViewD3D11};
+#ifdef DILIGENT_DEVELOPMENT
+ {
+ auto& CachedSRV = ResourceCache.GetSRV(Attr.CacheOffset + ArrayIndex);
+ VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
+ pView, pViewD3D11.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE},
+ RESOURCE_DIM_BUFFER, false, CachedSRV.pView.RawPtr());
+ }
+#endif
+ ResourceCache.SetBufSRV(Attr.CacheOffset, ArrayIndex, Attr.BindPoints, std::move(pViewD3D11));
+}
+
+
+void ShaderVariableManagerD3D11::TexUAVBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
+{
+ const auto& Desc = GetDesc();
+ const auto& Attr = GetAttribs();
+ DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
+ auto& ResourceCache = m_ParentManager.m_ResourceCache;
+
+ VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV);
+
+ // We cannot use ValidatedCast<> here as the resource retrieved from the
+ // resource mapping can be of wrong type
+ RefCntAutoPtr<TextureViewD3D11Impl> pViewD3D11{pView, IID_TextureViewD3D11};
+#ifdef DILIGENT_DEVELOPMENT
+ {
+ auto& CachedUAV = ResourceCache.GetUAV(Attr.CacheOffset + ArrayIndex);
+ VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
+ pView, pViewD3D11.RawPtr(), {TEXTURE_VIEW_UNORDERED_ACCESS},
+ RESOURCE_DIM_UNDEFINED, false, CachedUAV.pView.RawPtr());
+ }
+#endif
+ ResourceCache.SetTexUAV(Attr.CacheOffset, ArrayIndex, Attr.BindPoints, std::move(pViewD3D11));
+}
+
+
+void ShaderVariableManagerD3D11::BuffUAVBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
+{
+ const auto& Desc = GetDesc();
+ const auto& Attr = GetAttribs();
+ DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
+ auto& ResourceCache = m_ParentManager.m_ResourceCache;
+
+ VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV);
+
+ // We cannot use ValidatedCast<> here as the resource retrieved from the
+ // resource mapping can be of wrong type
+ RefCntAutoPtr<BufferViewD3D11Impl> pViewD3D11{pView, IID_BufferViewD3D11};
+#ifdef DILIGENT_DEVELOPMENT
+ {
+ auto& CachedUAV = ResourceCache.GetUAV(Attr.CacheOffset + ArrayIndex);
+ VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
+ pView, pViewD3D11.RawPtr(), {BUFFER_VIEW_UNORDERED_ACCESS},
+ RESOURCE_DIM_BUFFER, false, CachedUAV.pView.RawPtr());
+ }
+#endif
+ ResourceCache.SetBufUAV(Attr.CacheOffset, ArrayIndex, Attr.BindPoints, std::move(pViewD3D11));
+}
+
+void ShaderVariableManagerD3D11::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags)
+{
+ if (pResourceMapping == nullptr)
+ {
+ LOG_ERROR_MESSAGE("Failed to bind resources: resource mapping is null");
+ return;
+ }
+
+ if ((Flags & BIND_SHADER_RESOURCES_UPDATE_ALL) == 0)
+ Flags |= BIND_SHADER_RESOURCES_UPDATE_ALL;
+
+ HandleResources(
+ [&](ConstBuffBindInfo& cb) {
+ cb.BindResources<ConstBuffBindInfo>(pResourceMapping, Flags);
+ },
+ [&](TexSRVBindInfo& ts) {
+ ts.BindResources<TexSRVBindInfo>(pResourceMapping, Flags);
+ },
+ [&](TexUAVBindInfo& uav) {
+ uav.BindResources<TexUAVBindInfo>(pResourceMapping, Flags);
+ },
+ [&](BuffSRVBindInfo& srv) {
+ srv.BindResources<BuffSRVBindInfo>(pResourceMapping, Flags);
+ },
+ [&](BuffUAVBindInfo& uav) {
+ uav.BindResources<BuffUAVBindInfo>(pResourceMapping, Flags);
+ },
+ [&](SamplerBindInfo& sam) {
+ sam.BindResources<SamplerBindInfo>(pResourceMapping, Flags);
+ });
+}
+
+template <typename ResourceType>
+IShaderResourceVariable* ShaderVariableManagerD3D11::GetResourceByName(const Char* Name) const
+{
+ auto NumResources = GetNumResources<ResourceType>();
+ for (Uint32 res = 0; res < NumResources; ++res)
+ {
+ auto& Resource = GetResource<ResourceType>(res);
+ if (strcmp(Resource.GetDesc().Name, Name) == 0)
+ return &Resource;
+ }
+
+ return nullptr;
+}
+
+IShaderResourceVariable* ShaderVariableManagerD3D11::GetVariable(const Char* Name) const
+{
+ if (auto* pCB = GetResourceByName<ConstBuffBindInfo>(Name))
+ return pCB;
+
+ if (auto* pTexSRV = GetResourceByName<TexSRVBindInfo>(Name))
+ return pTexSRV;
+
+ if (auto* pTexUAV = GetResourceByName<TexUAVBindInfo>(Name))
+ return pTexUAV;
+
+ if (auto* pBuffSRV = GetResourceByName<BuffSRVBindInfo>(Name))
+ return pBuffSRV;
+
+ if (auto* pBuffUAV = GetResourceByName<BuffUAVBindInfo>(Name))
+ return pBuffUAV;
+
+ if (!m_pSignature->IsUsingCombinedSamplers())
+ {
+ // Immutable samplers are never created in the resource layout
+ if (auto* pSampler = GetResourceByName<SamplerBindInfo>(Name))
+ return pSampler;
+ }
+
+ return nullptr;
+}
+
+class ShaderVariableIndexLocator
+{
+public:
+ ShaderVariableIndexLocator(const ShaderVariableManagerD3D11& _Layout, const ShaderVariableManagerD3D11::ShaderVariableD3D11Base& Variable) :
+ // clang-format off
+ Layout {_Layout},
+ VarOffset(reinterpret_cast<const Uint8*>(&Variable) - reinterpret_cast<const Uint8*>(_Layout.m_ResourceBuffer))
+ // clang-format on
+ {}
+
+ template <typename ResourceType>
+ bool TryResource(ShaderVariableManagerD3D11::OffsetType NextResourceTypeOffset)
+ {
+#ifdef DILIGENT_DEBUG
+ {
+ VERIFY(Layout.GetResourceOffset<ResourceType>() >= dbgPreviousResourceOffset, "Resource types are processed out of order!");
+ dbgPreviousResourceOffset = Layout.GetResourceOffset<ResourceType>();
+ VERIFY_EXPR(NextResourceTypeOffset >= Layout.GetResourceOffset<ResourceType>());
+ }
+#endif
+ if (VarOffset < NextResourceTypeOffset)
+ {
+ auto RelativeOffset = VarOffset - Layout.GetResourceOffset<ResourceType>();
+ DEV_CHECK_ERR(RelativeOffset % sizeof(ResourceType) == 0, "Offset is not multiple of resource type (", sizeof(ResourceType), ")");
+ Index += static_cast<Uint32>(RelativeOffset / sizeof(ResourceType));
+ return true;
+ }
+ else
+ {
+ Index += Layout.GetNumResources<ResourceType>();
+ return false;
+ }
+ }
+
+ Uint32 GetIndex() const { return Index; }
+
+private:
+ const ShaderVariableManagerD3D11& Layout;
+ const size_t VarOffset;
+ Uint32 Index = 0;
+#ifdef DILIGENT_DEBUG
+ Uint32 dbgPreviousResourceOffset = 0;
+#endif
+};
+
+Uint32 ShaderVariableManagerD3D11::GetVariableIndex(const ShaderVariableD3D11Base& Variable) const
+{
+ if (m_ResourceBuffer == nullptr)
+ {
+ LOG_ERROR("This shader resource layout does not have resources");
+ return static_cast<Uint32>(-1);
+ }
+
+ ShaderVariableIndexLocator IdxLocator(*this, Variable);
+ if (IdxLocator.TryResource<ConstBuffBindInfo>(m_TexSRVsOffset))
+ return IdxLocator.GetIndex();
+
+ if (IdxLocator.TryResource<TexSRVBindInfo>(m_TexUAVsOffset))
+ return IdxLocator.GetIndex();
+
+ if (IdxLocator.TryResource<TexUAVBindInfo>(m_BuffSRVsOffset))
+ return IdxLocator.GetIndex();
+
+ if (IdxLocator.TryResource<BuffSRVBindInfo>(m_BuffUAVsOffset))
+ return IdxLocator.GetIndex();
+
+ if (IdxLocator.TryResource<BuffUAVBindInfo>(m_SamplerOffset))
+ return IdxLocator.GetIndex();
+
+ if (!m_pSignature->IsUsingCombinedSamplers())
+ {
+ if (IdxLocator.TryResource<SamplerBindInfo>(m_MemorySize))
+ return IdxLocator.GetIndex();
+ }
+
+ LOG_ERROR("Failed to get variable index. The variable ", &Variable, " does not belong to this shader resource layout");
+ return static_cast<Uint32>(-1);
+}
+
+class ShaderVariableLocator
+{
+public:
+ ShaderVariableLocator(const ShaderVariableManagerD3D11& _Layout, Uint32 _Index) :
+ // clang-format off
+ Layout{_Layout},
+ Index {_Index }
+ // clang-format on
+ {
+ }
+
+ template <typename ResourceType>
+ IShaderResourceVariable* TryResource()
+ {
+#ifdef DILIGENT_DEBUG
+ {
+ VERIFY(Layout.GetResourceOffset<ResourceType>() >= dbgPreviousResourceOffset, "Resource types are processed out of order!");
+ dbgPreviousResourceOffset = Layout.GetResourceOffset<ResourceType>();
+ }
+#endif
+ auto NumResources = Layout.GetNumResources<ResourceType>();
+ if (Index < NumResources)
+ return &Layout.GetResource<ResourceType>(Index);
+ else
+ {
+ Index -= NumResources;
+ return nullptr;
+ }
+ }
+
+private:
+ ShaderVariableManagerD3D11 const& Layout;
+ Uint32 Index = 0;
+#ifdef DILIGENT_DEBUG
+ Uint32 dbgPreviousResourceOffset = 0;
+#endif
+};
+
+IShaderResourceVariable* ShaderVariableManagerD3D11::GetVariable(Uint32 Index) const
+{
+ ShaderVariableLocator VarLocator(*this, Index);
+
+ if (auto* pCB = VarLocator.TryResource<ConstBuffBindInfo>())
+ return pCB;
+
+ if (auto* pTexSRV = VarLocator.TryResource<TexSRVBindInfo>())
+ return pTexSRV;
+
+ if (auto* pTexUAV = VarLocator.TryResource<TexUAVBindInfo>())
+ return pTexUAV;
+
+ if (auto* pBuffSRV = VarLocator.TryResource<BuffSRVBindInfo>())
+ return pBuffSRV;
+
+ if (auto* pBuffUAV = VarLocator.TryResource<BuffUAVBindInfo>())
+ return pBuffUAV;
+
+ if (!m_pSignature->IsUsingCombinedSamplers())
+ {
+ if (auto* pSampler = VarLocator.TryResource<SamplerBindInfo>())
+ return pSampler;
+ }
+
+ LOG_ERROR(Index, " is not a valid variable index.");
+ return nullptr;
+}
+
+Uint32 ShaderVariableManagerD3D11::GetVariableCount() const
+{
+ return GetNumCBs() + GetNumTexSRVs() + GetNumTexUAVs() + GetNumBufSRVs() + GetNumBufUAVs() + GetNumSamplers();
+}
+
+// AZ TODO
+#if 0 //def DILIGENT_DEVELOPMENT
+bool ShaderVariableManagerD3D11::dvpVerifyBindings() const
+{
+
+# define LOG_MISSING_BINDING(VarType, Attrs, BindPt) \
+ do \
+ { \
+ if (Attrs.BindCount == 1) \
+ LOG_ERROR_MESSAGE("No resource is bound to ", VarType, " variable '", Attrs.Name, "' in shader '", GetShaderName(), "'"); \
+ else \
+ LOG_ERROR_MESSAGE("No resource is bound to ", VarType, " variable '", Attrs.Name, "[", BindPt - Attrs.BindPoint, "]' in shader '", GetShaderName(), "'"); \
+ } while (false)
+
+ m_ResourceCache.DvpVerifyCacheConsistency();
+
+ bool BindingsOK = true;
+ HandleConstResources(
+ [&](const ConstBuffBindInfo& cb) //
+ {
+ for (Uint32 BindPoint = cb.m_Attribs.BindPoint; BindPoint < Uint32{cb.m_Attribs.BindPoint} + cb.m_Attribs.BindCount; ++BindPoint)
+ {
+ if (!m_ResourceCache.IsCBBound(BindPoint))
+ {
+ LOG_MISSING_BINDING("constant buffer", cb.m_Attribs, BindPoint);
+ BindingsOK = false;
+ }
+ }
+ },
+
+ [&](const TexSRVBindInfo& ts) //
+ {
+ for (Uint32 BindPoint = ts.m_Attribs.BindPoint; BindPoint < Uint32{ts.m_Attribs.BindPoint} + ts.m_Attribs.BindCount; ++BindPoint)
+ {
+ if (!m_ResourceCache.IsSRVBound(BindPoint, true))
+ {
+ LOG_MISSING_BINDING("texture", ts.m_Attribs, BindPoint);
+ BindingsOK = false;
+ }
+
+ if (ts.ValidSamplerAssigned())
+ {
+ const auto& Sampler = GetConstResource<SamplerBindInfo>(ts.SamplerIndex);
+ VERIFY_EXPR(Sampler.m_Attribs.BindCount == ts.m_Attribs.BindCount || Sampler.m_Attribs.BindCount == 1);
+
+ // Verify that if single sampler is used for all texture array elements, all samplers set in the resource views are consistent
+ if (ts.m_Attribs.BindCount > 1 && Sampler.m_Attribs.BindCount == 1)
+ {
+ ShaderResourceCacheD3D11::CachedSampler* pCachedSamplers = nullptr;
+ ID3D11SamplerState** ppCachedD3D11Samplers = nullptr;
+ m_ResourceCache.GetSamplerArrays(pCachedSamplers, ppCachedD3D11Samplers);
+ VERIFY_EXPR(Sampler.m_Attribs.BindPoint < m_ResourceCache.GetSamplerCount());
+ const auto& CachedSampler = pCachedSamplers[Sampler.m_Attribs.BindPoint];
+
+ ShaderResourceCacheD3D11::CachedResource* pCachedResources = nullptr;
+ ID3D11ShaderResourceView** ppCachedD3D11Resources = nullptr;
+ m_ResourceCache.GetSRVArrays(pCachedResources, ppCachedD3D11Resources);
+ VERIFY_EXPR(BindPoint < m_ResourceCache.GetSRVCount());
+ auto& CachedResource = pCachedResources[BindPoint];
+ if (CachedResource.pView)
+ {
+ auto* pTexView = CachedResource.pView.RawPtr<ITextureView>();
+ auto* pSampler = pTexView->GetSampler();
+ if (pSampler != nullptr && pSampler != CachedSampler.pSampler.RawPtr())
+ {
+ LOG_ERROR_MESSAGE("All elements of texture array '", ts.m_Attribs.Name, "' in shader '", GetShaderName(), "' share the same sampler. However, the sampler set in view for element ", BindPoint - ts.m_Attribs.BindPoint, " does not match bound sampler. This may cause incorrect behavior on GL platform.");
+ }
+ }
+ }
+ }
+ }
+ },
+
+ [&](const TexUAVBindInfo& uav) //
+ {
+ for (Uint32 BindPoint = uav.m_Attribs.BindPoint; BindPoint < Uint32{uav.m_Attribs.BindPoint} + uav.m_Attribs.BindCount; ++BindPoint)
+ {
+ if (!m_ResourceCache.IsUAVBound(BindPoint, true))
+ {
+ LOG_MISSING_BINDING("texture UAV", uav.m_Attribs, BindPoint);
+ BindingsOK = false;
+ }
+ }
+ },
+
+ [&](const BuffSRVBindInfo& buf) //
+ {
+ for (Uint32 BindPoint = buf.m_Attribs.BindPoint; BindPoint < Uint32{buf.m_Attribs.BindPoint} + buf.m_Attribs.BindCount; ++BindPoint)
+ {
+ if (!m_ResourceCache.IsSRVBound(BindPoint, false))
+ {
+ LOG_MISSING_BINDING("buffer", buf.m_Attribs, BindPoint);
+ BindingsOK = false;
+ }
+ }
+ },
+
+ [&](const BuffUAVBindInfo& uav) //
+ {
+ for (Uint32 BindPoint = uav.m_Attribs.BindPoint; BindPoint < Uint32{uav.m_Attribs.BindPoint} + uav.m_Attribs.BindCount; ++BindPoint)
+ {
+ if (!m_ResourceCache.IsUAVBound(BindPoint, false))
+ {
+ LOG_MISSING_BINDING("buffer UAV", uav.m_Attribs, BindPoint);
+ BindingsOK = false;
+ }
+ }
+ },
+
+ [&](const SamplerBindInfo& sam) //
+ {
+ for (Uint32 BindPoint = sam.m_Attribs.BindPoint; BindPoint < Uint32{sam.m_Attribs.BindPoint} + sam.m_Attribs.BindCount; ++BindPoint)
+ {
+ if (!m_ResourceCache.IsSamplerBound(BindPoint))
+ {
+ LOG_MISSING_BINDING("sampler", sam.m_Attribs, BindPoint);
+ BindingsOK = false;
+ }
+ }
+ } // clang-format off
+ ); // clang-format on
+# undef LOG_MISSING_BINDING
+
+ return BindingsOK;
+}
+
+#endif
+} // namespace Diligent