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 | |
| 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')
45 files changed, 868 insertions, 930 deletions
diff --git a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp index b909b016..918b81ae 100644 --- a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp +++ b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp @@ -1087,21 +1087,20 @@ String GetResourceStateString(RESOURCE_STATE State) const char* GetQueryTypeString(QUERY_TYPE QueryType) { static_assert(QUERY_TYPE_NUM_TYPES == 6, "Not all QUERY_TYPE enum values are handled"); - // clang-format off - switch(QueryType) + switch (QueryType) { + // clang-format off case QUERY_TYPE_UNDEFINED: return "QUERY_TYPE_UNDEFINED"; case QUERY_TYPE_OCCLUSION: return "QUERY_TYPE_OCCLUSION"; case QUERY_TYPE_BINARY_OCCLUSION: return "QUERY_TYPE_BINARY_OCCLUSION"; case QUERY_TYPE_TIMESTAMP: return "QUERY_TYPE_TIMESTAMP"; case QUERY_TYPE_PIPELINE_STATISTICS: return "QUERY_TYPE_PIPELINE_STATISTICS"; case QUERY_TYPE_DURATION: return "QUERY_TYPE_DURATION"; - + // clang-format on default: UNEXPECTED("Unepxected query type"); return "Unknown"; } - // clang-format on } const char* GetSurfaceTransformString(SURFACE_TRANSFORM SrfTransform) @@ -1133,37 +1132,35 @@ const char* GetSurfaceTransformString(SURFACE_TRANSFORM SrfTransform) const char* GetPipelineTypeString(PIPELINE_TYPE PipelineType) { static_assert(PIPELINE_TYPE_LAST == PIPELINE_TYPE_RAY_TRACING, "Please update this function to handle the new pipeline type"); - // clang-format off switch (PipelineType) { + // clang-format off case PIPELINE_TYPE_COMPUTE: return "compute"; case PIPELINE_TYPE_GRAPHICS: return "graphics"; case PIPELINE_TYPE_MESH: return "mesh"; case PIPELINE_TYPE_RAY_TRACING: return "ray tracing"; - + // clang-format on default: UNEXPECTED("Unexpected pipeline type"); return "unknown"; } - // clang-format on } const char* GetShaderCompilerTypeString(SHADER_COMPILER Compiler) { static_assert(SHADER_COMPILER_LAST == SHADER_COMPILER_FXC, "Please update this function to handle the new shader compiler"); - // clang-format off switch (Compiler) { + // clang-format off case SHADER_COMPILER_DEFAULT: return "Default"; case SHADER_COMPILER_GLSLANG: return "glslang"; case SHADER_COMPILER_DXC: return "DXC"; case SHADER_COMPILER_FXC: return "FXC"; - + // clang-format on default: UNEXPECTED("Unexpected shader compiler"); return "UNKNOWN"; - }; - // clang-format on + } } Uint32 ComputeMipLevelsCount(Uint32 Width) @@ -1351,7 +1348,7 @@ Int32 GetShaderTypePipelineIndex(SHADER_TYPE ShaderType, PIPELINE_TYPE PipelineT case SHADER_TYPE_VERTEX: // Graphics case SHADER_TYPE_AMPLIFICATION: // Mesh case SHADER_TYPE_COMPUTE: // Compute - case SHADER_TYPE_RAY_GEN: // RayTracing + case SHADER_TYPE_RAY_GEN: // Ray tracing return 0; case SHADER_TYPE_HULL: // Graphics @@ -1360,15 +1357,15 @@ Int32 GetShaderTypePipelineIndex(SHADER_TYPE ShaderType, PIPELINE_TYPE PipelineT return 1; case SHADER_TYPE_DOMAIN: // Graphics - case SHADER_TYPE_RAY_CLOSEST_HIT: // RayTracing + case SHADER_TYPE_RAY_CLOSEST_HIT: // Ray tracing return 2; case SHADER_TYPE_GEOMETRY: // Graphics - case SHADER_TYPE_RAY_ANY_HIT: // RayTracing + case SHADER_TYPE_RAY_ANY_HIT: // Ray tracing return 3; case SHADER_TYPE_PIXEL: // Graphics or Mesh - case SHADER_TYPE_RAY_INTERSECTION: // RayTracing + case SHADER_TYPE_RAY_INTERSECTION: // Ray tracing return 4; case SHADER_TYPE_CALLABLE: // RayTracing diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp index 42b3e16a..b85f05bc 100644 --- a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp +++ b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp @@ -144,15 +144,26 @@ public: RasterizerStateRegistry.ReportDeletedObject(); DSSRegistry.ReportDeletedObject(); */ + VERIFY(m_IsDestructed, "This object must be explicitly destructed with Destruct()"); } void Destruct() { - if (this->m_Desc.IsRayTracingPipeline() && m_pRayTracingPipelineData) + VERIFY(!m_IsDestructed, "This object has already been destructed"); + + if (this->m_Desc.IsAnyGraphicsPipeline() && m_pGraphicsPipelineDesc != nullptr) + { + m_pGraphicsPipelineDesc->~GraphicsPipelineDesc(); + m_pGraphicsPipelineDesc = nullptr; + } + else if (this->m_Desc.IsRayTracingPipeline() && m_pRayTracingPipelineData != nullptr) { m_pRayTracingPipelineData->~RayTracingPipelineData(); m_pRayTracingPipelineData = nullptr; } +#if DILIGENT_DEBUG + m_IsDestructed = true; +#endif } IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_PipelineState, TDeviceObjectBase) @@ -314,8 +325,7 @@ protected: MemPool.AddSpace<Uint32>(m_BufferSlotsUsed); - static_assert(std::is_trivially_destructible<decltype(*this->m_pGraphicsPipelineDesc)>::value, "add destructor for this object"); - static_assert(std::is_trivially_destructible<decltype(*InputLayout.LayoutElements)>::value, "add destructor for this object"); + static_assert(std::is_trivially_destructible<decltype(*InputLayout.LayoutElements)>::value, "Add destructor for this object to Destruct()"); } void ReserveSpaceForPipelineDesc(const ComputePipelineStateCreateInfo& CreateInfo, @@ -325,7 +335,6 @@ protected: } void ReserveSpaceForPipelineDesc(const RayTracingPipelineStateCreateInfo& CreateInfo, - Uint32 ShaderHandleSize, LinearAllocator& MemPool) const noexcept { ReserveResourceLayout(CreateInfo.PSODesc.ResourceLayout, MemPool); @@ -345,8 +354,9 @@ protected: size_t RTDataSize = sizeof(RayTracingPipelineData); // reserve size for shader handles + const auto ShaderHandleSize = m_pDevice->GetShaderGroupHandleSize(); RTDataSize += ShaderHandleSize * (CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount); - // 1 byte reserved to avoid compiler errors on zero sized arrays + // Extra bytes are reserved to avoid compiler errors on zero-sized arrays RTDataSize -= sizeof(RayTracingPipelineData::Shaders); MemPool.AddSpace(RTDataSize, alignof(RayTracingPipelineData)); } @@ -430,19 +440,17 @@ protected: auto AddShaderStage = [&ShaderStages, &UniqueShaders](IShader* pShader) { if (pShader != nullptr && UniqueShaders.insert(pShader).second) { - auto ShaderType = pShader->GetDesc().ShaderType; - ShaderStages[GetShaderTypePipelineIndex(ShaderType, PIPELINE_TYPE_RAY_TRACING)].Append(ValidatedCast<ShaderImplType>(pShader)); + auto ShaderType = pShader->GetDesc().ShaderType; + auto StageInd = GetShaderTypePipelineIndex(ShaderType, PIPELINE_TYPE_RAY_TRACING); + auto& Stage = ShaderStages[StageInd]; + Stage.Append(ValidatedCast<ShaderImplType>(pShader)); + VERIFY_EXPR(Stage.Type == SHADER_TYPE_UNKNOWN || Stage.Type == ShaderType); + Stage.Type = ShaderType; } }; ShaderStages.clear(); ShaderStages.resize(6); - ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_RAY_GEN, PIPELINE_TYPE_RAY_TRACING)].Type = SHADER_TYPE_RAY_GEN; - ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_RAY_MISS, PIPELINE_TYPE_RAY_TRACING)].Type = SHADER_TYPE_RAY_MISS; - ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_RAY_CLOSEST_HIT, PIPELINE_TYPE_RAY_TRACING)].Type = SHADER_TYPE_RAY_CLOSEST_HIT; - ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_RAY_ANY_HIT, PIPELINE_TYPE_RAY_TRACING)].Type = SHADER_TYPE_RAY_ANY_HIT; - ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_RAY_INTERSECTION, PIPELINE_TYPE_RAY_TRACING)].Type = SHADER_TYPE_RAY_INTERSECTION; - ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_CALLABLE, PIPELINE_TYPE_RAY_TRACING)].Type = SHADER_TYPE_CALLABLE; for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i) { @@ -523,7 +531,7 @@ protected: } const auto& InputLayout = GraphicsPipeline.InputLayout; - LayoutElement* pLayoutElements = MemPool.Allocate<LayoutElement>(InputLayout.NumElements); + LayoutElement* pLayoutElements = MemPool.ConstructArray<LayoutElement>(InputLayout.NumElements); for (size_t Elem = 0; Elem < InputLayout.NumElements; ++Elem) { const auto& SrcElem = InputLayout.LayoutElements[Elem]; @@ -603,7 +611,7 @@ protected: LayoutElem.Stride = Strides[BuffSlot]; } - m_pStrides = MemPool.Allocate<Uint32>(m_BufferSlotsUsed); + m_pStrides = MemPool.ConstructArray<Uint32>(m_BufferSlotsUsed); // Set strides for all unused slots to 0 for (Uint32 i = 0; i < m_BufferSlotsUsed; ++i) @@ -620,7 +628,6 @@ protected: } void InitializePipelineDesc(const RayTracingPipelineStateCreateInfo& CreateInfo, - Uint32 ShaderHandleSize, TNameToGroupIndexMap&& NameToGroupIndex, LinearAllocator& MemPool) noexcept { @@ -628,9 +635,10 @@ protected: size_t RTDataSize = sizeof(RayTracingPipelineData); // reserve size for shader handles - const Uint32 ShaderDataSize = ShaderHandleSize * (CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount); + const auto ShaderHandleSize = m_pDevice->GetShaderGroupHandleSize(); + const auto ShaderDataSize = ShaderHandleSize * (CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount); RTDataSize += ShaderDataSize; - // 1 byte reserved to avoid compiler errors on zero sized arrays + // Extra bytes are reserved to avoid compiler errors on zero-sized arrays RTDataSize -= sizeof(RayTracingPipelineData::Shaders); this->m_pRayTracingPipelineData = static_cast<RayTracingPipelineData*>(MemPool.Allocate(RTDataSize, alignof(RayTracingPipelineData))); @@ -664,15 +672,15 @@ private: } } - static_assert(std::is_trivially_destructible<decltype(*SrcLayout.Variables)>::value, "add destructor for this object"); - static_assert(std::is_trivially_destructible<decltype(*SrcLayout.ImmutableSamplers)>::value, "add destructor for this object"); + static_assert(std::is_trivially_destructible<decltype(*SrcLayout.Variables)>::value, "Add destructor for this object to Destruct()"); + static_assert(std::is_trivially_destructible<decltype(*SrcLayout.ImmutableSamplers)>::value, "Add destructor for this object to Destruct()"); } static void CopyResourceLayout(const PipelineResourceLayoutDesc& SrcLayout, PipelineResourceLayoutDesc& DstLayout, LinearAllocator& MemPool) { if (SrcLayout.Variables != nullptr) { - auto* Variables = MemPool.Allocate<ShaderResourceVariableDesc>(SrcLayout.NumVariables); + auto* Variables = MemPool.ConstructArray<ShaderResourceVariableDesc>(SrcLayout.NumVariables); DstLayout.Variables = Variables; for (Uint32 i = 0; i < SrcLayout.NumVariables; ++i) { @@ -684,7 +692,7 @@ private: if (SrcLayout.ImmutableSamplers != nullptr) { - auto* ImmutableSamplers = MemPool.Allocate<ImmutableSamplerDesc>(SrcLayout.NumImmutableSamplers); + auto* ImmutableSamplers = MemPool.ConstructArray<ImmutableSamplerDesc>(SrcLayout.NumImmutableSamplers); DstLayout.ImmutableSamplers = ImmutableSamplers; for (Uint32 i = 0; i < SrcLayout.NumImmutableSamplers; ++i) { @@ -726,16 +734,23 @@ protected: { RayTracingPipelineDesc Desc; TNameToGroupIndexMap NameToGroupIndex; - Uint32 ShaderHandleSize; - Uint32 ShaderDataSize; - Uint8 Shaders[1]; + + Uint32 ShaderHandleSize = 0; + Uint32 ShaderDataSize = 0; + + Uint8 Shaders[sizeof(void*)] = {}; // The actual array size will be ShaderDataSize }; + static_assert(offsetof(RayTracingPipelineData, Shaders) % sizeof(void*) == 0, "Shaders member is expected to be sizeof(void*)-aligned"); union { - GraphicsPipelineDesc* m_pGraphicsPipelineDesc; + GraphicsPipelineDesc* m_pGraphicsPipelineDesc = nullptr; RayTracingPipelineData* m_pRayTracingPipelineData; }; + +#ifdef DILIGENT_DEBUG + bool m_IsDestructed = false; +#endif }; } // namespace Diligent diff --git a/Graphics/GraphicsEngine/src/PipelineStateBase.cpp b/Graphics/GraphicsEngine/src/PipelineStateBase.cpp index 9bd422db..29624b2f 100644 --- a/Graphics/GraphicsEngine/src/PipelineStateBase.cpp +++ b/Graphics/GraphicsEngine/src/PipelineStateBase.cpp @@ -251,7 +251,6 @@ void ValidateComputePipelineCreateInfo(const ComputePipelineStateCreateInfo& Cre void ValidateRayTracingPipelineCreateInfo(const RayTracingPipelineStateCreateInfo& CreateInfo) noexcept(false) { -#ifdef DILIGENT_DEVELOPMENT const auto& PSODesc = CreateInfo.PSODesc; if (PSODesc.PipelineType != PIPELINE_TYPE_RAY_TRACING) LOG_PSO_ERROR_AND_THROW("Pipeline type must be RAY_TRACING"); @@ -282,7 +281,7 @@ void ValidateRayTracingPipelineCreateInfo(const RayTracingPipelineStateCreateInf if (Group.Name == nullptr) LOG_PSO_ERROR_AND_THROW("pTriangleHitShaders[", i, "].Name must not be null"); - VALIDATE_SHADER_TYPE(Group.pClosestHitShader, SHADER_TYPE_RAY_CLOSEST_HIT, "ray tracing triangle closes hit"); + VALIDATE_SHADER_TYPE(Group.pClosestHitShader, SHADER_TYPE_RAY_CLOSEST_HIT, "ray tracing triangle closest hit"); if (Group.pAnyHitShader != nullptr) VALIDATE_SHADER_TYPE(Group.pAnyHitShader, SHADER_TYPE_RAY_ANY_HIT, "ray tracing triangle any hit"); @@ -303,7 +302,6 @@ void ValidateRayTracingPipelineCreateInfo(const RayTracingPipelineStateCreateInf if (Group.pAnyHitShader != nullptr) VALIDATE_SHADER_TYPE(Group.pAnyHitShader, SHADER_TYPE_RAY_ANY_HIT, "ray tracing procedural any hit"); } -#endif // DILIGENT_DEVELOPMENT } #undef VALIDATE_SHADER_TYPE diff --git a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp index 77b68360..9614ebab 100644 --- a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp +++ b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp @@ -167,6 +167,7 @@ private: // 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 diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.hpp index 1e7fd160..cd595f86 100644 --- a/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.hpp +++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.hpp @@ -111,6 +111,7 @@ private: // 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; diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp index 4453b598..91ab6592 100644 --- a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp @@ -416,7 +416,7 @@ void RenderDeviceD3D11Impl::CreateComputePipelineState(const ComputePipelineStat void RenderDeviceD3D11Impl::CreateRayTracingPipelineState(const RayTracingPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) { - UNSUPPORTED("CreateRayTracingPipelineState is not supported in DirectX 11"); + UNSUPPORTED("Ray tracing is not supported in DirectX 11"); *ppPipelineState = nullptr; } diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp index b6430c04..071d2f59 100755 --- a/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp @@ -448,7 +448,7 @@ void ShaderResourcesD3D11::dvpVerifyCommittedResources(ID3D11Buffer* [&](const D3DShaderResourceAttribs&, Uint32) // { - UNEXPECTED("acceleration structure is not supported in DirectX 11"); + UNEXPECTED("Acceleration structure is not supported in DirectX 11"); } // clang-format off ); // clang-format on } 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"); } } } diff --git a/Graphics/GraphicsEngineD3DBase/CMakeLists.txt b/Graphics/GraphicsEngineD3DBase/CMakeLists.txt index 0e116368..36e0c01a 100644 --- a/Graphics/GraphicsEngineD3DBase/CMakeLists.txt +++ b/Graphics/GraphicsEngineD3DBase/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required (VERSION 3.10) project(Diligent-GraphicsEngineD3DBase CXX) set(INCLUDE + include/D3DCommonTypeConversions.hpp include/D3DErrors.hpp include/D3DShaderResourceLoader.hpp include/D3DTypeConversionImpl.hpp @@ -22,6 +23,7 @@ set(INTERFACE ) set(SOURCE + src/D3DCommonTypeConversions.cpp src/DXGITypeConversions.cpp src/ShaderD3DBase.cpp src/ShaderResources.cpp diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DCommonTypeConversions.hpp b/Graphics/GraphicsEngineD3DBase/include/D3DCommonTypeConversions.hpp new file mode 100644 index 00000000..7b3f1e00 --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/D3DCommonTypeConversions.hpp @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Common D3D type conversions + +#include "GraphicsTypes.h" + +namespace Diligent +{ + +RESOURCE_DIMENSION D3DSrvDimensionToResourceDimension(D3D_SRV_DIMENSION SrvDim); + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.hpp b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.hpp index cc24414e..926ce209 100644 --- a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.hpp +++ b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.hpp @@ -67,6 +67,7 @@ #include "StringPool.hpp" #include "D3DShaderResourceLoader.hpp" #include "PipelineState.h" +#include "D3DCommonTypeConversions.hpp" namespace Diligent { @@ -81,7 +82,6 @@ struct D3DShaderResourceAttribs /* 8 */ const Uint16 BindPoint; /*10 */ const Uint16 BindCount; -private: // 4 4 24 // bit | 0 1 2 3 | 4 5 6 7 | 8 9 10 ... 31 | // | | | | @@ -94,6 +94,7 @@ private: static_assert(D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER < (1 << ShaderInputTypeBits), "Not enough bits to represent D3D_SHADER_INPUT_TYPE"); static_assert(D3D_SRV_DIMENSION_BUFFEREX < (1 << SRVDimBits), "Not enough bits to represent D3D_SRV_DIMENSION"); +private: // We need to use Uint32 instead of the actual type for reliability and correctness. // There originally was a problem when the type of InputType was D3D_SHADER_INPUT_TYPE: // the value of D3D_SIT_UAV_RWBYTEADDRESS (8) was interpreted as -8 (as the underlying enum type @@ -106,8 +107,9 @@ private: // clang-format on public: - static constexpr const Uint32 InvalidSamplerId = (1 << SamplerOrTexSRVIdBits) - 1; - static constexpr const Uint32 InvalidTexSRVId = (1 << SamplerOrTexSRVIdBits) - 1; + static constexpr const Uint32 InvalidSamplerId = (1U << SamplerOrTexSRVIdBits) - 1U; + static constexpr const Uint32 MaxSamplerId = InvalidSamplerId - 1; + static constexpr const Uint32 InvalidTexSRVId = (1U << SamplerOrTexSRVIdBits) - 1U; static constexpr const Uint16 InvalidBindPoint = std::numeric_limits<Uint16>::max(); static constexpr const Uint16 MaxBindPoint = InvalidBindPoint - 1; static constexpr const Uint16 MaxBindCount = std::numeric_limits<Uint16>::max(); @@ -157,7 +159,8 @@ public: } // clang-format on { - VERIFY(GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER, "Only texture SRV can be assigned a texture sampler"); + VERIFY(SamplerId == InvalidSamplerId || (GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER), + "Only texture SRV can be assigned a valid texture sampler"); } D3DShaderResourceAttribs(StringPool& NamesPool, const D3DShaderResourceAttribs& rhs) noexcept : @@ -192,13 +195,16 @@ public: return static_cast<D3D_SRV_DIMENSION>(SRVDimension); } - RESOURCE_DIMENSION GetResourceDimension() const; + RESOURCE_DIMENSION GetResourceDimension() const + { + return D3DSrvDimensionToResourceDimension(GetSRVDimension()); + } bool IsMultisample() const; bool IsCombinedWithSampler() const { - return GetCombinedSamplerId() != InvalidSamplerId; + return GetInputType() == D3D_SIT_TEXTURE && SamplerOrTexSRVId != InvalidSamplerId; } bool IsCombinedWithTexSRV() const @@ -236,15 +242,15 @@ public: HLSLShaderResourceDesc GetHLSLResourceDesc() const; -private: - friend class ShaderResources; - Uint32 GetCombinedSamplerId() const { VERIFY(GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER, "Invalid input type: D3D_SIT_TEXTURE is expected"); return SamplerOrTexSRVId; } +private: + friend class ShaderResources; + void SetTexSRVId(Uint32 TexSRVId) { VERIFY(GetInputType() == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected"); diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.hpp b/Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.hpp index 78525f30..2497b17d 100644 --- a/Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.hpp +++ b/Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.hpp @@ -87,8 +87,8 @@ protected: }; -template <typename BufferViewImplType, typename AttribsType> -bool VerifyBufferViewModeD3D(BufferViewImplType* pViewD3D11, const AttribsType& Attribs, const char* ShaderName) +template <typename BufferViewImplType> +bool VerifyBufferViewModeD3D(BufferViewImplType* pViewD3D11, const D3DShaderResourceAttribs& Attribs, const char* ShaderName) { if (pViewD3D11 == nullptr) return true; diff --git a/Graphics/GraphicsEngineD3DBase/src/D3DCommonTypeConversions.cpp b/Graphics/GraphicsEngineD3DBase/src/D3DCommonTypeConversions.cpp new file mode 100644 index 00000000..15f9cc76 --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/src/D3DCommonTypeConversions.cpp @@ -0,0 +1,55 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include <d3dcommon.h> +#include "D3DCommonTypeConversions.hpp" + +namespace Diligent +{ + +RESOURCE_DIMENSION D3DSrvDimensionToResourceDimension(D3D_SRV_DIMENSION SrvDim) +{ + switch (SrvDim) + { + // 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; + } +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp index 79d2cb22..7e6c1f50 100644 --- a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp +++ b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp @@ -55,6 +55,9 @@ ShaderResources::~ShaderResources() for (Uint32 n = 0; n < GetNumSamplers(); ++n) GetSampler(n).~D3DShaderResourceAttribs(); + + for (Uint32 n = 0; n < GetNumAccelStructs(); ++n) + GetAccelStruct(n).~D3DShaderResourceAttribs(); } void ShaderResources::AllocateMemory(IMemoryAllocator& Allocator, @@ -467,27 +470,6 @@ HLSLShaderResourceDesc D3DShaderResourceAttribs::GetHLSLResourceDesc() const return ResourceDesc; } -RESOURCE_DIMENSION D3DShaderResourceAttribs::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 D3DShaderResourceAttribs::IsMultisample() const { switch (GetSRVDimension()) diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index 7707f979..c55b958f 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -149,13 +149,18 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters, sizeof(FenceGLImpl), sizeof(QueryGLImpl), sizeof(RenderPassGLImpl), - sizeof(FramebufferGLImpl) + sizeof(FramebufferGLImpl), + 0, + 0, + 0 } }, // Device caps must be filled in before the constructor of Pipeline Cache is called! m_GLContext{InitAttribs, m_DeviceCaps, pSCDesc} // clang-format on { + static_assert(sizeof(DeviceObjectSizes) == sizeof(size_t) * 15, "Please add new objects to DeviceObjectSizes constructor"); + GLint NumExtensions = 0; glGetIntegerv(GL_NUM_EXTENSIONS, &NumExtensions); CHECK_GL_ERROR("Failed to get the number of extensions"); @@ -738,7 +743,7 @@ void RenderDeviceGLImpl::CreateComputePipelineState(const ComputePipelineStateCr void RenderDeviceGLImpl::CreateRayTracingPipelineState(const RayTracingPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) { - UNSUPPORTED("CreateRayTracingPipelineState is not supported in OpenGL"); + UNSUPPORTED("Ray tracing is not supported in OpenGL"); *ppPipelineState = nullptr; } diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.hpp index 8a0fab15..f9f51920 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.hpp @@ -136,6 +136,7 @@ public: // set by the same Vulkan command. If there are no dynamic descriptors, this // function also binds descriptor sets rightaway. void PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkImpl, + VkPipelineBindPoint BindPoint, const ShaderResourceCacheVk& ResourceCache, DescriptorSetBindInfo& BindInfo, VkDescriptorSet VkDynamicDescrSet) const; diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp index a02c8d74..6aa4e073 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp @@ -129,10 +129,11 @@ public: private: using TShaderStages = ShaderResourceLayoutVk::TShaderStages; - template <typename PSOCreateInfoType> + template <typename PSOCreateInfoType, typename InitPSODescType> void InitInternalObjects(const PSOCreateInfoType& CreateInfo, std::vector<VkPipelineShaderStageCreateInfo>& vkShaderStages, - std::vector<VulkanUtilities::ShaderModuleWrapper>& ShaderModules); + std::vector<VulkanUtilities::ShaderModuleWrapper>& ShaderModules, + InitPSODescType InitPSODesc); void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages); @@ -170,6 +171,7 @@ private: // Resource layout index in m_ShaderResourceLayouts 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_HasStaticResources = false; bool m_HasNonStaticResources = false; diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp index 9ceed3e4..6abe5213 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp @@ -197,6 +197,11 @@ public: IDXCompiler* GetDxCompiler() const { return m_pDxCompiler.get(); } + Uint32 GetShaderGroupHandleSize() const + { + return GetPhysicalDevice().GetExtProperties().RayTracing.shaderGroupHandleSize; + } + private: template <typename PSOCreateInfoType> void CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState); diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp index 68401f52..0b427640 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp @@ -84,6 +84,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; Uint8 m_NumShaders = 0; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp index e5cddb0c..a0e40615 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp @@ -44,20 +44,9 @@ // d == m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] // // +// Every ShaderVariableVkImpl variable managed by ShaderVariableManagerVk keeps a reference to corresponding VkResource. // -// * Every VkResource structure holds a reference to SPIRVShaderResourceAttribs structure from SPIRVShaderResources. -// * ShaderResourceLayoutVk keeps a shared pointer to SPIRVShaderResources instance. -// * Every ShaderVariableVkImpl variable managed by ShaderVariableManagerVk keeps a reference to corresponding VkResource. -// -// -// ______________________ ________________________________________________________________________ -// | | unique_ptr | | | | | | | | -// | SPIRVShaderResources |--------------->| UBs | SBs | StrgImgs | SmplImgs | ACs | SepSamplers | SepImgs | -// |______________________| |________|_________|__________|__________|_______|_____________|_________| -// A A A -// | | | -// |shared_ptr Ref Ref -// ________|__________________ ________\____________________|_____________________________________________ +// ___________________________ ___________________________________________________________________________ // | | unique_ptr | | | | | // | ShaderResourceLayoutVk |--------------->| VkResource[0] | VkResource[1] | ... | VkResource[s+m+d-1] | // |___________________________| |___________________|_________________|_______________|_____________________| @@ -99,13 +88,14 @@ #include <array> #include <memory> +#include <unordered_map> #include "PipelineState.h" #include "ShaderBase.hpp" #include "HashUtils.hpp" #include "ShaderResourceCacheVk.hpp" -#include "SPIRVShaderResources.hpp" #include "VulkanUtilities/VulkanLogicalDevice.hpp" +#include "StringPool.hpp" namespace Diligent { @@ -113,7 +103,7 @@ namespace Diligent class ShaderVkImpl; /// Diligent::ShaderResourceLayoutVk class -// sizeof(ShaderResourceLayoutVk)==72 (MS compiler, x64) +// sizeof(ShaderResourceLayoutVk)==40 (MS compiler, x64) class ShaderResourceLayoutVk { public: @@ -134,6 +124,9 @@ public: ShaderResourceLayoutVk(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) noexcept : m_LogicalDevice{LogicalDevice} { +#if defined(_MSC_VER) && defined(_WIN64) + static_assert(sizeof(*this) == 40, "Unexpected sizeof(ShaderResourceLayoutVk)."); +#endif } // clang-format off @@ -181,20 +174,27 @@ public: static constexpr const Uint32 InvalidSamplerInd = (1 << SamplerIndBits)-1; + static constexpr const Uint32 ResourceDimBits = 7; + static constexpr const Uint32 IsMSFlagBits = 8 - ResourceDimBits; + static_assert(RESOURCE_DIM_NUM_DIMENSIONS <= (1 << ResourceDimBits), "Not enough bits to represent RESOURCE_DIMENSION"); + using ResourceType = SPIRVShaderResourceAttribs::ResourceType; /* 0 */ const Uint16 Binding; -/* 2 */ const Uint16 ArraySize; +/* 2 */ const Uint16 DescriptorSet; + /* 4.0 */ const Uint32 CacheOffset : CacheOffsetBits; // Offset from the beginning of the cached descriptor set /* 6.5 */ const Uint32 SamplerInd : SamplerIndBits; // When using combined texture samplers, index of the separate sampler // assigned to separate image /* 7.5 */ const Uint32 VariableType : VariableTypeBits; /* 7.7 */ const Uint32 ImmutableSamplerAssigned : ImmutableSamplerFlagBits; -/* 8 */ const Uint8 DescriptorSet; -/* 9 */ const ResourceType Type; -/* 10.0*/ const Uint8 ResourceDim : 7; -/* 10.7*/ const Uint8 IsMS : 1; +/* 8 */ const Uint16 ArraySize; + +/* 10 */ const ResourceType Type; +/* 11.0*/ const Uint8 ResourceDim : ResourceDimBits; +/* 11.7*/ const Uint8 IsMS : IsMSFlagBits; + /* 16 */ const char* const Name; /* 24 */ const ShaderResourceLayoutVk& ParentResLayout; // clang-format on @@ -203,8 +203,8 @@ public: const char* _Name, Uint16 _ArraySize, ResourceType _Type, - Uint8 _ResourceDim, - Uint8 _IsMS, + RESOURCE_DIMENSION _ResourceDim, + bool _IsMS, SHADER_RESOURCE_VARIABLE_TYPE _VariableType, uint32_t _Binding, uint32_t _DescriptorSet, @@ -218,20 +218,28 @@ public: SamplerInd {_SamplerInd }, VariableType {_VariableType }, ImmutableSamplerAssigned {_ImmutableSamplerAssigned ? 1U : 0U}, - Name {_Name }, - ArraySize {_ArraySize }, - Type {_Type }, - ResourceDim {_ResourceDim }, - IsMS {_IsMS }, - ParentResLayout {_ParentLayout } + ArraySize {_ArraySize }, + Type {_Type }, + ResourceDim {_ResourceDim }, + IsMS {_IsMS ? 1U : 0U}, + Name {_Name }, + ParentResLayout {_ParentLayout } // clang-format on { - VERIFY(_CacheOffset < (1 << CacheOffsetBits), "Cache offset (", _CacheOffset, ") exceeds max representable value ", (1 << CacheOffsetBits)); - VERIFY(_SamplerInd < (1 << SamplerIndBits), "Sampler index (", _SamplerInd, ") exceeds max representable value ", (1 << SamplerIndBits)); - VERIFY(_Binding <= std::numeric_limits<decltype(Binding)>::max(), "Binding (", _Binding, ") exceeds max representable value ", std::numeric_limits<decltype(Binding)>::max()); +#if defined(_MSC_VER) && defined(_WIN64) + static_assert(sizeof(*this) == 32, "Unexpected sizeof(VkResource)"); +#endif + // clang-format off + VERIFY(_CacheOffset < (1 << CacheOffsetBits), "Cache offset (", _CacheOffset, ") exceeds max representable value ", (1 << CacheOffsetBits) ); + VERIFY(_SamplerInd < (1 << SamplerIndBits), "Sampler index (", _SamplerInd, ") exceeds max representable value ", (1 << SamplerIndBits) ); + VERIFY(_Binding <= std::numeric_limits<decltype(Binding)>::max(), "Binding (", _Binding, ") exceeds max representable value ", std::numeric_limits<decltype(Binding)>::max() ); VERIFY(_DescriptorSet <= std::numeric_limits<decltype(DescriptorSet)>::max(), "Descriptor set (", _DescriptorSet, ") exceeds max representable value ", std::numeric_limits<decltype(DescriptorSet)>::max()); + VERIFY(_VariableType < (1 << VariableTypeBits), "Variable type (", Uint32{_VariableType}, ") exceeds max representable value ", (1 << VariableTypeBits) ); + VERIFY(_ResourceDim < (1 << ResourceDimBits), "Resource dimension (", Uint32{_ResourceDim}, ") exceeds max representable value ", (1 << ResourceDimBits) ); + // clang-format on } + // Checks if a resource is bound in ResourceCache at the given ArrayIndex bool IsBound(Uint32 ArrayIndex, const ShaderResourceCacheVk& ResourceCache) const; @@ -273,7 +281,10 @@ public: return Name; } - ShaderResourceDesc GetResourceDesc() const; + ShaderResourceDesc GetResourceDesc() const + { + return ShaderResourceDesc{Name, SPIRVShaderResourceAttribs::GetShaderResourceType(Type), ArraySize}; + } RESOURCE_DIMENSION GetResourceDimension() const { @@ -403,14 +414,16 @@ private: return m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; } + static constexpr Uint32 InvalidResourceIndex = ~0u; + using ResourceNameToIndex_t = std::unordered_map<HashMapStringKey, Uint32, HashMapStringKey::Hasher>; - void AllocateMemory(const std::vector<const ShaderVkImpl*>& Shaders, - IMemoryAllocator& Allocator, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - ResourceNameToIndex_t& UniqueNames, - bool AllocateImmutableSamplers); + StringPool AllocateMemory(const std::vector<const ShaderVkImpl*>& Shaders, + IMemoryAllocator& Allocator, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + ResourceNameToIndex_t& UniqueNames, + bool AllocateImmutableSamplers); using ImmutableSamplerPtrType = RefCntAutoPtr<ISampler>; ImmutableSamplerPtrType& GetImmutableSampler(Uint32 n) noexcept @@ -422,16 +435,15 @@ private: // clang-format off /* 0 */ const VulkanUtilities::VulkanLogicalDevice& m_LogicalDevice; -/* 8 */ std::unique_ptr<void, STDDeleterRawMem<void> > m_ResourceBuffer; // AZ TODO: use linear allocator -/*24 */ StringPool m_StringPool; +/* 8 */ std::unique_ptr<void, STDDeleterRawMem<void> > m_ResourceBuffer; -/*48 */ std::array<Uint16, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES+1> m_NumResources = {}; +/*24 */ std::array<Uint16, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES+1> m_NumResources = {}; -/*56 */ Uint32 m_NumImmutableSamplers = 0; -/*60 */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN; -/*64 */ bool m_IsUsingSeparateSamplers = false; +/*32 */ Uint16 m_NumImmutableSamplers = 0; +/*34 */ bool m_IsUsingSeparateSamplers = false; +/*36 */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN; -/*72 */ // End of class +/*40 */ // End of class // clang-format on }; diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp index fcb64973..189b1073 100644 --- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp @@ -252,22 +252,26 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E GetFeatureState(EngineCI.Features.Feature, IsFeatureSupported, FeatureName); \ } while (false) - ENABLE_FEATURE(DeviceExtFeatures.MeshShader.taskShader != VK_FALSE && DeviceExtFeatures.MeshShader.meshShader != VK_FALSE, MeshShaders, "Mesh shaders are"); + const auto& MeshShaderFeats = DeviceExtFeatures.MeshShader; + ENABLE_FEATURE(MeshShaderFeats.taskShader != VK_FALSE && MeshShaderFeats.meshShader != VK_FALSE, MeshShaders, "Mesh shaders are"); + const auto& ShaderFloat16Int8Feats = DeviceExtFeatures.ShaderFloat16Int8; // clang-format off - ENABLE_FEATURE(DeviceExtFeatures.ShaderFloat16Int8.shaderFloat16 != VK_FALSE, ShaderFloat16, "16-bit float shader operations are"); - ENABLE_FEATURE(DeviceExtFeatures.ShaderFloat16Int8.shaderInt8 != VK_FALSE, ShaderInt8, "8-bit int shader operations are"); + ENABLE_FEATURE(ShaderFloat16Int8Feats.shaderFloat16 != VK_FALSE, ShaderFloat16, "16-bit float shader operations are"); + ENABLE_FEATURE(ShaderFloat16Int8Feats.shaderInt8 != VK_FALSE, ShaderInt8, "8-bit int shader operations are"); // clang-format on + const auto& Storage16BitFeats = DeviceExtFeatures.Storage16Bit; // clang-format off - ENABLE_FEATURE(DeviceExtFeatures.Storage16Bit.storageBuffer16BitAccess != VK_FALSE, ResourceBuffer16BitAccess, "16-bit resoure buffer access is"); - ENABLE_FEATURE(DeviceExtFeatures.Storage16Bit.uniformAndStorageBuffer16BitAccess != VK_FALSE, UniformBuffer16BitAccess, "16-bit uniform buffer access is"); - ENABLE_FEATURE(DeviceExtFeatures.Storage16Bit.storageInputOutput16 != VK_FALSE, ShaderInputOutput16, "16-bit shader inputs/outputs are"); + ENABLE_FEATURE(Storage16BitFeats.storageBuffer16BitAccess != VK_FALSE, ResourceBuffer16BitAccess, "16-bit resoure buffer access is"); + ENABLE_FEATURE(Storage16BitFeats.uniformAndStorageBuffer16BitAccess != VK_FALSE, UniformBuffer16BitAccess, "16-bit uniform buffer access is"); + ENABLE_FEATURE(Storage16BitFeats.storageInputOutput16 != VK_FALSE, ShaderInputOutput16, "16-bit shader inputs/outputs are"); // clang-format on + const auto& Storage8BitFeats = DeviceExtFeatures.Storage8Bit; // clang-format off - ENABLE_FEATURE(DeviceExtFeatures.Storage8Bit.storageBuffer8BitAccess != VK_FALSE, ResourceBuffer8BitAccess, "8-bit resoure buffer access is"); - ENABLE_FEATURE(DeviceExtFeatures.Storage8Bit.uniformAndStorageBuffer8BitAccess != VK_FALSE, UniformBuffer8BitAccess, "8-bit uniform buffer access is"); + ENABLE_FEATURE(Storage8BitFeats.storageBuffer8BitAccess != VK_FALSE, ResourceBuffer8BitAccess, "8-bit resoure buffer access is"); + ENABLE_FEATURE(Storage8BitFeats.uniformAndStorageBuffer8BitAccess != VK_FALSE, UniformBuffer8BitAccess, "8-bit uniform buffer access is"); // clang-format on ENABLE_FEATURE((DeviceExtFeatures.RayTracing.rayTracing != VK_FALSE && DeviceExtFeatures.Spirv14) || DeviceExtFeatures.RayTracingNV, RayTracing, "Ray tracing is"); @@ -286,7 +290,7 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E // Mesh shader if (EngineCI.Features.MeshShaders != DEVICE_FEATURE_STATE_DISABLED) { - EnabledExtFeats.MeshShader = DeviceExtFeatures.MeshShader; + EnabledExtFeats.MeshShader = MeshShaderFeats; VERIFY_EXPR(EnabledExtFeats.MeshShader.taskShader != VK_FALSE && EnabledExtFeats.MeshShader.meshShader != VK_FALSE); VERIFY(PhysicalDevice->IsExtensionSupported(VK_NV_MESH_SHADER_EXTENSION_NAME), "VK_NV_mesh_shader extension must be supported as it has already been checked by VulkanPhysicalDevice and " @@ -299,7 +303,7 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E if (EngineCI.Features.ShaderFloat16 != DEVICE_FEATURE_STATE_DISABLED || EngineCI.Features.ShaderInt8 != DEVICE_FEATURE_STATE_DISABLED) { - EnabledExtFeats.ShaderFloat16Int8 = DeviceExtFeatures.ShaderFloat16Int8; + EnabledExtFeats.ShaderFloat16Int8 = ShaderFloat16Int8Feats; VERIFY_EXPR(EnabledExtFeats.ShaderFloat16Int8.shaderFloat16 != VK_FALSE || EnabledExtFeats.ShaderFloat16Int8.shaderInt8 != VK_FALSE); VERIFY(PhysicalDevice->IsExtensionSupported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME), "VK_KHR_shader_float16_int8 extension must be supported as it has already been checked by VulkanPhysicalDevice " @@ -324,7 +328,7 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E // clang-format on { // clang-format off - EnabledExtFeats.Storage16Bit = DeviceExtFeatures.Storage16Bit; + EnabledExtFeats.Storage16Bit = Storage16BitFeats; VERIFY_EXPR(EngineCI.Features.ResourceBuffer16BitAccess == DEVICE_FEATURE_STATE_DISABLED || EnabledExtFeats.Storage16Bit.storageBuffer16BitAccess != VK_FALSE); VERIFY_EXPR(EngineCI.Features.UniformBuffer16BitAccess == DEVICE_FEATURE_STATE_DISABLED || EnabledExtFeats.Storage16Bit.uniformAndStorageBuffer16BitAccess != VK_FALSE); VERIFY_EXPR(EngineCI.Features.ShaderInputOutput16 == DEVICE_FEATURE_STATE_DISABLED || EnabledExtFeats.Storage16Bit.storageInputOutput16 != VK_FALSE); @@ -360,7 +364,7 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E // clang-format on { // clang-format off - EnabledExtFeats.Storage8Bit = DeviceExtFeatures.Storage8Bit; + EnabledExtFeats.Storage8Bit = Storage8BitFeats; VERIFY_EXPR(EngineCI.Features.ResourceBuffer8BitAccess == DEVICE_FEATURE_STATE_DISABLED || EnabledExtFeats.Storage8Bit.storageBuffer8BitAccess != VK_FALSE); VERIFY_EXPR(EngineCI.Features.UniformBuffer8BitAccess == DEVICE_FEATURE_STATE_DISABLED || EnabledExtFeats.Storage8Bit.uniformAndStorageBuffer8BitAccess != VK_FALSE); // clang-format on diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp index d0e37670..c24ed496 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp @@ -433,6 +433,7 @@ void PipelineLayout::InitResourceCache(RenderDeviceVkImpl* pDeviceVkImpl, } void PipelineLayout::PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkImpl, + VkPipelineBindPoint BindPoint, const ShaderResourceCacheVk& ResourceCache, DescriptorSetBindInfo& BindInfo, VkDescriptorSet VkDynamicDescrSet) const @@ -478,6 +479,7 @@ void PipelineLayout::PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkIm BindInfo.DynamicOffsetCount = TotalDynamicDescriptors; if (TotalDynamicDescriptors > BindInfo.DynamicOffsets.size()) BindInfo.DynamicOffsets.resize(TotalDynamicDescriptors); + BindInfo.BindPoint = BindPoint; BindInfo.pResourceCache = &ResourceCache; #ifdef DILIGENT_DEBUG BindInfo.pDbgPipelineLayout = this; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index c7b9e05f..11be4dba 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -129,11 +129,11 @@ void InitPipelineShaderStages(const VulkanUtilities::VulkanLogicalDevice& } -void CreateComputePipeline(RenderDeviceVkImpl* pDeviceVk, - std::vector<VkPipelineShaderStageCreateInfo>& Stages, - const PipelineLayout& Layout, - const PipelineStateDesc& PSODesc, - VulkanUtilities::PipelineWrapper& Pipeline) +static void CreateComputePipeline(RenderDeviceVkImpl* pDeviceVk, + std::vector<VkPipelineShaderStageCreateInfo>& Stages, + const PipelineLayout& Layout, + const PipelineStateDesc& PSODesc, + VulkanUtilities::PipelineWrapper& Pipeline) { const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); @@ -154,13 +154,13 @@ void CreateComputePipeline(RenderDeviceVkImpl* pDevice } -void CreateGraphicsPipeline(RenderDeviceVkImpl* pDeviceVk, - std::vector<VkPipelineShaderStageCreateInfo>& Stages, - const PipelineLayout& Layout, - const PipelineStateDesc& PSODesc, - const GraphicsPipelineDesc& GraphicsPipeline, - VulkanUtilities::PipelineWrapper& Pipeline, - RefCntAutoPtr<IRenderPass>& pRenderPass) +static void CreateGraphicsPipeline(RenderDeviceVkImpl* pDeviceVk, + std::vector<VkPipelineShaderStageCreateInfo>& Stages, + const PipelineLayout& Layout, + const PipelineStateDesc& PSODesc, + const GraphicsPipelineDesc& GraphicsPipeline, + VulkanUtilities::PipelineWrapper& Pipeline, + RefCntAutoPtr<IRenderPass>& pRenderPass) { const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); const auto& PhysicalDevice = pDeviceVk->GetPhysicalDevice(); @@ -338,13 +338,13 @@ void CreateGraphicsPipeline(RenderDeviceVkImpl* pDevic } -void CreateRayTracingPipeline(RenderDeviceVkImpl* pDeviceVk, - std::vector<VkPipelineShaderStageCreateInfo>& Stages, - const std::vector<VkRayTracingShaderGroupCreateInfoKHR>& ShaderGroups, - const PipelineLayout& Layout, - const PipelineStateDesc& PSODesc, - const RayTracingPipelineDesc& RayTracingPipeline, - VulkanUtilities::PipelineWrapper& Pipeline) +static void CreateRayTracingPipeline(RenderDeviceVkImpl* pDeviceVk, + std::vector<VkPipelineShaderStageCreateInfo>& Stages, + const std::vector<VkRayTracingShaderGroupCreateInfoKHR>& ShaderGroups, + const PipelineLayout& Layout, + const PipelineStateDesc& PSODesc, + const RayTracingPipelineDesc& RayTracingPipeline, + VulkanUtilities::PipelineWrapper& Pipeline) { const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); const auto& PhysicalDevice = pDeviceVk->GetPhysicalDevice(); @@ -410,16 +410,18 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i) { + const auto& GeneralShader = CreateInfo.pGeneralShaders[i]; + VkRayTracingShaderGroupCreateInfoKHR Group = {}; Group.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR; Group.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR; - Group.generalShader = ShaderToIndex(CreateInfo.pGeneralShaders[i].pShader); + Group.generalShader = ShaderToIndex(GeneralShader.pShader); Group.closestHitShader = VK_SHADER_UNUSED_KHR; Group.anyHitShader = VK_SHADER_UNUSED_KHR; Group.intersectionShader = VK_SHADER_UNUSED_KHR; - 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"); @@ -428,16 +430,18 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i) { + const auto& TriHitShader = CreateInfo.pTriangleHitShaders[i]; + VkRayTracingShaderGroupCreateInfoKHR Group = {}; Group.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR; Group.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR; Group.generalShader = VK_SHADER_UNUSED_KHR; - Group.closestHitShader = ShaderToIndex(CreateInfo.pTriangleHitShaders[i].pClosestHitShader); - Group.anyHitShader = ShaderToIndex(CreateInfo.pTriangleHitShaders[i].pAnyHitShader); + Group.closestHitShader = ShaderToIndex(TriHitShader.pClosestHitShader); + Group.anyHitShader = ShaderToIndex(TriHitShader.pAnyHitShader); Group.intersectionShader = VK_SHADER_UNUSED_KHR; - 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"); @@ -446,23 +450,25 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i) { + const auto& ProcHitShader = CreateInfo.pProceduralHitShaders[i]; + VkRayTracingShaderGroupCreateInfoKHR Group = {}; Group.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR; Group.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR; Group.generalShader = VK_SHADER_UNUSED_KHR; - Group.intersectionShader = ShaderToIndex(CreateInfo.pProceduralHitShaders[i].pIntersectionShader); - Group.closestHitShader = ShaderToIndex(CreateInfo.pProceduralHitShaders[i].pClosestHitShader); - Group.anyHitShader = ShaderToIndex(CreateInfo.pProceduralHitShaders[i].pAnyHitShader); + Group.intersectionShader = ShaderToIndex(ProcHitShader.pIntersectionShader); + Group.closestHitShader = ShaderToIndex(ProcHitShader.pClosestHitShader); + Group.anyHitShader = ShaderToIndex(ProcHitShader.pAnyHitShader); - 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"); ShaderGroups.push_back(Group); } - VERIFY_EXPR(Uint32(CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount) == GroupIndex); + VERIFY_EXPR(Uint32{CreateInfo.GeneralShaderCount} + Uint32{CreateInfo.TriangleHitShaderCount} + Uint32{CreateInfo.ProceduralHitShaderCount} == GroupIndex); #ifdef DILIGENT_DEVELOPMENT Uint32 ShaderIndex2 = 0; @@ -474,7 +480,7 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& if (iter != UniqueShaders.end()) VERIFY_EXPR(iter->second == ShaderIndex2); else - UNEXPECTED("shader is not used in ray tracing shader groups"); + UNEXPECTED("Shader '", pShader->GetDesc().Name, "' is not used in ray tracing shader groups"); ++ShaderIndex2; } @@ -630,10 +636,11 @@ void PipelineStateVkImpl::InitResourceLayouts(const PipelineStateCreateInfo& Cre m_ShaderResourceLayoutHash = m_PipelineLayout.GetHash(); } -template <typename PSOCreateInfoType> +template <typename PSOCreateInfoType, typename InitPSODescType> void PipelineStateVkImpl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, std::vector<VkPipelineShaderStageCreateInfo>& vkShaderStages, - std::vector<VulkanUtilities::ShaderModuleWrapper>& ShaderModules) + std::vector<VulkanUtilities::ShaderModuleWrapper>& ShaderModules, + InitPSODescType InitPSODesc) { m_ResourceLayoutIndex.fill(-1); @@ -668,7 +675,7 @@ void PipelineStateVkImpl::InitInternalObjects(const PSOCreateInfoType& for (Uint32 s = 0; s < NumShaderStages; ++s) new (m_StaticVarsMgrs + s) ShaderVariableManagerVk{*this, m_StaticResCaches[s]}; - InitializePipelineDesc(CreateInfo, MemPool); + InitPSODesc(CreateInfo, MemPool, ShaderStages); // It is important to construct all objects before initializing them because if an exception is thrown, // destructors will be called for all objects @@ -691,7 +698,12 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* std::vector<VkPipelineShaderStageCreateInfo> vkShaderStages; std::vector<VulkanUtilities::ShaderModuleWrapper> ShaderModules; - InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules); + InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules, + [this](const GraphicsPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool, TShaderStages /*ShaderStages*/) // + { + InitializePipelineDesc(CreateInfo, MemPool); + } // + ); CreateGraphicsPipeline(pDeviceVk, vkShaderStages, m_PipelineLayout, m_Desc, GetGraphicsPipelineDesc(), m_Pipeline, m_pRenderPass); } @@ -714,7 +726,12 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* p std::vector<VkPipelineShaderStageCreateInfo> vkShaderStages; std::vector<VulkanUtilities::ShaderModuleWrapper> ShaderModules; - InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules); + InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules, + [this](const ComputePipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool, TShaderStages /*ShaderStages*/) // + { + InitializePipelineDesc(CreateInfo, MemPool); + } // + ); CreateComputePipeline(pDeviceVk, vkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline); } @@ -733,57 +750,24 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* { try { - m_ResourceLayoutIndex.fill(-1); - - TShaderStages ShaderStages; - ExtractShaders<ShaderVkImpl>(CreateInfo, ShaderStages); - - const auto ShaderGroupHandleSize = pDeviceVk->GetPhysicalDevice().GetExtProperties().RayTracing.shaderGroupHandleSize; - TNameToGroupIndexMap NameToGroupIndex; - LinearAllocator MemPool{GetRawAllocator()}; - - const auto NumShaderStages = GetNumShaderStages(); - VERIFY_EXPR(NumShaderStages > 0 && NumShaderStages == ShaderStages.size()); - - MemPool.AddSpace<ShaderResourceCacheVk>(NumShaderStages); - MemPool.AddSpace<ShaderResourceLayoutVk>(NumShaderStages * 2); - MemPool.AddSpace<ShaderVariableManagerVk>(NumShaderStages); - - ReserveSpaceForPipelineDesc(CreateInfo, ShaderGroupHandleSize, MemPool); - - MemPool.Reserve(); - - const auto& LogicalDevice = GetDevice()->GetLogicalDevice(); - - m_StaticResCaches = MemPool.ConstructArray<ShaderResourceCacheVk>(NumShaderStages, ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources); - - // The memory is now owned by PipelineStateVkImpl and will be freed by Destruct(). - auto* Ptr = MemPool.ReleaseOwnership(); - VERIFY_EXPR(Ptr == m_StaticResCaches); - (void)Ptr; - - m_ShaderResourceLayouts = MemPool.ConstructArray<ShaderResourceLayoutVk>(NumShaderStages * 2, LogicalDevice); - - m_StaticVarsMgrs = MemPool.Allocate<ShaderVariableManagerVk>(NumShaderStages); - for (Uint32 s = 0; s < NumShaderStages; ++s) - new (m_StaticVarsMgrs + s) ShaderVariableManagerVk{*this, m_StaticResCaches[s]}; - - std::vector<VkRayTracingShaderGroupCreateInfoKHR> ShaderGroups; - BuildRTPipelineDescription(CreateInfo, NameToGroupIndex, ShaderGroups, ShaderStages, MemPool); - InitializePipelineDesc(CreateInfo, ShaderGroupHandleSize, std::move(NameToGroupIndex), 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, ShaderStages); - - // Create shader modules and initialize shader stages std::vector<VkPipelineShaderStageCreateInfo> vkShaderStages; std::vector<VulkanUtilities::ShaderModuleWrapper> ShaderModules; - InitPipelineShaderStages(GetDevice()->GetLogicalDevice(), ShaderStages, ShaderModules, vkShaderStages); + + std::vector<VkRayTracingShaderGroupCreateInfoKHR> ShaderGroups; + InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules, + [&](const RayTracingPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool, TShaderStages& ShaderStages) // + { + TNameToGroupIndexMap NameToGroupIndex; + BuildRTPipelineDescription(CreateInfo, NameToGroupIndex, ShaderGroups, ShaderStages, MemPool); + InitializePipelineDesc(CreateInfo, std::move(NameToGroupIndex), MemPool); + } // + ); CreateRayTracingPipeline(pDeviceVk, vkShaderStages, ShaderGroups, m_PipelineLayout, m_Desc, GetRayTracingPipelineDesc(), m_Pipeline); + const auto& LogicalDevice = GetDevice()->GetLogicalDevice(); + const auto ShaderGroupHandleSize = pDeviceVk->GetShaderGroupHandleSize(); + auto err = LogicalDevice.GetRayTracingShaderGroupHandles(m_Pipeline, 0, static_cast<uint32_t>(ShaderGroups.size()), ShaderGroupHandleSize, &m_pRayTracingPipelineData->Shaders[0]); VERIFY(err == VK_SUCCESS, "Failed to get shader group handles"); (void)err; @@ -978,20 +962,22 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind } } - VERIFY_EXPR(pDescrSetBindInfo != nullptr); + + VkPipelineBindPoint BindPoint = VK_PIPELINE_BIND_POINT_MAX_ENUM; switch (m_Desc.PipelineType) { // clang-format off case PIPELINE_TYPE_GRAPHICS: - case PIPELINE_TYPE_MESH: pDescrSetBindInfo->BindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; break; - case PIPELINE_TYPE_COMPUTE: pDescrSetBindInfo->BindPoint = VK_PIPELINE_BIND_POINT_COMPUTE; break; - case PIPELINE_TYPE_RAY_TRACING: pDescrSetBindInfo->BindPoint = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR; break; - default: UNEXPECTED("unknown pipeline type"); - // clang-format on + case PIPELINE_TYPE_MESH: BindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; break; + case PIPELINE_TYPE_COMPUTE: BindPoint = VK_PIPELINE_BIND_POINT_COMPUTE; break; + case PIPELINE_TYPE_RAY_TRACING: BindPoint = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR; break; + // clang-format on + default: UNEXPECTED("Unknown pipeline type"); } + VERIFY_EXPR(pDescrSetBindInfo != nullptr); // Prepare descriptor sets, and also bind them if there are no dynamic descriptors - m_PipelineLayout.PrepareDescriptorSets(pCtxVkImpl, ResourceCache, *pDescrSetBindInfo, DynamicDescrSet); + m_PipelineLayout.PrepareDescriptorSets(pCtxVkImpl, BindPoint, ResourceCache, *pDescrSetBindInfo, DynamicDescrSet); // Dynamic descriptor sets are not released individually. Instead, all dynamic descriptor pools // are released at the end of the frame by DeviceContextVkImpl::FinishFrame(). } @@ -1036,7 +1022,7 @@ IShaderResourceVariable* PipelineStateVkImpl::GetStaticVariableByIndex(SHADER_TY if (LayoutInd < 0) return nullptr; - auto& StaticVarMgr = GetStaticVarMgr(LayoutInd); + const auto& StaticVarMgr = GetStaticVarMgr(LayoutInd); return StaticVarMgr.GetVariable(Index); } diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index 3199a014..4d2c01e3 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -81,7 +81,7 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters* sizeof(FramebufferVkImpl), sizeof(BottomLevelASVkImpl), sizeof(TopLevelASVkImpl), - sizeof(ShaderBindingTableVkImpl) + sizeof(ShaderBindingTableVkImpl), } }, m_VulkanInstance {Instance }, diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 16b6bee3..499c35ef 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -95,10 +95,10 @@ static SHADER_RESOURCE_VARIABLE_TYPE FindShaderVariableType(SHADER_TYPE ShaderResourceLayoutVk::ShaderStageInfo::ShaderStageInfo(SHADER_TYPE Stage, const ShaderVkImpl* pShader) : - Type{Stage} + Type{Stage}, + Shaders{{pShader}}, + SPIRVs{{pShader->GetSPIRV()}} { - Shaders.push_back(pShader); - SPIRVs.push_back(pShader->GetSPIRV()); } void ShaderResourceLayoutVk::ShaderStageInfo::Append(const ShaderVkImpl* pShader) @@ -123,13 +123,13 @@ ShaderResourceLayoutVk::~ShaderResourceLayoutVk() GetImmutableSampler(s).~ImmutableSamplerPtrType(); } -void ShaderResourceLayoutVk::AllocateMemory(const std::vector<const ShaderVkImpl*>& Shaders, - IMemoryAllocator& Allocator, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - ResourceNameToIndex_t& UniqueNames, - bool AllocateImmutableSamplers) +StringPool ShaderResourceLayoutVk::AllocateMemory(const std::vector<const ShaderVkImpl*>& Shaders, + IMemoryAllocator& Allocator, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + ResourceNameToIndex_t& UniqueNames, + bool AllocateImmutableSamplers) { VERIFY(!m_ResourceBuffer, "Memory has already been initialized"); VERIFY_EXPR(Shaders.size() > 0); @@ -143,16 +143,18 @@ void ShaderResourceLayoutVk::AllocateMemory(const std::vector<const ShaderVkImpl // Count the number of resources to allocate all needed memory for (size_t s = 0; s < Shaders.size(); ++s) { - auto pResources = Shaders[s]->GetShaderResources(); - const auto* CombinedSamplerSuffix = pResources->GetCombinedSamplerSuffix(); - VERIFY_EXPR(pResources->GetShaderType() == m_ShaderType); - pResources->ProcessResources( + const auto& Resources = *Shaders[s]->GetShaderResources(); + const auto* CombinedSamplerSuffix = Resources.GetCombinedSamplerSuffix(); + VERIFY(Resources.GetShaderType() == m_ShaderType, "Unexpected shader type"); + VERIFY(m_IsUsingSeparateSamplers == !Resources.IsUsingCombinedSamplers(), "All shaders in the stage must either use or not use combined image samplers"); + + Resources.ProcessResources( [&](const SPIRVShaderResourceAttribs& ResAttribs, Uint32) // { auto VarType = FindShaderVariableType(m_ShaderType, ResAttribs, ResourceLayoutDesc, CombinedSamplerSuffix); if (IsAllowedType(VarType, AllowedTypeBits)) { - bool IsUniqueName = UniqueNames.emplace(HashMapStringKey{ResAttribs.Name}, ~0u).second; + bool IsUniqueName = UniqueNames.emplace(HashMapStringKey{ResAttribs.Name}, InvalidResourceIndex).second; if (IsUniqueName) { StringPoolSize += strlen(ResAttribs.Name) + 1; @@ -165,11 +167,8 @@ void ShaderResourceLayoutVk::AllocateMemory(const std::vector<const ShaderVkImpl } } // ); - VERIFY_EXPR(m_IsUsingSeparateSamplers == !pResources->IsUsingCombinedSamplers()); } - m_StringPool.Reserve(StringPoolSize, GetRawAllocator()); - Uint32 TotalResources = 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)) { @@ -189,19 +188,26 @@ void ShaderResourceLayoutVk::AllocateMemory(const std::vector<const ShaderVkImpl } } - size_t MemSize = TotalResources * sizeof(VkResource) + m_NumImmutableSamplers * sizeof(ImmutableSamplerPtrType); - static_assert((sizeof(VkResource) % sizeof(void*)) == 0, "sizeof(VkResource) must be multiple of sizeof(void*)"); - if (MemSize == 0) - return; + LinearAllocator MemPool{Allocator}; - auto* pRawMem = ALLOCATE_RAW(Allocator, "Raw memory buffer for shader resource layout resources", MemSize); - m_ResourceBuffer = std::unique_ptr<void, STDDeleterRawMem<void>>(pRawMem, Allocator); - for (Uint32 s = 0; s < m_NumImmutableSamplers; ++s) - { - // We need to initialize immutable samplers - auto& UninitializedImmutableSampler = GetImmutableSampler(s); - new (std::addressof(UninitializedImmutableSampler)) ImmutableSamplerPtrType; - } + MemPool.AddSpace<VkResource>(TotalResources); + MemPool.AddSpace<ImmutableSamplerPtrType>(m_NumImmutableSamplers); + MemPool.AddSpace<char>(StringPoolSize); + + MemPool.Reserve(); + + auto* pResources = MemPool.Allocate<VkResource>(TotalResources); + auto* pImtblSamplers = MemPool.ConstructArray<ImmutableSamplerPtrType>(m_NumImmutableSamplers); + auto* pStringData = MemPool.ConstructArray<char>(StringPoolSize); + + m_ResourceBuffer = std::unique_ptr<void, STDDeleterRawMem<void>>(MemPool.Release(), Allocator); + + VERIFY_EXPR(m_ResourceBuffer.get() == pResources); + VERIFY_EXPR(m_NumImmutableSamplers == 0 || pImtblSamplers == std::addressof(GetImmutableSampler(0))); + + StringPool stringPool; + stringPool.AssignMemory(pStringData, StringPoolSize); + return stringPool; } @@ -254,18 +260,19 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(const std::vector<co // are relevant only when the main layout is initialized ResourceNameToIndex_t ResourceNameToIndex; constexpr bool AllocateImmutableSamplers = false; - AllocateMemory(Shaders, LayoutDataAllocator, ResourceLayoutDesc, &AllowedVarType, 1, ResourceNameToIndex, AllocateImmutableSamplers); + + auto stringPool = AllocateMemory(Shaders, LayoutDataAllocator, ResourceLayoutDesc, &AllowedVarType, 1, ResourceNameToIndex, AllocateImmutableSamplers); std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrResInd = {}; Uint32 StaticResCacheSize = 0; const Uint32 AllowedTypeBits = GetAllowedTypeBits(&AllowedVarType, 1); - for (auto* pShader : Shaders) + for (const auto* pShader : Shaders) { - auto pResources = pShader->GetShaderResources(); - const auto* CombinedSamplerSuffix = pResources->GetCombinedSamplerSuffix(); - pResources->ProcessResources( + const auto& Resources = *pShader->GetShaderResources(); + const auto* CombinedSamplerSuffix = Resources.GetCombinedSamplerSuffix(); + Resources.ProcessResources( [&](const SPIRVShaderResourceAttribs& Attribs, Uint32) // { auto VarType = FindShaderVariableType(m_ShaderType, Attribs, ResourceLayoutDesc, CombinedSamplerSuffix); @@ -275,7 +282,7 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(const std::vector<co auto ResIter = ResourceNameToIndex.find(HashMapStringKey{Attribs.Name}); VERIFY_EXPR(ResIter != ResourceNameToIndex.end()); - if (ResIter->second == ~0u) + if (ResIter->second == InvalidResourceIndex) { Int32 SrcImmutableSamplerInd = -1; if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || @@ -296,14 +303,26 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(const std::vector<co { // Separate samplers are enumerated before separate images, so the sampler // assigned to this separate image must have already been created. - SamplerInd = FindAssignedSampler(*this, *pResources, Attribs, CurrResInd[VarType], VarType); + SamplerInd = FindAssignedSampler(*this, Resources, Attribs, CurrResInd[VarType], VarType); } // add new resource ResIter->second = CurrResInd[VarType]; - ::new (&GetResource(VarType, CurrResInd[VarType]++)) VkResource(*this, m_StringPool.CopyString(Attribs.Name), Attribs.ArraySize, - Attribs.Type, Attribs.ResourceDim, Attribs.IsMS, VarType, - Binding, DescriptorSet, CacheOffset, SamplerInd, SrcImmutableSamplerInd >= 0); + ::new (&GetResource(VarType, CurrResInd[VarType]++)) VkResource // + { + *this, + stringPool.CopyString(Attribs.Name), + Attribs.ArraySize, + Attribs.Type, + Attribs.GetResourceDimension(), + Attribs.IsMultisample(), + VarType, + Binding, + DescriptorSet, + CacheOffset, + SamplerInd, + SrcImmutableSamplerInd >= 0 // + }; } else { @@ -325,7 +344,7 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(const std::vector<co VERIFY(CurrResInd[VarType] == m_NumResources[VarType], "Not all resources have been initialized, which will cause a crash when dtor is called"); } - VERIFY_EXPR(m_StringPool.GetRemainingSize() == 0); + VERIFY_EXPR(stringPool.GetRemainingSize() == 0); #endif StaticResourceCache.InitializeSets(GetRawAllocator(), 1, &StaticResCacheSize); @@ -394,17 +413,19 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const TShaderStages& bool VariableFound = false; for (size_t s = 0; s < ShaderStages.size() && !VariableFound; ++s) { - auto& Shaders = ShaderStages[s].Shaders; - for (size_t i = 0; i < Shaders.size() && !VariableFound; ++i) + const auto& Stage = ShaderStages[s]; + if ((Stage.Type & VarDesc.ShaderStages) == 0) + continue; + + for (size_t i = 0; i < Stage.Shaders.size() && !VariableFound; ++i) { - const auto& Resources = *Shaders[i]->GetShaderResources(); - if ((VarDesc.ShaderStages & Resources.GetShaderType()) != 0) + const auto& Resources = *Stage.Shaders[i]->GetShaderResources(); + VERIFY_EXPR(Resources.GetShaderType() == Stage.Type); + + for (Uint32 res = 0; res < Resources.GetTotalResources() && !VariableFound; ++res) { - for (Uint32 res = 0; res < Resources.GetTotalResources() && !VariableFound; ++res) - { - const auto& ResAttribs = Resources.GetResource(res); - VariableFound = (strcmp(ResAttribs.Name, VarDesc.Name) == 0); - } + const auto& ResAttribs = Resources.GetResource(res); + VariableFound = (strcmp(ResAttribs.Name, VarDesc.Name) == 0); } } } @@ -431,15 +452,17 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const TShaderStages& bool SamplerFound = false; for (size_t s = 0; s < ShaderStages.size() && !SamplerFound; ++s) { - auto& Shaders = ShaderStages[s].Shaders; - for (size_t j = 0; j < Shaders.size() && !SamplerFound; ++j) + const auto& Stage = ShaderStages[s]; + if ((Stage.Type & ImtblSamDesc.ShaderStages) == 0) + continue; + + for (size_t j = 0; j < Stage.Shaders.size() && !SamplerFound; ++j) { - const auto& Resources = *Shaders[j]->GetShaderResources(); - if ((ImtblSamDesc.ShaderStages & Resources.GetShaderType()) == 0) - continue; + const auto& Resources = *Stage.Shaders[j]->GetShaderResources(); + VERIFY_EXPR(Resources.GetShaderType() == Stage.Type); // Irrespective of whether HLSL-style combined image samplers are used, - // a static sampler can be assigned to GLSL sampled image (i.e. sampler2D g_tex) + // an immutable sampler can be assigned to GLSL sampled image (i.e. sampler2D g_tex) for (Uint32 i = 0; i < Resources.GetNumSmpldImgs() && !SamplerFound; ++i) { const auto& SmplImg = Resources.GetSmpldImg(i); @@ -448,7 +471,7 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const TShaderStages& if (!SamplerFound) { - // Check if static sampler is assigned to a separate sampler. + // Check if immutable is assigned to a separate sampler. // In case HLSL-style combined image samplers are used, the condition is SepSmpl.Name == "g_Texture" + "_sampler". // Otherwise the condition is SepSmpl.Name == "g_Texture_sampler" + "". const auto* CombinedSamplerSuffix = Resources.GetCombinedSamplerSuffix(); @@ -486,15 +509,21 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende #endif std::array<ResourceNameToIndex_t, MAX_SHADERS_IN_PIPELINE> ResourceNameToIndexArray; - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes = nullptr; - const Uint32 NumAllowedTypes = 0; - const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); - constexpr bool AllocateImmutableSamplers = true; + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes = nullptr; + const Uint32 NumAllowedTypes = 0; + const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + + constexpr bool AllocateImmutableSamplers = true; + + std::vector<StringPool> stringPools; + stringPools.reserve(ShaderStages.size()); for (size_t s = 0; s < ShaderStages.size(); ++s) { - Layouts[s].AllocateMemory(ShaderStages[s].Shaders, LayoutDataAllocator, ResourceLayoutDesc, - AllowedVarTypes, NumAllowedTypes, ResourceNameToIndexArray[s], AllocateImmutableSamplers); + stringPools.emplace_back( + Layouts[s].AllocateMemory(ShaderStages[s].Shaders, LayoutDataAllocator, ResourceLayoutDesc, + AllowedVarTypes, NumAllowedTypes, ResourceNameToIndexArray[s], + AllocateImmutableSamplers)); } //VERIFY_EXPR(NumShaders <= MAX_SHADERS_IN_PIPELINE); @@ -504,7 +533,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende std::unordered_map<Uint32, std::pair<Uint32, Uint32>> dbgBindings_CacheOffsets; #endif - auto AddResource = [&](Uint32 ShaderInd, + auto AddResource = [&](const Uint32 ShaderInd, ShaderResourceLayoutVk& ResLayout, const SPIRVShaderResources& Resources, const SPIRVShaderResourceAttribs& Attribs, @@ -519,7 +548,8 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende auto ResIter = ResourceNameToIndex.find(HashMapStringKey{Attribs.Name}); VERIFY_EXPR(ResIter != ResourceNameToIndex.end()); - if (ResIter->second == ~0u) + const VkResource* pResource = nullptr; + if (ResIter->second == InvalidResourceIndex) { // add new resource Uint32 Binding = 0; @@ -554,9 +584,6 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende VERIFY(DescriptorSet <= std::numeric_limits<decltype(VkResource::DescriptorSet)>::max(), "Descriptor set (", DescriptorSet, ") excceeds maximum representable value"); VERIFY(Binding <= std::numeric_limits<decltype(VkResource::Binding)>::max(), "Binding (", Binding, ") excceeds maximum representable value"); - SPIRV[Attribs.BindingDecorationOffset] = Binding; - SPIRV[Attribs.DescriptorSetDecorationOffset] = DescriptorSet; - #ifdef DILIGENT_DEBUG // Verify that bindings and cache offsets monotonically increase in every descriptor set auto Binding_OffsetIt = dbgBindings_CacheOffsets.find(DescriptorSet); @@ -570,24 +597,37 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende auto& ResInd = CurrResInd[ShaderInd][VarType]; ResIter->second = ResInd; - ::new (&ResLayout.GetResource(VarType, ResInd++)) VkResource(ResLayout, ResLayout.m_StringPool.CopyString(Attribs.Name), Attribs.ArraySize, - Attribs.Type, Attribs.ResourceDim, Attribs.IsMS, VarType, - Binding, DescriptorSet, CacheOffset, SamplerInd, vkImmutableSampler != VK_NULL_HANDLE ? 1 : 0); + + pResource = ::new (&ResLayout.GetResource(VarType, ResInd++)) VkResource // + { + ResLayout, + stringPools[ShaderInd].CopyString(Attribs.Name), + Attribs.ArraySize, + Attribs.Type, + Attribs.GetResourceDimension(), + Attribs.IsMultisample(), + VarType, + Binding, + DescriptorSet, + CacheOffset, + SamplerInd, + vkImmutableSampler != VK_NULL_HANDLE // + }; } else { // merge with existing - auto& ExistingRes = ResLayout.GetResource(VarType, ResIter->second); + pResource = &ResLayout.GetResource(VarType, ResIter->second); - VERIFY_EXPR(ExistingRes.VariableType == VarType); - VERIFY_EXPR(ExistingRes.Type == Attribs.Type); - VERIFY_EXPR(ExistingRes.ResourceDim == Attribs.ResourceDim); - VERIFY_EXPR(ExistingRes.IsMS == Attribs.IsMS); - VERIFY_EXPR(ExistingRes.ArraySize == Attribs.ArraySize); - - SPIRV[Attribs.BindingDecorationOffset] = ExistingRes.Binding; - SPIRV[Attribs.DescriptorSetDecorationOffset] = ExistingRes.DescriptorSet; + VERIFY_EXPR(pResource->VariableType == VarType); + VERIFY_EXPR(pResource->Type == Attribs.Type); + VERIFY_EXPR(pResource->ResourceDim == Attribs.ResourceDim); + VERIFY_EXPR(pResource->IsMS == Attribs.IsMS); + VERIFY_EXPR(pResource->ArraySize == Attribs.ArraySize); } + VERIFY_EXPR(pResource != nullptr); + SPIRV[Attribs.BindingDecorationOffset] = pResource->Binding; + SPIRV[Attribs.DescriptorSetDecorationOffset] = pResource->DescriptorSet; }; // First process uniform buffers for all shader stages to make sure all UBs go first in every descriptor set @@ -707,7 +747,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende // Some immutable samplers may never be initialized if they are not present in shaders VERIFY_EXPR(CurrImmutableSamplerInd[s] <= Layout.m_NumImmutableSamplers); - VERIFY_EXPR(Layout.m_StringPool.GetRemainingSize() == 0); + VERIFY_EXPR(stringPools[s].GetRemainingSize() == 0); } #endif } @@ -1184,72 +1224,6 @@ bool ShaderResourceLayoutVk::VkResource::IsBound(Uint32 ArrayIndex, const Shader return false; } -ShaderResourceDesc ShaderResourceLayoutVk::VkResource::GetResourceDesc() const -{ - ShaderResourceDesc ResourceDesc; - ResourceDesc.Name = Name; - ResourceDesc.ArraySize = ArraySize; - - static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please handle the new resource type below"); - switch (Type) - { - case SPIRVShaderResourceAttribs::ResourceType::UniformBuffer: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_CONSTANT_BUFFER; - break; - - case SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer: - // Read-only storage buffers map to buffer SRV - // https://github.com/KhronosGroup/SPIRV-Cross/wiki/Reflection-API-user-guide#read-write-vs-read-only-resources-for-hlsl - ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_SRV; - break; - - case SPIRVShaderResourceAttribs::ResourceType::RWStorageBuffer: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV; - break; - - case SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_SRV; - break; - - case SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV; - break; - - case SPIRVShaderResourceAttribs::ResourceType::StorageImage: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_TEXTURE_UAV; - break; - - case SPIRVShaderResourceAttribs::ResourceType::SampledImage: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_TEXTURE_SRV; - break; - - case SPIRVShaderResourceAttribs::ResourceType::AtomicCounter: - LOG_WARNING_MESSAGE("There is no appropriate shader resource type for atomic counter resource '", Name, "'"); - ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV; - break; - - case SPIRVShaderResourceAttribs::ResourceType::SeparateImage: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_TEXTURE_SRV; - break; - - case SPIRVShaderResourceAttribs::ResourceType::SeparateSampler: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_SAMPLER; - break; - - case SPIRVShaderResourceAttribs::ResourceType::InputAttachment: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT; - break; - - case SPIRVShaderResourceAttribs::ResourceType::AccelerationStructure: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_ACCEL_STRUCT; - break; - - default: - UNEXPECTED("Unknown SPIRV resource type"); - } - return ResourceDesc; -} - void ShaderResourceLayoutVk::InitializeStaticResources(const ShaderResourceLayoutVk& SrcLayout, const ShaderResourceCacheVk& SrcResourceCache, diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp index 825bf872..405149a5 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp @@ -192,7 +192,7 @@ VulkanInstance::VulkanInstance(uint32_t ApiVersion, uint32_t MaxApiVersion = 0; vkEnumerateInstanceVersion(&MaxApiVersion); ApiVersion = std::min(ApiVersion, MaxApiVersion); - LOG_INFO_MESSAGE("Used Vulkan API version ", VK_VERSION_MAJOR(ApiVersion), ".", VK_VERSION_MINOR(ApiVersion)); + LOG_INFO_MESSAGE("Using Vulkan API version ", VK_VERSION_MAJOR(ApiVersion), ".", VK_VERSION_MINOR(ApiVersion)); } #endif diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp index b66ac8af..a80d7f73 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp @@ -198,7 +198,7 @@ VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice, m_ExtProperties.RayTracing.shaderGroupBaseAlignment = RayTracingNV.shaderGroupBaseAlignment; m_ExtProperties.RayTracing.maxGeometryCount = RayTracingNV.maxGeometryCount; m_ExtProperties.RayTracing.maxInstanceCount = RayTracingNV.maxInstanceCount; - m_ExtProperties.RayTracing.maxPrimitiveCount = RayTracingNV.maxTriangleCount / 3; + m_ExtProperties.RayTracing.maxPrimitiveCount = RayTracingNV.maxTriangleCount; m_ExtProperties.RayTracing.maxDescriptorSetAccelerationStructures = RayTracingNV.maxDescriptorSetAccelerationStructures; m_ExtProperties.RayTracing.shaderGroupHandleCaptureReplaySize = 0; } diff --git a/Graphics/ShaderTools/include/SPIRVShaderResources.hpp b/Graphics/ShaderTools/include/SPIRVShaderResources.hpp index 338bf602..7e75fb07 100644 --- a/Graphics/ShaderTools/include/SPIRVShaderResources.hpp +++ b/Graphics/ShaderTools/include/SPIRVShaderResources.hpp @@ -75,6 +75,8 @@ struct SPIRVShaderResourceAttribs NumResourceTypes }; + static SHADER_RESOURCE_TYPE GetShaderResourceType(ResourceType Type); + // clang-format off static constexpr const Uint32 InvalidSepSmplrOrImgInd = static_cast<Uint32>(-1); @@ -147,7 +149,10 @@ public: // clang-format on } - ShaderResourceDesc GetResourceDesc() const; + ShaderResourceDesc GetResourceDesc() const + { + return ShaderResourceDesc{Name, GetShaderResourceType(Type), ArraySize}; + } RESOURCE_DIMENSION GetResourceDimension() const { diff --git a/Graphics/ShaderTools/src/DXCompiler.cpp b/Graphics/ShaderTools/src/DXCompiler.cpp index 75782aaa..237d7cea 100644 --- a/Graphics/ShaderTools/src/DXCompiler.cpp +++ b/Graphics/ShaderTools/src/DXCompiler.cpp @@ -589,7 +589,7 @@ void DXCompilerImpl::GetD3D12ShaderReflection(IDxcBlob* pShaderBy if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to load shader reflection from bytecode"); - UINT32 shaderIdx; + UINT32 shaderIdx = 0; hr = pReflection->FindFirstPartKind(DXC_PART_DXIL, &shaderIdx); if (SUCCEEDED(hr)) @@ -598,7 +598,7 @@ void DXCompilerImpl::GetD3D12ShaderReflection(IDxcBlob* pShaderBy if (SUCCEEDED(hr)) return; - // for ray tracing shaders + // Try to get the reflection via library reflection CComPtr<ID3D12LibraryReflection> pLib; hr = pReflection->GetPartReflection(shaderIdx, IID_PPV_ARGS(&pLib)); diff --git a/Graphics/ShaderTools/src/GLSLangUtils.cpp b/Graphics/ShaderTools/src/GLSLangUtils.cpp index 75d97528..85a3efa1 100644 --- a/Graphics/ShaderTools/src/GLSLangUtils.cpp +++ b/Graphics/ShaderTools/src/GLSLangUtils.cpp @@ -456,9 +456,9 @@ std::vector<unsigned int> HLSLtoSPIRV(const ShaderCreateInfo& ShaderCI, VERIFY_EXPR(ShaderCI.SourceLanguage == SHADER_SOURCE_LANGUAGE_HLSL); VERIFY(ShLang != EShLangRayGen && ShLang != EShLangIntersect && ShLang != EShLangAnyHit && ShLang != EShLangClosestHit && ShLang != EShLangMiss && ShLang != EShLangCallable, - "ray tracing shaders are not supported, use DXCompiler to build SPIRV from HLSL"); + "Ray tracing shaders are not supported, use DXCompiler to build SPIRV from HLSL"); VERIFY(ShLang != EShLangTaskNV && ShLang != EShLangMeshNV, - "mesh shaders are not supported, use DXCompiler to build SPIRV from HLSL"); + "Mesh shaders are not supported, use DXCompiler to build SPIRV from HLSL"); Shader.setEnvInput(::glslang::EShSourceHlsl, ShLang, ::glslang::EShClientVulkan, 100); Shader.setEnvClient(::glslang::EShClientVulkan, ::glslang::EShTargetVulkan_1_0); diff --git a/Graphics/ShaderTools/src/SPIRVShaderResources.cpp b/Graphics/ShaderTools/src/SPIRVShaderResources.cpp index 7f1d78d5..bb15cc06 100644 --- a/Graphics/ShaderTools/src/SPIRVShaderResources.cpp +++ b/Graphics/ShaderTools/src/SPIRVShaderResources.cpp @@ -127,70 +127,54 @@ SPIRVShaderResourceAttribs::SPIRVShaderResourceAttribs(const diligent_spirv_cros } -ShaderResourceDesc SPIRVShaderResourceAttribs::GetResourceDesc() const +SHADER_RESOURCE_TYPE SPIRVShaderResourceAttribs::GetShaderResourceType(ResourceType Type) { - ShaderResourceDesc ResourceDesc; - ResourceDesc.Name = Name; - ResourceDesc.ArraySize = ArraySize; - static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please handle the new resource type below"); switch (Type) { case SPIRVShaderResourceAttribs::ResourceType::UniformBuffer: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_CONSTANT_BUFFER; - break; + return SHADER_RESOURCE_TYPE_CONSTANT_BUFFER; case SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer: // Read-only storage buffers map to buffer SRV // https://github.com/KhronosGroup/SPIRV-Cross/wiki/Reflection-API-user-guide#read-write-vs-read-only-resources-for-hlsl - ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_SRV; - break; + return SHADER_RESOURCE_TYPE_BUFFER_SRV; case SPIRVShaderResourceAttribs::ResourceType::RWStorageBuffer: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV; - break; + return SHADER_RESOURCE_TYPE_BUFFER_UAV; case SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_SRV; - break; + return SHADER_RESOURCE_TYPE_BUFFER_SRV; case SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV; - break; + return SHADER_RESOURCE_TYPE_BUFFER_UAV; case SPIRVShaderResourceAttribs::ResourceType::StorageImage: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_TEXTURE_UAV; - break; + return SHADER_RESOURCE_TYPE_TEXTURE_UAV; case SPIRVShaderResourceAttribs::ResourceType::SampledImage: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_TEXTURE_SRV; - break; + return SHADER_RESOURCE_TYPE_TEXTURE_SRV; case SPIRVShaderResourceAttribs::ResourceType::AtomicCounter: - LOG_WARNING_MESSAGE("There is no appropriate shader resource type for atomic counter resource '", Name, "'"); - ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV; - break; + LOG_WARNING_MESSAGE("There is no appropriate shader resource type for atomic counter"); + return SHADER_RESOURCE_TYPE_BUFFER_UAV; case SPIRVShaderResourceAttribs::ResourceType::SeparateImage: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_TEXTURE_SRV; - break; + return SHADER_RESOURCE_TYPE_TEXTURE_SRV; case SPIRVShaderResourceAttribs::ResourceType::SeparateSampler: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_SAMPLER; - break; + return SHADER_RESOURCE_TYPE_SAMPLER; case SPIRVShaderResourceAttribs::ResourceType::InputAttachment: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT; - break; + return SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT; case SPIRVShaderResourceAttribs::ResourceType::AccelerationStructure: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_ACCEL_STRUCT; - break; + return SHADER_RESOURCE_TYPE_ACCEL_STRUCT; default: UNEXPECTED("Unknown SPIRV resource type"); + return SHADER_RESOURCE_TYPE_UNKNOWN; } - return ResourceDesc; } @@ -692,12 +676,12 @@ SPIRVShaderResources::~SPIRVShaderResources() for (Uint32 n = 0; n < GetNumInptAtts(); ++n) GetInptAtt(n).~SPIRVShaderResourceAttribs(); - for (Uint32 n = 0; n < GetNumAccelStructs(); ++n) - GetAccelStruct(n).~SPIRVShaderResourceAttribs(); - for (Uint32 n = 0; n < GetNumShaderStageInputs(); ++n) GetShaderStageInputAttribs(n).~SPIRVShaderStageInputAttribs(); + for (Uint32 n = 0; n < GetNumAccelStructs(); ++n) + GetAccelStruct(n).~SPIRVShaderResourceAttribs(); + static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please add destructor for the new resource"); } @@ -755,12 +739,12 @@ std::string SPIRVShaderResources::DumpResources() if (Img.Type == SPIRVShaderResourceAttribs::ResourceType::StorageImage) { ss << std::endl - << std::setw(3) << ResNum << " Storage Image "; + << std::setw(3) << ResNum << " Storage Image "; } else if (Img.Type == SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer) { ss << std::endl - << std::setw(3) << ResNum << " Storage Txl Buff "; + << std::setw(3) << ResNum << " Storage Txl Buff "; } else UNEXPECTED("Unexpected resource type"); @@ -771,12 +755,12 @@ std::string SPIRVShaderResources::DumpResources() if (SmplImg.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage) { ss << std::endl - << std::setw(3) << ResNum << " Sampled Image "; + << std::setw(3) << ResNum << " Sampled Image "; } else if (SmplImg.Type == SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer) { ss << std::endl - << std::setw(3) << ResNum << " Uniform Txl Buff "; + << std::setw(3) << ResNum << " Uniform Txl Buff "; } else UNEXPECTED("Unexpected resource type"); @@ -786,35 +770,35 @@ std::string SPIRVShaderResources::DumpResources() { VERIFY(AC.Type == SPIRVShaderResourceAttribs::ResourceType::AtomicCounter, "Unexpected resource type"); ss << std::endl - << std::setw(3) << ResNum << " Atomic Cntr "; + << std::setw(3) << ResNum << " Atomic Cntr "; DumpResource(AC); }, [&](const SPIRVShaderResourceAttribs& SepSmpl, Uint32) // { VERIFY(SepSmpl.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler, "Unexpected resource type"); ss << std::endl - << std::setw(3) << ResNum << " Separate Smpl "; + << std::setw(3) << ResNum << " Separate Smpl "; DumpResource(SepSmpl); }, [&](const SPIRVShaderResourceAttribs& SepImg, Uint32) // { VERIFY(SepImg.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage, "Unexpected resource type"); ss << std::endl - << std::setw(3) << ResNum << " Separate Img "; + << std::setw(3) << ResNum << " Separate Img "; DumpResource(SepImg); }, [&](const SPIRVShaderResourceAttribs& InptAtt, Uint32) // { VERIFY(InptAtt.Type == SPIRVShaderResourceAttribs::ResourceType::InputAttachment, "Unexpected resource type"); ss << std::endl - << std::setw(3) << ResNum << " Input Attachment "; + << std::setw(3) << ResNum << " Input Attachment "; DumpResource(InptAtt); }, [&](const SPIRVShaderResourceAttribs& AccelStruct, Uint32) // { VERIFY(AccelStruct.Type == SPIRVShaderResourceAttribs::ResourceType::AccelerationStructure, "Unexpected resource type"); ss << std::endl - << std::setw(3) << ResNum << " Acceleration Struct"; + << std::setw(3) << ResNum << " Accel Struct "; DumpResource(AccelStruct); } // ); |
