diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2020-10-11 02:28:54 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-10-11 02:28:54 +0000 |
| commit | 91aac63f651da1079be93d2fe722cd10e4e15570 (patch) | |
| tree | a342deebcf83a91fac3b35587860e2f2017c1637 /Graphics | |
| parent | formating (diff) | |
| download | DiligentCore-91aac63f651da1079be93d2fe722cd10e4e15570.tar.gz DiligentCore-91aac63f651da1079be93d2fe722cd10e4e15570.zip | |
A number of corrections for PSO refactoring
Diffstat (limited to 'Graphics')
19 files changed, 262 insertions, 255 deletions
diff --git a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp index 29e5aff3..b07a2194 100644 --- a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp +++ b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp @@ -1316,7 +1316,7 @@ Int32 GetShaderTypePipelineIndex(SHADER_TYPE ShaderType, PIPELINE_TYPE PipelineT { VERIFY(IsConsistentShaderType(ShaderType, PipelineType), "Shader type ", GetShaderTypeLiteralName(ShaderType), " is inconsistent with pipeline type ", GetPipelineTypeString(PipelineType)); - VERIFY((ShaderType & (ShaderType - 1)) == 0, "More than one shader type specified"); + VERIFY(IsPowerOfTwo(Uint32{ShaderType}), "More than one shader type is specified"); static_assert(SHADER_TYPE_LAST == 0x080, "Please update the switch below to handle the new shader type"); switch (ShaderType) diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp index 76760db5..09f1bddc 100644 --- a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp +++ b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp @@ -68,6 +68,16 @@ public: bool bIsDeviceInternal = false) : TDeviceObjectBase{pRefCounters, pDevice, PSODesc, bIsDeviceInternal} { + switch (PSODesc.PipelineType) + { + // clang-format off + case PIPELINE_TYPE_GRAPHICS: + case PIPELINE_TYPE_MESH: ValidateGraphicsPipeline(); break; + case PIPELINE_TYPE_COMPUTE: ValidateComputePipeline(); break; + default: UNEXPECTED("unknown pipeline type"); + // clang-format on + } + const auto& SrcLayout = PSODesc.ResourceLayout; size_t StringPoolSize = 0; if (SrcLayout.Variables != nullptr) @@ -88,14 +98,11 @@ public: } } - switch (PSODesc.PipelineType) + if (PSODesc.IsAnyGraphicsPipeline()) { - // clang-format off - case PIPELINE_TYPE_GRAPHICS: - case PIPELINE_TYPE_MESH: ValidateGraphicsPipeline( StringPoolSize); break; - case PIPELINE_TYPE_COMPUTE: ValidateComputePipeline( StringPoolSize); break; - default: UNEXPECTED("unknown pipeline type"); - // clang-format on + const auto& InputLayout = this->m_Desc.GraphicsPipeline.InputLayout; + for (Uint32 i = 0; i < InputLayout.NumElements; ++i) + StringPoolSize += strlen(InputLayout.LayoutElements[i].HLSLSemantic) + 1; } m_StringPool.Reserve(StringPoolSize, GetRawAllocator()); @@ -143,8 +150,8 @@ public: { // clang-format off case PIPELINE_TYPE_GRAPHICS: - case PIPELINE_TYPE_MESH: InitGraphicsPipeline(); break; - case PIPELINE_TYPE_COMPUTE: InitComputePipeline(); break; + case PIPELINE_TYPE_MESH: InitGraphicsPipeline(); break; + case PIPELINE_TYPE_COMPUTE: InitComputePipeline(); break; default: UNEXPECTED("unknown pipeline type"); // clang-format on } @@ -201,8 +208,8 @@ public: return m_BufferSlotsUsed; } - SHADER_TYPE const* GetShaderTypes() const { return m_pShaderTypes.data(); } - Uint32 GetNumShaderTypes() const { return m_NumShaderTypes; } + SHADER_TYPE GetShaderStageType(Uint32 Stage) const { return m_ShaderStageTypes[Stage]; } + Uint32 GetNumShaderStages() const { return m_NumShaderStages; } // This function only compares shader resource layout hashes, so // it can potentially give false negatives @@ -219,10 +226,12 @@ protected: RefCntAutoPtr<IRenderPass> m_pRenderPass; ///< Strong reference to the render pass object - Uint8 m_NumShaderTypes = 0; ///< Number of shader types that this PSO uses + Uint8 m_NumShaderStages = 0; ///< Number of shader stages in this PSO + + /// Array of shader types for every shader stage used by this PSO + std::array<SHADER_TYPE, MAX_SHADERS_IN_PIPELINE> m_ShaderStageTypes = {}; - std::array<SHADER_TYPE, MAX_SHADERS_IN_PIPELINE> m_pShaderTypes = {}; ///< Array of shader types used by this PSO - size_t m_ShaderResourceLayoutHash = 0; ///< Hash computed from the shader resource layout + size_t m_ShaderResourceLayoutHash = 0; ///< Hash computed from the shader resource layout protected: #define LOG_PSO_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of ", GetPipelineTypeString(this->m_Desc.PipelineType), " PSO '", this->m_Desc.Name, "' is invalid: ", ##__VA_ARGS__) @@ -287,51 +296,50 @@ protected: return LayoutInd; } -public: - using ShaderStages_t = std::vector<std::pair<SHADER_TYPE, IShader*>>; protected: - void ExtractShaders(ShaderStages_t& ShaderStages) + template <typename ShaderImplType, typename TShaderStages> + void ExtractShaders(TShaderStages& ShaderStages) { + VERIFY(m_NumShaderStages == 0, "The number of shader stages is not zero! ExtractShaders must only be called once."); + + ShaderStages.clear(); + auto AddShaderStage = [&](IShader*& pShader) { + if (pShader != nullptr) + { + auto ShaderType = pShader->GetDesc().ShaderType; + ShaderStages.emplace_back(ShaderType, ValidatedCast<ShaderImplType>(pShader)); + m_ShaderStageTypes[m_NumShaderStages++] = ShaderType; + + // Reset shader pointers in PSO desc because we don't keep strong references to shaders. + pShader = nullptr; + } + }; + auto& Desc = this->m_Desc; switch (Desc.PipelineType) { case PIPELINE_TYPE_COMPUTE: { - if (Desc.ComputePipeline.pCS) ShaderStages.push_back({SHADER_TYPE_COMPUTE, Desc.ComputePipeline.pCS}); - - // reset shader pointers because we don't keep strong references to shaders - Desc.ComputePipeline.pCS = nullptr; + AddShaderStage(Desc.ComputePipeline.pCS); break; } case PIPELINE_TYPE_GRAPHICS: { - if (Desc.GraphicsPipeline.pVS) ShaderStages.push_back({SHADER_TYPE_VERTEX, Desc.GraphicsPipeline.pVS}); - if (Desc.GraphicsPipeline.pHS) ShaderStages.push_back({SHADER_TYPE_HULL, Desc.GraphicsPipeline.pHS}); - if (Desc.GraphicsPipeline.pDS) ShaderStages.push_back({SHADER_TYPE_DOMAIN, Desc.GraphicsPipeline.pDS}); - if (Desc.GraphicsPipeline.pGS) ShaderStages.push_back({SHADER_TYPE_GEOMETRY, Desc.GraphicsPipeline.pGS}); - if (Desc.GraphicsPipeline.pPS) ShaderStages.push_back({SHADER_TYPE_PIXEL, Desc.GraphicsPipeline.pPS}); - - // reset shader pointers because we don't keep strong references to shaders - Desc.GraphicsPipeline.pVS = nullptr; - Desc.GraphicsPipeline.pHS = nullptr; - Desc.GraphicsPipeline.pDS = nullptr; - Desc.GraphicsPipeline.pGS = nullptr; - Desc.GraphicsPipeline.pPS = nullptr; + AddShaderStage(Desc.GraphicsPipeline.pVS); + AddShaderStage(Desc.GraphicsPipeline.pHS); + AddShaderStage(Desc.GraphicsPipeline.pDS); + AddShaderStage(Desc.GraphicsPipeline.pGS); + AddShaderStage(Desc.GraphicsPipeline.pPS); break; } case PIPELINE_TYPE_MESH: { - if (Desc.GraphicsPipeline.pAS) ShaderStages.push_back({SHADER_TYPE_AMPLIFICATION, Desc.GraphicsPipeline.pAS}); - if (Desc.GraphicsPipeline.pMS) ShaderStages.push_back({SHADER_TYPE_MESH, Desc.GraphicsPipeline.pMS}); - if (Desc.GraphicsPipeline.pPS) ShaderStages.push_back({SHADER_TYPE_PIXEL, Desc.GraphicsPipeline.pPS}); - - // reset shader pointers because we don't keep strong references to shaders - Desc.GraphicsPipeline.pAS = nullptr; - Desc.GraphicsPipeline.pMS = nullptr; - Desc.GraphicsPipeline.pPS = nullptr; + AddShaderStage(Desc.GraphicsPipeline.pAS); + AddShaderStage(Desc.GraphicsPipeline.pMS); + AddShaderStage(Desc.GraphicsPipeline.pPS); break; } @@ -339,14 +347,7 @@ protected: UNEXPECTED("unknown pipeline type"); } -#ifdef DILIGENT_DEVELOPMENT - VERIFY_EXPR(ShaderStages.size() == m_NumShaderTypes); - - for (Uint32 s = 0; s < m_NumShaderTypes; ++s) - { - VERIFY_EXPR(ShaderStages[s].first == m_pShaderTypes[s]); - } -#endif + VERIFY_EXPR(!ShaderStages.empty() && ShaderStages.size() == m_NumShaderStages); } @@ -448,7 +449,7 @@ private: } } - void ValidateGraphicsPipeline(size_t& StringPoolSize) + void ValidateGraphicsPipeline() { const auto& GraphicsPipeline = this->m_Desc.GraphicsPipeline; if (GraphicsPipeline.pRenderPass != nullptr) @@ -477,13 +478,9 @@ private: CheckAndCorrectBlendStateDesc(); CheckRasterizerStateDesc(); CheckAndCorrectDepthStencilDesc(); - - const auto& InputLayout = this->m_Desc.GraphicsPipeline.InputLayout; - for (Uint32 i = 0; i < InputLayout.NumElements; ++i) - StringPoolSize += strlen(InputLayout.LayoutElements[i].HLSLSemantic) + 1; } - void ValidateComputePipeline(size_t& StringPoolSize) + void ValidateComputePipeline() { if (this->m_Desc.GraphicsPipeline.pRenderPass != nullptr) { @@ -527,16 +524,6 @@ private: "Primitive topology is ignored in a mesh pipeline, set it to undefined or keep default value (triangle list)"); } - if (GraphicsPipeline.pVS) m_pShaderTypes[m_NumShaderTypes++] = SHADER_TYPE_VERTEX; - if (GraphicsPipeline.pHS) m_pShaderTypes[m_NumShaderTypes++] = SHADER_TYPE_HULL; - if (GraphicsPipeline.pDS) m_pShaderTypes[m_NumShaderTypes++] = SHADER_TYPE_DOMAIN; - if (GraphicsPipeline.pGS) m_pShaderTypes[m_NumShaderTypes++] = SHADER_TYPE_GEOMETRY; - if (GraphicsPipeline.pAS) m_pShaderTypes[m_NumShaderTypes++] = SHADER_TYPE_AMPLIFICATION; - if (GraphicsPipeline.pMS) m_pShaderTypes[m_NumShaderTypes++] = SHADER_TYPE_MESH; - if (GraphicsPipeline.pPS) m_pShaderTypes[m_NumShaderTypes++] = SHADER_TYPE_PIXEL; - - DEV_CHECK_ERR(m_NumShaderTypes > 0, "There must be at least one shader in the Pipeline State"); - m_pRenderPass = PSODesc.GraphicsPipeline.pRenderPass; for (Uint32 rt = GraphicsPipeline.NumRenderTargets; rt < _countof(GraphicsPipeline.RTVFormats); ++rt) @@ -682,8 +669,6 @@ private: } VALIDATE_SHADER_TYPE(ComputePipeline.pCS, SHADER_TYPE_COMPUTE, "compute"); - - m_pShaderTypes[m_NumShaderTypes++] = SHADER_TYPE_COMPUTE; } #undef VALIDATE_SHADER_TYPE diff --git a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp index 7acb15f0..1d836ab3 100644 --- a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp +++ b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp @@ -118,13 +118,13 @@ public: const ShaderResourceLayoutD3D11& GetStaticResourceLayout(Uint32 s) const { - VERIFY_EXPR(s < GetNumShaderTypes()); + VERIFY_EXPR(s < GetNumShaderStages()); return m_pStaticResourceLayouts[s]; } ShaderResourceCacheD3D11& GetStaticResourceCache(Uint32 s) { - VERIFY_EXPR(s < GetNumShaderTypes()); + VERIFY_EXPR(s < GetNumShaderStages()); return m_pStaticResourceCaches[s]; } diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index cd942aed..75ce9094 100755 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -179,7 +179,7 @@ void DeviceContextD3D11Impl::TransitionAndCommitShaderResources(IPipelineState* { #ifdef DILIGENT_DEVELOPMENT bool ResourcesPresent = false; - for (Uint32 s = 0; s < pPipelineStateD3D11->GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < pPipelineStateD3D11->GetNumShaderStages(); ++s) { auto* pShaderD3D11 = pPipelineStateD3D11->GetShader(s); if (pShaderD3D11->GetD3D11Resources()->GetTotalResources() > 0) @@ -206,7 +206,7 @@ void DeviceContextD3D11Impl::TransitionAndCommitShaderResources(IPipelineState* #endif auto NumShaders = pShaderResBindingD3D11->GetNumActiveShaders(); - VERIFY(NumShaders == pPipelineStateD3D11->GetNumShaderTypes(), "Number of active shaders in shader resource binding is not consistent with the number of shaders in the pipeline state"); + VERIFY(NumShaders == pPipelineStateD3D11->GetNumShaderStages(), "Number of active shaders in shader resource binding is not consistent with the number of shaders in the pipeline state"); #ifdef DILIGENT_DEVELOPMENT { diff --git a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp index 0e312740..4893f97e 100644 --- a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp @@ -131,28 +131,35 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pR UNEXPECTED(GetPipelineTypeString(m_Desc.PipelineType), " pipelines are not supported by Direct3D11 backend"); } + // We do not really need ShaderStages, but ExtractShaders() also initializes + // shader stage types and shader stage counter. + std::vector<std::pair<SHADER_TYPE, ShaderD3D11Impl*>> ShaderStages; + ExtractShaders<ShaderD3D11Impl>(ShaderStages); + VERIFY_EXPR(GetNumShaderStages() == ShaderStages.size()); + // clang-format off static_assert((sizeof(ShaderResourceLayoutD3D11) % sizeof(void*)) == 0, "sizeof(ShaderResourceLayoutD3D11) is expected to be a multiple of sizeof(void*)"); static_assert((sizeof(ShaderResourceCacheD3D11) % sizeof(void*)) == 0, "sizeof(ShaderResourceCacheD3D11) is expected to be a multiple of sizeof(void*)"); // clang-format on - const auto MemSize = (sizeof(ShaderResourceLayoutD3D11) + sizeof(ShaderResourceCacheD3D11)) * GetNumShaderTypes(); + + const auto MemSize = (sizeof(ShaderResourceLayoutD3D11) + sizeof(ShaderResourceCacheD3D11)) * GetNumShaderStages(); auto* const pRawMem = ALLOCATE_RAW(GetRawAllocator(), "Raw memory for ShaderResourceLayoutD3D11 and ShaderResourceCacheD3D11 arrays", MemSize); m_pStaticResourceLayouts = reinterpret_cast<ShaderResourceLayoutD3D11*>(pRawMem); - m_pStaticResourceCaches = reinterpret_cast<ShaderResourceCacheD3D11*>(m_pStaticResourceLayouts + GetNumShaderTypes()); + m_pStaticResourceCaches = reinterpret_cast<ShaderResourceCacheD3D11*>(m_pStaticResourceLayouts + GetNumShaderStages()); const auto& ResourceLayout = m_Desc.ResourceLayout; #ifdef DILIGENT_DEVELOPMENT { const ShaderResources* pResources[MAX_SHADERS_IN_PIPELINE] = {}; - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { auto* pShader = GetShader(s); pResources[s] = &(*pShader->GetD3D11Resources()); } - ShaderResources::DvpVerifyResourceLayout(ResourceLayout, pResources, GetNumShaderTypes(), + ShaderResources::DvpVerifyResourceLayout(ResourceLayout, pResources, GetNumShaderStages(), (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_VARIABLES) == 0, (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_STATIC_SAMPLERS) == 0); } @@ -161,7 +168,7 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pR decltype(m_StaticSamplers) StaticSamplers(STD_ALLOCATOR_RAW_MEM(StaticSamplerInfo, GetRawAllocator(), "Allocator for vector<StaticSamplerInfo>")); std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderResLayoutDataSizes = {}; std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderResCacheDataSizes = {}; - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { const auto* pShader = GetShader(s); const auto& ShaderDesc = pShader->GetDesc(); @@ -221,14 +228,14 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pR if (m_Desc.SRBAllocationGranularity > 1) { - m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderTypes(), ShaderResLayoutDataSizes.data(), GetNumShaderTypes(), ShaderResCacheDataSizes.data()); + m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderStages(), ShaderResLayoutDataSizes.data(), GetNumShaderStages(), ShaderResCacheDataSizes.data()); } m_StaticSamplers.reserve(StaticSamplers.size()); for (auto& Sam : StaticSamplers) m_StaticSamplers.emplace_back(std::move(Sam)); - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { // Initialize static samplers in the static resource cache to avoid warning messages SetStaticSamplers(m_pStaticResourceCaches[s], s); @@ -238,19 +245,19 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pR PipelineStateD3D11Impl::~PipelineStateD3D11Impl() { - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { m_pStaticResourceCaches[s].Destroy(GetRawAllocator()); m_pStaticResourceCaches[s].~ShaderResourceCacheD3D11(); } - for (Uint32 l = 0; l < GetNumShaderTypes(); ++l) + for (Uint32 l = 0; l < GetNumShaderStages(); ++l) { m_pStaticResourceLayouts[l].~ShaderResourceLayoutD3D11(); } // m_pStaticResourceLayouts and m_pStaticResourceCaches are allocated in contiguous chunks of memory. - auto* pRawMem = m_pStaticResourceLayouts; - GetRawAllocator().Free(pRawMem); + if (auto* pRawMem = m_pStaticResourceLayouts) + GetRawAllocator().Free(pRawMem); } IMPLEMENT_QUERY_INTERFACE(PipelineStateD3D11Impl, IID_PipelineStateD3D11, TPipelineStateBase) @@ -297,10 +304,10 @@ bool PipelineStateD3D11Impl::IsCompatibleWith(const IPipelineState* pPSO) const if (m_ShaderResourceLayoutHash != pPSOD3D11->m_ShaderResourceLayoutHash) return false; - if (GetNumShaderTypes() != pPSOD3D11->GetNumShaderTypes()) + if (GetNumShaderStages() != pPSOD3D11->GetNumShaderStages()) return false; - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { auto* pShader0 = GetShader(s); auto* pShader1 = pPSOD3D11->GetShader(s); @@ -360,7 +367,7 @@ ID3D11ComputeShader* PipelineStateD3D11Impl::GetD3D11ComputeShader() void PipelineStateD3D11Impl::BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) { - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { auto& StaticResLayout = m_pStaticResourceLayouts[s]; if ((ShaderFlags & StaticResLayout.GetShaderType()) != 0) @@ -374,7 +381,7 @@ Uint32 PipelineStateD3D11Impl::GetStaticVariableCount(SHADER_TYPE ShaderType) co if (LayoutInd < 0) return 0; - VERIFY_EXPR(static_cast<Uint32>(LayoutInd) <= GetNumShaderTypes()); + VERIFY_EXPR(static_cast<Uint32>(LayoutInd) <= GetNumShaderStages()); return m_pStaticResourceLayouts[LayoutInd].GetTotalResourceCount(); } @@ -384,7 +391,7 @@ IShaderResourceVariable* PipelineStateD3D11Impl::GetStaticVariableByName(SHADER_ if (LayoutInd < 0) return nullptr; - VERIFY_EXPR(static_cast<Uint32>(LayoutInd) <= GetNumShaderTypes()); + VERIFY_EXPR(static_cast<Uint32>(LayoutInd) <= GetNumShaderStages()); return m_pStaticResourceLayouts[LayoutInd].GetShaderVariable(Name); } @@ -394,7 +401,7 @@ IShaderResourceVariable* PipelineStateD3D11Impl::GetStaticVariableByIndex(SHADER if (LayoutInd < 0) return nullptr; - VERIFY_EXPR(static_cast<Uint32>(LayoutInd) <= GetNumShaderTypes()); + VERIFY_EXPR(static_cast<Uint32>(LayoutInd) <= GetNumShaderStages()); return m_pStaticResourceLayouts[LayoutInd].GetShaderVariable(Index); } @@ -431,8 +438,8 @@ const ShaderD3D11Impl* PipelineStateD3D11Impl::GetShaderByType(SHADER_TYPE Shade const ShaderD3D11Impl* PipelineStateD3D11Impl::GetShader(Uint32 Index) const { - if (Index < GetNumShaderTypes()) - return GetShaderByType(GetShaderTypes()[Index]); + if (Index < GetNumShaderStages()) + return GetShaderByType(GetShaderStageType(Index)); UNEXPECTED("Shader index is out of range"); return nullptr; diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp index 17083bbc..88c7b77f 100644 --- a/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp @@ -50,7 +50,7 @@ ShaderResourceBindingD3D11Impl::ShaderResourceBindingD3D11Impl(IReferenceCounter // clang-format on { m_ResourceLayoutIndex.fill(-1); - m_NumActiveShaders = static_cast<Uint8>(pPSO->GetNumShaderTypes()); + m_NumActiveShaders = static_cast<Uint8>(pPSO->GetNumShaderStages()); // clang-format off m_pResourceLayouts = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceLayoutD3D11", ShaderResourceLayoutD3D11, m_NumActiveShaders); @@ -151,7 +151,7 @@ void ShaderResourceBindingD3D11Impl::InitializeStaticResources(const IPipelineSt } const auto* pPSOD3D11 = ValidatedCast<const PipelineStateD3D11Impl>(pPipelineState); - auto NumShaders = pPSOD3D11->GetNumShaderTypes(); + auto NumShaders = pPSOD3D11->GetNumShaderStages(); VERIFY_EXPR(NumShaders == m_NumActiveShaders); for (Uint32 shader = 0; shader < NumShaders; ++shader) diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index 1ce53c24..00b2affd 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -95,19 +95,19 @@ public: const ShaderResourceLayoutD3D12& GetShaderResLayout(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < GetNumShaderTypes()); + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); return m_pShaderResourceLayouts[ShaderInd]; } const ShaderResourceLayoutD3D12& GetStaticShaderResLayout(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < GetNumShaderTypes()); - return m_pShaderResourceLayouts[GetNumShaderTypes() + ShaderInd]; + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); + return m_pShaderResourceLayouts[GetNumShaderStages() + ShaderInd]; } ShaderResourceCacheD3D12& GetStaticShaderResCache(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < GetNumShaderTypes()); + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); return m_pStaticResourceCaches[ShaderInd]; } diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 3e8673d5..f5d60b60 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -106,8 +106,19 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR { m_ResourceLayoutIndex.fill(-1); - ShaderStages_t ShaderStages; - ExtractShaders(ShaderStages); + struct D3D12PipelineShaderStageInfo + { + const SHADER_TYPE Type; + ShaderD3D12Impl* const pShader; + D3D12PipelineShaderStageInfo(SHADER_TYPE _Type, + ShaderD3D12Impl* _pShader) : + Type{_Type}, + pShader{_pShader} + {} + }; + std::vector<D3D12PipelineShaderStageInfo> ShaderStages; + ExtractShaders<ShaderD3D12Impl>(ShaderStages); + VERIFY_EXPR(GetNumShaderStages() == ShaderStages.size()); auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); const auto& ResourceLayout = m_Desc.ResourceLayout; @@ -118,23 +129,23 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR static_assert((sizeof(ShaderResourceCacheD3D12) % sizeof(void*)) == 0, "sizeof(ShaderResourceCacheD3D12) is expected to be a multiple of sizeof(void*)"); static_assert((sizeof(ShaderVariableManagerD3D12) % sizeof(void*)) == 0, "sizeof(ShaderVariableManagerD3D12) is expected to be a multiple of sizeof(void*)"); // clang-format on - const auto MemSize = (sizeof(ShaderResourceLayoutD3D12) * 2 + sizeof(ShaderResourceCacheD3D12) + sizeof(ShaderVariableManagerD3D12)) * GetNumShaderTypes(); + const auto MemSize = (sizeof(ShaderResourceLayoutD3D12) * 2 + sizeof(ShaderResourceCacheD3D12) + sizeof(ShaderVariableManagerD3D12)) * GetNumShaderStages(); auto* const pRawMem = ALLOCATE_RAW(GetRawAllocator(), "Raw memory for ShaderResourceLayoutD3D12, ShaderResourceCacheD3D12, and ShaderVariableManagerD3D12 arrays", MemSize); m_pShaderResourceLayouts = reinterpret_cast<ShaderResourceLayoutD3D12*>(pRawMem); - m_pStaticResourceCaches = reinterpret_cast<ShaderResourceCacheD3D12*>(m_pShaderResourceLayouts + GetNumShaderTypes() * 2); - m_pStaticVarManagers = reinterpret_cast<ShaderVariableManagerD3D12*>(m_pStaticResourceCaches + GetNumShaderTypes()); + m_pStaticResourceCaches = reinterpret_cast<ShaderResourceCacheD3D12*>(m_pShaderResourceLayouts + GetNumShaderStages() * 2); + m_pStaticVarManagers = reinterpret_cast<ShaderVariableManagerD3D12*>(m_pStaticResourceCaches + GetNumShaderStages()); #ifdef DILIGENT_DEVELOPMENT { const ShaderResources* pResources[MAX_SHADERS_IN_PIPELINE] = {}; for (size_t s = 0; s < ShaderStages.size(); ++s) { - const auto* pShader = ValidatedCast<ShaderD3D12Impl>(ShaderStages[s].second); + const auto* pShader = ShaderStages[s].pShader; pResources[s] = &(*pShader->GetShaderResources()); } - ShaderResources::DvpVerifyResourceLayout(ResourceLayout, pResources, GetNumShaderTypes(), + ShaderResources::DvpVerifyResourceLayout(ResourceLayout, pResources, GetNumShaderStages(), (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_VARIABLES) == 0, (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_STATIC_SAMPLERS) == 0); } @@ -142,7 +153,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto* pShaderD3D12 = ValidatedCast<ShaderD3D12Impl>(ShaderStages[s].second); + auto* pShaderD3D12 = ShaderStages[s].pShader; auto ShaderType = pShaderD3D12->GetDesc().ShaderType; auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType); @@ -166,7 +177,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR new (m_pStaticResourceCaches + s) ShaderResourceCacheD3D12{ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources}; const SHADER_RESOURCE_VARIABLE_TYPE StaticVarType[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; - new (m_pShaderResourceLayouts + GetNumShaderTypes() + s) + new (m_pShaderResourceLayouts + GetNumShaderStages() + s) ShaderResourceLayoutD3D12 // { *this, @@ -200,7 +211,8 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR { D3D12_COMPUTE_PIPELINE_STATE_DESC d3d12PSODesc = {}; - auto* pByteCode = ValidatedCast<ShaderD3D12Impl>(ShaderStages[0].second)->GetShaderByteCode(); + VERIFY_EXPR(ShaderStages[0].Type == SHADER_TYPE_COMPUTE); + auto* pByteCode = ShaderStages[0].pShader->GetShaderByteCode(); d3d12PSODesc.CS.pShaderBytecode = pByteCode->GetBufferPointer(); d3d12PSODesc.CS.BytecodeLength = pByteCode->GetBufferSize(); @@ -229,10 +241,11 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR D3D12_GRAPHICS_PIPELINE_STATE_DESC d3d12PSODesc = {}; - for (size_t s = 0; s < ShaderStages.size(); ++s) + for (const auto& Stage : ShaderStages) { - auto* pShaderD3D12 = ValidatedCast<ShaderD3D12Impl>(ShaderStages[s].second); + auto* pShaderD3D12 = Stage.pShader; auto ShaderType = pShaderD3D12->GetDesc().ShaderType; + VERIFY_EXPR(ShaderType == Stage.Type); D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr; switch (ShaderType) @@ -333,10 +346,11 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR }; MESH_SHADER_PIPELINE_STATE_DESC d3d12PSODesc = {}; - for (size_t s = 0; s < ShaderStages.size(); ++s) + for (const auto& Stage : ShaderStages) { - auto* pShaderD3D12 = ValidatedCast<ShaderD3D12Impl>(ShaderStages[s].second); + auto* pShaderD3D12 = Stage.pShader; auto ShaderType = pShaderD3D12->GetDesc().ShaderType; + VERIFY_EXPR(ShaderType == Stage.Type); D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr; switch (ShaderType) @@ -410,7 +424,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR if (m_Desc.SRBAllocationGranularity > 1) { std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderVarMgrDataSizes = {}; - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { std::array<SHADER_RESOURCE_VARIABLE_TYPE, 2> AllowedVarTypes = { @@ -423,7 +437,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR } auto CacheMemorySize = m_RootSig.GetResourceCacheRequiredMemSize(); - m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderTypes(), ShaderVarMgrDataSizes.data(), 1, &CacheMemorySize); + m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderStages(), ShaderVarMgrDataSizes.data(), 1, &CacheMemorySize); } m_ShaderResourceLayoutHash = m_RootSig.GetHash(); @@ -432,13 +446,13 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR PipelineStateD3D12Impl::~PipelineStateD3D12Impl() { auto& ShaderResLayoutAllocator = GetRawAllocator(); - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { m_pStaticVarManagers[s].Destroy(GetRawAllocator()); m_pStaticVarManagers[s].~ShaderVariableManagerD3D12(); m_pStaticResourceCaches[s].~ShaderResourceCacheD3D12(); m_pShaderResourceLayouts[s].~ShaderResourceLayoutD3D12(); - m_pShaderResourceLayouts[GetNumShaderTypes() + s].~ShaderResourceLayoutD3D12(); + m_pShaderResourceLayouts[GetNumShaderStages() + s].~ShaderResourceLayoutD3D12(); } // m_pShaderResourceLayouts, m_pStaticResourceCaches, and m_pShaderResourceLayouts are allocated in // contiguous chunks of memory. @@ -477,14 +491,14 @@ bool PipelineStateD3D12Impl::IsCompatibleWith(const IPipelineState* pPSO) const #ifdef DILIGENT_DEBUG { bool IsCompatibleShaders = true; - if (GetNumShaderTypes() != pPSOD3D12->GetNumShaderTypes()) + if (GetNumShaderStages() != pPSOD3D12->GetNumShaderStages()) IsCompatibleShaders = false; if (IsCompatibleShaders) { - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { - if (GetShaderTypes()[s] != pPSOD3D12->GetShaderTypes()[s]) + if (GetShaderStageType(s) != pPSOD3D12->GetShaderStageType(s)) { IsCompatibleShaders = false; break; @@ -603,7 +617,7 @@ bool PipelineStateD3D12Impl::ContainsShaderResources() const void PipelineStateD3D12Impl::BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) { - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { auto ShaderType = GetStaticShaderResLayout(s).GetShaderType(); if ((ShaderFlags & ShaderType) != 0) @@ -617,7 +631,7 @@ Uint32 PipelineStateD3D12Impl::GetStaticVariableCount(SHADER_TYPE ShaderType) co if (LayoutInd < 0) return 0; - VERIFY_EXPR(static_cast<Uint32>(LayoutInd) < GetNumShaderTypes()); + VERIFY_EXPR(static_cast<Uint32>(LayoutInd) < GetNumShaderStages()); return m_pStaticVarManagers[LayoutInd].GetVariableCount(); } @@ -627,7 +641,7 @@ IShaderResourceVariable* PipelineStateD3D12Impl::GetStaticVariableByName(SHADER_ if (LayoutInd < 0) return nullptr; - VERIFY_EXPR(static_cast<Uint32>(LayoutInd) < GetNumShaderTypes()); + VERIFY_EXPR(static_cast<Uint32>(LayoutInd) < GetNumShaderStages()); return m_pStaticVarManagers[LayoutInd].GetVariable(Name); } @@ -637,7 +651,7 @@ IShaderResourceVariable* PipelineStateD3D12Impl::GetStaticVariableByIndex(SHADER if (LayoutInd < 0) return nullptr; - VERIFY_EXPR(static_cast<Uint32>(LayoutInd) < GetNumShaderTypes()); + VERIFY_EXPR(static_cast<Uint32>(LayoutInd) < GetNumShaderStages()); return m_pStaticVarManagers[LayoutInd].GetVariable(Index); } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp index 17387138..3293283a 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp @@ -45,7 +45,7 @@ ShaderResourceBindingD3D12Impl::ShaderResourceBindingD3D12Impl(IReferenceCounter IsPSOInternal }, m_ShaderResourceCache{ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources}, - m_NumShaders {static_cast<decltype(m_NumShaders)>(pPSO->GetNumShaderTypes())} + m_NumShaders {static_cast<decltype(m_NumShaders)>(pPSO->GetNumShaderStages())} // clang-format on { m_ResourceLayoutIndex.fill(-1); @@ -58,7 +58,7 @@ ShaderResourceBindingD3D12Impl::ShaderResourceBindingD3D12Impl(IReferenceCounter for (Uint32 s = 0; s < m_NumShaders; ++s) { - auto ShaderType = pPSO->GetShaderTypes()[s]; + auto ShaderType = pPSO->GetShaderStageType(s); auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, pPSO->GetDesc().PipelineType); auto& VarDataAllocator = pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); @@ -187,7 +187,7 @@ void ShaderResourceBindingD3D12Impl::InitializeStaticResources(const IPipelineSt } auto* pPSO12 = ValidatedCast<const PipelineStateD3D12Impl>(pPSO); - auto NumShaders = pPSO12->GetNumShaderTypes(); + auto NumShaders = pPSO12->GetNumShaderStages(); // Copy static resources for (Uint32 s = 0; s < NumShaders; ++s) { @@ -200,7 +200,7 @@ void ShaderResourceBindingD3D12Impl::InitializeStaticResources(const IPipelineSt { LOG_ERROR_MESSAGE("Static resources in SRB of PSO '", pPSO12->GetDesc().Name, "' will not be successfully initialized because not all static resource bindings in shader type '", - GetShaderTypeLiteralName(pPSO12->GetShaderTypes()[s]), + GetShaderTypeLiteralName(pPSO12->GetShaderStageType(s)), "' are valid. Please make sure you bind all static resources to PSO before calling InitializeStaticResources() " "directly or indirectly by passing InitStaticResources=true to CreateShaderResourceBinding() method."); } diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp index bc0f32e6..d4c4b87e 100644 --- a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp @@ -92,7 +92,7 @@ public: /// Implementation of IShader::GetResource() in OpenGL backend. virtual void DILIGENT_CALL_TYPE GetResourceDesc(Uint32 Index, ShaderResourceDesc& ResourceDesc) const override final; - static GLObjectWrappers::GLProgramObj LinkProgram(IShader** ppShaders, Uint32 NumShaders, bool IsSeparableProgram); + static GLObjectWrappers::GLProgramObj LinkProgram(ShaderGLImpl** ppShaders, Uint32 NumShaders, bool IsSeparableProgram); private: GLObjectWrappers::GLShaderObj m_GLShaderObj; diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index e6e6a84f..8590e203 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -52,8 +52,7 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun m_StaticResourceLayout{*this} // clang-format on { - RefCntAutoPtr<IShader> pTempPS; - + RefCntAutoPtr<ShaderGLImpl> pTempPS; if (m_Desc.IsAnyGraphicsPipeline() && m_Desc.GraphicsPipeline.pPS == nullptr) { // Some OpenGL implementations fail if fragment shader is not present, so @@ -63,17 +62,23 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun ShaderCI.Source = "void main(){}"; ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL; ShaderCI.Desc.Name = "Dummy fragment shader"; - pDeviceGL->CreateShader(ShaderCI, &pTempPS); - } + pDeviceGL->CreateShader(ShaderCI, reinterpret_cast<IShader**>(static_cast<ShaderGLImpl**>(&pTempPS))); - ShaderStages_t ShaderStages; - ExtractShaders(ShaderStages); + m_Desc.GraphicsPipeline.pPS = pTempPS; + } - if (pTempPS) + struct GLPipelineShaderStageInfo { - m_pShaderTypes[m_NumShaderTypes++] = SHADER_TYPE_PIXEL; - ShaderStages.push_back({SHADER_TYPE_PIXEL, pTempPS}); - } + const SHADER_TYPE Type; + ShaderGLImpl* const pShader; + GLPipelineShaderStageInfo(SHADER_TYPE _Type, + ShaderGLImpl* _pShader) : + Type{_Type}, + pShader{_pShader} + {} + }; + std::vector<GLPipelineShaderStageInfo> ShaderStages; + ExtractShaders<ShaderGLImpl>(ShaderStages); auto& DeviceCaps = pDeviceGL->GetDeviceCaps(); VERIFY(DeviceCaps.DevType != RENDER_DEVICE_TYPE_UNDEFINED, "Device caps are not initialized"); @@ -96,10 +101,9 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun m_GLPrograms.reserve(ShaderStages.size()); for (size_t i = 0; i < ShaderStages.size(); ++i) { - auto* pShader = ShaderStages[i].second; - auto* pShaderGL = ValidatedCast<ShaderGLImpl>(pShader); + auto* pShaderGL = ShaderStages[i].pShader; const auto& ShaderDesc = pShaderGL->GetDesc(); - m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(&pShader, 1, true)); + m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(&pShaderGL, 1, true)); // Load uniforms and assign bindings m_ProgramResources[i].LoadUniforms(ShaderDesc.ShaderType, m_GLPrograms[i], GLState, m_TotalUniformBufferBindings, @@ -112,12 +116,14 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCoun } else { - std::vector<IShader*> Shaders; - SHADER_TYPE ActiveStages = SHADER_TYPE_UNKNOWN; - for (size_t i = 0; i < ShaderStages.size(); ++i) + std::vector<ShaderGLImpl*> Shaders; + + SHADER_TYPE ActiveStages = SHADER_TYPE_UNKNOWN; + for (const auto& Stage : ShaderStages) { - Shaders.push_back(ShaderStages[i].second); - ActiveStages |= ShaderStages[i].first; + Shaders.push_back(Stage.pShader); + VERIFY((ActiveStages & Stage.Type) == 0, "Shader stage ", GetShaderTypeLiteralName(Stage.Type), " is already active"); + ActiveStages |= Stage.Type; } m_GLPrograms.emplace_back(ShaderGLImpl::LinkProgram(Shaders.data(), static_cast<Uint32>(ShaderStages.size()), false)); @@ -226,9 +232,9 @@ GLObjectWrappers::GLPipelineObj& PipelineStateGLImpl::GetGLProgramPipeline(GLCon m_GLProgPipelines.emplace_back(Context, true); auto& ctx_pipeline = m_GLProgPipelines.back(); GLuint Pipeline = ctx_pipeline.second; - for (Uint32 i = 0; i < GetNumShaderTypes(); ++i) + for (Uint32 i = 0; i < GetNumShaderStages(); ++i) { - auto GLShaderBit = ShaderTypeToGLShaderBit(GetShaderTypes()[i]); + auto GLShaderBit = ShaderTypeToGLShaderBit(GetShaderStageType(i)); // If the program has an active code for each stage mentioned in set flags, // then that code will be used by the pipeline. If program is 0, then the given // stages are cleared from the pipeline. diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp index c7a493cd..e27a8a4c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp @@ -158,7 +158,7 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters, if (deviceCaps.Features.SeparablePrograms) { - IShader* ThisShader[] = {this}; + ShaderGLImpl* ThisShader[] = {this}; GLObjectWrappers::GLProgramObj Program = LinkProgram(ThisShader, 1, true); Uint32 UniformBufferBinding = 0; Uint32 SamplerBinding = 0; @@ -178,7 +178,7 @@ ShaderGLImpl::~ShaderGLImpl() IMPLEMENT_QUERY_INTERFACE(ShaderGLImpl, IID_ShaderGL, TShaderBase) -GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(IShader** ppShaders, Uint32 NumShaders, bool IsSeparableProgram) +GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(ShaderGLImpl** ppShaders, Uint32 NumShaders, bool IsSeparableProgram) { VERIFY(!IsSeparableProgram || NumShaders == 1, "Number of shaders must be 1 when separable program is created"); @@ -190,7 +190,7 @@ GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(IShader** ppShaders, Ui for (Uint32 i = 0; i < NumShaders; ++i) { - auto* pCurrShader = ValidatedCast<ShaderGLImpl>(ppShaders[i]); + auto* pCurrShader = ppShaders[i]; glAttachShader(GLProg, pCurrShader->m_GLShaderObj); CHECK_GL_ERROR("glAttachShader() failed"); } diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp index 303496bb..2185dabd 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp @@ -56,7 +56,6 @@ class PipelineStateVkImpl final : public PipelineStateBase<IPipelineStateVk, Ren { public: using TPipelineStateBase = PipelineStateBase<IPipelineStateVk, RenderDeviceVkImpl>; - using ShaderSPIRVs_t = std::vector<std::vector<uint32_t>>; PipelineStateVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const PipelineStateCreateInfo& CreateInfo); ~PipelineStateVkImpl(); @@ -105,7 +104,7 @@ public: const ShaderResourceLayoutVk& GetShaderResLayout(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaderTypes); + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); return m_ShaderResourceLayouts[ShaderInd]; } @@ -128,19 +127,19 @@ public: private: const ShaderResourceLayoutVk& GetStaticShaderResLayout(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaderTypes); - return m_ShaderResourceLayouts[m_NumShaderTypes + ShaderInd]; + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); + return m_ShaderResourceLayouts[GetNumShaderStages() + ShaderInd]; } const ShaderResourceCacheVk& GetStaticResCache(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaderTypes); + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); return m_StaticResCaches[ShaderInd]; } ShaderVariableManagerVk& GetStaticVarMgr(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaderTypes); + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); return m_StaticVarsMgrs[ShaderInd]; } @@ -156,7 +155,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; + std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1}; bool m_HasStaticResources = false; bool m_HasNonStaticResources = false; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp index 85230b02..026bb9da 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp @@ -81,7 +81,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; + std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1}; bool m_bStaticResourcesInitialized = false; Uint8 m_NumShaders = 0; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp index c6432f4a..62ff38b5 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp @@ -110,13 +110,23 @@ namespace Diligent { +class ShaderVkImpl; + /// Diligent::ShaderResourceLayoutVk class // sizeof(ShaderResourceLayoutVk)==56 (MS compiler, x64) class ShaderResourceLayoutVk { public: - using ShaderStages_t = std::vector<std::pair<SHADER_TYPE, IShader*>>; - using ShaderSPIRVs_t = std::vector<std::vector<uint32_t>>; + struct ShaderStageInfo + { + ShaderStageInfo(SHADER_TYPE _Type, + const ShaderVkImpl* _pShader); + + const SHADER_TYPE Type; + const ShaderVkImpl* const pShader; + std::vector<uint32_t> SPIRV; + }; + using TShaderStages = std::vector<ShaderStageInfo>; ShaderResourceLayoutVk(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) : m_LogicalDevice{LogicalDevice} @@ -134,7 +144,7 @@ public: // This method is called by PipelineStateVkImpl class instance to initialize static // shader resource layout and the cache - void InitializeStaticResourceLayout(IShader* pShader, + void InitializeStaticResourceLayout(const ShaderVkImpl* pShader, IMemoryAllocator& LayoutDataAllocator, const PipelineResourceLayoutDesc& ResourceLayoutDesc, ShaderResourceCacheVk& StaticResourceCache); @@ -142,11 +152,10 @@ public: // This method is called by PipelineStateVkImpl class instance to initialize resource // layouts for all shader stages in the pipeline. static void Initialize(IRenderDevice* pRenderDevice, - const ShaderStages_t& ShaderStages, + TShaderStages& ShaderStages, ShaderResourceLayoutVk Layouts[], IMemoryAllocator& LayoutDataAllocator, const PipelineResourceLayoutDesc& ResourceLayoutDesc, - ShaderSPIRVs_t& SPIRVs, class PipelineLayout& PipelineLayout, bool VerifyVariables, bool VerifyStaticSamplers); @@ -281,7 +290,7 @@ public: #ifdef DILIGENT_DEVELOPMENT bool dvpVerifyBindings(const ShaderResourceCacheVk& ResourceCache) const; - static void dvpVerifyResourceLayoutDesc(const ShaderStages_t& ShaderStages, + static void dvpVerifyResourceLayoutDesc(const TShaderStages& ShaderStages, const PipelineResourceLayoutDesc& ResourceLayoutDesc, bool VerifyVariables, bool VerifyStaticSamplers); @@ -349,7 +358,7 @@ private: return m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; } - void AllocateMemory(IShader* pShader, + void AllocateMemory(const ShaderVkImpl* pShader, IMemoryAllocator& Allocator, const PipelineResourceLayoutDesc& ResourceLayoutDesc, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 881196ec..fbc5fae3 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -149,26 +149,21 @@ static bool StripReflection(std::vector<uint32_t>& SPIRV) #endif } -static void InitializeShaderStages(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice, - const PipelineStateVkImpl::ShaderStages_t& ShaderStages, - PipelineStateVkImpl::ShaderSPIRVs_t& ShaderSPIRVs, - std::vector<VulkanUtilities::ShaderModuleWrapper>& ShaderModules, - std::vector<VkPipelineShaderStageCreateInfo>& Stages) +static void InitPipelineShaderStages(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice, + ShaderResourceLayoutVk::TShaderStages& ShaderStages, + std::vector<VulkanUtilities::ShaderModuleWrapper>& vkShaderModules, + std::vector<VkPipelineShaderStageCreateInfo>& vkPipelineShaderStages) { - VERIFY_EXPR(ShaderStages.size() == ShaderSPIRVs.size()); - for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto* pShaderVk = ValidatedCast<ShaderVkImpl>(ShaderStages[s].second); - auto& SPIRV = ShaderSPIRVs[s]; - const auto ShaderType = ShaderStages[s].first; + auto& StageInfo = ShaderStages[s]; VkPipelineShaderStageCreateInfo StageCI = {}; StageCI.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; StageCI.pNext = nullptr; StageCI.flags = 0; // reserved for future use - StageCI.stage = ShaderTypeToVkShaderStageFlagBit(ShaderType); + StageCI.stage = ShaderTypeToVkShaderStageFlagBit(StageInfo.Type); VkShaderModuleCreateInfo ShaderModuleCI = {}; @@ -179,22 +174,22 @@ static void InitializeShaderStages(const VulkanUtilities::VulkanLogicalDevice& // We have to strip reflection instructions to fix the follownig validation error: // SPIR-V module not valid: DecorateStringGOOGLE requires one of the following extensions: SPV_GOOGLE_decorate_string // Optimizer also performs validation and may catch problems with the byte code. - if (!StripReflection(SPIRV)) - LOG_ERROR("Failed to strip reflection information from shader '", pShaderVk->GetDesc().Name, "'. This may indicate a problem with the byte code."); + if (!StripReflection(StageInfo.SPIRV)) + LOG_ERROR("Failed to strip reflection information from shader '", StageInfo.pShader->GetDesc().Name, "'. This may indicate a problem with the byte code."); - ShaderModuleCI.codeSize = SPIRV.size() * sizeof(uint32_t); - ShaderModuleCI.pCode = SPIRV.data(); + ShaderModuleCI.codeSize = StageInfo.SPIRV.size() * sizeof(uint32_t); + ShaderModuleCI.pCode = StageInfo.SPIRV.data(); - ShaderModules.push_back(LogicalDevice.CreateShaderModule(ShaderModuleCI, pShaderVk->GetDesc().Name)); + vkShaderModules.push_back(LogicalDevice.CreateShaderModule(ShaderModuleCI, StageInfo.pShader->GetDesc().Name)); - StageCI.module = ShaderModules.back(); - StageCI.pName = pShaderVk->GetEntryPoint(); + StageCI.module = vkShaderModules.back(); + StageCI.pName = StageInfo.pShader->GetEntryPoint(); StageCI.pSpecializationInfo = nullptr; - Stages.push_back(StageCI); + vkPipelineShaderStages.push_back(StageCI); } - VERIFY_EXPR(ShaderModules.size() == Stages.size()); + VERIFY_EXPR(vkShaderModules.size() == vkPipelineShaderStages.size()); } @@ -417,47 +412,41 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); - ShaderStages_t ShaderStages; - ShaderSPIRVs_t ShaderSPIRVs; - ExtractShaders(ShaderStages); - - ShaderSPIRVs.resize(ShaderStages.size()); - for (size_t s = 0; s < ShaderSPIRVs.size(); ++s) - { - auto* pShaderVk = ValidatedCast<ShaderVkImpl>(ShaderStages[s].second); - ShaderSPIRVs[s] = pShaderVk->GetSPIRV(); - } + ShaderResourceLayoutVk::TShaderStages ShaderStages; + ExtractShaders<ShaderVkImpl>(ShaderStages); // clang-format off static_assert((sizeof(ShaderResourceLayoutVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceLayoutVk) is expected to be a multiple of sizeof(void*)"); static_assert((sizeof(ShaderResourceCacheVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceCacheVk) is expected to be a multiple of sizeof(void*)"); static_assert((sizeof(ShaderVariableManagerVk) % sizeof(void*)) == 0, "sizeof(ShaderVariableManagerVk) is expected to be a multiple of sizeof(void*)"); // clang-format on - const auto MemSize = (sizeof(ShaderResourceLayoutVk) * 2 + sizeof(ShaderResourceCacheVk) + sizeof(ShaderVariableManagerVk)) * GetNumShaderTypes(); + const auto MemSize = (sizeof(ShaderResourceLayoutVk) * 2 + sizeof(ShaderResourceCacheVk) + sizeof(ShaderVariableManagerVk)) * GetNumShaderStages(); auto* const pRawMem = ALLOCATE_RAW(GetRawAllocator(), "Raw memory for ShaderResourceLayoutVk, ShaderResourceCacheVk, and ShaderVariableManagerVk arrays", MemSize); m_ShaderResourceLayouts = reinterpret_cast<ShaderResourceLayoutVk*>(pRawMem); - m_StaticResCaches = reinterpret_cast<ShaderResourceCacheVk*>(m_ShaderResourceLayouts + GetNumShaderTypes() * 2); - m_StaticVarsMgrs = reinterpret_cast<ShaderVariableManagerVk*>(m_StaticResCaches + GetNumShaderTypes()); + m_StaticResCaches = reinterpret_cast<ShaderResourceCacheVk*>(m_ShaderResourceLayouts + GetNumShaderStages() * 2); + m_StaticVarsMgrs = reinterpret_cast<ShaderVariableManagerVk*>(m_StaticResCaches + GetNumShaderStages()); for (size_t s = 0; s < ShaderStages.size(); ++s) { + auto& StageInfo = ShaderStages[s]; + const auto ShaderType = StageInfo.Type; + const auto ShaderTypeInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType); + new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk{LogicalDevice}; - const auto ShaderType = ShaderStages[s].first; - auto& Shaders = ShaderStages[s].second; - const auto ShaderTypeInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType); + m_ResourceLayoutIndex[ShaderTypeInd] = static_cast<Int8>(s); auto* pStaticResLayout = new (m_ShaderResourceLayouts + ShaderStages.size() + s) ShaderResourceLayoutVk{LogicalDevice}; auto* pStaticResCache = new (m_StaticResCaches + s) ShaderResourceCacheVk{ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources}; - pStaticResLayout->InitializeStaticResourceLayout(Shaders, GetRawAllocator(), m_Desc.ResourceLayout, m_StaticResCaches[s]); + pStaticResLayout->InitializeStaticResourceLayout(StageInfo.pShader, GetRawAllocator(), m_Desc.ResourceLayout, m_StaticResCaches[s]); new (m_StaticVarsMgrs + s) ShaderVariableManagerVk{*this, *pStaticResLayout, GetRawAllocator(), nullptr, 0, *pStaticResCache}; } ShaderResourceLayoutVk::Initialize(pDeviceVk, ShaderStages, m_ShaderResourceLayouts, GetRawAllocator(), - m_Desc.ResourceLayout, ShaderSPIRVs, m_PipelineLayout, + m_Desc.ResourceLayout, m_PipelineLayout, (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_VARIABLES) == 0, (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_STATIC_SAMPLERS) == 0); m_PipelineLayout.Finalize(LogicalDevice); @@ -465,7 +454,7 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun if (m_Desc.SRBAllocationGranularity > 1) { std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderVariableDataSizes = {}; - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { const SHADER_RESOURCE_VARIABLE_TYPE AllowedVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; @@ -477,13 +466,13 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun auto DescriptorSetSizes = m_PipelineLayout.GetDescriptorSetSizes(NumSets); auto CacheMemorySize = ShaderResourceCacheVk::GetRequiredMemorySize(NumSets, DescriptorSetSizes.data()); - m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderTypes(), ShaderVariableDataSizes.data(), 1, &CacheMemorySize); + m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderStages(), ShaderVariableDataSizes.data(), 1, &CacheMemorySize); } // Create shader modules and initialize shader stages std::vector<VkPipelineShaderStageCreateInfo> VkShaderStages; std::vector<VulkanUtilities::ShaderModuleWrapper> ShaderModules; - InitializeShaderStages(LogicalDevice, ShaderStages, ShaderSPIRVs, ShaderModules, VkShaderStages); + InitPipelineShaderStages(LogicalDevice, ShaderStages, ShaderModules, VkShaderStages); // Create pipeline switch (m_Desc.PipelineType) @@ -498,7 +487,7 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun m_HasStaticResources = false; m_HasNonStaticResources = false; - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { const auto& Layout = m_ShaderResourceLayouts[s]; if (Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_STATIC) != 0) @@ -518,12 +507,12 @@ PipelineStateVkImpl::~PipelineStateVkImpl() m_PipelineLayout.Release(m_pDevice, m_Desc.CommandQueueMask); auto& RawAllocator = GetRawAllocator(); - for (Uint32 s = 0; s < GetNumShaderTypes() * 2; ++s) + for (Uint32 s = 0; s < GetNumShaderStages() * 2; ++s) { m_ShaderResourceLayouts[s].~ShaderResourceLayoutVk(); } - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { m_StaticResCaches[s].~ShaderResourceCacheVk(); m_StaticVarsMgrs[s].DestroyVariables(GetRawAllocator()); @@ -563,14 +552,14 @@ bool PipelineStateVkImpl::IsCompatibleWith(const IPipelineState* pPSO) const #ifdef DILIGENT_DEBUG { bool IsCompatibleShaders = true; - if (GetNumShaderTypes() != pPSOVk->GetNumShaderTypes()) + if (GetNumShaderStages() != pPSOVk->GetNumShaderStages()) IsCompatibleShaders = false; if (IsCompatibleShaders) { - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { - if (GetShaderTypes()[s] != pPSOVk->GetShaderTypes()[s]) + if (GetShaderStageType(s) != pPSOVk->GetShaderStageType(s)) { IsCompatibleShaders = false; break; @@ -636,7 +625,7 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind auto& ResourceCache = pResBindingVkImpl->GetResourceCache(); #ifdef DILIGENT_DEVELOPMENT - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { m_ShaderResourceLayouts[s].dvpVerifyBindings(ResourceCache); } @@ -671,7 +660,7 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind // Allocate vulkan descriptor set for dynamic resources DynamicDescrSet = pCtxVkImpl->AllocateDynamicDescriptorSet(DynamicDescriptorSetVkLayout, DynamicDescrSetName); // Commit all dynamic resource descriptors - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { const auto& Layout = m_ShaderResourceLayouts[s]; if (Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) != 0) @@ -688,7 +677,7 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind void PipelineStateVkImpl::BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) { - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { auto ShaderType = GetStaticShaderResLayout(s).GetShaderType(); if ((ShaderType & ShaderFlags) != 0) @@ -732,7 +721,7 @@ IShaderResourceVariable* PipelineStateVkImpl::GetStaticVariableByIndex(SHADER_TY void PipelineStateVkImpl::InitializeStaticSRBResources(ShaderResourceCacheVk& ResourceCache) const { - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { const auto& StaticResLayout = GetStaticShaderResLayout(s); const auto& StaticResCache = GetStaticResCache(s); @@ -742,7 +731,7 @@ void PipelineStateVkImpl::InitializeStaticSRBResources(ShaderResourceCacheVk& Re { LOG_ERROR_MESSAGE("Static resources in SRB of PSO '", GetDesc().Name, "' will not be successfully initialized because not all static resource bindings in shader '", - GetShaderTypeLiteralName(GetShaderTypes()[s]), + GetShaderTypeLiteralName(GetShaderStageType(s)), "' are valid. Please make sure you bind all static resources to PSO before calling InitializeStaticResources() " "directly or indirectly by passing InitStaticResources=true to CreateShaderResourceBinding() method."); } diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index 75f3bb37..91008811 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -49,8 +49,7 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl(IReferenceCounters* pR { m_ResourceLayoutIndex.fill(-1); - auto* pShaderTypes = pPSO->GetShaderTypes(); - m_NumShaders = static_cast<decltype(m_NumShaders)>(pPSO->GetNumShaderTypes()); + m_NumShaders = static_cast<decltype(m_NumShaders)>(pPSO->GetNumShaderStages()); auto* pRenderDeviceVkImpl = pPSO->GetDevice(); // This will only allocate memory and initialize descriptor sets in the resource cache @@ -62,7 +61,7 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl(IReferenceCounters* pR for (Uint32 s = 0; s < m_NumShaders; ++s) { - auto ShaderInd = GetShaderTypePipelineIndex(pShaderTypes[s], pPSO->GetDesc().PipelineType); + auto ShaderInd = GetShaderTypePipelineIndex(pPSO->GetShaderStageType(s), pPSO->GetDesc().PipelineType); m_ResourceLayoutIndex[ShaderInd] = static_cast<Int8>(s); diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index a7410210..8b00c394 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -93,6 +93,14 @@ static SHADER_RESOURCE_VARIABLE_TYPE FindShaderVariableType(SHADER_TYPE } } +ShaderResourceLayoutVk::ShaderStageInfo::ShaderStageInfo(SHADER_TYPE _Type, + const ShaderVkImpl* _pShader) : + Type{_Type}, + pShader{_pShader}, + SPIRV{pShader->GetSPIRV()} +{ +} + ShaderResourceLayoutVk::~ShaderResourceLayoutVk() { @@ -103,7 +111,7 @@ ShaderResourceLayoutVk::~ShaderResourceLayoutVk() GetImmutableSampler(s).~ImmutableSamplerPtrType(); } -void ShaderResourceLayoutVk::AllocateMemory(IShader* pShader, +void ShaderResourceLayoutVk::AllocateMemory(const ShaderVkImpl* pShader, IMemoryAllocator& Allocator, const PipelineResourceLayoutDesc& ResourceLayoutDesc, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, @@ -112,16 +120,14 @@ void ShaderResourceLayoutVk::AllocateMemory(IShader* { VERIFY(!m_ResourceBuffer, "Memory has already been initialized"); VERIFY_EXPR(!m_pResources); + m_pResources = pShader->GetShaderResources(); - const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); - const auto ShaderType = pShader->GetDesc().ShaderType; + const auto ShaderType = pShader->GetDesc().ShaderType; + VERIFY_EXPR(m_pResources->GetShaderType() == ShaderType); // Count the number of resources to allocate all needed memory { - auto* pShaderVk = ValidatedCast<ShaderVkImpl>(pShader); - auto pResources = pShaderVk->GetShaderResources(); - const auto* CombinedSamplerSuffix = pResources->GetCombinedSamplerSuffix(); - VERIFY_EXPR(pResources->GetShaderType() == ShaderType); - m_pResources = pResources; + const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + const auto* CombinedSamplerSuffix = m_pResources->GetCombinedSamplerSuffix(); m_pResources->ProcessResources( [&](const SPIRVShaderResourceAttribs& ResAttribs, Uint32) // { @@ -172,11 +178,11 @@ void ShaderResourceLayoutVk::AllocateMemory(IShader* } -Uint32 FindAssignedSampler(const ShaderResourceLayoutVk& Layout, - const SPIRVShaderResources& Resources, - const SPIRVShaderResourceAttribs& SepImg, - Uint32 CurrResourceCount, - SHADER_RESOURCE_VARIABLE_TYPE ImgVarType) +static Uint32 FindAssignedSampler(const ShaderResourceLayoutVk& Layout, + const SPIRVShaderResources& Resources, + const SPIRVShaderResourceAttribs& SepImg, + Uint32 CurrResourceCount, + SHADER_RESOURCE_VARIABLE_TYPE ImgVarType) { using VkResource = ShaderResourceLayoutVk::VkResource; VERIFY_EXPR(SepImg.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage); @@ -211,7 +217,7 @@ Uint32 FindAssignedSampler(const ShaderResourceLayoutVk& Layout, } -void ShaderResourceLayoutVk::InitializeStaticResourceLayout(IShader* pShader, +void ShaderResourceLayoutVk::InitializeStaticResourceLayout(const ShaderVkImpl* pShader, IMemoryAllocator& LayoutDataAllocator, const PipelineResourceLayoutDesc& ResourceLayoutDesc, ShaderResourceCacheVk& StaticResourceCache) @@ -277,7 +283,7 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(IShader* } #ifdef DILIGENT_DEVELOPMENT -void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const ShaderStages_t& ShaderStages, +void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const TShaderStages& ShaderStages, const PipelineResourceLayoutDesc& ResourceLayoutDesc, bool VerifyVariables, bool VerifyStaticSamplers) @@ -290,11 +296,11 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const ShaderStages_t& const auto ShaderType = Stages & static_cast<SHADER_TYPE>(~(static_cast<Uint32>(Stages) - 1)); const char* ShaderName = nullptr; - for (size_t s = 0; s < ShaderStages.size(); ++s) + for (const auto& StageInfo : ShaderStages) { - if ((Stages & ShaderStages[s].first) != 0) + if ((Stages & StageInfo.Type) != 0) { - ShaderName = ShaderStages[s].second->GetDesc().Name; + ShaderName = StageInfo.pShader->GetDesc().Name; break; } } @@ -334,8 +340,7 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const ShaderStages_t& bool VariableFound = false; for (size_t s = 0; s < ShaderStages.size() && !VariableFound; ++s) { - const auto* pShaderVk = ValidatedCast<ShaderVkImpl>(ShaderStages[s].second); - const auto& Resources = *pShaderVk->GetShaderResources(); + const auto& Resources = *ShaderStages[s].pShader->GetShaderResources(); if ((VarDesc.ShaderStages & Resources.GetShaderType()) != 0) { for (Uint32 res = 0; res < Resources.GetTotalResources() && !VariableFound; ++res) @@ -368,8 +373,7 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const ShaderStages_t& bool SamplerFound = false; for (size_t s = 0; s < ShaderStages.size() && !SamplerFound; ++s) { - const auto* pShaderVk = ValidatedCast<ShaderVkImpl>(ShaderStages[s].second); - const auto& Resources = *pShaderVk->GetShaderResources(); + const auto& Resources = *ShaderStages[s].pShader->GetShaderResources(); if ((StSamDesc.ShaderStages & Resources.GetShaderType()) == 0) continue; @@ -407,11 +411,10 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const ShaderStages_t& #endif void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRenderDevice, - const ShaderStages_t& ShaderStages, + TShaderStages& ShaderStages, ShaderResourceLayoutVk Layouts[], IMemoryAllocator& LayoutDataAllocator, const PipelineResourceLayoutDesc& ResourceLayoutDesc, - ShaderSPIRVs_t& SPIRVs, class PipelineLayout& PipelineLayout, bool VerifyVariables, bool VerifyStaticSamplers) @@ -427,7 +430,8 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende for (size_t s = 0; s < ShaderStages.size(); ++s) { - Layouts[s].AllocateMemory(ShaderStages[s].second, LayoutDataAllocator, ResourceLayoutDesc, AllowedVarTypes, NumAllowedTypes, AllocateImmutableSamplers); + Layouts[s].AllocateMemory(ShaderStages[s].pShader, LayoutDataAllocator, ResourceLayoutDesc, + AllowedVarTypes, NumAllowedTypes, AllocateImmutableSamplers); } //VERIFY_EXPR(NumShaders <= MAX_SHADERS_IN_PIPELINE); @@ -475,7 +479,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende } } - auto& ShaderSPIRV = SPIRVs[ShaderInd]; + auto& ShaderSPIRV = ShaderStages[ShaderInd].SPIRV; PipelineLayout.AllocateResourceSlot(Attribs, VarType, vkImmutableSampler, Resources.GetShaderType(), DescriptorSet, Binding, CacheOffset, ShaderSPIRV); 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"); @@ -498,9 +502,8 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende // First process uniform buffers for all shader stages to make sure all UBs go first in every descriptor set for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto& pShader = ShaderStages[s].second; auto& Layout = Layouts[s]; - auto* pShaderVk = ValidatedCast<ShaderVkImpl>(pShader); + auto* pShaderVk = ShaderStages[s].pShader; auto& Resources = *pShaderVk->GetShaderResources(); for (Uint32 n = 0; n < Resources.GetNumUBs(); ++n) { @@ -516,10 +519,8 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende // Second, process all storage buffers for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto& pShader = ShaderStages[s].second; auto& Layout = Layouts[s]; - auto* pShaderVk = ValidatedCast<ShaderVkImpl>(pShader); - auto& Resources = *pShaderVk->GetShaderResources(); + auto& Resources = *ShaderStages[s].pShader->GetShaderResources(); for (Uint32 n = 0; n < Resources.GetNumSBs(); ++n) { const auto& SB = Resources.GetSB(n); @@ -534,10 +535,8 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende // Finally, process all other resource types for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto& pShader = ShaderStages[s].second; auto& Layout = Layouts[s]; - auto* pShaderVk = ValidatedCast<ShaderVkImpl>(pShader); - auto& Resources = *pShaderVk->GetShaderResources(); + auto& Resources = *ShaderStages[s].pShader->GetShaderResources(); // clang-format off Resources.ProcessResources( [&](const SPIRVShaderResourceAttribs& UB, Uint32) diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp index 95261295..55bb7d8f 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp @@ -1515,7 +1515,7 @@ VkAccessFlags AccessFlagsToVkAccessFlags(ACCESS_FLAGS AccessFlags) VkShaderStageFlagBits ShaderTypeToVkShaderStageFlagBit(SHADER_TYPE ShaderType) { static_assert(SHADER_TYPE_LAST == SHADER_TYPE_MESH, "Please update the switch below to handle the new shader type"); - VERIFY((ShaderType & (ShaderType - 1)) == 0, "More than one shader type specified"); + VERIFY(IsPowerOfTwo(Uint32{ShaderType}), "More than one shader type is specified"); switch (ShaderType) { // clang-format off |
