diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2020-10-28 02:08:28 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-10-28 02:08:28 +0000 |
| commit | f8be662d357be9dcbb4b298d93b43d29ae93ce04 (patch) | |
| tree | dcc972b937b3ad92b71c3ba136d11e4ad3da38bc /Graphics/GraphicsEngineD3D12 | |
| parent | PSO refactoring for ray tracing (diff) | |
| download | DiligentCore-f8be662d357be9dcbb4b298d93b43d29ae93ce04.tar.gz DiligentCore-f8be662d357be9dcbb4b298d93b43d29ae93ce04.zip | |
A number of updates/fixes to PSO refactor merge
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
15 files changed, 363 insertions, 503 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp index 89e52955..c6678ddd 100644 --- a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp +++ b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp @@ -75,4 +75,8 @@ D3D12_QUERY_TYPE QueryTypeToD3D12QueryType(QUERY_TYPE QueryType); D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE AttachmentLoadOpToD3D12BeginningAccessType(ATTACHMENT_LOAD_OP LoadOp); D3D12_RENDER_PASS_ENDING_ACCESS_TYPE AttachmentStoreOpToD3D12EndingAccessType(ATTACHMENT_STORE_OP StoreOp); +D3D12_SHADER_VISIBILITY ShaderTypeToD3D12ShaderVisibility(SHADER_TYPE ShaderType); +SHADER_TYPE D3D12ShaderVisibilityToShaderType(D3D12_SHADER_VISIBILITY ShaderVisibility); + + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index 4bdeb08c..6a27a029 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -133,13 +133,13 @@ private: void Append(ShaderD3D12Impl* pShader); size_t Count() const; - SHADER_TYPE Type; + SHADER_TYPE Type = SHADER_TYPE_UNKNOWN; std::vector<ShaderD3D12Impl*> Shaders; }; using TShaderStages = std::vector<ShaderStageInfo>; - template <typename PSOCreateInfoType> - void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages); + template <typename PSOCreateInfoType, typename InitPSODescType> + void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages, InitPSODescType InitPSODesc); void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages); void Destruct(); @@ -157,6 +157,7 @@ private: // Resource layout index in m_pShaderResourceLayouts 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"); }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp index 2bc13c31..ab72e22a 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -178,6 +178,11 @@ public: ShaderVersion GetMaxShaderModel() const; D3D_FEATURE_LEVEL GetD3DFeatureLevel() const; + static Uint32 GetShaderGroupHandleSize() + { + return D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; + } + private: template <typename PSOCreateInfoType> void CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState); diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp index 6deac5f0..a6bf76b1 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp @@ -32,11 +32,11 @@ #include <array> #include "ShaderResourceLayoutD3D12.hpp" #include "BufferD3D12Impl.hpp" +#include "D3D12TypeConversions.hpp" namespace Diligent { -D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType); D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapTypeFromRangeType(D3D12_DESCRIPTOR_RANGE_TYPE RangeType); class RootParameter @@ -513,10 +513,6 @@ private: class CommandContext& Ctx, bool IsCompute, bool ValidateStates) const; - -#ifdef DILIGENT_DEBUG - SHADER_TYPE m_DbgShaderStages = SHADER_TYPE_UNKNOWN; -#endif }; void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, @@ -537,7 +533,11 @@ void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN; #ifdef DILIGENT_DEBUG - dbgShaderType = m_DbgShaderStages; + { + auto& Param = static_cast<const D3D12_ROOT_PARAMETER&>(RootView); + VERIFY_EXPR(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV); + dbgShaderType = D3D12ShaderVisibilityToShaderType(Param.ShaderVisibility); + } #endif auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(0, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, dbgShaderType); diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp index ac16cf9f..f1eb5c85 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp @@ -86,6 +86,7 @@ private: // Resource layout index in m_ShaderResourceCache 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"); bool m_bStaticResourcesInitialized = false; const Uint8 m_NumShaders = 0; diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp index cf69793a..73ebe3b8 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp @@ -167,7 +167,7 @@ public: const SHADER_TYPE dbgRefShaderType) const { VERIFY(m_dbgHeapType == dbgDescriptorHeapType, "Incosistent descriptor heap type"); - VERIFY((m_dbgShaderType & dbgRefShaderType) == dbgRefShaderType, "Incosistent shader type"); + VERIFY(dbgRefShaderType == SHADER_TYPE_UNKNOWN || m_dbgShaderType == SHADER_TYPE_UNKNOWN || m_dbgShaderType == dbgRefShaderType, "Incosistent shader type"); VERIFY(OffsetFromTableStart < m_NumResources, "Root table is not large enough to store descriptor at offset ", OffsetFromTableStart); return m_pResources[OffsetFromTableStart]; diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp index bd581101..1f2b3d2d 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp @@ -50,22 +50,9 @@ // m' == NumSamplers[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] // d' == NumSamplers[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] // -// Every D3D12Resource structure holds a reference to D3DShaderResourceAttribs structure from ShaderResourcesD3D12. -// ShaderResourceLayoutD3D12 holds shared pointer to ShaderResourcesD3D12 instance. Note that ShaderResourcesD3D12::SamplerId -// references a sampler in ShaderResourcesD3D12, while D3D12Resource::SamplerId references a sampler in ShaderResourceLayoutD3D12, -// and the two are not necessarily the same // // -// ________________SamplerId____________________ -// | | -// _____________________ ______________|_____________________________________________V________ -// | | unique_ptr | | | | | | | -// |ShaderResourcesD3D12 |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | -// |_____________________| |________|___________|___________|___________|___________|____________| -// A A A A -// | \ / \ -// |shared_ptr Ref Ref Ref -// ________|__________________ ________\________________________/_________________________\________________________________________________ +// ___________________________ ____________________________________________________________________________________________________________ // | | unique_ptr | | | | | | | // | ShaderResourceLayoutD3D12 |--------------->| D3D12Resource[0] | D3D12Resource[1] | ... | D3D12Resource[smd] | D3D12Resource[smd+1] | ... | // |___________________________| |__________________|__________________|_______________|____________________|______________________|__________| @@ -79,9 +66,27 @@ // | | | | | | // | ShaderVariableManagerD3D12 |---------------->| ShaderVariableD3D12Impl[0] | ShaderVariableD3D12Impl[1] | ... | // |____________________________| |____________________________|____________________________|_________________| - // -// http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Figure2 +// +// +// +// +// One ShaderResourceLayoutD3D12 instance can be referenced by multiple objects +// +// +// ________________________ _<m_pShaderResourceLayouts>_ _____<m_pShaderVarMgrs>_____ ________________________________ +// | | | | | | | | +// | PipelineStateD3D12Impl |========>| ShaderResourceLayoutD3D12 |<-------| ShaderVariableManagerD3D12 |<====| ShaderResourceBindingD3D12Impl | +// |________________________| |____________________________| |____________________________| |________________________________| +// A +// \ +// \ _____<m_pShaderVarMgrs>_____ ________________________________ +// \ | | | | +// '-------| ShaderVariableManagerD3D12 |<====| ShaderResourceBindingD3D12Impl | +// |____________________________| |________________________________| +// +// +// // Resources in the resource cache are identified by the root index and offset in the descriptor table // // @@ -101,21 +106,26 @@ #include <array> #include "ShaderBase.hpp" -#include "ShaderResourcesD3D12.hpp" #include "ShaderResourceCacheD3D12.hpp" #include "ShaderD3D12Impl.hpp" +#include "StringPool.hpp" +#include "D3DCommonTypeConversions.hpp" namespace Diligent { /// Diligent::ShaderResourceLayoutD3D12 class -// sizeof(ShaderResourceLayoutD3D12) == 64 (MS compiler, x64) +// sizeof(ShaderResourceLayoutD3D12) == 56 (MS compiler, x64) class ShaderResourceLayoutD3D12 final { public: explicit ShaderResourceLayoutD3D12(IObject& Owner) noexcept : m_Owner{Owner} - {} + { +#if defined(_MSC_VER) && defined(_WIN64) + static_assert(sizeof(*this) == 56, "Unexpected sizeof(ShaderResourceLayoutD3D12)"); +#endif + } // There are two modes a layout can be initialized: // - initialize static resource layout and initialize shader resource cache to hold static resources @@ -141,7 +151,7 @@ public: ~ShaderResourceLayoutD3D12(); - // sizeof(D3D12Resource) == 24 (x64) + // sizeof(D3D12Resource) == 32 (x64) struct D3D12Resource final { // clang-format off @@ -153,68 +163,57 @@ public: static constexpr const Uint32 ResourceTypeBits = 3; static constexpr const Uint32 VariableTypeBits = 2; - static constexpr const Uint32 RootIndexBits = 16 - ResourceTypeBits - VariableTypeBits; + static constexpr const Uint32 RootIndexBits = 32 - ResourceTypeBits - VariableTypeBits; - static constexpr const Uint32 InvalidRootIndex = (1 << RootIndexBits) - 1; - static constexpr const Uint32 MaxRootIndex = InvalidRootIndex - 1; + static constexpr const Uint32 InvalidRootIndex = (1U << RootIndexBits) - 1U; + static constexpr const Uint32 MaxRootIndex = InvalidRootIndex - 1U; - static constexpr const Uint32 InvalidSamplerId = 0xFFFF; - static constexpr const Uint32 MaxSamplerId = InvalidSamplerId-1; static constexpr const Uint32 InvalidOffset = static_cast<Uint32>(-1); - static_assert( SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES < (1 << VariableTypeBits), "2 bits is not enough to store SHADER_RESOURCE_VARIABLE_TYPE"); - static_assert( static_cast<int>(CachedResourceType::NumTypes) < (1 << ResourceTypeBits), "3 bits is not enough to store CachedResourceType"); - + static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES < (1 << VariableTypeBits), "Not enough bits to represent SHADER_RESOURCE_VARIABLE_TYPE"); + static_assert(static_cast<int>(CachedResourceType::NumTypes) < (1 << ResourceTypeBits), "Not enough bits to represent CachedResourceType"); + /* 0 */ const ShaderResourceLayoutD3D12& ParentResLayout; -/*16 */ const Uint32 OffsetFromTableStart; -/*20.0*/ const Uint16 ResourceType : ResourceTypeBits; // | 0 1 2 | -/*20.3*/ const Uint16 VariableType : VariableTypeBits; // | 3 4 | -/*20.5*/ const Uint16 RootIndex : RootIndexBits; // | 5 6 7 ... 15 | -/*22 */ const Uint16 SamplerId; -/* */ const char* const Name; -/* */ const Uint16 BindCount; -/* */ const Uint16 BindPoint; -/* */ const Uint8 InputType; -/* */ const Uint8 SRVDimension; -/* */ // End of data +/* 8 */ const D3DShaderResourceAttribs Attribs; +/*24 */ const Uint32 OffsetFromTableStart; +/*28.0*/ const Uint32 ResourceType : ResourceTypeBits; // | 0 1 2 | +/*28.3*/ const Uint32 VariableType : VariableTypeBits; // | 3 4 | +/*28.5*/ const Uint32 RootIndex : RootIndexBits; // | 5 6 7 ... 15 | +/*32 */ // End of data // clang-format on D3D12Resource(const ShaderResourceLayoutD3D12& _ParentLayout, + StringPool& _StringPool, + const D3DShaderResourceAttribs& _Attribs, + Uint32 _SamplerId, SHADER_RESOURCE_VARIABLE_TYPE _VariableType, CachedResourceType _ResType, Uint32 _RootIndex, - Uint32 _OffsetFromTableStart, - Uint32 _SamplerId, - const char* _Name, - Uint32 _BindCount, - Uint32 _BindPoint, - D3D_SHADER_INPUT_TYPE _InputType, - D3D_SRV_DIMENSION _SRVDimension) noexcept : + Uint32 _OffsetFromTableStart) noexcept : // clang-format off - ParentResLayout {_ParentLayout }, - ResourceType {static_cast<Uint16>(_ResType) }, - VariableType {static_cast<Uint16>(_VariableType)}, - RootIndex {static_cast<Uint16>(_RootIndex) }, - SamplerId {static_cast<Uint16>(_SamplerId) }, - OffsetFromTableStart{ _OffsetFromTableStart }, - Name {_Name}, - BindCount {static_cast<Uint16>(_BindCount) }, - BindPoint {static_cast<Uint16>(_BindPoint) }, - InputType {static_cast<Uint8>(_InputType) }, - SRVDimension {static_cast<Uint8>(_SRVDimension) } + ParentResLayout{_ParentLayout}, + Attribs + { + _StringPool, + _Attribs, + _SamplerId + }, + ResourceType {static_cast<Uint32>(_ResType) }, + VariableType {static_cast<Uint32>(_VariableType)}, + RootIndex {static_cast<Uint32>(_RootIndex) }, + OffsetFromTableStart{ _OffsetFromTableStart } // clang-format on { +#if defined(_MSC_VER) && defined(_WIN64) + static_assert(sizeof(*this) == 32, "Unexpected sizeof(D3D12Resource)"); +#endif + VERIFY(IsValidOffset(), "Offset must be valid"); VERIFY(IsValidRootIndex(), "Root index must be valid"); VERIFY(_RootIndex <= MaxRootIndex, "Root index (", _RootIndex, ") exceeds max allowed value (", MaxRootIndex, ")"); + VERIFY(static_cast<Uint32>(_ResType) < (1 << ResourceTypeBits), "Resource type is out of representable range"); VERIFY(_VariableType < (1 << VariableTypeBits), "Variable type is out of representable range"); - VERIFY(_SamplerId == InvalidSamplerId || _SamplerId <= MaxSamplerId, "Sampler id (", _SamplerId, ") exceeds max allowed value (", MaxSamplerId, ")"); - VERIFY(_SamplerId == InvalidSamplerId || GetResType() == CachedResourceType::TexSRV, "A sampler can only be assigned to a Texture SRV"); - VERIFY(_BindCount <= std::numeric_limits<decltype(BindCount)>::max(), "BindCount (", _BindCount, ") exceeds max representable value ", std::numeric_limits<decltype(BindCount)>::max()); - VERIFY(_BindPoint <= std::numeric_limits<decltype(BindPoint)>::max(), "BindPoint (", _BindPoint, ") exceeds max representable value ", std::numeric_limits<decltype(BindPoint)>::max()); - VERIFY(_InputType <= std::numeric_limits<decltype(InputType)>::max(), "InputType (", _InputType, ") exceeds max representable value ", std::numeric_limits<decltype(InputType)>::max()); - VERIFY(_SRVDimension <= std::numeric_limits<decltype(SRVDimension)>::max(), "SRVDimension (", _SRVDimension, ") exceeds max representable value ", std::numeric_limits<decltype(SRVDimension)>::max()); } bool IsBound(Uint32 ArrayIndex, @@ -225,42 +224,12 @@ public: ShaderResourceCacheD3D12& ResourceCache) const; // clang-format off - bool ValidSamplerAssigned()const { return SamplerId != InvalidSamplerId; } - bool IsValidRootIndex() const { return RootIndex != InvalidRootIndex; } - bool IsValidOffset() const { return OffsetFromTableStart != InvalidOffset; } + bool IsValidRootIndex() const { return RootIndex != InvalidRootIndex; } + bool IsValidOffset() const { return OffsetFromTableStart != InvalidOffset; } // clang-format on CachedResourceType GetResType() const { return static_cast<CachedResourceType>(ResourceType); } SHADER_RESOURCE_VARIABLE_TYPE GetVariableType() const { return static_cast<SHADER_RESOURCE_VARIABLE_TYPE>(VariableType); } - HLSLShaderResourceDesc GetHLSLResourceDesc() const; - - bool IsValidBindPoint() const - { - return BindPoint != D3DShaderResourceAttribs::InvalidBindPoint; - } - - String GetPrintName(Uint32 ArrayInd) const - { - VERIFY_EXPR(ArrayInd < BindCount); - if (BindCount > 1) - return String(Name) + '[' + std::to_string(ArrayInd) + ']'; - else - return Name; - } - - D3D_SHADER_INPUT_TYPE GetInputType() const - { - return static_cast<D3D_SHADER_INPUT_TYPE>(InputType); - } - - D3D_SRV_DIMENSION GetSRVDimension() const - { - return static_cast<D3D_SRV_DIMENSION>(SRVDimension); - } - - RESOURCE_DIMENSION GetResourceDimension() const; - - bool IsMultisample() const; private: void CacheCB(IDeviceObject* pBuffer, @@ -393,21 +362,21 @@ private: return GetResource(m_SamplersOffsets[0] + s); } - void AllocateMemory(IMemoryAllocator& Allocator, - const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& CbvSrvUavCount, - const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& SamplerCount); + StringPool AllocateMemory(IMemoryAllocator& Allocator, + const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& CbvSrvUavCount, + const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& SamplerCount, + size_t StringPoolSize); // clang-format off /* 0 */ std::unique_ptr<void, STDDeleterRawMem<void> > m_ResourceBuffer; /* 16 */ std::array<Uint16, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES + 1> m_CbvSrvUavOffsets = {}; /* 24 */ std::array<Uint16, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES + 1> m_SamplersOffsets = {}; -/* 24 */ StringPool m_StringPool; /* 32 */ IObject& m_Owner; -/* 48 */ CComPtr<ID3D12Device> m_pd3d12Device; -/* */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN; +/* 40 */ CComPtr<ID3D12Device> m_pd3d12Device; +/* 48 */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN; /* */ bool m_IsUsingSeparateSamplers = false; -/* 64 */ // End of data +/* 56 */ // End of data // clang-format on }; diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp index fe867d89..1c4af270 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp @@ -30,7 +30,7 @@ /// \file /// Declaration of Diligent::ShaderResourcesD3D12 class -// ShaderResourcesD3D12 are created by ShaderD3D12Impl instances. They are then referenced by ShaderResourceLayoutD3D12 objects, which are in turn +// ShaderResourcesD3D12 are created by ShaderD3D12Impl instances. They are then used by ShaderResourceLayoutD3D12 objects, which are // created by instances of PipelineStatesD3D12Impl and ShaderD3D12Impl // // _________________ @@ -43,10 +43,10 @@ // | | unique_ptr | | | | | | | // | ShaderResourcesD3D12 |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | // |______________________| |________|___________|___________|___________|___________|____________| -// A A A A -// | \ / \ -// |shared_ptr Ref Ref Ref -// ________|__________________ ________\________________________/_________________________\_________________________________________ +// A A A +// \ / \ +// Copy Copy Copy +// ___________________________ ________\________________________/_________________________\_________________________________________ // | | unique_ptr | | | | | | | // | ShaderResourceLayoutD3D12 |--------------->| SRV_CBV_UAV[0] | SRV_CBV_UAV[1] | ... | Sampler[0] | Sampler[1] | ... | // |___________________________| |___________________|_________________|_______________|__________________|_________________|__________| @@ -58,29 +58,6 @@ // | PipelineStateD3D12Impl | // |________________________| // -// -// -// One ShaderResourcesD3D12 instance can be referenced by multiple objects -// -// -// ________________________ _<m_pShaderResourceLayouts>_ _____<m_pShaderVarMgrs>_____ ________________________________ -// | | | | | | | | -// | PipelineStateD3D12Impl |========>| ShaderResourceLayoutD3D12 |<-------| ShaderVariableManagerD3D12 |<====| ShaderResourceBindingD3D12Impl | -// |________________________| |____________________________| |____________________________| |________________________________| -// | A -// |shared_ptr \ -// _________________ ___________V__________ \ _____<m_pShaderVarMgrs>_____ ________________________________ -// | | shared_ptr | | \ | | | | -// | ShaderD3D12Impl |---------------->| ShaderResourcesD3D12 | '-------| ShaderVariableManagerD3D12 |<====| ShaderResourceBindingD3D12Impl | -// |_________________| |______________________| |____________________________| |________________________________| -// | |___________________ A -// | | | -// V V |shared_ptr -// _______<m_StaticVarsMgr>____ ___<m_StaticResLayout>_|___ -// | | | | -// | ShaderVariableManagerD3D12 |------>| ShaderResourceLayoutD3D12 | -// |____________________________| |___________________________| -// #include "ShaderResources.hpp" diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp index 1e60ecd8..c30d8296 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp @@ -186,7 +186,7 @@ public: virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) override final { - VerifyAndCorrectSetArrayArguments(m_Resource.Name, m_Resource.BindCount, FirstElement, NumElements); + VerifyAndCorrectSetArrayArguments(m_Resource.Attribs.Name, m_Resource.Attribs.BindCount, FirstElement, NumElements); for (Uint32 Elem = 0; Elem < NumElements; ++Elem) m_Resource.BindResource(ppObjects[Elem], FirstElement + Elem, m_ParentManager.m_ResourceCache); } @@ -198,7 +198,7 @@ public: virtual HLSLShaderResourceDesc DILIGENT_CALL_TYPE GetHLSLResourceDesc() const override final { - return m_Resource.GetHLSLResourceDesc(); + return m_Resource.Attribs.GetHLSLResourceDesc(); } virtual Uint32 DILIGENT_CALL_TYPE GetIndex() const override final diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index 89c495b9..3ea4bad0 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -540,4 +540,57 @@ D3D12_RENDER_PASS_ENDING_ACCESS_TYPE AttachmentStoreOpToD3D12EndingAccessType(AT // clang-format on } +D3D12_SHADER_VISIBILITY ShaderTypeToD3D12ShaderVisibility(SHADER_TYPE ShaderType) +{ + static_assert(SHADER_TYPE_LAST == SHADER_TYPE_CALLABLE, "Please update the switch below to handle the new shader type"); + switch (ShaderType) + { + // clang-format off + case SHADER_TYPE_VERTEX: return D3D12_SHADER_VISIBILITY_VERTEX; + case SHADER_TYPE_PIXEL: return D3D12_SHADER_VISIBILITY_PIXEL; + case SHADER_TYPE_GEOMETRY: return D3D12_SHADER_VISIBILITY_GEOMETRY; + case SHADER_TYPE_HULL: return D3D12_SHADER_VISIBILITY_HULL; + case SHADER_TYPE_DOMAIN: return D3D12_SHADER_VISIBILITY_DOMAIN; + case SHADER_TYPE_COMPUTE: return D3D12_SHADER_VISIBILITY_ALL; +# ifdef D3D12_H_HAS_MESH_SHADER + case SHADER_TYPE_AMPLIFICATION: return D3D12_SHADER_VISIBILITY_AMPLIFICATION; + case SHADER_TYPE_MESH: return D3D12_SHADER_VISIBILITY_MESH; +# endif + case SHADER_TYPE_RAY_GEN: + case SHADER_TYPE_RAY_MISS: + case SHADER_TYPE_RAY_CLOSEST_HIT: + case SHADER_TYPE_RAY_ANY_HIT: + case SHADER_TYPE_RAY_INTERSECTION: + case SHADER_TYPE_CALLABLE: return D3D12_SHADER_VISIBILITY_ALL; + // clang-format on + default: + LOG_ERROR("Unknown shader type (", ShaderType, ")"); + return D3D12_SHADER_VISIBILITY_ALL; + } +} + +SHADER_TYPE D3D12ShaderVisibilityToShaderType(D3D12_SHADER_VISIBILITY ShaderVisibility) +{ + static_assert(SHADER_TYPE_LAST == SHADER_TYPE_CALLABLE, "Please update the switch below to handle the new shader type"); + switch (ShaderVisibility) + { + // clang-format off + case D3D12_SHADER_VISIBILITY_ALL: return SHADER_TYPE_UNKNOWN; + case D3D12_SHADER_VISIBILITY_VERTEX: return SHADER_TYPE_VERTEX; + case D3D12_SHADER_VISIBILITY_PIXEL: return SHADER_TYPE_PIXEL; + case D3D12_SHADER_VISIBILITY_GEOMETRY: return SHADER_TYPE_GEOMETRY; + case D3D12_SHADER_VISIBILITY_HULL: return SHADER_TYPE_HULL; + case D3D12_SHADER_VISIBILITY_DOMAIN: return SHADER_TYPE_DOMAIN; +# ifdef D3D12_H_HAS_MESH_SHADER + case D3D12_SHADER_VISIBILITY_AMPLIFICATION: return SHADER_TYPE_AMPLIFICATION; + case D3D12_SHADER_VISIBILITY_MESH: return SHADER_TYPE_MESH; +# endif + // clang-format on + default: + LOG_ERROR("Unknown shader visibility (", ShaderVisibility, ")"); + return SHADER_TYPE_UNKNOWN; + } +} + + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 6efa4acc..a446e960 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -108,8 +108,9 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI { #define LOG_PSO_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of ray tracing PSO '", CreateInfo.PSODesc.Name, "' is invalid: ", ##__VA_ARGS__) - Uint32 ShaderIndex = 0; - Uint32 GroupIndex = 0; + Uint32 ShaderIndex = 0; + Uint32 GroupIndex = 0; + std::unordered_map<IShader*, LPCWSTR> UniqueShaders; const auto ShaderIndexToStr = [&TempPool](Uint32 Index) -> LPCWSTR { @@ -131,8 +132,8 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI auto Result = UniqueShaders.emplace(pShader, nullptr); if (Result.second) { - auto& LibDesc = *TempPool.Allocate<D3D12_DXIL_LIBRARY_DESC>(); - auto& ExportDesc = *TempPool.Allocate<D3D12_EXPORT_DESC>(); + auto& LibDesc = *TempPool.Construct<D3D12_DXIL_LIBRARY_DESC>(); + auto& ExportDesc = *TempPool.Construct<D3D12_EXPORT_DESC>(); auto* pShaderD3D12 = ValidatedCast<ShaderD3D12Impl>(pShader); LibDesc.DXILLibrary.BytecodeLength = pShaderD3D12->GetShaderByteCode()->GetBufferSize(); @@ -161,56 +162,61 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i) { - AddDxilLib(CreateInfo.pGeneralShaders[i].pShader, CreateInfo.pGeneralShaders[i].Name); + const auto& GeneralShader = CreateInfo.pGeneralShaders[i]; + AddDxilLib(GeneralShader.pShader, GeneralShader.Name); - bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pGeneralShaders[i].Name)}, GroupIndex++).second; + bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(GeneralShader.Name)}, GroupIndex++).second; if (!IsUniqueName) LOG_PSO_ERROR_AND_THROW("pGeneralShaders[", i, "].Name must be unique"); } for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i) { - auto& HitGroupDesc = *TempPool.Allocate<D3D12_HIT_GROUP_DESC>(); - HitGroupDesc.HitGroupExport = TempPool.CopyWString(CreateInfo.pTriangleHitShaders[i].Name); + const auto& TriHitShader = CreateInfo.pTriangleHitShaders[i]; + + auto& HitGroupDesc = *TempPool.Construct<D3D12_HIT_GROUP_DESC>(); + HitGroupDesc.HitGroupExport = TempPool.CopyWString(TriHitShader.Name); HitGroupDesc.Type = D3D12_HIT_GROUP_TYPE_TRIANGLES; - HitGroupDesc.ClosestHitShaderImport = AddDxilLib(CreateInfo.pTriangleHitShaders[i].pClosestHitShader, nullptr); - HitGroupDesc.AnyHitShaderImport = AddDxilLib(CreateInfo.pTriangleHitShaders[i].pAnyHitShader, nullptr); + HitGroupDesc.ClosestHitShaderImport = AddDxilLib(TriHitShader.pClosestHitShader, nullptr); + HitGroupDesc.AnyHitShaderImport = AddDxilLib(TriHitShader.pAnyHitShader, nullptr); HitGroupDesc.IntersectionShaderImport = nullptr; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc}); - bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pTriangleHitShaders[i].Name)}, GroupIndex++).second; + bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(TriHitShader.Name)}, GroupIndex++).second; if (!IsUniqueName) LOG_PSO_ERROR_AND_THROW("pTriangleHitShaders[", i, "].Name must be unique"); } for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i) { - auto& HitGroupDesc = *TempPool.Allocate<D3D12_HIT_GROUP_DESC>(); - HitGroupDesc.HitGroupExport = TempPool.CopyWString(CreateInfo.pProceduralHitShaders[i].Name); + const auto& ProcHitShader = CreateInfo.pProceduralHitShaders[i]; + + auto& HitGroupDesc = *TempPool.Construct<D3D12_HIT_GROUP_DESC>(); + HitGroupDesc.HitGroupExport = TempPool.CopyWString(ProcHitShader.Name); HitGroupDesc.Type = D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE; - HitGroupDesc.ClosestHitShaderImport = AddDxilLib(CreateInfo.pProceduralHitShaders[i].pClosestHitShader, nullptr); - HitGroupDesc.AnyHitShaderImport = AddDxilLib(CreateInfo.pProceduralHitShaders[i].pAnyHitShader, nullptr); - HitGroupDesc.IntersectionShaderImport = AddDxilLib(CreateInfo.pProceduralHitShaders[i].pIntersectionShader, nullptr); + HitGroupDesc.ClosestHitShaderImport = AddDxilLib(ProcHitShader.pClosestHitShader, nullptr); + HitGroupDesc.AnyHitShaderImport = AddDxilLib(ProcHitShader.pAnyHitShader, nullptr); + HitGroupDesc.IntersectionShaderImport = AddDxilLib(ProcHitShader.pIntersectionShader, nullptr); Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc}); - bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pProceduralHitShaders[i].Name)}, GroupIndex++).second; + bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(ProcHitShader.Name)}, GroupIndex++).second; if (!IsUniqueName) LOG_PSO_ERROR_AND_THROW("pProceduralHitShaders[", i, "].Name must be unique"); } - VERIFY_EXPR(Uint32(CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount) == GroupIndex); + VERIFY_EXPR(Uint32{CreateInfo.GeneralShaderCount} + Uint32{CreateInfo.TriangleHitShaderCount} + Uint32{CreateInfo.ProceduralHitShaderCount} == GroupIndex); if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH) LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth must be less than equal to ", D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH); - auto& PipelineConfig = *TempPool.Allocate<D3D12_RAYTRACING_PIPELINE_CONFIG>(); + auto& PipelineConfig = *TempPool.Construct<D3D12_RAYTRACING_PIPELINE_CONFIG>(); // for compatibility with Vulkan set minimal recursion depth to 1 PipelineConfig.MaxTraceRecursionDepth = std::max<Uint32>(1, CreateInfo.RayTracingPipeline.MaxRecursionDepth); Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG, &PipelineConfig}); - auto& ShaderConfig = *TempPool.Allocate<D3D12_RAYTRACING_SHADER_CONFIG>(); + auto& ShaderConfig = *TempPool.Construct<D3D12_RAYTRACING_SHADER_CONFIG>(); ShaderConfig.MaxAttributeSizeInBytes = D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES; ShaderConfig.MaxPayloadSizeInBytes = 32; // AZ TODO Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG, &ShaderConfig}); @@ -225,56 +231,51 @@ void GetShaderIdentifiers(ID3D12StateObject* pSO, { const Uint32 ShaderIdentifierSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; - WCHAR TempName[256] = {}; - auto ConvertWStr = [&TempName](const char* Src) { - Uint32 i = 0; - for (; i < _countof(TempName) && Src[i] != 0; ++i) - TempName[i] = static_cast<WCHAR>(Src[i]); - TempName[i] = 0; - return TempName; - }; - CComPtr<ID3D12StateObjectProperties> pStateObjectProperties; - auto hr = pSO->QueryInterface(IID_PPV_ARGS(&pStateObjectProperties)); + + auto hr = pSO->QueryInterface(IID_PPV_ARGS(&pStateObjectProperties)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to get state object properties"); for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i) { - auto iter = NameToGroupIndex.find(CreateInfo.pGeneralShaders[i].Name); + const auto& GeneralShader = CreateInfo.pGeneralShaders[i]; + + auto iter = NameToGroupIndex.find(GeneralShader.Name); if (iter == NameToGroupIndex.end()) - LOG_ERROR_AND_THROW("Failed to get shader group index by name"); + LOG_ERROR_AND_THROW("Failed to get shader group index for general shader group '", GeneralShader.Name, "'"); - WCHAR* ShaderName = ConvertWStr(CreateInfo.pGeneralShaders[i].Name); - const void* ShaderID = pStateObjectProperties->GetShaderIdentifier(ShaderName); + const auto* ShaderID = pStateObjectProperties->GetShaderIdentifier(WidenString(GeneralShader.Name).c_str()); if (ShaderID == nullptr) - LOG_ERROR_AND_THROW("Failed to get shader identifier"); + LOG_ERROR_AND_THROW("Failed to get shader identifier for general shader group '", GeneralShader.Name, "'"); std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize); } for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i) { - auto iter = NameToGroupIndex.find(CreateInfo.pTriangleHitShaders[i].Name); + const auto& TriHitShader = CreateInfo.pTriangleHitShaders[i]; + + auto iter = NameToGroupIndex.find(TriHitShader.Name); if (iter == NameToGroupIndex.end()) - LOG_ERROR_AND_THROW("Failed to get shader group index by name"); + LOG_ERROR_AND_THROW("Failed to get shader group index for triangle hit group '", TriHitShader.Name, "'"); - WCHAR* ShaderName = ConvertWStr(CreateInfo.pTriangleHitShaders[i].Name); - const void* ShaderID = pStateObjectProperties->GetShaderIdentifier(ShaderName); + const auto* ShaderID = pStateObjectProperties->GetShaderIdentifier(WidenString(TriHitShader.Name).c_str()); if (ShaderID == nullptr) - LOG_ERROR_AND_THROW("Failed to get shader identifier"); + LOG_ERROR_AND_THROW("Failed to get shader identifier for triangle hit group '", TriHitShader.Name, "'"); std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize); } for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i) { - auto iter = NameToGroupIndex.find(CreateInfo.pProceduralHitShaders[i].Name); + const auto& ProcHitShader = CreateInfo.pProceduralHitShaders[i]; + + auto iter = NameToGroupIndex.find(ProcHitShader.Name); if (iter == NameToGroupIndex.end()) - LOG_ERROR_AND_THROW("Failed to get shader group index by name"); + LOG_ERROR_AND_THROW("Failed to get shader group index for procedural hit shader group '", ProcHitShader.Name, "'"); - WCHAR* ShaderName = ConvertWStr(CreateInfo.pProceduralHitShaders[i].Name); - const void* ShaderID = pStateObjectProperties->GetShaderIdentifier(ShaderName); + const auto* ShaderID = pStateObjectProperties->GetShaderIdentifier(WidenString(ProcHitShader.Name).c_str()); if (ShaderID == nullptr) - LOG_ERROR_AND_THROW("Failed to get shader identifier"); + LOG_ERROR_AND_THROW("Failed to get shader identifier for procedural hit shader group '", ProcHitShader.Name, "'"); std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize); } @@ -284,9 +285,9 @@ void GetShaderIdentifiers(ID3D12StateObject* pSO, PipelineStateD3D12Impl::ShaderStageInfo::ShaderStageInfo(SHADER_TYPE _Type, ShaderD3D12Impl* _pShader) : - Type{_Type} + Type{_Type}, + Shaders{{_pShader}} { - Shaders.push_back(_pShader); } void PipelineStateD3D12Impl::ShaderStageInfo::Append(ShaderD3D12Impl* pShader) @@ -300,9 +301,10 @@ size_t PipelineStateD3D12Impl::ShaderStageInfo::Count() const } -template <typename PSOCreateInfoType> +template <typename PSOCreateInfoType, typename InitPSODescType> void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, - TShaderStages& ShaderStages) + TShaderStages& ShaderStages, + InitPSODescType InitPSODesc) { m_ResourceLayoutIndex.fill(-1); @@ -334,7 +336,7 @@ void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& Create for (Uint32 s = 0; s < NumShaderStages; ++s) new (m_pStaticVarManagers + s) ShaderVariableManagerD3D12{*this, GetStaticShaderResCache(s)}; - InitializePipelineDesc(CreateInfo, MemPool); + InitPSODesc(CreateInfo, MemPool); m_RootSig.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout); @@ -354,7 +356,12 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* try { TShaderStages ShaderStages; - InitInternalObjects(CreateInfo, ShaderStages); + InitInternalObjects(CreateInfo, ShaderStages, + [this](const GraphicsPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) // + { + InitializePipelineDesc(CreateInfo, MemPool); + } // + ); auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); if (m_Desc.PipelineType == PIPELINE_TYPE_GRAPHICS) @@ -439,12 +446,9 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* // The only valid bit is D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices. d3d12PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; - CComPtr<ID3D12PipelineState> pPSO; - HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, IID_PPV_ARGS(&pPSO)); + HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, IID_PPV_ARGS(&m_pd3d12PSO)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create pipeline state"); - - m_pd3d12PSO = pPSO; } #ifdef D3D12_H_HAS_MESH_SHADER @@ -527,13 +531,10 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* streamDesc.SizeInBytes = sizeof(d3d12PSODesc); streamDesc.pPipelineStateSubobjectStream = &d3d12PSODesc; - auto* device2 = pDeviceD3D12->GetD3D12Device2(); - CComPtr<ID3D12PipelineState> pPSO; - HRESULT hr = device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&pPSO)); + auto* device2 = pDeviceD3D12->GetD3D12Device2(); + HRESULT hr = device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&m_pd3d12PSO)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create pipeline state"); - - m_pd3d12PSO = pPSO; } #endif // D3D12_H_HAS_MESH_SHADER else @@ -566,7 +567,12 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* try { TShaderStages ShaderStages; - InitInternalObjects(CreateInfo, ShaderStages); + InitInternalObjects(CreateInfo, ShaderStages, + [this](const ComputePipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) // + { + InitializePipelineDesc(CreateInfo, MemPool); + } // + ); auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); @@ -591,13 +597,10 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature(); - CComPtr<ID3D12PipelineState> pPSO; - HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, IID_PPV_ARGS(&pPSO)); + HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, IID_PPV_ARGS(&m_pd3d12PSO)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create pipeline state"); - m_pd3d12PSO = pPSO; - if (*m_Desc.Name != 0) { m_pd3d12PSO->SetName(WidenString(m_Desc.Name).c_str()); @@ -622,63 +625,30 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* { try { - m_ResourceLayoutIndex.fill(-1); - - TShaderStages ShaderStages; - ExtractShaders<ShaderD3D12Impl>(CreateInfo, ShaderStages); - - TNameToGroupIndexMap NameToGroupIndex; + TShaderStages ShaderStages; std::vector<D3D12_STATE_SUBOBJECT> Subobjects; - const Uint32 ShaderIdentifierSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; DynamicLinearAllocator TempPool{GetRawAllocator(), 4 << 10}; - LinearAllocator MemPool{GetRawAllocator()}; - - const auto NumShaderStages = GetNumShaderStages(); - VERIFY_EXPR(NumShaderStages > 0 && NumShaderStages == ShaderStages.size()); - - MemPool.AddSpace<ShaderResourceCacheD3D12>(NumShaderStages); - MemPool.AddSpace<ShaderResourceLayoutD3D12>(NumShaderStages * 2); - MemPool.AddSpace<ShaderVariableManagerD3D12>(NumShaderStages); - - ReserveSpaceForPipelineDesc(CreateInfo, ShaderIdentifierSize, MemPool); - - MemPool.Reserve(); - - m_pStaticResourceCaches = MemPool.ConstructArray<ShaderResourceCacheD3D12>(NumShaderStages, ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources); - - // The memory is now owned by PipelineStateD3D12Impl and will be freed by Destruct(). - auto* Ptr = MemPool.ReleaseOwnership(); - VERIFY_EXPR(Ptr == m_pStaticResourceCaches); - (void)Ptr; - - m_pShaderResourceLayouts = MemPool.ConstructArray<ShaderResourceLayoutD3D12>(NumShaderStages * 2, std::ref(*this)); - - m_pStaticVarManagers = MemPool.Allocate<ShaderVariableManagerD3D12>(NumShaderStages); - for (Uint32 s = 0; s < NumShaderStages; ++s) - new (m_pStaticVarManagers + s) ShaderVariableManagerD3D12{*this, GetStaticShaderResCache(s)}; - - BuildRTPipelineDescription(CreateInfo, NameToGroupIndex, Subobjects, TempPool, MemPool); - InitializePipelineDesc(CreateInfo, ShaderIdentifierSize, std::move(NameToGroupIndex), MemPool); - - m_RootSig.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout); - - // 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, ShaderStages); + InitInternalObjects(CreateInfo, ShaderStages, + [&](const RayTracingPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) // + { + TNameToGroupIndexMap NameToGroupIndex; + BuildRTPipelineDescription(CreateInfo, NameToGroupIndex, Subobjects, TempPool, MemPool); + InitializePipelineDesc(CreateInfo, std::move(NameToGroupIndex), MemPool); + } // + ); - D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot; - GlobalRoot.pGlobalRootSignature = m_RootSig.GetD3D12RootSignature(); + D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot = {m_RootSig.GetD3D12RootSignature()}; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &GlobalRoot}); - D3D12_STATE_OBJECT_DESC RTPipelineDesc; - RTPipelineDesc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE; - RTPipelineDesc.NumSubobjects = static_cast<UINT>(Subobjects.size()); - RTPipelineDesc.pSubobjects = Subobjects.data(); + D3D12_STATE_OBJECT_DESC RTPipelineDesc = {}; + RTPipelineDesc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE; + RTPipelineDesc.NumSubobjects = static_cast<UINT>(Subobjects.size()); + RTPipelineDesc.pSubobjects = Subobjects.data(); - auto pd3d12Device = pDeviceD3D12->GetD3D12Device5(); CComPtr<ID3D12StateObject> pSO; - HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&pSO)); + + auto pd3d12Device = pDeviceD3D12->GetD3D12Device5(); + HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&pSO)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create ray tracing state object"); diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index eee2e1fa..9feabb6a 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -136,7 +136,10 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo sizeof(FenceD3D12Impl), sizeof(QueryD3D12Impl), sizeof(RenderPassD3D12Impl), - sizeof(FramebufferD3D12Impl) + sizeof(FramebufferD3D12Impl), + 0, + 0, + 0 } }, m_pd3d12Device {pd3d12Device}, @@ -312,8 +315,8 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo CHECK_REQUIRED_FEATURE(ShaderInt8, "8-bit shader operations are"); CHECK_REQUIRED_FEATURE(ResourceBuffer8BitAccess, "8-bit resoure buffer access is"); CHECK_REQUIRED_FEATURE(UniformBuffer8BitAccess, "8-bit uniform buffer access is"); - - CHECK_REQUIRED_FEATURE(RayTracing, "ray tracing is"); + + CHECK_REQUIRED_FEATURE(RayTracing, "ray tracing is"); // clang-format on #undef CHECK_REQUIRED_FEATURE diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index 718f4b17..35274af3 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -173,62 +173,6 @@ RootSignature::RootSignature() : } // clang-format off -static constexpr D3D12_SHADER_VISIBILITY ShaderTypeInd2ShaderVisibilityMap[] -{ - D3D12_SHADER_VISIBILITY_VERTEX, // 0 - D3D12_SHADER_VISIBILITY_PIXEL, // 1 - D3D12_SHADER_VISIBILITY_GEOMETRY, // 2 - D3D12_SHADER_VISIBILITY_HULL, // 3 - D3D12_SHADER_VISIBILITY_DOMAIN, // 4 - D3D12_SHADER_VISIBILITY_ALL, // 5 -#ifdef D3D12_H_HAS_MESH_SHADER - D3D12_SHADER_VISIBILITY_AMPLIFICATION, // 6 - D3D12_SHADER_VISIBILITY_MESH, // 7 -#else - D3D12_SHADER_VISIBILITY(6), - D3D12_SHADER_VISIBILITY(7), -#endif - D3D12_SHADER_VISIBILITY_ALL, // 8 - D3D12_SHADER_VISIBILITY_ALL, // 9 - D3D12_SHADER_VISIBILITY_ALL, // 10 - D3D12_SHADER_VISIBILITY_ALL, // 11 - D3D12_SHADER_VISIBILITY_ALL, // 12 - D3D12_SHADER_VISIBILITY_ALL, // 13 -}; -// clang-format on -D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType) -{ - auto ShaderInd = GetShaderTypeIndex(ShaderType); - auto ShaderVisibility = ShaderTypeInd2ShaderVisibilityMap[ShaderInd]; -#ifdef DILIGENT_DEBUG - static_assert(SHADER_TYPE_LAST == SHADER_TYPE_CALLABLE, "Please update the switch below to handle the new shader type"); - switch (ShaderType) - { - // clang-format off - case SHADER_TYPE_VERTEX: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_VERTEX); break; - case SHADER_TYPE_PIXEL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_PIXEL); break; - case SHADER_TYPE_GEOMETRY: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_GEOMETRY); break; - case SHADER_TYPE_HULL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_HULL); break; - case SHADER_TYPE_DOMAIN: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_DOMAIN); break; - case SHADER_TYPE_COMPUTE: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_ALL); break; -# ifdef D3D12_H_HAS_MESH_SHADER - case SHADER_TYPE_AMPLIFICATION: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_AMPLIFICATION); break; - case SHADER_TYPE_MESH: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_MESH); break; -# endif - case SHADER_TYPE_RAY_GEN: - case SHADER_TYPE_RAY_MISS: - case SHADER_TYPE_RAY_CLOSEST_HIT: - case SHADER_TYPE_RAY_ANY_HIT: - case SHADER_TYPE_RAY_INTERSECTION: - case SHADER_TYPE_CALLABLE: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_ALL); break; - // clang-format on - default: LOG_ERROR("Unknown shader type (", ShaderType, ")"); break; - } -#endif - return ShaderVisibility; -} - -// clang-format off static D3D12_DESCRIPTOR_HEAP_TYPE RangeType2HeapTypeMap[] { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0 @@ -263,11 +207,7 @@ void RootSignature::InitImmutableSampler(SHADER_TYPE ShaderT const char* SamplerSuffix, const D3DShaderResourceAttribs& SamplerAttribs) { -#ifdef DILIGENT_DEBUG - m_DbgShaderStages |= ShaderType; -#endif - - auto ShaderVisibility = GetShaderVisibility(ShaderType); + auto ShaderVisibility = ShaderTypeToD3D12ShaderVisibility(ShaderType); auto SamplerFound = false; for (auto& ImtblSmplr : m_ImmutableSamplers) { @@ -299,11 +239,7 @@ void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderT Uint32& OffsetFromTableStart // Output parameter ) { -#ifdef DILIGENT_DEBUG - m_DbgShaderStages |= ShaderType; -#endif - - const auto ShaderVisibility = GetShaderVisibility(ShaderType); + const auto ShaderVisibility = ShaderTypeToD3D12ShaderVisibility(ShaderType); if (RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV && ShaderResAttribs.BindCount == 1) { // Allocate single CBV directly in the root signature @@ -443,7 +379,7 @@ void RootSignature::AllocateImmutableSamplers(const PipelineResourceLayoutDesc& while (ShaderStages != 0) { auto Stage = ShaderStages & ~(ShaderStages - 1); - m_ImmutableSamplers.emplace_back(ImtblSamDesc, GetShaderVisibility(static_cast<SHADER_TYPE>(Stage))); + m_ImmutableSamplers.emplace_back(ImtblSamDesc, ShaderTypeToD3D12ShaderVisibility(static_cast<SHADER_TYPE>(Stage))); ShaderStages &= ~Stage; } } @@ -652,7 +588,7 @@ void RootSignature::InitResourceCache(RenderDeviceD3D12Impl* pDeviceD3D12Impl auto HeapType = HeapTypeFromRangeType(D3D12RootParam.DescriptorTable.pDescriptorRanges[0].RangeType); #ifdef DILIGENT_DEBUG - RootTableCache.SetDebugAttribs(TableSize, HeapType, m_DbgShaderStages); + RootTableCache.SetDebugAttribs(TableSize, HeapType, D3D12ShaderVisibilityToShaderType(D3D12RootParam.ShaderVisibility)); #endif // Space for dynamic variables is allocated at every draw call @@ -685,7 +621,7 @@ void RootSignature::InitResourceCache(RenderDeviceD3D12Impl* pDeviceD3D12Impl VERIFY_EXPR(RootTableCache.m_TableStartOffset == ShaderResourceCacheD3D12::InvalidDescriptorOffset); VERIFY_EXPR(D3D12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV); - RootTableCache.SetDebugAttribs(1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_DbgShaderStages); + RootTableCache.SetDebugAttribs(1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12ShaderVisibilityToShaderType(D3D12RootParam.ShaderVisibility)); } #endif @@ -915,11 +851,14 @@ __forceinline void ProcessCachedTableResources(Uint32 RootI const auto& range = D3D12Param.DescriptorTable.pDescriptorRanges[r]; for (UINT d = 0; d < range.NumDescriptors; ++d) { + SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN; #ifdef DILIGENT_DEBUG - VERIFY(dbgHeapType == HeapTypeFromRangeType(range.RangeType), "Mistmatch between descriptor heap type and descriptor range type"); + dbgShaderType = D3D12ShaderVisibilityToShaderType(D3D12Param.ShaderVisibility); #endif + VERIFY(dbgHeapType == HeapTypeFromRangeType(range.RangeType), "Mistmatch between descriptor heap type and descriptor range type"); + auto OffsetFromTableStart = range.OffsetInDescriptorsFromTableStart + d; - auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(OffsetFromTableStart, dbgHeapType, SHADER_TYPE_UNKNOWN); + auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(OffsetFromTableStart, dbgHeapType, dbgShaderType); Operation(OffsetFromTableStart, range, Res); } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index 157e42f7..34b15c4c 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -39,6 +39,7 @@ #include "PipelineStateD3D12Impl.hpp" #include "ShaderResourceVariableBase.hpp" #include "ShaderVariableD3DBase.hpp" +#include "LinearAllocator.hpp" namespace Diligent { @@ -83,9 +84,10 @@ D3D12_DESCRIPTOR_RANGE_TYPE GetDescriptorRangeType(CachedResourceType ResType) } -void ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& Allocator, - const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& CbvSrvUavCount, - const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& SamplerCount) +StringPool ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& Allocator, + const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& CbvSrvUavCount, + const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& SamplerCount, + size_t StringPoolSize) { m_CbvSrvUavOffsets[0] = 0; for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast<SHADER_RESOURCE_VARIABLE_TYPE>(VarType + 1)) @@ -103,12 +105,21 @@ void ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& VERIFY_EXPR(GetSamplerCount(VarType) == SamplerCount[VarType]); } - size_t MemSize = GetTotalResourceCount() * sizeof(D3D12Resource); - if (MemSize == 0) - return; + LinearAllocator MemPool{Allocator}; + MemPool.AddSpace<D3D12Resource>(GetTotalResourceCount()); + MemPool.AddSpace<char>(StringPoolSize); - auto* pRawMem = ALLOCATE_RAW(Allocator, "Raw memory buffer for shader resource layout resources", MemSize); - m_ResourceBuffer = std::unique_ptr<void, STDDeleterRawMem<void>>(pRawMem, Allocator); + MemPool.Reserve(); + + auto* pResources = MemPool.Allocate<D3D12Resource>(GetTotalResourceCount()); + auto* pStringPoolData = MemPool.ConstructArray<char>(StringPoolSize); + + m_ResourceBuffer = std::unique_ptr<void, STDDeleterRawMem<void>>(MemPool.Release(), Allocator); + VERIFY_EXPR(m_ResourceBuffer.get() == pResources); + + StringPool stringPool; + stringPool.AssignMemory(pStringPoolData, StringPoolSize); + return stringPool; } @@ -136,21 +147,23 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* std::unordered_map<HashMapStringKey, Uint32, HashMapStringKey::Hasher> ResourceNameToIndex; - // Count number of resources to allocate all needed memory + // Count the number of resources to allocate all needed memory m_IsUsingSeparateSamplers = !Shaders[0]->GetShaderResources()->IsUsingCombinedTextureSamplers(); m_ShaderType = Shaders[0]->GetDesc().ShaderType; size_t StringPoolSize = 0; + static constexpr Uint32 InvalidResourceIndex = ~0u; + for (auto* pShader : Shaders) { auto pResources = pShader->GetShaderResources(); VERIFY_EXPR(pResources->GetShaderType() == m_ShaderType); - const auto HandleResType = [&](const auto& Res, Uint32) // + const auto HandleCbvSrvUav = [&](const auto& Res, Uint32) // { auto VarType = pResources->FindVariableType(Res, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) { - bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Res.Name}, ~0u).second; + bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Res.Name}, InvalidResourceIndex).second; if (IsUniqueName) { StringPoolSize += strlen(Res.Name) + 1; @@ -158,8 +171,9 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* } } }; + pResources->ProcessResources( - HandleResType, + HandleCbvSrvUav, [&](const D3DShaderResourceAttribs& Sam, Uint32) // { auto VarType = pResources->FindVariableType(Sam, ResourceLayout); @@ -171,7 +185,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* // Skip immutable samplers if (ImtblSamplerInd < 0) { - bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Sam.Name}, ~0u).second; + bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Sam.Name}, InvalidResourceIndex).second; if (IsUniqueName) { StringPoolSize += strlen(Sam.Name) + 1; @@ -185,7 +199,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* auto VarType = pResources->FindVariableType(TexSRV, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) { - bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{TexSRV.Name}, ~0u).second; + bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{TexSRV.Name}, InvalidResourceIndex).second; if (IsUniqueName) { StringPoolSize += strlen(TexSRV.Name) + 1; @@ -203,15 +217,13 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* } } }, - HandleResType, - HandleResType, - HandleResType, - HandleResType); + HandleCbvSrvUav, + HandleCbvSrvUav, + HandleCbvSrvUav, + HandleCbvSrvUav); } - AllocateMemory(LayoutDataAllocator, CbvSrvUavCount, SamplerCount); - - m_StringPool.Reserve(StringPoolSize, GetRawAllocator()); + auto stringPool = AllocateMemory(LayoutDataAllocator, CbvSrvUavCount, SamplerCount, StringPoolSize); std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrCbvSrvUav = {}; std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrSampler = {}; @@ -220,12 +232,12 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* auto AddResource = [&](const D3DShaderResourceAttribs& Attribs, CachedResourceType ResType, SHADER_RESOURCE_VARIABLE_TYPE VarType, - Uint32 SamplerId = D3D12Resource::InvalidSamplerId) // + Uint32 SamplerId = D3DShaderResourceAttribs::InvalidSamplerId) // { auto ResIter = ResourceNameToIndex.find(HashMapStringKey{Attribs.Name}); VERIFY_EXPR(ResIter != ResourceNameToIndex.end()); - if (ResIter->second == ~0u) + if (ResIter->second == InvalidResourceIndex) { Uint32 RootIndex = D3D12Resource::InvalidRootIndex; Uint32 Offset = D3D12Resource::InvalidOffset; @@ -258,22 +270,31 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* VERIFY(RootIndex != D3D12Resource::InvalidRootIndex, "Root index must be valid"); VERIFY(Offset != D3D12Resource::InvalidOffset, "Offset must be valid"); - // Static samplers are never copied, and SamplerId == InvalidSamplerId + // Immutable samplers are never copied, and SamplerId == InvalidSamplerId Uint32 ResOffset = (ResType == CachedResourceType::Sampler) ? GetSamplerOffset(VarType, CurrSampler[VarType]++) : GetSrvCbvUavOffset(VarType, CurrCbvSrvUav[VarType]++); ResIter->second = ResOffset; auto& NewResource = GetResource(ResOffset); - ::new (&NewResource) D3D12Resource{*this, VarType, ResType, RootIndex, Offset, SamplerId, m_StringPool.CopyString(Attribs.Name), Attribs.BindCount, Attribs.BindPoint, - Attribs.GetInputType(), Attribs.GetSRVDimension()}; + ::new (&NewResource) D3D12Resource // + { + *this, + stringPool, + Attribs, + SamplerId, + VarType, + ResType, + RootIndex, + Offset // + }; } else { // merge with existing auto& ExistingRes = GetResource(ResIter->second); VERIFY_EXPR(ExistingRes.VariableType == VarType); - VERIFY_EXPR(ExistingRes.GetInputType() == Attribs.GetInputType()); - VERIFY_EXPR(ExistingRes.BindCount == Attribs.BindCount); + VERIFY_EXPR(ExistingRes.Attribs.GetInputType() == Attribs.GetInputType()); + VERIFY_EXPR(ExistingRes.Attribs.BindCount == Attribs.BindCount); } }; @@ -293,9 +314,9 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* if (IsAllowedType(VarType, AllowedTypeBits)) { // The error (if any) have already been logged when counting the resources - constexpr bool LogStaticSamplerArrayError = false; - auto StaticSamplerInd = pResources->FindImmutableSampler(Sam, ResourceLayout, LogStaticSamplerArrayError); - if (StaticSamplerInd >= 0) + constexpr bool LogImtblSamplerArrayError = false; + const auto ImtblSamplerInd = pResources->FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError); + if (ImtblSamplerInd >= 0) { if (pRootSig != nullptr) pRootSig->InitImmutableSampler(pResources->GetShaderType(), Sam.Name, pResources->GetCombinedSamplerSuffix(), Sam); @@ -314,7 +335,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES == 3, "Unexpected number of shader variable types"); VERIFY(CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] == GetTotalSamplerCount(), "All samplers must be initialized before texture SRVs"); - Uint32 SamplerId = D3D12Resource::InvalidSamplerId; + Uint32 SamplerId = D3DShaderResourceAttribs::InvalidSamplerId; if (TexSRV.IsCombinedWithSampler()) { const auto& SamplerAttribs = pResources->GetCombinedSampler(TexSRV); @@ -325,18 +346,18 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it"); // The error (if any) have already been logged when counting the resources - constexpr bool LogStaticSamplerArrayError = false; - auto StaticSamplerInd = pResources->FindImmutableSampler(SamplerAttribs, ResourceLayout, LogStaticSamplerArrayError); - if (StaticSamplerInd >= 0) + constexpr bool LogImtblSamplerArrayError = false; + const auto ImtblSamplerInd = pResources->FindImmutableSampler(SamplerAttribs, ResourceLayout, LogImtblSamplerArrayError); + if (ImtblSamplerInd >= 0) { - // Static samplers are never copied, and SamplerId == InvalidSamplerId + // Immutable samplers are never copied, and SamplerId == InvalidSamplerId #ifdef DILIGENT_DEBUG auto SamplerCount = GetTotalSamplerCount(); for (Uint32 s = 0; s < SamplerCount; ++s) { const auto& Sampler = GetSampler(s); - if (strcmp(Sampler.Name, SamplerAttribs.Name) == 0) - LOG_ERROR("Static sampler '", Sampler.Name, "' was found among resources. This seems to be a bug"); + if (strcmp(Sampler.Attribs.Name, SamplerAttribs.Name) == 0) + LOG_ERROR("Immutable sampler '", Sampler.Attribs.Name, "' was found among resources. This seems to be a bug"); } #endif } @@ -347,7 +368,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* for (SamplerId = 0; SamplerId < SamplerCount; ++SamplerId) { const auto& Sampler = GetSampler(SamplerId); - SamplerFound = strcmp(Sampler.Name, SamplerAttribs.Name) == 0; + SamplerFound = strcmp(Sampler.Attribs.Name, SamplerAttribs.Name) == 0; if (SamplerFound) break; } @@ -355,9 +376,9 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* if (!SamplerFound) { LOG_ERROR("Unable to find sampler '", SamplerAttribs.Name, "' assigned to texture SRV '", TexSRV.Name, "' in the list of already created resources. This seems to be a bug."); - SamplerId = D3D12Resource::InvalidSamplerId; + SamplerId = D3DShaderResourceAttribs::InvalidSamplerId; } - VERIFY(SamplerId <= D3D12Resource::MaxSamplerId, "Sampler index excceeds allowed limit"); + VERIFY(SamplerId <= D3DShaderResourceAttribs::MaxSamplerId, "Sampler index excceeds allowed limit"); } } AddResource(TexSRV, CachedResourceType::TexSRV, VarType, SamplerId); @@ -391,6 +412,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* } #ifdef DILIGENT_DEBUG + VERIFY_EXPR(stringPool.GetRemainingSize() == 0); for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast<SHADER_RESOURCE_VARIABLE_TYPE>(VarType + 1)) { VERIFY(CurrCbvSrvUav[VarType] == CbvSrvUavCount[VarType], "Not all Srv/Cbv/Uavs are initialized, which result in a crash when dtor is called"); @@ -427,7 +449,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheCB(IDeviceObject* // resource mapping can be of wrong type RefCntAutoPtr<BufferD3D12Impl> pBuffD3D12(pBuffer, IID_BufferD3D12); #ifdef DILIGENT_DEVELOPMENT - VerifyConstantBufferBinding(*this, GetVariableType(), ArrayInd, pBuffer, pBuffD3D12.RawPtr(), DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); + VerifyConstantBufferBinding(Attribs, GetVariableType(), ArrayInd, pBuffer, pBuffD3D12.RawPtr(), DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); #endif if (pBuffD3D12) { @@ -463,40 +485,6 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheCB(IDeviceObject* } } -RESOURCE_DIMENSION ShaderResourceLayoutD3D12::D3D12Resource::GetResourceDimension() const -{ - switch (GetSRVDimension()) - { - // clang-format off - case D3D_SRV_DIMENSION_BUFFER: return RESOURCE_DIM_BUFFER; - case D3D_SRV_DIMENSION_TEXTURE1D: return RESOURCE_DIM_TEX_1D; - case D3D_SRV_DIMENSION_TEXTURE1DARRAY: return RESOURCE_DIM_TEX_1D_ARRAY; - case D3D_SRV_DIMENSION_TEXTURE2D: return RESOURCE_DIM_TEX_2D; - case D3D_SRV_DIMENSION_TEXTURE2DARRAY: return RESOURCE_DIM_TEX_2D_ARRAY; - case D3D_SRV_DIMENSION_TEXTURE2DMS: return RESOURCE_DIM_TEX_2D; - case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY: return RESOURCE_DIM_TEX_2D_ARRAY; - case D3D_SRV_DIMENSION_TEXTURE3D: return RESOURCE_DIM_TEX_3D; - case D3D_SRV_DIMENSION_TEXTURECUBE: return RESOURCE_DIM_TEX_CUBE; - case D3D_SRV_DIMENSION_TEXTURECUBEARRAY: return RESOURCE_DIM_TEX_CUBE_ARRAY; - // clang-format on - default: - return RESOURCE_DIM_BUFFER; - } -} - -bool ShaderResourceLayoutD3D12::D3D12Resource::IsMultisample() const -{ - switch (GetSRVDimension()) - { - case D3D_SRV_DIMENSION_TEXTURE2DMS: - case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY: - return true; - default: - return false; - } -} - - template <typename TResourceViewType> struct ResourceViewTraits {}; @@ -506,7 +494,7 @@ struct ResourceViewTraits<ITextureViewD3D12> { static const INTERFACE_ID& IID; - static bool VerifyView(ITextureViewD3D12* pViewD3D12, const ShaderResourceLayoutD3D12::D3D12Resource& Attribs, const char* ShaderName) + static bool VerifyView(ITextureViewD3D12* pViewD3D12, const D3DShaderResourceAttribs& Attribs, const char* ShaderName) { return true; } @@ -518,7 +506,7 @@ struct ResourceViewTraits<IBufferViewD3D12> { static const INTERFACE_ID& IID; - static bool VerifyView(IBufferViewD3D12* pViewD3D12, const ShaderResourceLayoutD3D12::D3D12Resource& Attribs, const char* ShaderName) + static bool VerifyView(IBufferViewD3D12* pViewD3D12, const D3DShaderResourceAttribs& Attribs, const char* ShaderName) { return VerifyBufferViewModeD3D(pViewD3D12, Attribs, ShaderName); } @@ -539,8 +527,8 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheResourceView(IDeviceObject* // resource mapping can be of wrong type RefCntAutoPtr<TResourceViewType> pViewD3D12{pView, ResourceViewTraits<TResourceViewType>::IID}; #ifdef DILIGENT_DEVELOPMENT - VerifyResourceViewBinding(*this, GetVariableType(), ArrayIndex, pView, pViewD3D12.RawPtr(), {dbgExpectedViewType}, DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); - ResourceViewTraits<TResourceViewType>::VerifyView(pViewD3D12, *this, ParentResLayout.GetShaderName()); + VerifyResourceViewBinding(Attribs, GetVariableType(), ArrayIndex, pView, pViewD3D12.RawPtr(), {dbgExpectedViewType}, DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); + ResourceViewTraits<TResourceViewType>::VerifyView(pViewD3D12, Attribs, ParentResLayout.GetShaderName()); #endif if (pViewD3D12) { @@ -576,8 +564,8 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheSampler(IDeviceObject* Uint32 ArrayIndex, D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) const { - VERIFY(IsValidBindPoint(), "Invalid bind point"); - VERIFY_EXPR(ArrayIndex < BindCount); + VERIFY(Attribs.IsValidBindPoint(), "Invalid bind point"); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); RefCntAutoPtr<ISamplerD3D12> pSamplerD3D12(pSampler, IID_SamplerD3D12); if (pSamplerD3D12) @@ -587,7 +575,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheSampler(IDeviceObject* if (DstSam.pObject != pSampler) { auto VarTypeStr = GetShaderVariableTypeLiteralName(GetVariableType()); - LOG_ERROR_MESSAGE("Non-null sampler is already bound to ", VarTypeStr, " shader variable '", GetPrintName(ArrayIndex), + LOG_ERROR_MESSAGE("Non-null sampler is already bound to ", VarTypeStr, " shader variable '", Attribs.GetPrintName(ArrayIndex), "' in shader '", ParentResLayout.GetShaderName(), "'. Attempting to bind another sampler is an error and will " "be ignored. Use another shader resource binding instance or label the variable as dynamic."); } @@ -616,7 +604,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheSampler(IDeviceObject* } else { - LOG_ERROR_MESSAGE("Failed to bind object '", pSampler->GetDesc().Name, "' to variable '", GetPrintName(ArrayIndex), + LOG_ERROR_MESSAGE("Failed to bind object '", pSampler->GetDesc().Name, "' to variable '", Attribs.GetPrintName(ArrayIndex), "' in shader '", ParentResLayout.GetShaderName(), "'. Incorect object type: sampler is expected."); } } @@ -631,8 +619,8 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheAccelStruct(IDeviceObject* const ShaderResourceLayoutD3D12::D3D12Resource& ShaderResourceLayoutD3D12::GetAssignedSampler(const D3D12Resource& TexSrv) const { VERIFY(TexSrv.GetResType() == CachedResourceType::TexSRV, "Unexpected resource type: texture SRV is expected"); - VERIFY(TexSrv.ValidSamplerAssigned(), "Texture SRV has no associated sampler"); - const auto& SamInfo = GetSampler(TexSrv.SamplerId); + VERIFY(TexSrv.Attribs.IsCombinedWithSampler(), "Texture SRV has no associated sampler"); + const auto& SamInfo = GetSampler(TexSrv.Attribs.GetCombinedSamplerId()); VERIFY(SamInfo.GetVariableType() == TexSrv.GetVariableType(), "Inconsistent texture and sampler variable types"); //VERIFY(StreqSuff(SamInfo.Name, TexSrv.Name, GetCombinedSamplerSuffix()), "Sampler name '", SamInfo.Name, "' does not match texture name '", TexSrv.Name, '\''); return SamInfo; @@ -648,7 +636,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* Uint32 ArrayIndex, ShaderResourceCacheD3D12& ResourceCache) const { - VERIFY_EXPR(ArrayIndex < BindCount); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); const bool IsSampler = GetResType() == CachedResourceType::Sampler; auto DescriptorHeapType = IsSampler ? D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER : D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; @@ -666,7 +654,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* } else if (ResourceCache.DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources) { - if (GetResType() == CachedResourceType::CBV && BindCount == 1) + if (GetResType() == CachedResourceType::CBV && Attribs.BindCount == 1) { VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Non-array constant buffers are bound as root views and should not be assigned shader visible descriptor space"); } @@ -699,12 +687,12 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* pObj, DstRes, ArrayIndex, ShdrVisibleHeapCPUDescriptorHandle, TEXTURE_VIEW_SHADER_RESOURCE, [&](ITextureViewD3D12* pTexView) // { - if (ValidSamplerAssigned()) + if (Attribs.IsCombinedWithSampler()) { auto& Sam = ParentResLayout.GetAssignedSampler(*this); //VERIFY( !Sam.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache" ); - VERIFY_EXPR(BindCount == Sam.BindCount || Sam.BindCount == 1); - auto SamplerArrInd = Sam.BindCount > 1 ? ArrayIndex : 0; + VERIFY_EXPR(Attribs.BindCount == Sam.Attribs.BindCount || Sam.Attribs.BindCount == 1); + auto SamplerArrInd = Sam.Attribs.BindCount > 1 ? ArrayIndex : 0; auto ShdrVisibleSamplerHeapCPUDescriptorHandle = ResourceCache.GetShaderVisibleTableCPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER>(Sam.RootIndex, Sam.OffsetFromTableStart + SamplerArrInd); @@ -735,7 +723,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* } else { - LOG_ERROR_MESSAGE("Failed to bind sampler to variable '", Sam.Name, ". Sampler is not set in the texture view '", pTexView->GetDesc().Name, '\''); + LOG_ERROR_MESSAGE("Failed to bind sampler to variable '", Sam.Attribs.Name, ". Sampler is not set in the texture view '", pTexView->GetDesc().Name, '\''); } } }); @@ -768,17 +756,17 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* else { if (DstRes.pObject != nullptr && GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) - LOG_ERROR_MESSAGE("Shader variable '", Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another resource."); + LOG_ERROR_MESSAGE("Shader variable '", Attribs.Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another resource."); DstRes = ShaderResourceCacheD3D12::Resource{}; - if (ValidSamplerAssigned()) + if (Attribs.IsCombinedWithSampler()) { auto& Sam = ParentResLayout.GetAssignedSampler(*this); D3D12_CPU_DESCRIPTOR_HANDLE NullHandle = {0}; - auto SamplerArrInd = Sam.BindCount > 1 ? ArrayIndex : 0; + auto SamplerArrInd = Sam.Attribs.BindCount > 1 ? ArrayIndex : 0; auto& DstSam = ResourceCache.GetRootTable(Sam.RootIndex).GetResource(Sam.OffsetFromTableStart + SamplerArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, ParentResLayout.GetShaderType()); if (DstSam.pObject != nullptr && Sam.GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) - LOG_ERROR_MESSAGE("Sampler variable '", Sam.Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another sampler."); + LOG_ERROR_MESSAGE("Sampler variable '", Sam.Attribs.Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another sampler."); DstSam = ShaderResourceCacheD3D12::Resource{}; } } @@ -786,7 +774,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* bool ShaderResourceLayoutD3D12::D3D12Resource::IsBound(Uint32 ArrayIndex, const ShaderResourceCacheD3D12& ResourceCache) const { - VERIFY_EXPR(ArrayIndex < BindCount); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); if (RootIndex < ResourceCache.GetNumRootTables()) { @@ -808,56 +796,6 @@ bool ShaderResourceLayoutD3D12::D3D12Resource::IsBound(Uint32 ArrayIndex, const return false; } -HLSLShaderResourceDesc ShaderResourceLayoutD3D12::D3D12Resource::GetHLSLResourceDesc() const -{ - HLSLShaderResourceDesc ResourceDesc; - ResourceDesc.Name = Name; - ResourceDesc.ArraySize = BindCount; - ResourceDesc.ShaderRegister = BindPoint; - switch (GetInputType()) - { - case D3D_SIT_CBUFFER: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_CONSTANT_BUFFER; - break; - - case D3D_SIT_TBUFFER: - UNSUPPORTED("TBuffers are not supported"); - ResourceDesc.Type = SHADER_RESOURCE_TYPE_UNKNOWN; - break; - - case D3D_SIT_TEXTURE: - ResourceDesc.Type = (GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ? SHADER_RESOURCE_TYPE_BUFFER_SRV : SHADER_RESOURCE_TYPE_TEXTURE_SRV); - break; - - case D3D_SIT_SAMPLER: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_SAMPLER; - break; - - case D3D_SIT_UAV_RWTYPED: - ResourceDesc.Type = (GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ? SHADER_RESOURCE_TYPE_BUFFER_UAV : SHADER_RESOURCE_TYPE_TEXTURE_UAV); - break; - - case D3D_SIT_STRUCTURED: - case D3D_SIT_BYTEADDRESS: - ResourceDesc.Type = 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: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV; - break; - - default: - UNEXPECTED("Unknown input type"); - } - - return ResourceDesc; -} - - void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderResourceCacheD3D12& SrcCache, const ShaderResourceLayoutD3D12& DstLayout, ShaderResourceCacheD3D12& DstCache) const { // Static shader resources are stored as follows: @@ -875,16 +813,16 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR // Get resource attributes const auto& res = DstLayout.GetSrvCbvUav(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, r); auto RangeType = GetDescriptorRangeType(res.GetResType()); - for (Uint32 ArrInd = 0; ArrInd < res.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < res.Attribs.BindCount; ++ArrInd) { - auto BindPoint = res.BindPoint + ArrInd; + auto BindPoint = res.Attribs.BindPoint + ArrInd; // Source resource in the static resource cache is in the root table at index RangeType, at offset BindPoint // D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0, // D3D12_DESCRIPTOR_RANGE_TYPE_UAV = 1 // D3D12_DESCRIPTOR_RANGE_TYPE_CBV = 2 const auto& SrcRes = SrcCache.GetRootTable(RangeType).GetResource(BindPoint, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); if (!SrcRes.pObject) - LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", res.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); + LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", res.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); // Destination resource is at the root index and offset defined by the resource layout auto& DstRes = DstCache.GetRootTable(res.RootIndex).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); @@ -925,14 +863,14 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR } } - if (res.ValidSamplerAssigned()) + if (res.Attribs.IsCombinedWithSampler()) { const auto& SamInfo = DstLayout.GetAssignedSampler(res); //VERIFY(!SamInfo.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache"); - VERIFY(SamInfo.IsValidBindPoint(), "Sampler bind point must be valid"); - VERIFY_EXPR(SamInfo.BindCount == res.BindCount || SamInfo.BindCount == 1); + VERIFY(SamInfo.Attribs.IsValidBindPoint(), "Sampler bind point must be valid"); + VERIFY_EXPR(SamInfo.Attribs.BindCount == res.Attribs.BindCount || SamInfo.Attribs.BindCount == 1); } } @@ -941,14 +879,14 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR for (Uint32 s = 0; s < SamplerCount; ++s) { const auto& SamInfo = DstLayout.GetSampler(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, s); - for (Uint32 ArrInd = 0; ArrInd < SamInfo.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < SamInfo.Attribs.BindCount; ++ArrInd) { - auto BindPoint = SamInfo.BindPoint + ArrInd; + auto BindPoint = SamInfo.Attribs.BindPoint + ArrInd; // Source sampler in the static resource cache is in the root table at index 3 // (D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER = 3), at offset BindPoint const auto& SrcSampler = SrcCache.GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER).GetResource(BindPoint, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); if (!SrcSampler.pObject) - LOG_ERROR_MESSAGE("No sampler assigned to static shader variable '", SamInfo.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); + LOG_ERROR_MESSAGE("No sampler assigned to static shader variable '", SamInfo.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); auto& DstSampler = DstCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); if (DstSampler.pObject != SrcSampler.pObject) @@ -988,7 +926,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 const auto& res = GetSrvCbvUav(VarType, r); VERIFY(res.GetVariableType() == VarType, "Unexpected variable type"); - for (Uint32 ArrInd = 0; ArrInd < res.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < res.Attribs.BindCount; ++ArrInd) { const auto& CachedRes = ResourceCache.GetRootTable(res.RootIndex).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); if (CachedRes.pObject) @@ -1000,15 +938,15 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 // Dynamic buffers do not have CPU descriptor handle as they do not keep D3D12 buffer, and space is allocated from the GPU ring buffer CachedRes.CPUDescriptorHandle.ptr == 0 && !(CachedRes.Type == CachedResourceType::CBV && CachedRes.pObject.RawPtr<const BufferD3D12Impl>()->GetDesc().Usage == USAGE_DYNAMIC)) { - LOG_ERROR_MESSAGE("No resource is bound to ", GetShaderVariableTypeLiteralName(res.GetVariableType()), " variable '", res.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); + LOG_ERROR_MESSAGE("No resource is bound to ", GetShaderVariableTypeLiteralName(res.GetVariableType()), " variable '", res.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); BindingsOK = false; } - if (res.BindCount > 1 && res.ValidSamplerAssigned()) + if (res.Attribs.BindCount > 1 && res.Attribs.IsCombinedWithSampler()) { // Verify that if single sampler is used for all texture array elements, all samplers set in the resource views are consistent const auto& SamInfo = GetAssignedSampler(res); - if (SamInfo.BindCount == 1) + if (SamInfo.Attribs.BindCount == 1) { const auto& CachedSampler = ResourceCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); // Conversion must always succeed as the type is verified when resource is bound to the variable @@ -1017,7 +955,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 const auto* pSampler = pTexView->GetSampler(); if (pSampler != nullptr && CachedSampler.pObject != nullptr && CachedSampler.pObject != pSampler) { - LOG_ERROR_MESSAGE("All elements of texture array '", res.Name, "' in shader '", GetShaderName(), "' share the same sampler. However, the sampler set in view for element ", ArrInd, " does not match bound sampler. This may cause incorrect behavior on GL platform."); + LOG_ERROR_MESSAGE("All elements of texture array '", res.Attribs.Name, "' in shader '", GetShaderName(), "' share the same sampler. However, the sampler set in view for element ", ArrInd, " does not match bound sampler. This may cause incorrect behavior on GL platform."); } } } @@ -1032,7 +970,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 } else if (ResourceCache.DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources) { - if (res.GetResType() == CachedResourceType::CBV && res.BindCount == 1) + if (res.GetResType() == CachedResourceType::CBV && res.Attribs.BindCount == 1) { VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Non-array constant buffers are bound as root views and should not be assigned shader visible descriptor space"); } @@ -1052,14 +990,14 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 # endif } - if (res.ValidSamplerAssigned()) + if (res.Attribs.IsCombinedWithSampler()) { VERIFY(res.GetResType() == CachedResourceType::TexSRV, "Sampler can only be assigned to a texture SRV"); const auto& SamInfo = GetAssignedSampler(res); //VERIFY(!SamInfo.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache" ); - VERIFY(SamInfo.IsValidBindPoint(), "Sampler bind point must be valid"); + VERIFY(SamInfo.Attribs.IsValidBindPoint(), "Sampler bind point must be valid"); - for (Uint32 ArrInd = 0; ArrInd < SamInfo.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < SamInfo.Attribs.BindCount; ++ArrInd) { const auto& CachedSampler = ResourceCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); if (CachedSampler.pObject) @@ -1068,7 +1006,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 VERIFY(CachedSampler.Type == CachedResourceType::Unknown, "Unexpected cached sampler type"); if (!CachedSampler.pObject || CachedSampler.CPUDescriptorHandle.ptr == 0) { - LOG_ERROR_MESSAGE("No sampler is assigned to texture variable '", res.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); + LOG_ERROR_MESSAGE("No sampler is assigned to texture variable '", res.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); BindingsOK = false; } @@ -1101,7 +1039,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 const auto& sam = GetSampler(VarType, s); VERIFY(sam.GetVariableType() == VarType, "Unexpected sampler variable type"); - for (Uint32 ArrInd = 0; ArrInd < sam.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < sam.Attribs.BindCount; ++ArrInd) { const auto& CachedSampler = ResourceCache.GetRootTable(sam.RootIndex).GetResource(sam.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); if (CachedSampler.pObject) @@ -1110,7 +1048,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 VERIFY(CachedSampler.Type == CachedResourceType::Unknown, "Unexpected cached sampler type"); if (!CachedSampler.pObject || CachedSampler.CPUDescriptorHandle.ptr == 0) { - LOG_ERROR_MESSAGE("No sampler is bound to sampler variable '", sam.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); + LOG_ERROR_MESSAGE("No sampler is bound to sampler variable '", sam.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); BindingsOK = false; } } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp index 1c3afa53..fd58eacf 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp @@ -125,7 +125,7 @@ ShaderVariableD3D12Impl* ShaderVariableManagerD3D12::GetVariable(const Char* Nam for (Uint32 v = 0; v < m_NumVariables; ++v) { auto& Var = m_pVariables[v]; - if (strcmp(Var.m_Resource.Name, Name) == 0) + if (strcmp(Var.m_Resource.Attribs.Name, Name) == 0) { pVar = &Var; break; @@ -181,14 +181,14 @@ void ShaderVariableManagerD3D12::BindResources(IResourceMapping* pResourceMappin if ((Flags & (1 << Res.GetVariableType())) == 0) continue; - for (Uint32 ArrInd = 0; ArrInd < Res.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < Res.Attribs.BindCount; ++ArrInd) { if ((Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) && Res.IsBound(ArrInd, m_ResourceCache)) continue; RefCntAutoPtr<IDeviceObject> pObj; VERIFY_EXPR(pResourceMapping != nullptr); - pResourceMapping->GetResource(Res.Name, &pObj, ArrInd); + pResourceMapping->GetResource(Res.Attribs.Name, &pObj, ArrInd); if (pObj) { // Call non-virtual function @@ -197,7 +197,7 @@ void ShaderVariableManagerD3D12::BindResources(IResourceMapping* pResourceMappin else { if ((Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) && !Res.IsBound(ArrInd, m_ResourceCache)) - LOG_ERROR_MESSAGE("Unable to bind resource to shader variable '", Res.GetPrintName(ArrInd), "': resource is not found in the resource mapping"); + LOG_ERROR_MESSAGE("Unable to bind resource to shader variable '", Res.Attribs.GetPrintName(ArrInd), "': resource is not found in the resource mapping"); } } } |
