From 9529875002896fa87db5adee4fa3f4e477408072 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 23 Nov 2019 00:05:15 -0800 Subject: clang-formatted GraphicsAccessories --- .../interface/ColorConversion.h | 4 +- .../interface/GraphicsAccessories.h | 118 ++-- .../interface/ResourceReleaseQueue.h | 84 +-- .../GraphicsAccessories/interface/RingBuffer.h | 335 +++++------ .../interface/SRBMemoryAllocator.h | 8 +- .../interface/VariableSizeAllocationsManager.h | 629 +++++++++++---------- .../interface/VariableSizeGPUAllocationsManager.h | 132 ++--- .../GraphicsAccessories/src/ColorConversion.cpp | 4 +- .../src/GraphicsAccessories.cpp | 289 +++++----- .../GraphicsAccessories/src/SRBMemoryAllocator.cpp | 17 +- 10 files changed, 853 insertions(+), 767 deletions(-) (limited to 'Graphics') diff --git a/Graphics/GraphicsAccessories/interface/ColorConversion.h b/Graphics/GraphicsAccessories/interface/ColorConversion.h index 188e75dc..51af254f 100644 --- a/Graphics/GraphicsAccessories/interface/ColorConversion.h +++ b/Graphics/GraphicsAccessories/interface/ColorConversion.h @@ -32,7 +32,7 @@ namespace Diligent // https://en.wikipedia.org/wiki/SRGB inline float LinearToSRGB(float x) { - return x <= 0.0031308 ? x * 12.92f : 1.055f * std::pow(x, 1.f / 2.4f) - 0.055f; + return x <= 0.0031308 ? x * 12.92f : 1.055f * std::pow(x, 1.f / 2.4f) - 0.055f; } inline float SRGBToLinear(float x) @@ -54,4 +54,4 @@ inline float FastSRGBToLinear(float x) return x * (x * (x * 0.305306011f + 0.682171111f) + 0.012522878f); } -} +} // namespace Diligent diff --git a/Graphics/GraphicsAccessories/interface/GraphicsAccessories.h b/Graphics/GraphicsAccessories/interface/GraphicsAccessories.h index 8606f180..e0d33199 100644 --- a/Graphics/GraphicsAccessories/interface/GraphicsAccessories.h +++ b/Graphics/GraphicsAccessories/interface/GraphicsAccessories.h @@ -37,70 +37,95 @@ namespace Diligent { /// Template structure to convert VALUE_TYPE enumeration into C-type -template +template struct VALUE_TYPE2CType {}; - + /// VALUE_TYPE2CType<> template specialization for 8-bit integer value type. /// Usage example: /// /// VALUE_TYPE2CType::CType MyInt8Var; -template<>struct VALUE_TYPE2CType { typedef Int8 CType; }; +template <> struct VALUE_TYPE2CType +{ + typedef Int8 CType; +}; /// VALUE_TYPE2CType<> template specialization for 16-bit integer value type. /// Usage example: /// /// VALUE_TYPE2CType::CType MyInt16Var; -template<>struct VALUE_TYPE2CType { typedef Int16 CType; }; +template <> struct VALUE_TYPE2CType +{ + typedef Int16 CType; +}; /// VALUE_TYPE2CType<> template specialization for 32-bit integer value type. /// Usage example: /// /// VALUE_TYPE2CType::CType MyInt32Var; -template<>struct VALUE_TYPE2CType { typedef Int32 CType; }; - +template <> struct VALUE_TYPE2CType +{ + typedef Int32 CType; +}; + /// VALUE_TYPE2CType<> template specialization for 8-bit unsigned-integer value type. /// Usage example: /// /// VALUE_TYPE2CType::CType MyUint8Var; -template<>struct VALUE_TYPE2CType { typedef Uint8 CType; }; +template <> struct VALUE_TYPE2CType +{ + typedef Uint8 CType; +}; /// VALUE_TYPE2CType<> template specialization for 16-bit unsigned-integer value type. /// Usage example: /// /// VALUE_TYPE2CType::CType MyUint16Var; -template<>struct VALUE_TYPE2CType{ typedef Uint16 CType; }; +template <> struct VALUE_TYPE2CType +{ + typedef Uint16 CType; +}; /// VALUE_TYPE2CType<> template specialization for 32-bit unsigned-integer value type. /// Usage example: /// /// VALUE_TYPE2CType::CType MyUint32Var; -template<>struct VALUE_TYPE2CType{ typedef Uint32 CType; }; +template <> struct VALUE_TYPE2CType +{ + typedef Uint32 CType; +}; /// VALUE_TYPE2CType<> template specialization for half-precision 16-bit floating-point value type. - + /// Usage example: /// /// VALUE_TYPE2CType::CType MyFloat16Var; /// /// \note 16-bit floating-point values have no corresponding C++ type and are translated to Uint16 -template<>struct VALUE_TYPE2CType{ typedef Uint16 CType; }; +template <> struct VALUE_TYPE2CType +{ + typedef Uint16 CType; +}; /// VALUE_TYPE2CType<> template specialization for full-precision 32-bit floating-point value type. /// Usage example: /// /// VALUE_TYPE2CType::CType MyFloat32Var; -template<>struct VALUE_TYPE2CType{ typedef Float32 CType; }; +template <> struct VALUE_TYPE2CType +{ + typedef Float32 CType; +}; -static const Uint32 ValueTypeToSizeMap[] = +static const Uint32 ValueTypeToSizeMap[] = + // clang-format off { 0, sizeof(VALUE_TYPE2CType :: CType), @@ -112,6 +137,7 @@ static const Uint32 ValueTypeToSizeMap[] = sizeof(VALUE_TYPE2CType :: CType), sizeof(VALUE_TYPE2CType :: CType) }; +// clang-format on static_assert(VT_NUM_TYPES == VT_FLOAT32 + 1, "Not all value type sizes initialized."); /// Returns the size of the specified value type @@ -122,7 +148,7 @@ inline Uint32 GetValueSize(VALUE_TYPE Val) } /// Returns the string representing the specified value type -const Char* GetValueTypeString( VALUE_TYPE Val ); +const Char* GetValueTypeString(VALUE_TYPE Val); /// Returns invariant texture format attributes, see TextureFormatAttribs for details. @@ -157,7 +183,7 @@ TEXTURE_FORMAT GetDefaultTextureViewFormat(TEXTURE_FORMAT TextureFormat, TEXTURE /// \param [in] TexDesc - texture description /// \param [in] ViewType - texture view type /// \return texture view type format -inline TEXTURE_FORMAT GetDefaultTextureViewFormat(const TextureDesc &TexDesc, TEXTURE_VIEW_TYPE ViewType) +inline TEXTURE_FORMAT GetDefaultTextureViewFormat(const TextureDesc& TexDesc, TEXTURE_VIEW_TYPE ViewType) { return GetDefaultTextureViewFormat(TexDesc.Format, ViewType, TexDesc.BindFlags); } @@ -184,7 +210,7 @@ const Char* GetBufferViewTypeLiteralName(BUFFER_VIEW_TYPE ViewType); const Char* GetShaderTypeLiteralName(SHADER_TYPE ShaderType); /// \param [in] ShaderStages - Shader stages. -/// \return The string representing the shader stages. For example, +/// \return The string representing the shader stages. For example, /// if ShaderStages == SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, /// the following string will be returned: /// "SHADER_TYPE_VERTEX, SHADER_TYPE_PIXEL" @@ -212,14 +238,14 @@ const Char* GetShaderResourceTypeLiteralName(SHADER_RESOURCE_TYPE ResourceType, /// see GetTexViewTypeLiteralName(). inline const Char* GetViewTypeLiteralName(TEXTURE_VIEW_TYPE TexViewType) { - return GetTexViewTypeLiteralName( TexViewType ); + return GetTexViewTypeLiteralName(TexViewType); } /// Overloaded function that returns the literal name of a buffer view type. /// see GetBufferViewTypeLiteralName(). inline const Char* GetViewTypeLiteralName(BUFFER_VIEW_TYPE BuffViewType) { - return GetBufferViewTypeLiteralName( BuffViewType ); + return GetBufferViewTypeLiteralName(BuffViewType); } /// Returns the string containing the map type @@ -229,75 +255,75 @@ const Char* GetMapTypeString(MAP_TYPE MapType); const Char* GetUsageString(USAGE Usage); /// Returns the string containing the texture type -const Char* GetResourceDimString( RESOURCE_DIMENSION TexType ); +const Char* GetResourceDimString(RESOURCE_DIMENSION TexType); /// Returns the string containing single bind flag -const Char* GetBindFlagString( Uint32 BindFlag ); +const Char* GetBindFlagString(Uint32 BindFlag); /// Returns the string containing the bind flags -String GetBindFlagsString( Uint32 BindFlags ); +String GetBindFlagsString(Uint32 BindFlags); /// Returns the string containing the CPU access flags -String GetCPUAccessFlagsString( Uint32 CpuAccessFlags ); +String GetCPUAccessFlagsString(Uint32 CpuAccessFlags); /// Returns the string containing the texture description -String GetTextureDescString(const TextureDesc &Desc); +String GetTextureDescString(const TextureDesc& Desc); /// Returns the string containing the buffer format description String GetBufferFormatString(const BufferFormat& Fmt); /// Returns the string containing the buffer mode description -const Char* GetBufferModeString( BUFFER_MODE Mode ); +const Char* GetBufferModeString(BUFFER_MODE Mode); /// Returns the string containing the buffer description -String GetBufferDescString(const BufferDesc &Desc); +String GetBufferDescString(const BufferDesc& Desc); /// Returns the string containing the buffer mode description -const Char* GetResourceStateFlagString( RESOURCE_STATE State ); -String GetResourceStateString( RESOURCE_STATE State ); +const Char* GetResourceStateFlagString(RESOURCE_STATE State); +String GetResourceStateString(RESOURCE_STATE State); /// Helper template function that converts object description into a string -template -String GetObjectDescString( const TObjectDescType& ) +template +String GetObjectDescString(const TObjectDescType&) { return ""; } /// Template specialization for texture description -template<> -inline String GetObjectDescString( const TextureDesc& TexDesc ) +template <> +inline String GetObjectDescString(const TextureDesc& TexDesc) { - String Str( "Tex desc: " ); - Str += GetTextureDescString( TexDesc ); + String Str{"Tex desc: "}; + Str += GetTextureDescString(TexDesc); return Str; } /// Template specialization for buffer description -template<> -inline String GetObjectDescString( const BufferDesc& BuffDesc ) +template <> +inline String GetObjectDescString(const BufferDesc& BuffDesc) { - String Str( "Buff desc: " ); - Str += GetBufferDescString( BuffDesc ); + String Str{"Buff desc: "}; + Str += GetBufferDescString(BuffDesc); return Str; } -Uint32 ComputeMipLevelsCount( Uint32 Width ); -Uint32 ComputeMipLevelsCount( Uint32 Width, Uint32 Height ); -Uint32 ComputeMipLevelsCount( Uint32 Width, Uint32 Height, Uint32 Depth ); +Uint32 ComputeMipLevelsCount(Uint32 Width); +Uint32 ComputeMipLevelsCount(Uint32 Width, Uint32 Height); +Uint32 ComputeMipLevelsCount(Uint32 Width, Uint32 Height, Uint32 Depth); inline bool IsComparisonFilter(FILTER_TYPE FilterType) { return FilterType == FILTER_TYPE_COMPARISON_POINT || - FilterType == FILTER_TYPE_COMPARISON_LINEAR || - FilterType == FILTER_TYPE_COMPARISON_ANISOTROPIC; + FilterType == FILTER_TYPE_COMPARISON_LINEAR || + FilterType == FILTER_TYPE_COMPARISON_ANISOTROPIC; } inline bool IsAnisotropicFilter(FILTER_TYPE FilterType) { return FilterType == FILTER_TYPE_ANISOTROPIC || - FilterType == FILTER_TYPE_COMPARISON_ANISOTROPIC || - FilterType == FILTER_TYPE_MINIMUM_ANISOTROPIC || - FilterType == FILTER_TYPE_MAXIMUM_ANISOTROPIC; + FilterType == FILTER_TYPE_COMPARISON_ANISOTROPIC || + FilterType == FILTER_TYPE_MINIMUM_ANISOTROPIC || + FilterType == FILTER_TYPE_MAXIMUM_ANISOTROPIC; } bool VerifyResourceStates(RESOURCE_STATE State, bool IsTexture); @@ -317,4 +343,4 @@ struct MipLevelProperties MipLevelProperties GetMipLevelProperties(const TextureDesc& TexDesc, Uint32 MipLevel); -} +} // namespace Diligent diff --git a/Graphics/GraphicsAccessories/interface/ResourceReleaseQueue.h b/Graphics/GraphicsAccessories/interface/ResourceReleaseQueue.h index 9afc8727..b3816315 100644 --- a/Graphics/GraphicsAccessories/interface/ResourceReleaseQueue.h +++ b/Graphics/GraphicsAccessories/interface/ResourceReleaseQueue.h @@ -60,7 +60,7 @@ public: // |__________________________________________________| // - template::value>::type> + template ::value>::type> static DynamicStaleResourceWrapper Create(ResourceType&& Resource, Atomics::Long NumReferences) { VERIFY_EXPR(NumReferences >= 1); @@ -72,10 +72,12 @@ public: m_SpecificResource(std::move(SpecificResource)) {} + // clang-format off SpecificStaleResource (const SpecificStaleResource&) = delete; SpecificStaleResource (SpecificStaleResource&&) = delete; SpecificStaleResource& operator = (const SpecificStaleResource&) = delete; SpecificStaleResource& operator = (SpecificStaleResource&&) = delete; + // clang-format on virtual void Release() override final { @@ -95,10 +97,12 @@ public: m_RefCounter = NumReferences; } + // clang-format off SpecificSharedStaleResource (const SpecificSharedStaleResource&) = delete; SpecificSharedStaleResource (SpecificSharedStaleResource&&) = delete; SpecificSharedStaleResource& operator = (const SpecificSharedStaleResource&) = delete; SpecificSharedStaleResource& operator = (SpecificSharedStaleResource&&) = delete; + // clang-format on virtual void Release() override final { @@ -109,15 +113,14 @@ public: } private: - ResourceType m_SpecificResource; + ResourceType m_SpecificResource; Atomics::AtomicLong m_RefCounter; }; return DynamicStaleResourceWrapper{ NumReferences == 1 ? - static_cast( new SpecificStaleResource {std::move(Resource)} ) : - static_cast( new SpecificSharedStaleResource{std::move(Resource), NumReferences} ) - }; + static_cast(new SpecificStaleResource{std::move(Resource)}) : + static_cast(new SpecificSharedStaleResource{std::move(Resource), NumReferences})}; } DynamicStaleResourceWrapper(DynamicStaleResourceWrapper&& rhs) noexcept : @@ -126,13 +129,15 @@ public: rhs.m_pStaleResource = nullptr; } - DynamicStaleResourceWrapper (const DynamicStaleResourceWrapper& rhs) noexcept : - m_pStaleResource(rhs.m_pStaleResource) + DynamicStaleResourceWrapper(const DynamicStaleResourceWrapper& rhs) noexcept : + m_pStaleResource{rhs.m_pStaleResource} { } + // clang-format off DynamicStaleResourceWrapper& operator = (const DynamicStaleResourceWrapper&) = delete; DynamicStaleResourceWrapper& operator = ( DynamicStaleResourceWrapper&&) = delete; + // clang-format on void GiveUpOwnership() { @@ -150,10 +155,10 @@ private: { public: virtual ~StaleResourceBase() = 0; - virtual void Release() = 0; + virtual void Release() = 0; }; - DynamicStaleResourceWrapper(StaleResourceBase *pStaleResource) : + DynamicStaleResourceWrapper(StaleResourceBase* pStaleResource) : m_pStaleResource(pStaleResource) {} @@ -165,7 +170,7 @@ inline DynamicStaleResourceWrapper::StaleResourceBase::~StaleResourceBase() } /// Helper class that wraps stale resources of the same type -template +template class StaticStaleResourceWrapper { public: @@ -179,18 +184,20 @@ public: m_StaleResource(std::move(rhs.m_StaleResource)) {} - StaticStaleResourceWrapper& operator = (StaticStaleResourceWrapper&& rhs) noexcept + StaticStaleResourceWrapper& operator=(StaticStaleResourceWrapper&& rhs) noexcept { m_StaleResource = std::move(rhs.m_StaleResource); return *this; } + // clang-format off StaticStaleResourceWrapper (const StaticStaleResourceWrapper&) = delete; StaticStaleResourceWrapper& operator = (const StaticStaleResourceWrapper&) = delete; + // clang-format on private: - StaticStaleResourceWrapper(ResourceType&& StaleResource) : - m_StaleResource(std::move(StaleResource)) + StaticStaleResourceWrapper(ResourceType&& StaleResource) : + m_StaleResource{std::move(StaleResource)} {} ResourceType m_StaleResource; @@ -206,14 +213,16 @@ private: /// * Resources are removed and actually destroyed from the queue when fence is signaled and the queue is Purged /// /// \tparam ResourceWrapperType - Type of the resource wrapper used by the release queue. -template +template class ResourceReleaseQueue { public: - ResourceReleaseQueue(IMemoryAllocator& Allocator) : - m_ReleaseQueue (STD_ALLOCATOR_RAW_MEM(ReleaseQueueElemType, Allocator, "Allocator for deque")), - m_StaleResources(STD_ALLOCATOR_RAW_MEM(ReleaseQueueElemType, Allocator, "Allocator for deque")) + // clang-format off + ResourceReleaseQueue(IMemoryAllocator& Allocator) : + m_ReleaseQueue {STD_ALLOCATOR_RAW_MEM(ReleaseQueueElemType, Allocator, "Allocator for deque")}, + m_StaleResources{STD_ALLOCATOR_RAW_MEM(ReleaseQueueElemType, Allocator, "Allocator for deque")} {} + // clang-format on ~ResourceReleaseQueue() { @@ -224,7 +233,7 @@ public: /// Creates a resource wrapper for the specific resource type /// \param [in] Resource - Resource to be released /// \param [in] NumReferences - Number of references to the resource - template::value>::type> + template ::value>::type> static ResourceWrapperType CreateWrapper(ResourceType&& Resource, Atomics::Long NumReferences) { return ResourceWrapperType::Create(std::move(Resource), NumReferences); @@ -233,7 +242,7 @@ public: /// Moves a resource to the stale resources queue /// \param [in] Resource - Resource to be released /// \param [in] NextCommandListNumber - Number of the command list that will be submitted to the queue next - template::value>::type> + template ::value>::type> void SafeReleaseResource(ResourceType&& Resource, Uint64 NextCommandListNumber) { SafeReleaseResource(CreateWrapper(std::move(Resource), 1), NextCommandListNumber); @@ -260,7 +269,7 @@ public: /// Adds a resource directly to the release queue /// \param [in] Resource - Resource to be released. /// \param [in] FenceValue - Fence value indicating when the resource was used last time. - template::value>::type> + template ::value>::type> void DiscardResource(ResourceType&& Resource, Uint64 FenceValue) { DiscardResource(CreateWrapper(std::move(Resource), 1), FenceValue); @@ -272,7 +281,7 @@ public: void DiscardResource(ResourceWrapperType&& Wrapper, Uint64 FenceValue) { std::lock_guard ReleaseQueueLock(m_ReleaseQueueMutex); - m_ReleaseQueue.emplace_back(FenceValue, std::move(Wrapper) ); + m_ReleaseQueue.emplace_back(FenceValue, std::move(Wrapper)); } /// Adds a copy of the resource wrapper directly to the release queue @@ -287,19 +296,19 @@ public: /// Adds multiple resources directly to the release queue /// \param [in] FenceValue - Fence value indicating when the resource was used last time. /// \param [in] Iterator - Iterator that returns resources to be relased. - template + template void DiscardResources(Uint64 FenceValue, IteratorType Iterator) { std::lock_guard ReleaseQueueLock(m_ReleaseQueueMutex); - ResourceType Resource; - while(Iterator(Resource)) + ResourceType Resource; + while (Iterator(Resource)) { - m_ReleaseQueue.emplace_back(FenceValue, CreateWrapper(std::move(Resource), 1) ); + m_ReleaseQueue.emplace_back(FenceValue, CreateWrapper(std::move(Resource), 1)); } } /// Moves stale objects to the release queue - /// \param [in] SubmittedCmdBuffNumber - number of the last submitted command list. + /// \param [in] SubmittedCmdBuffNumber - number of the last submitted command list. /// All resources in the stale object list whose command list number is /// less than or equal to this value are moved to the release queue. /// \param [in] FenceValue - Fence value associated with the resources moved to the release queue. @@ -311,15 +320,15 @@ public: // was executed std::lock_guard StaleObjectsLock(m_StaleObjectsMutex); std::lock_guard ReleaseQueueLock(m_ReleaseQueueMutex); - while (!m_StaleResources.empty() ) + while (!m_StaleResources.empty()) { - auto &FirstStaleObj = m_StaleResources.front(); + auto& FirstStaleObj = m_StaleResources.front(); if (FirstStaleObj.first <= SubmittedCmdBuffNumber) { m_ReleaseQueue.emplace_back(FenceValue, std::move(FirstStaleObj.second)); m_StaleResources.pop_front(); } - else + else break; } } @@ -336,34 +345,33 @@ public: // See http://diligentgraphics.com/diligent-engine/architecture/d3d12/managing-resource-lifetimes/ while (!m_ReleaseQueue.empty()) { - auto &FirstObj = m_ReleaseQueue.front(); + auto& FirstObj = m_ReleaseQueue.front(); if (FirstObj.first <= CompletedFenceValue) m_ReleaseQueue.pop_front(); else break; } } - + /// Returns the number of stale resources - size_t GetStaleResourceCount()const + size_t GetStaleResourceCount() const { return m_StaleResources.size(); } /// Returns the number of resources pending release - size_t GetPendingReleaseResourceCount()const + size_t GetPendingReleaseResourceCount() const { return m_ReleaseQueue.size(); } private: - std::mutex m_ReleaseQueueMutex; using ReleaseQueueElemType = std::pair; - std::deque< ReleaseQueueElemType, STDAllocatorRawMem > m_ReleaseQueue; + std::deque> m_ReleaseQueue; - std::mutex m_StaleObjectsMutex; - std::deque< ReleaseQueueElemType, STDAllocatorRawMem > m_StaleResources; + std::mutex m_StaleObjectsMutex; + std::deque> m_StaleResources; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsAccessories/interface/RingBuffer.h b/Graphics/GraphicsAccessories/interface/RingBuffer.h index 57ae5f90..3f99454b 100644 --- a/Graphics/GraphicsAccessories/interface/RingBuffer.h +++ b/Graphics/GraphicsAccessories/interface/RingBuffer.h @@ -35,193 +35,202 @@ namespace Diligent { - /// Implementation of a ring buffer. The class is not thread-safe. - class RingBuffer +/// Implementation of a ring buffer. The class is not thread-safe. +class RingBuffer +{ +public: + using OffsetType = size_t; + struct FrameHeadAttribs { - public: - using OffsetType = size_t; - struct FrameHeadAttribs - { - FrameHeadAttribs(Uint64 fv, OffsetType off, OffsetType sz)noexcept : - FenceValue(fv), - Offset (off), - Size (sz) - {} - - // Fence value associated with the command list in which - // the allocation could have been referenced last time - Uint64 FenceValue; - OffsetType Offset; - OffsetType Size; - }; - static constexpr const OffsetType InvalidOffset = static_cast(-1); - - RingBuffer(OffsetType MaxSize, IMemoryAllocator &Allocator)noexcept : - m_CompletedFrameHeads(STD_ALLOCATOR_RAW_MEM(FrameHeadAttribs, Allocator, "Allocator for deque")), - m_MaxSize(MaxSize) + // clang-format off + FrameHeadAttribs(Uint64 fv, OffsetType off, OffsetType sz) noexcept : + FenceValue{fv }, + Offset {off}, + Size {sz } {} + // clang-format on - RingBuffer(RingBuffer&& rhs)noexcept : - m_CompletedFrameHeads(std::move(rhs.m_CompletedFrameHeads)), - m_Tail (rhs.m_Tail), - m_Head (rhs.m_Head), - m_MaxSize (rhs.m_MaxSize), - m_UsedSize (rhs.m_UsedSize), - m_CurrFrameSize (rhs.m_CurrFrameSize) - { - rhs.m_Tail = 0; - rhs.m_Head = 0; - rhs.m_MaxSize = 0; - rhs.m_UsedSize = 0; - rhs.m_CurrFrameSize = 0; - } - - RingBuffer& operator = (RingBuffer&& rhs)noexcept - { - m_CompletedFrameHeads = std::move(rhs.m_CompletedFrameHeads); - m_Tail = rhs.m_Tail; - m_Head = rhs.m_Head; - m_MaxSize = rhs.m_MaxSize; - m_UsedSize = rhs.m_UsedSize; - m_CurrFrameSize = rhs.m_CurrFrameSize; - - rhs.m_MaxSize = 0; - rhs.m_Tail = 0; - rhs.m_Head = 0; - rhs.m_UsedSize = 0; - rhs.m_CurrFrameSize = 0; - - return *this; - } + // Fence value associated with the command list in which + // the allocation could have been referenced last time + Uint64 FenceValue; + OffsetType Offset; + OffsetType Size; + }; + static constexpr const OffsetType InvalidOffset = static_cast(-1); + + RingBuffer(OffsetType MaxSize, IMemoryAllocator& Allocator) noexcept : + m_CompletedFrameHeads{STD_ALLOCATOR_RAW_MEM(FrameHeadAttribs, Allocator, "Allocator for deque")}, + m_MaxSize{MaxSize} + {} + + // clang-format off + RingBuffer(RingBuffer&& rhs) noexcept : + m_CompletedFrameHeads{std::move(rhs.m_CompletedFrameHeads)}, + m_Tail {rhs.m_Tail }, + m_Head {rhs.m_Head }, + m_MaxSize {rhs.m_MaxSize }, + m_UsedSize {rhs.m_UsedSize }, + m_CurrFrameSize {rhs.m_CurrFrameSize} + // clang-format on + { + rhs.m_Tail = 0; + rhs.m_Head = 0; + rhs.m_MaxSize = 0; + rhs.m_UsedSize = 0; + rhs.m_CurrFrameSize = 0; + } + + RingBuffer& operator=(RingBuffer&& rhs) noexcept + { + m_CompletedFrameHeads = std::move(rhs.m_CompletedFrameHeads); + m_Tail = rhs.m_Tail; + m_Head = rhs.m_Head; + m_MaxSize = rhs.m_MaxSize; + m_UsedSize = rhs.m_UsedSize; + m_CurrFrameSize = rhs.m_CurrFrameSize; + + rhs.m_MaxSize = 0; + rhs.m_Tail = 0; + rhs.m_Head = 0; + rhs.m_UsedSize = 0; + rhs.m_CurrFrameSize = 0; + + return *this; + } + + // clang-format off + RingBuffer (const RingBuffer&) = delete; + RingBuffer& operator = (const RingBuffer&) = delete; + // clang-format on + + ~RingBuffer() + { + VERIFY(m_UsedSize == 0, "All space in the ring buffer must be released"); + } - RingBuffer (const RingBuffer&) = delete; - RingBuffer& operator = (const RingBuffer&) = delete; + OffsetType Allocate(OffsetType Size, OffsetType Alignment) + { + VERIFY_EXPR(Size > 0); + VERIFY(IsPowerOfTwo(Alignment), "Alignment (", Alignment, ") must be power of 2"); + Size = Align(Size, Alignment); - ~RingBuffer() + if (m_UsedSize + Size > m_MaxSize) { - VERIFY(m_UsedSize==0, "All space in the ring buffer must be released"); + return InvalidOffset; } - OffsetType Allocate(OffsetType Size, OffsetType Alignment) + auto AlignedHead = Align(m_Head, Alignment); + if (m_Head >= m_Tail) { - VERIFY_EXPR(Size > 0); - VERIFY(IsPowerOfTwo(Alignment), "Alignment (", Alignment, ") must be power of 2"); - Size = Align(Size, Alignment); - - if (m_UsedSize + Size > m_MaxSize) + // AlignedHead + // Tail Head | MaxSize + // | | | | + // [ xxxxxxxxxxxxxxxxx... ] + // + // + if (AlignedHead + Size <= m_MaxSize) { - return InvalidOffset; + auto Offset = AlignedHead; + auto AdjustedSize = Size + (AlignedHead - m_Head); + m_Head += AdjustedSize; + m_UsedSize += AdjustedSize; + m_CurrFrameSize += AdjustedSize; + return Offset; } - - auto AlignedHead = Align(m_Head, Alignment); - if (m_Head >= m_Tail) + else if (Size <= m_Tail) { - // AlignedHead - // Tail Head | MaxSize - // | | | | - // [ xxxxxxxxxxxxxxxxx... ] - // + // Allocate from the beginning of the buffer // - if (AlignedHead + Size <= m_MaxSize) - { - auto Offset = AlignedHead; - auto AdjustedSize = Size + (AlignedHead - m_Head); - m_Head += AdjustedSize; - m_UsedSize += AdjustedSize; - m_CurrFrameSize += AdjustedSize; - return Offset; - } - else if (Size <= m_Tail) - { - // Allocate from the beginning of the buffer - // - // - // Offset Tail Head MaxSize - // | | |<---AddSize--->| - // [ xxxxxxxxxxxxxxxxx++++++++++++++++] - // - OffsetType AddSize = (m_MaxSize - m_Head) + Size; - m_UsedSize += AddSize; - m_CurrFrameSize += AddSize; - m_Head = Size; - return 0; - } - } - else if (AlignedHead + Size <= m_Tail ) - { - // AlignedHead - // Head | Tail - // | | | - // [xxxx... xxxxxxxxxxxxxxxxxxxxxxxxxx] // - auto Offset = AlignedHead; - auto AdjustedSize = Size + (AlignedHead - m_Head); - m_Head += AdjustedSize; - m_UsedSize += AdjustedSize; - m_CurrFrameSize += AdjustedSize; - return Offset; + // Offset Tail Head MaxSize + // | | |<---AddSize--->| + // [ xxxxxxxxxxxxxxxxx++++++++++++++++] + // + OffsetType AddSize = (m_MaxSize - m_Head) + Size; + m_UsedSize += AddSize; + m_CurrFrameSize += AddSize; + m_Head = Size; + return 0; } - - return InvalidOffset; } - - // FenceValue is the fence value associated with the command list in which the head - // could have been referenced last time - // See http://diligentgraphics.com/diligent-engine/architecture/d3d12/managing-resource-lifetimes/ - void FinishCurrentFrame(Uint64 FenceValue) + else if (AlignedHead + Size <= m_Tail) { + // AlignedHead + // Head | Tail + // | | | + // [xxxx... xxxxxxxxxxxxxxxxxxxxxxxxxx] + // + auto Offset = AlignedHead; + auto AdjustedSize = Size + (AlignedHead - m_Head); + m_Head += AdjustedSize; + m_UsedSize += AdjustedSize; + m_CurrFrameSize += AdjustedSize; + return Offset; + } + + return InvalidOffset; + } + + // FenceValue is the fence value associated with the command list in which the head + // could have been referenced last time + // See http://diligentgraphics.com/diligent-engine/architecture/d3d12/managing-resource-lifetimes/ + void FinishCurrentFrame(Uint64 FenceValue) + { #ifdef _DEBUG - if (!m_CompletedFrameHeads.empty()) - VERIFY(FenceValue >= m_CompletedFrameHeads.back().FenceValue, "Current frame fence value (", FenceValue, ") is lower than the fence value of the previous frame (", m_CompletedFrameHeads.back().FenceValue, ")"); + if (!m_CompletedFrameHeads.empty()) + VERIFY(FenceValue >= m_CompletedFrameHeads.back().FenceValue, "Current frame fence value (", FenceValue, ") is lower than the fence value of the previous frame (", m_CompletedFrameHeads.back().FenceValue, ")"); #endif - // Ignore zero-size frames - if (m_CurrFrameSize != 0) - { - m_CompletedFrameHeads.emplace_back(FenceValue, m_Head, m_CurrFrameSize); - m_CurrFrameSize = 0; - } + // Ignore zero-size frames + if (m_CurrFrameSize != 0) + { + m_CompletedFrameHeads.emplace_back(FenceValue, m_Head, m_CurrFrameSize); + m_CurrFrameSize = 0; } + } - // CompletedFenceValue indicates GPU progress - // See http://diligentgraphics.com/diligent-engine/architecture/d3d12/managing-resource-lifetimes/ - void ReleaseCompletedFrames(Uint64 CompletedFenceValue) + // CompletedFenceValue indicates GPU progress + // See http://diligentgraphics.com/diligent-engine/architecture/d3d12/managing-resource-lifetimes/ + void ReleaseCompletedFrames(Uint64 CompletedFenceValue) + { + // We can release all heads whose associated fence value is less than or equal to CompletedFenceValue + while (!m_CompletedFrameHeads.empty() && m_CompletedFrameHeads.front().FenceValue <= CompletedFenceValue) { - // We can release all heads whose associated fence value is less than or equal to CompletedFenceValue - while(!m_CompletedFrameHeads.empty() && m_CompletedFrameHeads.front().FenceValue <= CompletedFenceValue) - { - const auto& OldestFrameHead = m_CompletedFrameHeads.front(); - VERIFY_EXPR(OldestFrameHead.Size <= m_UsedSize); - m_UsedSize -= OldestFrameHead.Size; - m_Tail = OldestFrameHead.Offset; - m_CompletedFrameHeads.pop_front(); - } + const auto& OldestFrameHead = m_CompletedFrameHeads.front(); + VERIFY_EXPR(OldestFrameHead.Size <= m_UsedSize); + m_UsedSize -= OldestFrameHead.Size; + m_Tail = OldestFrameHead.Offset; + m_CompletedFrameHeads.pop_front(); + } - if (IsEmpty()) - { + if (IsEmpty()) + { #ifdef _DEBUG - VERIFY(m_CompletedFrameHeads.empty(), "Zero-size heads are not added to the list, and since the buffer is empty, there must be no heads in the list"); - for(const auto& head : m_CompletedFrameHeads) - VERIFY(head.Size == 0, "Non zero-size head found"); + VERIFY(m_CompletedFrameHeads.empty(), "Zero-size heads are not added to the list, and since the buffer is empty, there must be no heads in the list"); + for (const auto& head : m_CompletedFrameHeads) + VERIFY(head.Size == 0, "Non zero-size head found"); #endif - m_CompletedFrameHeads.clear(); + m_CompletedFrameHeads.clear(); - // t,h t,h - // | | | ====> | | - m_Tail = m_Head = 0; - } + // t,h t,h + // | | | ====> | | + m_Tail = m_Head = 0; } - - OffsetType GetMaxSize() const { return m_MaxSize; } - bool IsFull() const { return m_UsedSize==m_MaxSize; }; - bool IsEmpty() const { return m_UsedSize==0; }; - OffsetType GetUsedSize()const { return m_UsedSize; } - - private: - std::deque< FrameHeadAttribs, STDAllocatorRawMem > m_CompletedFrameHeads; - OffsetType m_Tail = 0; - OffsetType m_Head = 0; - OffsetType m_MaxSize = 0; - OffsetType m_UsedSize = 0; - OffsetType m_CurrFrameSize = 0; - }; -} + } + + // clang-format off + OffsetType GetMaxSize() const { return m_MaxSize; } + bool IsFull() const { return m_UsedSize==m_MaxSize; }; + bool IsEmpty() const { return m_UsedSize==0; }; + OffsetType GetUsedSize()const { return m_UsedSize; } + // clang-format on + +private: + std::deque> m_CompletedFrameHeads; + + OffsetType m_Tail = 0; + OffsetType m_Head = 0; + OffsetType m_MaxSize = 0; + OffsetType m_UsedSize = 0; + OffsetType m_CurrFrameSize = 0; +}; +} // namespace Diligent diff --git a/Graphics/GraphicsAccessories/interface/SRBMemoryAllocator.h b/Graphics/GraphicsAccessories/interface/SRBMemoryAllocator.h index 27a5c195..c5bf986e 100644 --- a/Graphics/GraphicsAccessories/interface/SRBMemoryAllocator.h +++ b/Graphics/GraphicsAccessories/interface/SRBMemoryAllocator.h @@ -38,9 +38,9 @@ public: {} ~SRBMemoryAllocator(); - - void Initialize(Uint32 SRBAllocationGranularity, - Uint32 ShaderVariableDataAllocatorCount, + + void Initialize(Uint32 SRBAllocationGranularity, + Uint32 ShaderVariableDataAllocatorCount, const size_t* const ShaderVariableDataSizes, Uint32 ResourceCacheDataAllocatorCount, const size_t* const ResourceCacheDataSizes); @@ -67,4 +67,4 @@ private: Uint32 m_ResourceCacheDataAllocatorCount = 0; }; -} +} // namespace Diligent diff --git a/Graphics/GraphicsAccessories/interface/VariableSizeAllocationsManager.h b/Graphics/GraphicsAccessories/interface/VariableSizeAllocationsManager.h index d8b94882..66e89a5c 100644 --- a/Graphics/GraphicsAccessories/interface/VariableSizeAllocationsManager.h +++ b/Graphics/GraphicsAccessories/interface/VariableSizeAllocationsManager.h @@ -36,372 +36,385 @@ namespace Diligent { - // The class handles free memory block management to accommodate variable-size allocation requests. - // It keeps track of free blocks only and does not record allocation sizes. The class uses two ordered maps - // to facilitate operations. The first map keeps blocks sorted by their offsets. The second multimap keeps blocks - // sorted by their sizes. The elements of the two maps reference each other, which enables efficient block - // insertion, removal and merging. - // - // 8 32 64 104 - // |<---16--->| |<-----24------>| |<---16--->| |<-----32----->| - // - // - // m_FreeBlocksBySize m_FreeBlocksByOffset - // size->offset offset->size - // - // 16 ------------------> 8 ----------> {size = 16, &m_FreeBlocksBySize[0]} - // - // 16 ------. .-------> 32 ----------> {size = 24, &m_FreeBlocksBySize[2]} - // '.' - // 24 -------' '--------> 64 ----------> {size = 16, &m_FreeBlocksBySize[1]} - // - // 32 ------------------> 104 ----------> {size = 32, &m_FreeBlocksBySize[3]} - // - class VariableSizeAllocationsManager +// The class handles free memory block management to accommodate variable-size allocation requests. +// It keeps track of free blocks only and does not record allocation sizes. The class uses two ordered maps +// to facilitate operations. The first map keeps blocks sorted by their offsets. The second multimap keeps blocks +// sorted by their sizes. The elements of the two maps reference each other, which enables efficient block +// insertion, removal and merging. +// +// 8 32 64 104 +// |<---16--->| |<-----24------>| |<---16--->| |<-----32----->| +// +// +// m_FreeBlocksBySize m_FreeBlocksByOffset +// size->offset offset->size +// +// 16 ------------------> 8 ----------> {size = 16, &m_FreeBlocksBySize[0]} +// +// 16 ------. .-------> 32 ----------> {size = 24, &m_FreeBlocksBySize[2]} +// '.' +// 24 -------' '--------> 64 ----------> {size = 16, &m_FreeBlocksBySize[1]} +// +// 32 ------------------> 104 ----------> {size = 32, &m_FreeBlocksBySize[3]} +// +class VariableSizeAllocationsManager +{ +public: + using OffsetType = size_t; + +private: + struct FreeBlockInfo; + + // Type of the map that keeps memory blocks sorted by their offsets + using TFreeBlocksByOffsetMap = + std::map, // Standard ordering + STDAllocatorRawMem> // Raw memory allocator + >; + + // Type of the map that keeps memory blocks sorted by their sizes + using TFreeBlocksBySizeMap = + std::multimap, // Standard ordering + STDAllocatorRawMem> // Raw memory allocator + >; + + struct FreeBlockInfo { - public: - using OffsetType = size_t; - - private: - struct FreeBlockInfo; - - // Type of the map that keeps memory blocks sorted by their offsets - using TFreeBlocksByOffsetMap = - std::map, // Standard ordering - STDAllocatorRawMem> // Raw memory allocator - >; - - // Type of the map that keeps memory blocks sorted by their sizes - using TFreeBlocksBySizeMap = - std::multimap, // Standard ordering - STDAllocatorRawMem> // Raw memory allocator - >; - - struct FreeBlockInfo - { - // Block size (no reserved space for the size of the allocation) - OffsetType Size; + // Block size (no reserved space for the size of the allocation) + OffsetType Size; - // Iterator referencing this block in the multimap sorted by the block size - TFreeBlocksBySizeMap::iterator OrderBySizeIt; + // Iterator referencing this block in the multimap sorted by the block size + TFreeBlocksBySizeMap::iterator OrderBySizeIt; - FreeBlockInfo(OffsetType _Size) : Size(_Size){} - }; + FreeBlockInfo(OffsetType _Size) : + Size(_Size) {} + }; - public: - VariableSizeAllocationsManager(OffsetType MaxSize, IMemoryAllocator &Allocator) : - m_FreeBlocksByOffset( STD_ALLOCATOR_RAW_MEM(TFreeBlocksByOffsetMap::value_type, Allocator, "Allocator for map") ), - m_FreeBlocksBySize( STD_ALLOCATOR_RAW_MEM(TFreeBlocksBySizeMap::value_type, Allocator, "Allocator for multimap") ), - m_MaxSize(MaxSize), - m_FreeSize(MaxSize) - { - // Insert single maximum-size block - AddNewBlock(0, m_MaxSize); - ResetCurrAlignment(); +public: + VariableSizeAllocationsManager(OffsetType MaxSize, IMemoryAllocator& Allocator) : + m_FreeBlocksByOffset(STD_ALLOCATOR_RAW_MEM(TFreeBlocksByOffsetMap::value_type, Allocator, "Allocator for map")), + m_FreeBlocksBySize(STD_ALLOCATOR_RAW_MEM(TFreeBlocksBySizeMap::value_type, Allocator, "Allocator for multimap")), + m_MaxSize(MaxSize), + m_FreeSize(MaxSize) + { + // Insert single maximum-size block + AddNewBlock(0, m_MaxSize); + ResetCurrAlignment(); #ifdef _DEBUG - DbgVerifyList(); + DbgVerifyList(); #endif - } + } - ~VariableSizeAllocationsManager() - { + ~VariableSizeAllocationsManager() + { #ifdef _DEBUG - if( !m_FreeBlocksByOffset.empty() || !m_FreeBlocksBySize.empty() ) - { - VERIFY(m_FreeBlocksByOffset.size() == 1, "Single free block is expected"); - VERIFY(m_FreeBlocksByOffset.begin()->first == 0, "Head chunk offset is expected to be 0"); - VERIFY(m_FreeBlocksByOffset.begin()->second.Size == m_MaxSize, "Head chunk size is expected to be ", m_MaxSize); - VERIFY_EXPR(m_FreeBlocksByOffset.begin()->second.OrderBySizeIt == m_FreeBlocksBySize.begin()); - VERIFY(m_FreeBlocksBySize.size() == m_FreeBlocksByOffset.size(), "Sizes of the two maps must be equal"); - - VERIFY(m_FreeBlocksBySize.size() == 1, "Single free block is expected"); - VERIFY(m_FreeBlocksBySize.begin()->first == m_MaxSize, "Head chunk size is expected to be ", m_MaxSize); - VERIFY(m_FreeBlocksBySize.begin()->second == m_FreeBlocksByOffset.begin(), "Incorrect first block"); - } + if (!m_FreeBlocksByOffset.empty() || !m_FreeBlocksBySize.empty()) + { + VERIFY(m_FreeBlocksByOffset.size() == 1, "Single free block is expected"); + VERIFY(m_FreeBlocksByOffset.begin()->first == 0, "Head chunk offset is expected to be 0"); + VERIFY(m_FreeBlocksByOffset.begin()->second.Size == m_MaxSize, "Head chunk size is expected to be ", m_MaxSize); + VERIFY_EXPR(m_FreeBlocksByOffset.begin()->second.OrderBySizeIt == m_FreeBlocksBySize.begin()); + VERIFY(m_FreeBlocksBySize.size() == m_FreeBlocksByOffset.size(), "Sizes of the two maps must be equal"); + + VERIFY(m_FreeBlocksBySize.size() == 1, "Single free block is expected"); + VERIFY(m_FreeBlocksBySize.begin()->first == m_MaxSize, "Head chunk size is expected to be ", m_MaxSize); + VERIFY(m_FreeBlocksBySize.begin()->second == m_FreeBlocksByOffset.begin(), "Incorrect first block"); + } #endif + } + + // clang-format off + VariableSizeAllocationsManager(VariableSizeAllocationsManager&& rhs) noexcept : + m_FreeBlocksByOffset {std::move(rhs.m_FreeBlocksByOffset)}, + m_FreeBlocksBySize {std::move(rhs.m_FreeBlocksBySize) }, + m_MaxSize {rhs.m_MaxSize }, + m_FreeSize {rhs.m_FreeSize }, + m_CurrAlignment {rhs.m_CurrAlignment} + { + // clang-format on + rhs.m_MaxSize = 0; + rhs.m_FreeSize = 0; + rhs.m_CurrAlignment = 0; + } + + // clang-format off + VariableSizeAllocationsManager& operator = (VariableSizeAllocationsManager&& rhs) = default; + VariableSizeAllocationsManager (const VariableSizeAllocationsManager&) = delete; + VariableSizeAllocationsManager& operator = (const VariableSizeAllocationsManager&) = delete; + // clang-format on + + // Offset returned by Allocate() may not be aligned, but the size of the allocation + // is sufficient to properly align it + struct Allocation + { + // clang-format off + Allocation(OffsetType offset, OffsetType size) : + UnalignedOffset{offset}, + Size {size } + {} + // clang-format on + + Allocation() {} + + static constexpr OffsetType InvalidOffset = static_cast(-1); + static Allocation InvalidAllocation() + { + return Allocation{InvalidOffset, 0}; } - VariableSizeAllocationsManager(VariableSizeAllocationsManager&& rhs)noexcept : - m_FreeBlocksByOffset (std::move(rhs.m_FreeBlocksByOffset)), - m_FreeBlocksBySize (std::move(rhs.m_FreeBlocksBySize)), - m_MaxSize (rhs.m_MaxSize), - m_FreeSize (rhs.m_FreeSize), - m_CurrAlignment (rhs.m_CurrAlignment) + bool IsValid() const { - rhs.m_MaxSize = 0; - rhs.m_FreeSize = 0; - rhs.m_CurrAlignment = 0; + return UnalignedOffset != InvalidAllocation().UnalignedOffset; } - VariableSizeAllocationsManager& operator = (VariableSizeAllocationsManager&& rhs) = default; - VariableSizeAllocationsManager (const VariableSizeAllocationsManager&) = delete; - VariableSizeAllocationsManager& operator = (const VariableSizeAllocationsManager&) = delete; + OffsetType UnalignedOffset = InvalidOffset; + OffsetType Size = 0; + }; - // Offset returned by Allocate() may not be aligned, but the size of the allocation - // is sufficient to properly align it - struct Allocation + Allocation Allocate(OffsetType Size, OffsetType Alignment) + { + VERIFY_EXPR(Size > 0); + VERIFY(IsPowerOfTwo(Alignment), "Alignment (", Alignment, ") must be power of 2"); + Size = Align(Size, Alignment); + if (m_FreeSize < Size) + return Allocation::InvalidAllocation(); + + auto AlignmentReserve = (Alignment > m_CurrAlignment) ? Alignment - m_CurrAlignment : 0; + // Get the first block that is large enough to encompass Size + AlignmentReserve bytes + // lower_bound() returns an iterator pointing to the first element that + // is not less (i.e. >= ) than key + auto SmallestBlockItIt = m_FreeBlocksBySize.lower_bound(Size + AlignmentReserve); + if (SmallestBlockItIt == m_FreeBlocksBySize.end()) + return Allocation::InvalidAllocation(); + + auto SmallestBlockIt = SmallestBlockItIt->second; + VERIFY_EXPR(Size + AlignmentReserve <= SmallestBlockIt->second.Size); + VERIFY_EXPR(SmallestBlockIt->second.Size == SmallestBlockItIt->first); + + // SmallestBlockIt.Offset + // | | + // |<------SmallestBlockIt.Size------>| + // |<------Size------>|<---NewSize--->| + // | | + // Offset NewOffset + // + auto Offset = SmallestBlockIt->first; + VERIFY_EXPR(Offset % m_CurrAlignment == 0); + auto AlignedOffset = Align(Offset, Alignment); + auto AdjustedSize = Size + (AlignedOffset - Offset); + VERIFY_EXPR(AdjustedSize <= Size + AlignmentReserve); + auto NewOffset = Offset + AdjustedSize; + auto NewSize = SmallestBlockIt->second.Size - AdjustedSize; + VERIFY_EXPR(SmallestBlockItIt == SmallestBlockIt->second.OrderBySizeIt); + m_FreeBlocksBySize.erase(SmallestBlockItIt); + m_FreeBlocksByOffset.erase(SmallestBlockIt); + if (NewSize > 0) { - Allocation(OffsetType offset, OffsetType size) : - UnalignedOffset(offset), - Size (size) - {} + AddNewBlock(NewOffset, NewSize); + } - Allocation(){} + m_FreeSize -= AdjustedSize; - static constexpr OffsetType InvalidOffset = static_cast(-1); - static Allocation InvalidAllocation() + if ((Size & (m_CurrAlignment - 1)) != 0) + { + if (IsPowerOfTwo(Size)) { - return Allocation { InvalidOffset, 0 }; + VERIFY_EXPR(Size >= Alignment && Size < m_CurrAlignment); + m_CurrAlignment = Size; } - - bool IsValid() const + else { - return UnalignedOffset != InvalidAllocation().UnalignedOffset; + m_CurrAlignment = std::min(m_CurrAlignment, Alignment); } + } - OffsetType UnalignedOffset = InvalidOffset; - OffsetType Size = 0; - }; - - Allocation Allocate(OffsetType Size, OffsetType Alignment) - { - VERIFY_EXPR(Size > 0); - VERIFY(IsPowerOfTwo(Alignment), "Alignment (", Alignment, ") must be power of 2"); - Size = Align(Size, Alignment); - if(m_FreeSize < Size) - return Allocation::InvalidAllocation(); - - auto AlignmentReserve = (Alignment > m_CurrAlignment) ? Alignment - m_CurrAlignment : 0; - // Get the first block that is large enough to encompass Size + AlignmentReserve bytes - // lower_bound() returns an iterator pointing to the first element that - // is not less (i.e. >= ) than key - auto SmallestBlockItIt = m_FreeBlocksBySize.lower_bound(Size + AlignmentReserve); - if(SmallestBlockItIt == m_FreeBlocksBySize.end()) - return Allocation::InvalidAllocation(); - - auto SmallestBlockIt = SmallestBlockItIt->second; - VERIFY_EXPR(Size + AlignmentReserve <= SmallestBlockIt->second.Size); - VERIFY_EXPR(SmallestBlockIt->second.Size == SmallestBlockItIt->first); - - // SmallestBlockIt.Offset - // | | - // |<------SmallestBlockIt.Size------>| - // |<------Size------>|<---NewSize--->| - // | | - // Offset NewOffset - // - auto Offset = SmallestBlockIt->first; - VERIFY_EXPR(Offset % m_CurrAlignment == 0); - auto AlignedOffset = Align(Offset, Alignment); - auto AdjustedSize = Size + (AlignedOffset - Offset); - VERIFY_EXPR(AdjustedSize <= Size + AlignmentReserve); - auto NewOffset = Offset + AdjustedSize; - auto NewSize = SmallestBlockIt->second.Size - AdjustedSize; - VERIFY_EXPR(SmallestBlockItIt == SmallestBlockIt->second.OrderBySizeIt); - m_FreeBlocksBySize.erase(SmallestBlockItIt); - m_FreeBlocksByOffset.erase(SmallestBlockIt); - if (NewSize > 0) - { - AddNewBlock(NewOffset, NewSize); - } +#ifdef _DEBUG + DbgVerifyList(); +#endif + return Allocation{Offset, AdjustedSize}; + } - m_FreeSize -= AdjustedSize; + void Free(Allocation&& allocation) + { + Free(allocation.UnalignedOffset, allocation.Size); + allocation = Allocation{}; + } - if ((Size & (m_CurrAlignment-1)) != 0) - { - if (IsPowerOfTwo(Size)) - { - VERIFY_EXPR(Size >= Alignment && Size < m_CurrAlignment); - m_CurrAlignment = Size; - } - else - { - m_CurrAlignment = std::min(m_CurrAlignment, Alignment); - } - } + void Free(OffsetType Offset, OffsetType Size) + { + VERIFY_EXPR(Offset + Size <= m_MaxSize); + // Find the first element whose offset is greater than the specified offset. + // upper_bound() returns an iterator pointing to the first element in the + // container whose key is considered to go after k. + auto NextBlockIt = m_FreeBlocksByOffset.upper_bound(Offset); #ifdef _DEBUG - DbgVerifyList(); -#endif - return Allocation{Offset, AdjustedSize}; + { + auto LowBnd = m_FreeBlocksByOffset.lower_bound(Offset); // First element whose offset is >= + // Since zero-size allocations are not allowed, lower bound must always be equal to the upper bound + VERIFY_EXPR(LowBnd == NextBlockIt); } - - void Free(Allocation&& allocation) +#endif + // Block being deallocated must not overlap with the next block + VERIFY_EXPR(NextBlockIt == m_FreeBlocksByOffset.end() || Offset + Size <= NextBlockIt->first); + auto PrevBlockIt = NextBlockIt; + if (PrevBlockIt != m_FreeBlocksByOffset.begin()) { - Free(allocation.UnalignedOffset, allocation.Size); - allocation = Allocation{}; + --PrevBlockIt; + // Block being deallocated must not overlap with the previous block + VERIFY_EXPR(Offset >= PrevBlockIt->first + PrevBlockIt->second.Size); } + else + PrevBlockIt = m_FreeBlocksByOffset.end(); - void Free(OffsetType Offset, OffsetType Size) + OffsetType NewSize, NewOffset; + if (PrevBlockIt != m_FreeBlocksByOffset.end() && Offset == PrevBlockIt->first + PrevBlockIt->second.Size) { - VERIFY_EXPR(Offset+Size <= m_MaxSize); - - // Find the first element whose offset is greater than the specified offset. - // upper_bound() returns an iterator pointing to the first element in the - // container whose key is considered to go after k. - auto NextBlockIt = m_FreeBlocksByOffset.upper_bound(Offset); -#ifdef _DEBUG - { - auto LowBnd = m_FreeBlocksByOffset.lower_bound(Offset); // First element whose offset is >= - // Since zero-size allocations are not allowed, lower bound must always be equal to the upper bound - VERIFY_EXPR(LowBnd == NextBlockIt); - } -#endif - // Block being deallocated must not overlap with the next block - VERIFY_EXPR(NextBlockIt == m_FreeBlocksByOffset.end() || Offset+Size <= NextBlockIt->first); - auto PrevBlockIt = NextBlockIt; - if(PrevBlockIt != m_FreeBlocksByOffset.begin()) - { - --PrevBlockIt; - // Block being deallocated must not overlap with the previous block - VERIFY_EXPR(Offset >= PrevBlockIt->first + PrevBlockIt->second.Size); - } - else - PrevBlockIt = m_FreeBlocksByOffset.end(); + // PrevBlock.Offset Offset + // | | + // |<-----PrevBlock.Size----->|<------Size-------->| + // + NewSize = PrevBlockIt->second.Size + Size; + NewOffset = PrevBlockIt->first; - OffsetType NewSize, NewOffset; - if(PrevBlockIt != m_FreeBlocksByOffset.end() && Offset == PrevBlockIt->first + PrevBlockIt->second.Size) + if (NextBlockIt != m_FreeBlocksByOffset.end() && Offset + Size == NextBlockIt->first) { - // PrevBlock.Offset Offset - // | | - // |<-----PrevBlock.Size----->|<------Size-------->| + // PrevBlock.Offset Offset NextBlock.Offset + // | | | + // |<-----PrevBlock.Size----->|<------Size-------->|<-----NextBlock.Size----->| // - NewSize = PrevBlockIt->second.Size + Size; - NewOffset = PrevBlockIt->first; - - if (NextBlockIt != m_FreeBlocksByOffset.end() && Offset + Size == NextBlockIt->first) - { - // PrevBlock.Offset Offset NextBlock.Offset - // | | | - // |<-----PrevBlock.Size----->|<------Size-------->|<-----NextBlock.Size----->| - // - NewSize += NextBlockIt->second.Size; - m_FreeBlocksBySize.erase(PrevBlockIt->second.OrderBySizeIt); - m_FreeBlocksBySize.erase(NextBlockIt->second.OrderBySizeIt); - // Delete the range of two blocks - ++NextBlockIt; - m_FreeBlocksByOffset.erase(PrevBlockIt, NextBlockIt); - } - else - { - // PrevBlock.Offset Offset NextBlock.Offset - // | | | - // |<-----PrevBlock.Size----->|<------Size-------->| ~ ~ ~ |<-----NextBlock.Size----->| - // - m_FreeBlocksBySize.erase(PrevBlockIt->second.OrderBySizeIt); - m_FreeBlocksByOffset.erase(PrevBlockIt); - } - } - else if (NextBlockIt != m_FreeBlocksByOffset.end() && Offset + Size == NextBlockIt->first) - { - // PrevBlock.Offset Offset NextBlock.Offset - // | | | - // |<-----PrevBlock.Size----->| ~ ~ ~ |<------Size-------->|<-----NextBlock.Size----->| - // - NewSize = Size + NextBlockIt->second.Size; - NewOffset = Offset; + NewSize += NextBlockIt->second.Size; + m_FreeBlocksBySize.erase(PrevBlockIt->second.OrderBySizeIt); m_FreeBlocksBySize.erase(NextBlockIt->second.OrderBySizeIt); - m_FreeBlocksByOffset.erase(NextBlockIt); + // Delete the range of two blocks + ++NextBlockIt; + m_FreeBlocksByOffset.erase(PrevBlockIt, NextBlockIt); } else { - // PrevBlock.Offset Offset NextBlock.Offset - // | | | - // |<-----PrevBlock.Size----->| ~ ~ ~ |<------Size-------->| ~ ~ ~ |<-----NextBlock.Size----->| + // PrevBlock.Offset Offset NextBlock.Offset + // | | | + // |<-----PrevBlock.Size----->|<------Size-------->| ~ ~ ~ |<-----NextBlock.Size----->| // - NewSize = Size; - NewOffset = Offset; + m_FreeBlocksBySize.erase(PrevBlockIt->second.OrderBySizeIt); + m_FreeBlocksByOffset.erase(PrevBlockIt); } + } + else if (NextBlockIt != m_FreeBlocksByOffset.end() && Offset + Size == NextBlockIt->first) + { + // PrevBlock.Offset Offset NextBlock.Offset + // | | | + // |<-----PrevBlock.Size----->| ~ ~ ~ |<------Size-------->|<-----NextBlock.Size----->| + // + NewSize = Size + NextBlockIt->second.Size; + NewOffset = Offset; + m_FreeBlocksBySize.erase(NextBlockIt->second.OrderBySizeIt); + m_FreeBlocksByOffset.erase(NextBlockIt); + } + else + { + // PrevBlock.Offset Offset NextBlock.Offset + // | | | + // |<-----PrevBlock.Size----->| ~ ~ ~ |<------Size-------->| ~ ~ ~ |<-----NextBlock.Size----->| + // + NewSize = Size; + NewOffset = Offset; + } - AddNewBlock(NewOffset, NewSize); + AddNewBlock(NewOffset, NewSize); - m_FreeSize += Size; - if(IsEmpty()) - { - // Reset current alignment - VERIFY_EXPR(DbgGetNumFreeBlocks() == 1); - ResetCurrAlignment(); - } + m_FreeSize += Size; + if (IsEmpty()) + { + // Reset current alignment + VERIFY_EXPR(DbgGetNumFreeBlocks() == 1); + ResetCurrAlignment(); + } #ifdef _DEBUG - DbgVerifyList(); + DbgVerifyList(); #endif - } + } - bool IsFull() const{ return m_FreeSize==0; }; - bool IsEmpty()const{ return m_FreeSize==m_MaxSize; }; - OffsetType GetMaxSize() const{return m_MaxSize;} - OffsetType GetFreeSize()const{return m_FreeSize;} - OffsetType GetUsedSize()const{return m_MaxSize - m_FreeSize;} + // clang-format off + bool IsFull() const{ return m_FreeSize==0; }; + bool IsEmpty()const{ return m_FreeSize==m_MaxSize; }; + OffsetType GetMaxSize() const{return m_MaxSize;} + OffsetType GetFreeSize()const{return m_FreeSize;} + OffsetType GetUsedSize()const{return m_MaxSize - m_FreeSize;} + // clang-format on #ifdef _DEBUG - size_t DbgGetNumFreeBlocks()const{return m_FreeBlocksByOffset.size();} + size_t DbgGetNumFreeBlocks() const + { + return m_FreeBlocksByOffset.size(); + } #endif - private: - void AddNewBlock(OffsetType Offset, OffsetType Size) - { - auto NewBlockIt = m_FreeBlocksByOffset.emplace(Offset, Size); - VERIFY_EXPR(NewBlockIt.second); - auto OrderIt = m_FreeBlocksBySize.emplace(Size, NewBlockIt.first); - NewBlockIt.first->second.OrderBySizeIt = OrderIt; - } +private: + void AddNewBlock(OffsetType Offset, OffsetType Size) + { + auto NewBlockIt = m_FreeBlocksByOffset.emplace(Offset, Size); + VERIFY_EXPR(NewBlockIt.second); + auto OrderIt = m_FreeBlocksBySize.emplace(Size, NewBlockIt.first); + NewBlockIt.first->second.OrderBySizeIt = OrderIt; + } - void ResetCurrAlignment() - { - for(m_CurrAlignment = 1; m_CurrAlignment*2 <= m_MaxSize; m_CurrAlignment *= 2); - } + void ResetCurrAlignment() + { + for (m_CurrAlignment = 1; m_CurrAlignment * 2 <= m_MaxSize; m_CurrAlignment *= 2) + {} + } #ifdef _DEBUG - void DbgVerifyList() - { - OffsetType TotalFreeSize = 0; - - VERIFY_EXPR(IsPowerOfTwo(m_CurrAlignment)); - auto BlockIt = m_FreeBlocksByOffset.begin(); - auto PrevBlockIt = m_FreeBlocksByOffset.end(); - VERIFY_EXPR(m_FreeBlocksByOffset.size() == m_FreeBlocksBySize.size()); - while (BlockIt != m_FreeBlocksByOffset.end()) - { - VERIFY_EXPR(BlockIt->first >= 0 && BlockIt->first + BlockIt->second.Size <= m_MaxSize); - VERIFY( (BlockIt->first & (m_CurrAlignment-1)) == 0, "Block offset (", BlockIt->first, ") is not ", m_CurrAlignment, "-aligned" ); - if (BlockIt->first + BlockIt->second.Size < m_MaxSize) - VERIFY( (BlockIt->second.Size & (m_CurrAlignment-1)) == 0, "All block sizes except for the last one must be ", m_CurrAlignment, "-aligned" ); - VERIFY_EXPR(BlockIt == BlockIt->second.OrderBySizeIt->second); - VERIFY_EXPR(BlockIt->second.Size == BlockIt->second.OrderBySizeIt->first); - // PrevBlock.Offset BlockIt.first - // | | - // ~ ~ |<-----PrevBlock.Size----->| ~ ~ ~ |<------Size-------->| ~ ~ ~ - // - VERIFY(PrevBlockIt == m_FreeBlocksByOffset.end() || BlockIt->first > PrevBlockIt->first + PrevBlockIt->second.Size, "Unmerged adjacent or overlapping blocks detected" ); - TotalFreeSize += BlockIt->second.Size; + void DbgVerifyList() + { + OffsetType TotalFreeSize = 0; - PrevBlockIt = BlockIt; - ++BlockIt; - } + VERIFY_EXPR(IsPowerOfTwo(m_CurrAlignment)); + auto BlockIt = m_FreeBlocksByOffset.begin(); + auto PrevBlockIt = m_FreeBlocksByOffset.end(); + VERIFY_EXPR(m_FreeBlocksByOffset.size() == m_FreeBlocksBySize.size()); + while (BlockIt != m_FreeBlocksByOffset.end()) + { + VERIFY_EXPR(BlockIt->first >= 0 && BlockIt->first + BlockIt->second.Size <= m_MaxSize); + VERIFY((BlockIt->first & (m_CurrAlignment - 1)) == 0, "Block offset (", BlockIt->first, ") is not ", m_CurrAlignment, "-aligned"); + if (BlockIt->first + BlockIt->second.Size < m_MaxSize) + VERIFY((BlockIt->second.Size & (m_CurrAlignment - 1)) == 0, "All block sizes except for the last one must be ", m_CurrAlignment, "-aligned"); + VERIFY_EXPR(BlockIt == BlockIt->second.OrderBySizeIt->second); + VERIFY_EXPR(BlockIt->second.Size == BlockIt->second.OrderBySizeIt->first); + // PrevBlock.Offset BlockIt.first + // | | + // ~ ~ |<-----PrevBlock.Size----->| ~ ~ ~ |<------Size-------->| ~ ~ ~ + // + VERIFY(PrevBlockIt == m_FreeBlocksByOffset.end() || BlockIt->first > PrevBlockIt->first + PrevBlockIt->second.Size, "Unmerged adjacent or overlapping blocks detected"); + TotalFreeSize += BlockIt->second.Size; - auto OrderIt = m_FreeBlocksBySize.begin(); - while (OrderIt != m_FreeBlocksBySize.end()) - { - VERIFY_EXPR(OrderIt->first == OrderIt->second->second.Size); - ++OrderIt; - } + PrevBlockIt = BlockIt; + ++BlockIt; + } - VERIFY_EXPR(TotalFreeSize == m_FreeSize); + auto OrderIt = m_FreeBlocksBySize.begin(); + while (OrderIt != m_FreeBlocksBySize.end()) + { + VERIFY_EXPR(OrderIt->first == OrderIt->second->second.Size); + ++OrderIt; } + + VERIFY_EXPR(TotalFreeSize == m_FreeSize); + } #endif - TFreeBlocksByOffsetMap m_FreeBlocksByOffset; - TFreeBlocksBySizeMap m_FreeBlocksBySize; - - OffsetType m_MaxSize = 0; - OffsetType m_FreeSize = 0; - OffsetType m_CurrAlignment = 0; - // When adding new members, do not forget to update move ctor - }; -} + TFreeBlocksByOffsetMap m_FreeBlocksByOffset; + TFreeBlocksBySizeMap m_FreeBlocksBySize; + + OffsetType m_MaxSize = 0; + OffsetType m_FreeSize = 0; + OffsetType m_CurrAlignment = 0; + // When adding new members, do not forget to update move ctor +}; +} // namespace Diligent diff --git a/Graphics/GraphicsAccessories/interface/VariableSizeGPUAllocationsManager.h b/Graphics/GraphicsAccessories/interface/VariableSizeGPUAllocationsManager.h index 7e4c0925..52d7802b 100644 --- a/Graphics/GraphicsAccessories/interface/VariableSizeGPUAllocationsManager.h +++ b/Graphics/GraphicsAccessories/interface/VariableSizeGPUAllocationsManager.h @@ -32,80 +32,82 @@ namespace Diligent { - // Class extends basic variable-size memory block allocator by deferring deallocation - // of freed blocks untill the corresponding frame is completed - class VariableSizeGPUAllocationsManager : public VariableSizeAllocationsManager +// Class extends basic variable-size memory block allocator by deferring deallocation +// of freed blocks untill the corresponding frame is completed +class VariableSizeGPUAllocationsManager : public VariableSizeAllocationsManager +{ +private: + struct StaleAllocationAttribs { - private: - struct StaleAllocationAttribs - { - OffsetType Offset; - OffsetType Size; - Uint64 FenceValue; - StaleAllocationAttribs(OffsetType _Offset, OffsetType _Size, Uint64 _FenceValue) : - Offset(_Offset), Size(_Size), FenceValue(_FenceValue) - {} - }; - - public: - VariableSizeGPUAllocationsManager(OffsetType MaxSize, IMemoryAllocator &Allocator) : - VariableSizeAllocationsManager(MaxSize, Allocator), - m_StaleAllocations(0, StaleAllocationAttribs(0,0,0), STD_ALLOCATOR_RAW_MEM(StaleAllocationAttribs, Allocator, "Allocator for deque" )) + OffsetType Offset; + OffsetType Size; + Uint64 FenceValue; + StaleAllocationAttribs(OffsetType _Offset, OffsetType _Size, Uint64 _FenceValue) : + Offset{_Offset}, Size{_Size}, FenceValue{_FenceValue} {} + }; - ~VariableSizeGPUAllocationsManager() - { - VERIFY(m_StaleAllocations.empty(), "Not all stale allocations released"); - VERIFY(m_StaleAllocationsSize == 0, "Not all stale allocations released"); - } +public: + VariableSizeGPUAllocationsManager(OffsetType MaxSize, IMemoryAllocator& Allocator) : + VariableSizeAllocationsManager{MaxSize, Allocator}, + m_StaleAllocations{0, StaleAllocationAttribs(0, 0, 0), STD_ALLOCATOR_RAW_MEM(StaleAllocationAttribs, Allocator, "Allocator for deque")} + {} - // = default causes compiler error when instantiating std::vector::emplace_back() in Visual Studio 2015 (Version 14.0.23107.0 D14REL) - VariableSizeGPUAllocationsManager(VariableSizeGPUAllocationsManager&& rhs) noexcept : - VariableSizeAllocationsManager(std::move(rhs)), - m_StaleAllocations(std::move(rhs.m_StaleAllocations)), - m_StaleAllocationsSize(rhs.m_StaleAllocationsSize) - { - rhs.m_StaleAllocationsSize = 0; - } + ~VariableSizeGPUAllocationsManager() + { + VERIFY(m_StaleAllocations.empty(), "Not all stale allocations released"); + VERIFY(m_StaleAllocationsSize == 0, "Not all stale allocations released"); + } - VariableSizeGPUAllocationsManager& operator = (VariableSizeGPUAllocationsManager&& rhs) = delete; - VariableSizeGPUAllocationsManager(const VariableSizeGPUAllocationsManager&) = delete; - VariableSizeGPUAllocationsManager& operator = (const VariableSizeGPUAllocationsManager&) = delete; + // = default causes compiler error when instantiating std::vector::emplace_back() in Visual Studio 2015 (Version 14.0.23107.0 D14REL) + VariableSizeGPUAllocationsManager(VariableSizeGPUAllocationsManager&& rhs) noexcept : + VariableSizeAllocationsManager(std::move(rhs)), + m_StaleAllocations(std::move(rhs.m_StaleAllocations)), + m_StaleAllocationsSize(rhs.m_StaleAllocationsSize) + { + rhs.m_StaleAllocationsSize = 0; + } - void Free(VariableSizeAllocationsManager::Allocation&& allocation, Uint64 FenceValue) - { - Free(allocation.UnalignedOffset, allocation.Size, FenceValue); - allocation = VariableSizeAllocationsManager::Allocation{}; - } + // clang-format off + VariableSizeGPUAllocationsManager& operator = (VariableSizeGPUAllocationsManager&& rhs) = delete; + VariableSizeGPUAllocationsManager(const VariableSizeGPUAllocationsManager&) = delete; + VariableSizeGPUAllocationsManager& operator = (const VariableSizeGPUAllocationsManager&) = delete; + // clang-format on - void Free(OffsetType Offset, OffsetType Size, Uint64 FenceValue) - { - // Do not release the block immediately, but add - // it to the queue instead - m_StaleAllocations.emplace_back(Offset, Size, FenceValue); - m_StaleAllocationsSize += Size; - } + void Free(VariableSizeAllocationsManager::Allocation&& allocation, Uint64 FenceValue) + { + Free(allocation.UnalignedOffset, allocation.Size, FenceValue); + allocation = VariableSizeAllocationsManager::Allocation{}; + } - // Releases stale allocation from completed command lists - // The method takes the last known completed fence value N - // and releases all allocations whose associated fence value - // is at most N (n <= N) - void ReleaseStaleAllocations(Uint64 LastCompletedFenceValue) + void Free(OffsetType Offset, OffsetType Size, Uint64 FenceValue) + { + // Do not release the block immediately, but add + // it to the queue instead + m_StaleAllocations.emplace_back(Offset, Size, FenceValue); + m_StaleAllocationsSize += Size; + } + + // Releases stale allocation from completed command lists + // The method takes the last known completed fence value N + // and releases all allocations whose associated fence value + // is at most N (n <= N) + void ReleaseStaleAllocations(Uint64 LastCompletedFenceValue) + { + // Free all allocations from the beginning of the queue that belong to completed command lists + while (!m_StaleAllocations.empty() && m_StaleAllocations.front().FenceValue <= LastCompletedFenceValue) { - // Free all allocations from the beginning of the queue that belong to completed command lists - while(!m_StaleAllocations.empty() && m_StaleAllocations.front().FenceValue <= LastCompletedFenceValue) - { - auto &OldestAllocation = m_StaleAllocations.front(); - VariableSizeAllocationsManager::Free(OldestAllocation.Offset, OldestAllocation.Size); - m_StaleAllocationsSize -= OldestAllocation.Size; - m_StaleAllocations.pop_front(); - } + auto& OldestAllocation = m_StaleAllocations.front(); + VariableSizeAllocationsManager::Free(OldestAllocation.Offset, OldestAllocation.Size); + m_StaleAllocationsSize -= OldestAllocation.Size; + m_StaleAllocations.pop_front(); } + } - size_t GetStaleAllocationsSize()const { return m_StaleAllocationsSize; } + size_t GetStaleAllocationsSize() const { return m_StaleAllocationsSize; } - private: - std::deque< StaleAllocationAttribs, STDAllocatorRawMem > m_StaleAllocations; - size_t m_StaleAllocationsSize = 0; - }; -} +private: + std::deque> m_StaleAllocations; + size_t m_StaleAllocationsSize = 0; +}; +} // namespace Diligent diff --git a/Graphics/GraphicsAccessories/src/ColorConversion.cpp b/Graphics/GraphicsAccessories/src/ColorConversion.cpp index 8eb44e24..ca26fde6 100644 --- a/Graphics/GraphicsAccessories/src/ColorConversion.cpp +++ b/Graphics/GraphicsAccessories/src/ColorConversion.cpp @@ -36,7 +36,7 @@ class LinearToSRGBMap public: LinearToSRGBMap() noexcept { - for (Uint32 i=0; i < m_ToSRBG.size(); ++i) + for (Uint32 i = 0; i < m_ToSRBG.size(); ++i) { m_ToSRBG[i] = LinearToSRGB(static_cast(i) / 255.f); } @@ -56,7 +56,7 @@ class SRGBToLinearMap public: SRGBToLinearMap() noexcept { - for (Uint32 i=0; i < m_ToLinear.size(); ++i) + for (Uint32 i = 0; i < m_ToLinear.size(); ++i) { m_ToLinear[i] = SRGBToLinear(static_cast(i) / 255.f); } diff --git a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp index d0e671cd..1d6ebe81 100644 --- a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp +++ b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp @@ -30,12 +30,13 @@ namespace Diligent { -const Char* GetValueTypeString( VALUE_TYPE Val ) +const Char* GetValueTypeString(VALUE_TYPE Val) { static const Char* ValueTypeStrings[VT_NUM_TYPES] = {}; - static bool bIsInit = false; - if( !bIsInit ) + static bool bIsInit = false; + if (!bIsInit) { + // clang-format off #define INIT_VALUE_TYPE_STR( ValType ) ValueTypeStrings[ValType] = #ValType INIT_VALUE_TYPE_STR( VT_UNDEFINED ); INIT_VALUE_TYPE_STR( VT_INT8 ); @@ -47,17 +48,18 @@ const Char* GetValueTypeString( VALUE_TYPE Val ) INIT_VALUE_TYPE_STR( VT_FLOAT16 ); INIT_VALUE_TYPE_STR( VT_FLOAT32 ); #undef INIT_VALUE_TYPE_STR + // clang-format on static_assert(VT_NUM_TYPES == VT_FLOAT32 + 1, "Not all value type strings initialized."); bIsInit = true; } - if( Val >= VT_UNDEFINED && Val < VT_NUM_TYPES ) + if (Val >= VT_UNDEFINED && Val < VT_NUM_TYPES) { return ValueTypeStrings[Val]; } else { - UNEXPECTED( "Incorrect value type (", Val, ")" ); + UNEXPECTED("Incorrect value type (", Val, ")"); return "unknown value type"; } } @@ -67,6 +69,7 @@ class TexFormatToViewFormatConverter public: TexFormatToViewFormatConverter() { + // clang-format off static_assert(TEXTURE_VIEW_SHADER_RESOURCE == 1, "TEXTURE_VIEW_SHADER_RESOURCE == 1 expected"); static_assert(TEXTURE_VIEW_RENDER_TARGET == 2, "TEXTURE_VIEW_RENDER_TARGET == 2 expected"); static_assert(TEXTURE_VIEW_DEPTH_STENCIL == 3, "TEXTURE_VIEW_DEPTH_STENCIL == 3 expected"); @@ -200,6 +203,7 @@ public: INIT_TEX_VIEW_FORMAT_INFO( TEX_FORMAT_BC7_UNORM, BC7_UNORM, UNKNOWN, UNKNOWN, UNKNOWN); INIT_TEX_VIEW_FORMAT_INFO( TEX_FORMAT_BC7_UNORM_SRGB, BC7_UNORM_SRGB, UNKNOWN, UNKNOWN, UNKNOWN); #undef INIT_TVIEW_FORMAT_INFO + // clang-format on } TEXTURE_FORMAT GetViewFormat(TEXTURE_FORMAT Format, TEXTURE_VIEW_TYPE ViewType, Uint32 BindFlags) @@ -212,23 +216,24 @@ public: { if (BindFlags & BIND_DEPTH_STENCIL) { + // clang-format off static TEXTURE_FORMAT D16_ViewFmts[] = { TEX_FORMAT_R16_UNORM, TEX_FORMAT_R16_UNORM, TEX_FORMAT_D16_UNORM, TEX_FORMAT_R16_UNORM }; + // clang-format on return D16_ViewFmts[ViewType - 1]; } } - default: /*do nothing*/break; + default: /*do nothing*/ break; } - return m_ViewFormats[Format][ViewType-1]; + return m_ViewFormats[Format][ViewType - 1]; } private: - - TEXTURE_FORMAT m_ViewFormats[TEX_FORMAT_NUM_FORMATS][TEXTURE_VIEW_NUM_VIEWS-1]; + TEXTURE_FORMAT m_ViewFormats[TEX_FORMAT_NUM_FORMATS][TEXTURE_VIEW_NUM_VIEWS - 1]; }; TEXTURE_FORMAT GetDefaultTextureViewFormat(TEXTURE_FORMAT TextureFormat, TEXTURE_VIEW_TYPE ViewType, Uint32 BindFlags) @@ -237,16 +242,17 @@ TEXTURE_FORMAT GetDefaultTextureViewFormat(TEXTURE_FORMAT TextureFormat, TEXTURE return FmtConverter.GetViewFormat(TextureFormat, ViewType, BindFlags); } -const TextureFormatAttribs& GetTextureFormatAttribs( TEXTURE_FORMAT Format ) +const TextureFormatAttribs& GetTextureFormatAttribs(TEXTURE_FORMAT Format) { static TextureFormatAttribs FmtAttribs[TEX_FORMAT_NUM_FORMATS]; - static bool bIsInit = false; + static bool bIsInit = false; // Note that this implementation is thread-safe // Even if two threads try to call the function at the same time, // the worst thing that might happen is that the array will be // initialized multiple times. But the result will always be correct. - if( !bIsInit ) + if (!bIsInit) { + // clang-format off #define INIT_TEX_FORMAT_INFO(TexFmt, ComponentSize, NumComponents, ComponentType, IsTypeless, BlockWidth, BlockHeight) \ FmtAttribs[ TexFmt ] = TextureFormatAttribs(#TexFmt, TexFmt, ComponentSize, NumComponents, ComponentType, IsTypeless, BlockWidth, BlockHeight); @@ -369,40 +375,42 @@ const TextureFormatAttribs& GetTextureFormatAttribs( TEXTURE_FORMAT Format ) INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC7_UNORM, 16, 4, COMPONENT_TYPE_COMPRESSED, false, 4,4); INIT_TEX_FORMAT_INFO( TEX_FORMAT_BC7_UNORM_SRGB, 16, 4, COMPONENT_TYPE_COMPRESSED, false, 4,4); #undef INIT_TEX_FORMAT_INFO + // clang-format on static_assert(TEX_FORMAT_NUM_FORMATS == TEX_FORMAT_BC7_UNORM_SRGB + 1, "Not all texture formats initialized."); #ifdef _DEBUG - for( Uint32 Fmt = TEX_FORMAT_UNKNOWN; Fmt < TEX_FORMAT_NUM_FORMATS; ++Fmt ) + for (Uint32 Fmt = TEX_FORMAT_UNKNOWN; Fmt < TEX_FORMAT_NUM_FORMATS; ++Fmt) VERIFY(FmtAttribs[Fmt].Format == static_cast(Fmt), "Uninitialized format"); #endif bIsInit = true; } - if( Format >= TEX_FORMAT_UNKNOWN && Format < TEX_FORMAT_NUM_FORMATS ) + if (Format >= TEX_FORMAT_UNKNOWN && Format < TEX_FORMAT_NUM_FORMATS) { - const auto &Attribs = FmtAttribs[Format]; - VERIFY( Attribs.Format == Format, "Unexpected format" ); + const auto& Attribs = FmtAttribs[Format]; + VERIFY(Attribs.Format == Format, "Unexpected format"); return Attribs; } else { - UNEXPECTED( "Texture format (", int{Format}, ") is out of allowed range [0, ", int{TEX_FORMAT_NUM_FORMATS}-1, "]" ); + UNEXPECTED("Texture format (", int{Format}, ") is out of allowed range [0, ", int{TEX_FORMAT_NUM_FORMATS} - 1, "]"); return FmtAttribs[0]; } } -const Char* GetTexViewTypeLiteralName( TEXTURE_VIEW_TYPE ViewType ) +const Char* GetTexViewTypeLiteralName(TEXTURE_VIEW_TYPE ViewType) { static const Char* TexViewLiteralNames[TEXTURE_VIEW_NUM_VIEWS] = {}; - static bool bIsInit = false; + static bool bIsInit = false; // Note that this implementation is thread-safe // Even if two threads try to call the function at the same time, // the worst thing that might happen is that the array will be // initialized multiple times. But the result will always be correct. - if( !bIsInit ) + if (!bIsInit) { + // clang-format off #define INIT_TEX_VIEW_TYPE_NAME(ViewType)TexViewLiteralNames[ViewType] = #ViewType INIT_TEX_VIEW_TYPE_NAME( TEXTURE_VIEW_UNDEFINED ); INIT_TEX_VIEW_TYPE_NAME( TEXTURE_VIEW_SHADER_RESOURCE ); @@ -410,57 +418,61 @@ const Char* GetTexViewTypeLiteralName( TEXTURE_VIEW_TYPE ViewType ) INIT_TEX_VIEW_TYPE_NAME( TEXTURE_VIEW_DEPTH_STENCIL ); INIT_TEX_VIEW_TYPE_NAME( TEXTURE_VIEW_UNORDERED_ACCESS ); #undef INIT_TEX_VIEW_TYPE_NAME + // clang-format on static_assert(TEXTURE_VIEW_NUM_VIEWS == TEXTURE_VIEW_UNORDERED_ACCESS + 1, "Not all texture views names initialized."); bIsInit = true; } - if( ViewType >= TEXTURE_VIEW_UNDEFINED && ViewType < TEXTURE_VIEW_NUM_VIEWS ) + if (ViewType >= TEXTURE_VIEW_UNDEFINED && ViewType < TEXTURE_VIEW_NUM_VIEWS) { return TexViewLiteralNames[ViewType]; } else { - UNEXPECTED("Texture view type (", ViewType, ") is out of allowed range [0, ", TEXTURE_VIEW_NUM_VIEWS-1, "]" ); + UNEXPECTED("Texture view type (", ViewType, ") is out of allowed range [0, ", TEXTURE_VIEW_NUM_VIEWS - 1, "]"); return ""; } } -const Char* GetBufferViewTypeLiteralName( BUFFER_VIEW_TYPE ViewType ) +const Char* GetBufferViewTypeLiteralName(BUFFER_VIEW_TYPE ViewType) { static const Char* BuffViewLiteralNames[BUFFER_VIEW_NUM_VIEWS] = {}; - static bool bIsInit = false; + static bool bIsInit = false; // Note that this implementation is thread-safe // Even if two threads try to call the function at the same time, // the worst thing that might happen is that the array will be // initialized multiple times. But the result will always be correct. - if( !bIsInit ) + if (!bIsInit) { + // clang-format off #define INIT_BUFF_VIEW_TYPE_NAME(ViewType)BuffViewLiteralNames[ViewType] = #ViewType INIT_BUFF_VIEW_TYPE_NAME( BUFFER_VIEW_UNDEFINED ); INIT_BUFF_VIEW_TYPE_NAME( BUFFER_VIEW_SHADER_RESOURCE ); INIT_BUFF_VIEW_TYPE_NAME( BUFFER_VIEW_UNORDERED_ACCESS ); #undef INIT_BUFF_VIEW_TYPE_NAME + // clang-format on static_assert(BUFFER_VIEW_NUM_VIEWS == BUFFER_VIEW_UNORDERED_ACCESS + 1, "Not all buffer views names initialized."); bIsInit = true; } - if( ViewType >= BUFFER_VIEW_UNDEFINED && ViewType < BUFFER_VIEW_NUM_VIEWS ) + if (ViewType >= BUFFER_VIEW_UNDEFINED && ViewType < BUFFER_VIEW_NUM_VIEWS) { return BuffViewLiteralNames[ViewType]; } else { - UNEXPECTED( "Buffer view type (", ViewType, ") is out of allowed range [0, ", BUFFER_VIEW_NUM_VIEWS-1, "]" ); + UNEXPECTED("Buffer view type (", ViewType, ") is out of allowed range [0, ", BUFFER_VIEW_NUM_VIEWS - 1, "]"); return ""; } } -const Char* GetShaderTypeLiteralName( SHADER_TYPE ShaderType ) +const Char* GetShaderTypeLiteralName(SHADER_TYPE ShaderType) { - switch( ShaderType ) + switch (ShaderType) { + // clang-format off #define RETURN_SHADER_TYPE_NAME(ShaderType)\ case ShaderType: return #ShaderType; @@ -472,26 +484,26 @@ const Char* GetShaderTypeLiteralName( SHADER_TYPE ShaderType ) RETURN_SHADER_TYPE_NAME( SHADER_TYPE_DOMAIN ) RETURN_SHADER_TYPE_NAME( SHADER_TYPE_COMPUTE ) #undef RETURN_SHADER_TYPE_NAME + // clang-format on - default: UNEXPECTED( "Unknown shader type constant ", Uint32{ShaderType} ); return ""; + default: UNEXPECTED("Unknown shader type constant ", Uint32{ShaderType}); return ""; } } String GetShaderStagesString(SHADER_TYPE ShaderStages) { String StagesStr; - while(ShaderStages != 0) - for( Uint32 Stage = SHADER_TYPE_VERTEX; ShaderStages != 0 && Stage <= SHADER_TYPE_COMPUTE; Stage <<= 1 ) + for (Uint32 Stage = SHADER_TYPE_VERTEX; ShaderStages != 0 && Stage <= SHADER_TYPE_COMPUTE; Stage <<= 1) { - if( ShaderStages&Stage ) + if (ShaderStages & Stage) { - if( StagesStr.length() ) + if (StagesStr.length()) StagesStr += ", "; - StagesStr += GetShaderTypeLiteralName( static_cast(Stage)); + StagesStr += GetShaderTypeLiteralName(static_cast(Stage)); ShaderStages &= ~static_cast(Stage); } } - VERIFY_EXPR( ShaderStages == 0); + VERIFY_EXPR(ShaderStages == 0); return StagesStr; } @@ -499,21 +511,21 @@ const Char* GetShaderVariableTypeLiteralName(SHADER_RESOURCE_VARIABLE_TYPE VarTy { static const Char* ShortVarTypeNameStrings[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; static const Char* FullVarTypeNameStrings[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; - static bool bVarTypeStrsInit = false; - if( !bVarTypeStrsInit ) + static bool bVarTypeStrsInit = false; + if (!bVarTypeStrsInit) { ShortVarTypeNameStrings[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] = "static"; ShortVarTypeNameStrings[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] = "mutable"; ShortVarTypeNameStrings[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] = "dynamic"; - FullVarTypeNameStrings[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] = "SHADER_RESOURCE_VARIABLE_TYPE_STATIC"; - FullVarTypeNameStrings[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] = "SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE"; - FullVarTypeNameStrings[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] = "SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC"; + FullVarTypeNameStrings[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] = "SHADER_RESOURCE_VARIABLE_TYPE_STATIC"; + FullVarTypeNameStrings[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] = "SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE"; + FullVarTypeNameStrings[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] = "SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC"; static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC + 1, "Not all shader variable types initialized."); bVarTypeStrsInit = true; } - if( VarType >= SHADER_RESOURCE_VARIABLE_TYPE_STATIC && VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES ) + if (VarType >= SHADER_RESOURCE_VARIABLE_TYPE_STATIC && VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES) return (bGetFullName ? FullVarTypeNameStrings : ShortVarTypeNameStrings)[VarType]; else { @@ -525,8 +537,9 @@ const Char* GetShaderVariableTypeLiteralName(SHADER_RESOURCE_VARIABLE_TYPE VarTy const Char* GetShaderResourceTypeLiteralName(SHADER_RESOURCE_TYPE ResourceType, bool bGetFullName) { - switch(ResourceType) + switch (ResourceType) { + // clang-format off case SHADER_RESOURCE_TYPE_UNKNOWN: return bGetFullName ? "SHADER_RESOURCE_TYPE_UNKNOWN" : "unknown"; case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER: return bGetFullName ? "SHADER_RESOURCE_TYPE_CONSTANT_BUFFER" : "constant buffer"; case SHADER_RESOURCE_TYPE_TEXTURE_SRV: return bGetFullName ? "SHADER_RESOURCE_TYPE_TEXTURE_SRV" : "texture SRV"; @@ -534,6 +547,7 @@ const Char* GetShaderResourceTypeLiteralName(SHADER_RESOURCE_TYPE ResourceType, case SHADER_RESOURCE_TYPE_TEXTURE_UAV: return bGetFullName ? "SHADER_RESOURCE_TYPE_TEXTURE_UAV" : "texture UAV"; case SHADER_RESOURCE_TYPE_BUFFER_UAV: return bGetFullName ? "SHADER_RESOURCE_TYPE_BUFFER_UAV" : "buffer UAV"; case SHADER_RESOURCE_TYPE_SAMPLER: return bGetFullName ? "SHADER_RESOURCE_TYPE_SAMPLER" : "sampler"; + // clang-format on default: UNEXPECTED("Unexepcted resource type (", Uint32{ResourceType}, ")"); return "UNKNOWN"; @@ -542,12 +556,12 @@ const Char* GetShaderResourceTypeLiteralName(SHADER_RESOURCE_TYPE ResourceType, const Char* GetMapTypeString(MAP_TYPE MapType) { - switch(MapType) + switch (MapType) { - case MAP_READ: return "MAP_READ"; - case MAP_WRITE: return "MAP_WRITE"; + case MAP_READ: return "MAP_READ"; + case MAP_WRITE: return "MAP_WRITE"; case MAP_READ_WRITE: return "MAP_READ_WRITE"; - + default: UNEXPECTED("Unexpected map type"); return "Unknown map type"; @@ -555,21 +569,23 @@ const Char* GetMapTypeString(MAP_TYPE MapType) } /// Returns the string containing the usage -const Char* GetUsageString( USAGE Usage ) +const Char* GetUsageString(USAGE Usage) { static const Char* UsageStrings[4]; - static bool bUsageStringsInit = false; - if( !bUsageStringsInit ) + static bool bUsageStringsInit = false; + if (!bUsageStringsInit) { + // clang-format off #define INIT_USGAGE_STR(Usage)UsageStrings[Usage] = #Usage INIT_USGAGE_STR( USAGE_STATIC ); INIT_USGAGE_STR( USAGE_DEFAULT ); INIT_USGAGE_STR( USAGE_DYNAMIC ); INIT_USGAGE_STR( USAGE_STAGING ); #undef INIT_USGAGE_STR + // clang-format on bUsageStringsInit = true; } - if( Usage >= USAGE_STATIC && Usage <= USAGE_STAGING ) + if (Usage >= USAGE_STATIC && Usage <= USAGE_STAGING) return UsageStrings[Usage]; else { @@ -578,11 +594,11 @@ const Char* GetUsageString( USAGE Usage ) } } -const Char* GetResourceDimString( RESOURCE_DIMENSION TexType ) +const Char* GetResourceDimString(RESOURCE_DIMENSION TexType) { static const Char* TexTypeStrings[RESOURCE_DIM_NUM_DIMENSIONS]; - static bool bTexTypeStrsInit = false; - if( !bTexTypeStrsInit ) + static bool bTexTypeStrsInit = false; + if (!bTexTypeStrsInit) { TexTypeStrings[RESOURCE_DIM_UNDEFINED] = "Undefined"; TexTypeStrings[RESOURCE_DIM_BUFFER] = "Buffer"; @@ -597,7 +613,7 @@ const Char* GetResourceDimString( RESOURCE_DIMENSION TexType ) bTexTypeStrsInit = true; } - if( TexType >= RESOURCE_DIM_UNDEFINED && TexType < RESOURCE_DIM_NUM_DIMENSIONS ) + if (TexType >= RESOURCE_DIM_UNDEFINED && TexType < RESOURCE_DIM_NUM_DIMENSIONS) return TexTypeStrings[TexType]; else { @@ -606,11 +622,12 @@ const Char* GetResourceDimString( RESOURCE_DIMENSION TexType ) } } -const Char* GetBindFlagString( Uint32 BindFlag ) +const Char* GetBindFlagString(Uint32 BindFlag) { - VERIFY( (BindFlag & (BindFlag - 1)) == 0, "More than one bind flag specified" ); - switch( BindFlag ) + VERIFY((BindFlag & (BindFlag - 1)) == 0, "More than one bind flag specified"); + switch (BindFlag) { + // clang-format off #define BIND_FLAG_STR_CASE(Flag) case Flag: return #Flag; BIND_FLAG_STR_CASE( BIND_VERTEX_BUFFER ) BIND_FLAG_STR_CASE( BIND_INDEX_BUFFER ) @@ -622,105 +639,108 @@ const Char* GetBindFlagString( Uint32 BindFlag ) BIND_FLAG_STR_CASE( BIND_UNORDERED_ACCESS ) BIND_FLAG_STR_CASE( BIND_INDIRECT_DRAW_ARGS ) #undef BIND_FLAG_STR_CASE - default: UNEXPECTED( "Unexpected bind flag ", BindFlag ); return ""; + // clang-format on + default: UNEXPECTED("Unexpected bind flag ", BindFlag); return ""; } } -String GetBindFlagsString( Uint32 BindFlags ) +String GetBindFlagsString(Uint32 BindFlags) { - if( BindFlags == 0 ) + if (BindFlags == 0) return "0"; String Str; - for( Uint32 Flag = BIND_VERTEX_BUFFER; BindFlags && Flag <= BIND_INDIRECT_DRAW_ARGS; Flag <<= 1 ) + for (Uint32 Flag = BIND_VERTEX_BUFFER; BindFlags && Flag <= BIND_INDIRECT_DRAW_ARGS; Flag <<= 1) { - if( BindFlags&Flag ) + if (BindFlags & Flag) { - if( Str.length() ) + if (Str.length()) Str += '|'; - Str += GetBindFlagString( Flag ); + Str += GetBindFlagString(Flag); BindFlags &= ~Flag; } } - VERIFY( BindFlags == 0, "Unknown bind flags left" ); + VERIFY(BindFlags == 0, "Unknown bind flags left"); return Str; } -static const Char* GetSingleCPUAccessFlagString( Uint32 CPUAccessFlag ) +static const Char* GetSingleCPUAccessFlagString(Uint32 CPUAccessFlag) { - VERIFY( (CPUAccessFlag & (CPUAccessFlag - 1)) == 0, "More than one access flag specified" ); - switch( CPUAccessFlag ) + VERIFY((CPUAccessFlag & (CPUAccessFlag - 1)) == 0, "More than one access flag specified"); + switch (CPUAccessFlag) { + // clang-format off #define CPU_ACCESS_FLAG_STR_CASE(Flag) case Flag: return #Flag; CPU_ACCESS_FLAG_STR_CASE( CPU_ACCESS_READ ) CPU_ACCESS_FLAG_STR_CASE( CPU_ACCESS_WRITE ) #undef CPU_ACCESS_FLAG_STR_CASE - default: UNEXPECTED( "Unexpected CPU access flag ", CPUAccessFlag ); return ""; + // clang-format on + default: UNEXPECTED("Unexpected CPU access flag ", CPUAccessFlag); return ""; } } -String GetCPUAccessFlagsString( Uint32 CpuAccessFlags ) +String GetCPUAccessFlagsString(Uint32 CpuAccessFlags) { - if( CpuAccessFlags == 0 ) + if (CpuAccessFlags == 0) return "0"; String Str; - for( Uint32 Flag = CPU_ACCESS_READ; CpuAccessFlags && Flag <= CPU_ACCESS_WRITE; Flag <<= 1 ) + for (Uint32 Flag = CPU_ACCESS_READ; CpuAccessFlags && Flag <= CPU_ACCESS_WRITE; Flag <<= 1) { - if( CpuAccessFlags&Flag ) + if (CpuAccessFlags & Flag) { - if( Str.length() ) + if (Str.length()) Str += '|'; - Str += GetSingleCPUAccessFlagString( Flag ); + Str += GetSingleCPUAccessFlagString(Flag); CpuAccessFlags &= ~Flag; } } - VERIFY( CpuAccessFlags == 0, "Unknown CPU access flags left" ); + VERIFY(CpuAccessFlags == 0, "Unknown CPU access flags left"); return Str; } // There is a nice standard function to_string, but there is a bug on gcc // and it does not work -template -String ToString( T Val ) +template +String ToString(T Val) { std::stringstream ss; ss << Val; return ss.str(); } -String GetTextureDescString( const TextureDesc &Desc ) +String GetTextureDescString(const TextureDesc& Desc) { String Str = "Type: "; Str += GetResourceDimString(Desc.Type); Str += "; size: "; Str += ToString(Desc.Width); - if( Desc.Type == RESOURCE_DIM_TEX_2D || Desc.Type == RESOURCE_DIM_TEX_2D_ARRAY || Desc.Type == RESOURCE_DIM_TEX_3D || Desc.Type == RESOURCE_DIM_TEX_CUBE || Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY) + if (Desc.Type == RESOURCE_DIM_TEX_2D || Desc.Type == RESOURCE_DIM_TEX_2D_ARRAY || Desc.Type == RESOURCE_DIM_TEX_3D || Desc.Type == RESOURCE_DIM_TEX_CUBE || Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY) { Str += "x"; - Str += ToString( Desc.Height ); + Str += ToString(Desc.Height); } - if( Desc.Type == RESOURCE_DIM_TEX_3D ) + if (Desc.Type == RESOURCE_DIM_TEX_3D) { Str += "x"; - Str += ToString( Desc.Depth ); + Str += ToString(Desc.Depth); } - - if( Desc.Type == RESOURCE_DIM_TEX_1D_ARRAY || Desc.Type == RESOURCE_DIM_TEX_2D_ARRAY || Desc.Type == RESOURCE_DIM_TEX_CUBE || Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY ) + + if (Desc.Type == RESOURCE_DIM_TEX_1D_ARRAY || Desc.Type == RESOURCE_DIM_TEX_2D_ARRAY || Desc.Type == RESOURCE_DIM_TEX_CUBE || Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY) { Str += "; Num Slices: "; - Str += ToString( Desc.ArraySize ); + Str += ToString(Desc.ArraySize); } - auto FmtName = GetTextureFormatAttribs( Desc.Format ).Name; + auto FmtName = GetTextureFormatAttribs(Desc.Format).Name; Str += "; Format: "; Str += FmtName; Str += "; Mip levels: "; - Str += ToString( Desc.MipLevels ); + Str += ToString(Desc.MipLevels); Str += "; Sample Count: "; - Str += ToString( Desc.SampleCount ); + Str += ToString(Desc.SampleCount); Str += "; Usage: "; Str += GetUsageString(Desc.Usage); @@ -734,26 +754,28 @@ String GetTextureDescString( const TextureDesc &Desc ) return Str; } -const Char* GetBufferModeString( BUFFER_MODE Mode ) +const Char* GetBufferModeString(BUFFER_MODE Mode) { static const Char* BufferModeStrings[BUFFER_MODE_NUM_MODES]; - static bool bBuffModeStringsInit = false; - if( !bBuffModeStringsInit ) + static bool bBuffModeStringsInit = false; + if (!bBuffModeStringsInit) { + // clang-format off #define INIT_BUFF_MODE_STR(Mode)BufferModeStrings[Mode] = #Mode INIT_BUFF_MODE_STR( BUFFER_MODE_UNDEFINED ); INIT_BUFF_MODE_STR( BUFFER_MODE_FORMATTED ); INIT_BUFF_MODE_STR( BUFFER_MODE_STRUCTURED ); INIT_BUFF_MODE_STR( BUFFER_MODE_RAW ); #undef INIT_BUFF_MODE_STR + // clang-format on static_assert(BUFFER_MODE_NUM_MODES == BUFFER_MODE_RAW + 1, "Not all buffer mode strings initialized."); bBuffModeStringsInit = true; } - if( Mode >= BUFFER_MODE_UNDEFINED && Mode < BUFFER_MODE_NUM_MODES ) + if (Mode >= BUFFER_MODE_UNDEFINED && Mode < BUFFER_MODE_NUM_MODES) return BufferModeStrings[Mode]; else { - UNEXPECTED( "Unknown buffer mode" ); + UNEXPECTED("Unknown buffer mode"); return "Unknown buffer mode"; } } @@ -761,37 +783,37 @@ const Char* GetBufferModeString( BUFFER_MODE Mode ) String GetBufferFormatString(const BufferFormat& Fmt) { String Str; - Str += GetValueTypeString( Fmt.ValueType ); - if( Fmt.IsNormalized ) + Str += GetValueTypeString(Fmt.ValueType); + if (Fmt.IsNormalized) Str += " norm"; Str += " x "; Str += ToString(Uint32{Fmt.NumComponents}); return Str; } -String GetBufferDescString( const BufferDesc &Desc ) +String GetBufferDescString(const BufferDesc& Desc) { String Str; Str += "Size: "; bool bIsLarge = false; - if( Desc.uiSizeInBytes > (1 << 20) ) + if (Desc.uiSizeInBytes > (1 << 20)) { - Str += ToString( Desc.uiSizeInBytes / (1<<20) ); + Str += ToString(Desc.uiSizeInBytes / (1 << 20)); Str += " Mb ("; bIsLarge = true; } - else if( Desc.uiSizeInBytes > (1 << 10) ) + else if (Desc.uiSizeInBytes > (1 << 10)) { - Str += ToString( Desc.uiSizeInBytes / (1<<10) ); + Str += ToString(Desc.uiSizeInBytes / (1 << 10)); Str += " Kb ("; bIsLarge = true; } - Str += ToString( Desc.uiSizeInBytes ); + Str += ToString(Desc.uiSizeInBytes); Str += " bytes"; - if( bIsLarge ) + if (bIsLarge) Str += ')'; - + Str += "; Mode: "; Str += GetBufferModeString(Desc.Mode); @@ -805,17 +827,18 @@ String GetBufferDescString( const BufferDesc &Desc ) Str += GetCPUAccessFlagsString(Desc.CPUAccessFlags); Str += "; stride: "; - Str += ToString( Desc.ElementByteStride ); + Str += ToString(Desc.ElementByteStride); Str += " bytes"; return Str; } -const Char* GetResourceStateFlagString( RESOURCE_STATE State ) +const Char* GetResourceStateFlagString(RESOURCE_STATE State) { - VERIFY((State & (State-1)) == 0, "Single state is expected"); - switch(State) + VERIFY((State & (State - 1)) == 0, "Single state is expected"); + switch (State) { + // clang-format off case RESOURCE_STATE_UNKNOWN: return "UNKNOWN"; case RESOURCE_STATE_UNDEFINED: return "UNDEFINED"; case RESOURCE_STATE_VERTEX_BUFFER: return "VERTEX_BUFFER"; @@ -833,15 +856,16 @@ const Char* GetResourceStateFlagString( RESOURCE_STATE State ) case RESOURCE_STATE_RESOLVE_DEST: return "RESOLVE_DEST"; case RESOURCE_STATE_RESOLVE_SOURCE: return "RESOLVE_SOURCE"; case RESOURCE_STATE_PRESENT: return "PRESENT"; + // clang-format on default: UNEXPECTED("Unknown resource state"); return "UNKNOWN"; } } -String GetResourceStateString( RESOURCE_STATE State ) +String GetResourceStateString(RESOURCE_STATE State) { - if(State == RESOURCE_STATE_UNKNOWN) + if (State == RESOURCE_STATE_UNKNOWN) return "UNKNOWN"; String str; @@ -849,8 +873,8 @@ String GetResourceStateString( RESOURCE_STATE State ) { if (!str.empty()) str.push_back('|'); - - auto lsb = State & ~(State-1); + + auto lsb = State & ~(State - 1); const auto* StateFlagString = GetResourceStateFlagString(static_cast(lsb)); str.append(StateFlagString); State = static_cast(State & ~lsb); @@ -858,32 +882,33 @@ String GetResourceStateString( RESOURCE_STATE State ) return str; } -Uint32 ComputeMipLevelsCount( Uint32 Width ) +Uint32 ComputeMipLevelsCount(Uint32 Width) { if (Width == 0) return 0; Uint32 MipLevels = 0; - while( (Width >> MipLevels) > 0 ) + while ((Width >> MipLevels) > 0) ++MipLevels; - VERIFY( Width >= (1U << (MipLevels-1)) && Width < (1U << MipLevels), "Incorrect number of Mip levels" ); + VERIFY(Width >= (1U << (MipLevels - 1)) && Width < (1U << MipLevels), "Incorrect number of Mip levels"); return MipLevels; } -Uint32 ComputeMipLevelsCount( Uint32 Width, Uint32 Height ) +Uint32 ComputeMipLevelsCount(Uint32 Width, Uint32 Height) { - return ComputeMipLevelsCount( std::max( Width, Height ) ); + return ComputeMipLevelsCount(std::max(Width, Height)); } -Uint32 ComputeMipLevelsCount( Uint32 Width, Uint32 Height, Uint32 Depth ) +Uint32 ComputeMipLevelsCount(Uint32 Width, Uint32 Height, Uint32 Depth) { - return ComputeMipLevelsCount( std::max(std::max( Width, Height ), Depth) ); + return ComputeMipLevelsCount(std::max(std::max(Width, Height), Depth)); } bool VerifyResourceStates(RESOURCE_STATE State, bool IsTexture) { static_assert(RESOURCE_STATE_MAX_BIT == 0x8000, "Please update this function to handle the new resource state"); + // clang-format off #define VERIFY_EXCLUSIVE_STATE(ExclusiveState)\ if ( (State & ExclusiveState) != 0 && (State & ~ExclusiveState) != 0 )\ {\ @@ -899,9 +924,11 @@ if ( (State & ExclusiveState) != 0 && (State & ~ExclusiveState) != 0 )\ VERIFY_EXCLUSIVE_STATE(RESOURCE_STATE_RESOLVE_DEST); VERIFY_EXCLUSIVE_STATE(RESOURCE_STATE_PRESENT); #undef VERIFY_EXCLUSIVE_STATE + // clang-format on if (IsTexture) { + // clang-format off if (State & (RESOURCE_STATE_VERTEX_BUFFER | RESOURCE_STATE_CONSTANT_BUFFER | @@ -914,9 +941,11 @@ if ( (State & ExclusiveState) != 0 && (State & ~ExclusiveState) != 0 )\ "RESOURCE_STATE_INDIRECT_ARGUMENT are not applicable to a texture"); return false; } + // clang-format on } else { + // clang-format off if (State & (RESOURCE_STATE_RENDER_TARGET | RESOURCE_STATE_DEPTH_WRITE | @@ -929,30 +958,30 @@ if ( (State & ExclusiveState) != 0 && (State & ~ExclusiveState) != 0 )\ "RESOURCE_STATE_DEPTH_WRITE, RESOURCE_STATE_DEPTH_READ, RESOURCE_STATE_RESOLVE_SOURCE, " "RESOURCE_STATE_RESOLVE_DEST, RESOURCE_STATE_PRESENT are not applicable to a buffer"); return false; - } + // clang-format on } - + return true; } MipLevelProperties GetMipLevelProperties(const TextureDesc& TexDesc, Uint32 MipLevel) { MipLevelProperties MipProps; - const auto& FmtAttribs = GetTextureFormatAttribs(TexDesc.Format); + const auto& FmtAttribs = GetTextureFormatAttribs(TexDesc.Format); - MipProps.LogicalWidth = std::max(TexDesc.Width >> MipLevel, 1u); + MipProps.LogicalWidth = std::max(TexDesc.Width >> MipLevel, 1u); MipProps.LogicalHeight = std::max(TexDesc.Height >> MipLevel, 1u); - MipProps.Depth = (TexDesc.Type == RESOURCE_DIM_TEX_3D) ? std::max(TexDesc.Depth >> MipLevel, 1u) : 1u; + MipProps.Depth = (TexDesc.Type == RESOURCE_DIM_TEX_3D) ? std::max(TexDesc.Depth >> MipLevel, 1u) : 1u; if (FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED) { VERIFY_EXPR(FmtAttribs.BlockWidth > 1 && FmtAttribs.BlockHeight > 1); - VERIFY((FmtAttribs.BlockWidth & (FmtAttribs.BlockWidth-1)) == 0, "Compressed block width is expected to be power of 2"); - VERIFY((FmtAttribs.BlockHeight & (FmtAttribs.BlockHeight-1)) == 0, "Compressed block height is expected to be power of 2"); + VERIFY((FmtAttribs.BlockWidth & (FmtAttribs.BlockWidth - 1)) == 0, "Compressed block width is expected to be power of 2"); + VERIFY((FmtAttribs.BlockHeight & (FmtAttribs.BlockHeight - 1)) == 0, "Compressed block height is expected to be power of 2"); // For block-compression formats, all parameters are still specified in texels rather than compressed texel blocks (18.4.1) MipProps.StorageWidth = Align(MipProps.LogicalWidth, Uint32{FmtAttribs.BlockWidth}); - MipProps.StorageHeight = Align(MipProps.LogicalHeight,Uint32{FmtAttribs.BlockHeight}); - MipProps.RowSize = MipProps.StorageWidth / Uint32{FmtAttribs.BlockWidth} * Uint32{FmtAttribs.ComponentSize}; // ComponentSize is the block size + MipProps.StorageHeight = Align(MipProps.LogicalHeight, Uint32{FmtAttribs.BlockHeight}); + MipProps.RowSize = MipProps.StorageWidth / Uint32{FmtAttribs.BlockWidth} * Uint32{FmtAttribs.ComponentSize}; // ComponentSize is the block size MipProps.DepthSliceSize = MipProps.StorageHeight / Uint32{FmtAttribs.BlockHeight} * MipProps.RowSize; MipProps.MipSize = MipProps.DepthSliceSize * MipProps.Depth; } @@ -968,4 +997,4 @@ MipLevelProperties GetMipLevelProperties(const TextureDesc& TexDesc, Uint32 MipL return MipProps; } -} +} // namespace Diligent diff --git a/Graphics/GraphicsAccessories/src/SRBMemoryAllocator.cpp b/Graphics/GraphicsAccessories/src/SRBMemoryAllocator.cpp index bbb96e39..e27d3c95 100644 --- a/Graphics/GraphicsAccessories/src/SRBMemoryAllocator.cpp +++ b/Graphics/GraphicsAccessories/src/SRBMemoryAllocator.cpp @@ -31,7 +31,7 @@ SRBMemoryAllocator::~SRBMemoryAllocator() if (m_DataAllocators != nullptr) { auto TotalAllocatorCount = m_ShaderVariableDataAllocatorCount + m_ResourceCacheDataAllocatorCount; - for (Uint32 s=0; s < TotalAllocatorCount; ++s) + for (Uint32 s = 0; s < TotalAllocatorCount; ++s) { m_DataAllocators[s].~FixedBlockMemoryAllocator(); } @@ -39,8 +39,8 @@ SRBMemoryAllocator::~SRBMemoryAllocator() } } -void SRBMemoryAllocator::Initialize(Uint32 SRBAllocationGranularity, - Uint32 ShaderVariableDataAllocatorCount, +void SRBMemoryAllocator::Initialize(Uint32 SRBAllocationGranularity, + Uint32 ShaderVariableDataAllocatorCount, const size_t* const ShaderVariableDataSizes, Uint32 ResourceCacheDataAllocatorCount, const size_t* const ResourceCacheDataSizes) @@ -50,23 +50,22 @@ void SRBMemoryAllocator::Initialize(Uint32 SRBAllocationGranularity m_ShaderVariableDataAllocatorCount = ShaderVariableDataAllocatorCount; m_ResourceCacheDataAllocatorCount = ResourceCacheDataAllocatorCount; - auto TotalAllocatorCount = m_ShaderVariableDataAllocatorCount + m_ResourceCacheDataAllocatorCount; + auto TotalAllocatorCount = m_ShaderVariableDataAllocatorCount + m_ResourceCacheDataAllocatorCount; - if(TotalAllocatorCount == 0) + if (TotalAllocatorCount == 0) return; auto* pAllocatorsRawMem = m_RawMemAllocator.Allocate( sizeof(FixedBlockMemoryAllocator) * TotalAllocatorCount, "Raw memory for SRBMemoryAllocator::m_ShaderVariableDataAllocators", - __FILE__, __LINE__ - ); + __FILE__, __LINE__); m_DataAllocators = reinterpret_cast(pAllocatorsRawMem); for (Uint32 s = 0; s < TotalAllocatorCount; ++s) { auto size = s < ShaderVariableDataAllocatorCount ? ShaderVariableDataSizes[s] : ResourceCacheDataSizes[s - ShaderVariableDataAllocatorCount]; - new(m_DataAllocators + s)FixedBlockMemoryAllocator(GetRawAllocator(), size, SRBAllocationGranularity); + new (m_DataAllocators + s) FixedBlockMemoryAllocator(GetRawAllocator(), size, SRBAllocationGranularity); } } -} +} // namespace Diligent -- cgit v1.2.3