diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2021-03-17 22:53:27 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2021-03-19 00:38:24 +0000 |
| commit | a2012c6d6eafd57283b9a7ca5d911ea69c30326b (patch) | |
| tree | c4ac492fde70e2047e8ca95db47539741639b694 /Graphics/GraphicsEngineD3D11 | |
| parent | Some more code improvemnts in D3D11 backend (diff) | |
| download | DiligentCore-a2012c6d6eafd57283b9a7ca5d911ea69c30326b.tar.gz DiligentCore-a2012c6d6eafd57283b9a7ca5d911ea69c30326b.zip | |
D3D11 backend: optimized resource counters
Diffstat (limited to 'Graphics/GraphicsEngineD3D11')
3 files changed, 120 insertions, 32 deletions
diff --git a/Graphics/GraphicsEngineD3D11/include/PipelineResourceAttribsD3D11.hpp b/Graphics/GraphicsEngineD3D11/include/PipelineResourceAttribsD3D11.hpp index 4f62b906..14c182f9 100644 --- a/Graphics/GraphicsEngineD3D11/include/PipelineResourceAttribsD3D11.hpp +++ b/Graphics/GraphicsEngineD3D11/include/PipelineResourceAttribsD3D11.hpp @@ -118,18 +118,24 @@ struct D3D11ResourceBindPoints } private: - struct SetBindPointHelper + struct StageAccessor { - SetBindPointHelper(D3D11ResourceBindPoints& _BindPoints, - const Uint32 _ShaderInd) : + StageAccessor(D3D11ResourceBindPoints& _BindPoints, + const Uint32 _ShaderInd) : BindPoints{_BindPoints}, ShaderInd{_ShaderInd} {} + // clang-format off + StageAccessor (const StageAccessor&) = delete; + StageAccessor ( StageAccessor&&) = default; + StageAccessor& operator=(const StageAccessor&) = delete; + StageAccessor& operator=( StageAccessor&&) = delete; + // clang-format on + Uint8 operator=(Uint32 BindPoint) { - BindPoints.Set(ShaderInd, BindPoint); - return static_cast<Uint8>(BindPoint); + return BindPoints.Set(ShaderInd, BindPoint); } operator Uint8() const @@ -143,19 +149,20 @@ private: }; public: - SetBindPointHelper operator[](Uint32 ShaderInd) + StageAccessor operator[](Uint32 ShaderInd) { - return SetBindPointHelper{*this, ShaderInd}; + return StageAccessor{*this, ShaderInd}; } private: - void Set(Uint32 ShaderInd, Uint32 BindPoint) + Uint8 Set(Uint32 ShaderInd, Uint32 BindPoint) { VERIFY_EXPR(ShaderInd < NumShaderTypes); VERIFY(BindPoint < InvalidBindPoint, "Bind point (", BindPoint, ") is out of range"); Bindings[ShaderInd] = static_cast<Uint8>(BindPoint); ActiveStages |= Uint32{1} << ShaderInd; + return static_cast<Uint8>(BindPoint); } static constexpr Uint8 InvalidBindPoint = 0xFF; @@ -168,8 +175,99 @@ private: }; +/// Shader resource counters for one specific resource range +struct D3D11ResourceRangeCounters +{ + Uint8 operator[](Uint32 Stage) const + { + VERIFY_EXPR(Stage < D3D11ResourceBindPoints::NumShaderTypes); + return (PackedCounters >> (NumBitsPerStage * Stage)) & StageMask; + } + + D3D11ResourceRangeCounters& operator+=(const D3D11ResourceRangeCounters& rhs) + { +#ifdef DILIGENT_DEBUG + for (Uint32 s = 0; s < D3D11ResourceBindPoints::NumShaderTypes; ++s) + { + const Uint32 val0 = (*static_cast<const D3D11ResourceRangeCounters*>(this))[s]; + const Uint32 val1 = rhs[s]; + VERIFY(val0 + val1 <= MaxCounter, "The resulting value is out of range"); + } +#endif + PackedCounters += rhs.PackedCounters; + return *this; + } + + bool operator==(const D3D11ResourceRangeCounters& rhs) const + { + return PackedCounters == rhs.PackedCounters; + } + +private: + struct StageAccessor + { + StageAccessor(D3D11ResourceRangeCounters& _Counters, + const Uint32 _ShaderInd) : + Counters{_Counters}, + ShaderInd{_ShaderInd} + {} + + // clang-format off + StageAccessor (const StageAccessor&) = delete; + StageAccessor ( StageAccessor&&) = default; + StageAccessor& operator=(const StageAccessor&) = delete; + StageAccessor& operator=( StageAccessor&&) = delete; + // clang-format on + + Uint8 operator=(Uint32 Counter) + { + return Counters.Set(ShaderInd, Counter); + } + + Uint8 operator+=(Uint32 Val) + { + Uint32 CurrValue = static_cast<const D3D11ResourceRangeCounters&>(Counters)[ShaderInd]; + return Counters.Set(ShaderInd, CurrValue + Val); + } + + operator Uint8() const + { + return static_cast<const D3D11ResourceRangeCounters&>(Counters)[ShaderInd]; + } + + private: + D3D11ResourceRangeCounters& Counters; + const Uint32 ShaderInd; + }; + +public: + StageAccessor operator[](Uint32 ShaderInd) + { + return StageAccessor{*this, ShaderInd}; + } + + +private: + Uint8 Set(Uint32 ShaderInd, Uint32 Counter) + { + VERIFY_EXPR(Counter <= MaxCounter); + const Uint64 BitOffset = NumBitsPerStage * ShaderInd; + PackedCounters &= ~(StageMask << BitOffset); + PackedCounters |= Uint64{Counter} << BitOffset; + return static_cast<Uint8>(Counter); + } + + static constexpr Uint64 NumBitsPerStage = 8; + static constexpr Uint64 StageMask = (Uint64{1} << NumBitsPerStage) - 1; + static constexpr Uint32 MaxCounter = (Uint32{1} << NumBitsPerStage) - 1; + + // 0 1 2 3 4 5 6 7 8 + // | PS | VS | GS | HS | DS | CS |unused|unused| + Uint64 PackedCounters = 0; +}; + /// Resource counters for all shader stages and all resource types -using D3D11ShaderResourceCounters = std::array<std::array<Uint8, D3D11ResourceBindPoints::NumShaderTypes>, D3D11_RESOURCE_RANGE_COUNT>; +using D3D11ShaderResourceCounters = std::array<D3D11ResourceRangeCounters, D3D11_RESOURCE_RANGE_COUNT>; // sizeof(PipelineResourceAttribsD3D11) == 12, x64 diff --git a/Graphics/GraphicsEngineD3D11/include/PipelineResourceSignatureD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/PipelineResourceSignatureD3D11Impl.hpp index 9ae2215e..cf1c4add 100644 --- a/Graphics/GraphicsEngineD3D11/include/PipelineResourceSignatureD3D11Impl.hpp +++ b/Graphics/GraphicsEngineD3D11/include/PipelineResourceSignatureD3D11Impl.hpp @@ -89,15 +89,8 @@ public: __forceinline void ShiftBindings(D3D11ShaderResourceCounters& Bindings) const { - for (Uint32 r = 0; r < Bindings.size(); ++r) - { - for (Uint32 s = 0; s < Bindings[r].size(); ++s) - { - Uint32 Count = Bindings[r][s] + m_BindingCountPerStage[r][s]; - VERIFY_EXPR(Count < std::numeric_limits<Uint8>::max()); - Bindings[r][s] = static_cast<Uint8>(Count); - } - } + for (Uint32 r = 0; r < D3D11_RESOURCE_RANGE_COUNT; ++r) + Bindings[r] += m_ResourceCounters[r]; } void InitSRBResourceCache(ShaderResourceCacheD3D11& ResourceCache); @@ -122,9 +115,9 @@ private: void Destruct(); private: - D3D11ShaderResourceCounters m_BindingCountPerStage = {}; - ResourceAttribs* m_pResourceAttribs = nullptr; // [m_Desc.NumResources] - ImmutableSamplerAttribs* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers] + D3D11ShaderResourceCounters m_ResourceCounters = {}; + ResourceAttribs* m_pResourceAttribs = nullptr; // [m_Desc.NumResources] + ImmutableSamplerAttribs* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers] }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D11/src/PipelineResourceSignatureD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/PipelineResourceSignatureD3D11Impl.cpp index 65c42f76..924e7b36 100644 --- a/Graphics/GraphicsEngineD3D11/src/PipelineResourceSignatureD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/PipelineResourceSignatureD3D11Impl.cpp @@ -104,7 +104,7 @@ PipelineResourceSignatureD3D11Impl::PipelineResourceSignatureD3D11Impl(IReferenc ShaderVariableDataSizes[s] = ShaderVariableManagerD3D11::GetRequiredMemorySize(*this, AllowedVarTypes, _countof(AllowedVarTypes), GetActiveShaderStageType(s)); } - const size_t CacheMemorySize = ShaderResourceCacheD3D11::GetRequriedMemorySize(m_BindingCountPerStage); + const size_t CacheMemorySize = ShaderResourceCacheD3D11::GetRequriedMemorySize(m_ResourceCounters); m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumActiveShaderStages(), ShaderVariableDataSizes.data(), 1, &CacheMemorySize); } @@ -119,18 +119,15 @@ PipelineResourceSignatureD3D11Impl::PipelineResourceSignatureD3D11Impl(IReferenc void PipelineResourceSignatureD3D11Impl::CreateLayout() { - const auto AllocBindPoints = [](D3D11ShaderResourceCounters& BindingPerStage, D3D11ResourceBindPoints& BindPoints, SHADER_TYPE ShaderStages, Uint32 ArraySize, D3D11_RESOURCE_RANGE Range) // + const auto AllocBindPoints = [](D3D11ShaderResourceCounters& ResCounters, D3D11ResourceBindPoints& BindPoints, SHADER_TYPE ShaderStages, Uint32 ArraySize, D3D11_RESOURCE_RANGE Range) // { while (ShaderStages != 0) { auto Stage = ExtractLSB(ShaderStages); auto ShaderInd = GetShaderTypeIndex(Stage); - BindPoints[ShaderInd] = BindingPerStage[Range][ShaderInd]; - - using T = std::remove_reference<decltype(BindingPerStage[Range][ShaderInd])>::type; - VERIFY(Uint32{BindingPerStage[Range][ShaderInd]} + ArraySize < std::numeric_limits<T>::max(), "Binding value exceeds representable range"); - BindingPerStage[Range][ShaderInd] += static_cast<Uint8>(ArraySize); + BindPoints[ShaderInd] = ResCounters[Range][ShaderInd]; + ResCounters[Range][ShaderInd] += ArraySize; } }; @@ -214,7 +211,7 @@ void PipelineResourceSignatureD3D11Impl::CreateLayout() if (!ImtblSampAttribs.IsAllocated()) { - AllocBindPoints(m_BindingCountPerStage, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, D3D11_RESOURCE_RANGE_SAMPLER); + AllocBindPoints(m_ResourceCounters, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, D3D11_RESOURCE_RANGE_SAMPLER); } } @@ -225,7 +222,7 @@ void PipelineResourceSignatureD3D11Impl::CreateLayout() AssignedSamplerInd, SrcImmutableSamplerInd != InvalidImmutableSamplerIndex // }; - AllocBindPoints(m_BindingCountPerStage, pAttrib->BindPoints, ResDesc.ShaderStages, ResDesc.ArraySize, Range); + AllocBindPoints(m_ResourceCounters, pAttrib->BindPoints, ResDesc.ShaderStages, ResDesc.ArraySize, Range); } else { @@ -258,7 +255,7 @@ void PipelineResourceSignatureD3D11Impl::CreateLayout() if (!ImtblSampAttribs.IsAllocated()) { ImtblSampAttribs.ArraySize = 1; - AllocBindPoints(m_BindingCountPerStage, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, Range); + AllocBindPoints(m_ResourceCounters, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, Range); } } } @@ -345,7 +342,7 @@ void PipelineResourceSignatureD3D11Impl::CopyStaticResources(ShaderResourceCache void PipelineResourceSignatureD3D11Impl::InitSRBResourceCache(ShaderResourceCacheD3D11& ResourceCache) { - ResourceCache.Initialize(m_BindingCountPerStage, m_SRBMemAllocator.GetResourceCacheDataAllocator(0)); + ResourceCache.Initialize(m_ResourceCounters, m_SRBMemAllocator.GetResourceCacheDataAllocator(0)); VERIFY_EXPR(ResourceCache.IsInitialized()); // Copy immutable samplers. |
