From 16aebd657c96bd86617dc2167aac4abe065fb00f Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 26 Jan 2020 13:59:38 -0800 Subject: Renamed .h -> .hpp in GraphicsEngineNextGenBase and GraphicsEngineD3D12 projects --- Graphics/GraphicsEngineNextGenBase/CMakeLists.txt | 6 +- .../include/DeviceContextNextGenBase.h | 125 -------- .../include/DeviceContextNextGenBase.hpp | 125 ++++++++ .../include/DynamicHeap.h | 209 ------------- .../include/DynamicHeap.hpp | 209 +++++++++++++ .../include/RenderDeviceNextGenBase.h | 324 --------------------- .../include/RenderDeviceNextGenBase.hpp | 324 +++++++++++++++++++++ Graphics/GraphicsEngineNextGenBase/src/dummy.cpp | 2 +- 8 files changed, 662 insertions(+), 662 deletions(-) delete mode 100644 Graphics/GraphicsEngineNextGenBase/include/DeviceContextNextGenBase.h create mode 100644 Graphics/GraphicsEngineNextGenBase/include/DeviceContextNextGenBase.hpp delete mode 100644 Graphics/GraphicsEngineNextGenBase/include/DynamicHeap.h create mode 100644 Graphics/GraphicsEngineNextGenBase/include/DynamicHeap.hpp delete mode 100644 Graphics/GraphicsEngineNextGenBase/include/RenderDeviceNextGenBase.h create mode 100644 Graphics/GraphicsEngineNextGenBase/include/RenderDeviceNextGenBase.hpp (limited to 'Graphics/GraphicsEngineNextGenBase') diff --git a/Graphics/GraphicsEngineNextGenBase/CMakeLists.txt b/Graphics/GraphicsEngineNextGenBase/CMakeLists.txt index 21669229..f0bb4f01 100644 --- a/Graphics/GraphicsEngineNextGenBase/CMakeLists.txt +++ b/Graphics/GraphicsEngineNextGenBase/CMakeLists.txt @@ -3,9 +3,9 @@ cmake_minimum_required (VERSION 3.6) project(Diligent-GraphicsEngineNextGenBase CXX) set(INCLUDE - include/DeviceContextNextGenBase.h - include/DynamicHeap.h - include/RenderDeviceNextGenBase.h + include/DeviceContextNextGenBase.hpp + include/DynamicHeap.hpp + include/RenderDeviceNextGenBase.hpp ) set(SOURCE diff --git a/Graphics/GraphicsEngineNextGenBase/include/DeviceContextNextGenBase.h b/Graphics/GraphicsEngineNextGenBase/include/DeviceContextNextGenBase.h deleted file mode 100644 index 8954e3d4..00000000 --- a/Graphics/GraphicsEngineNextGenBase/include/DeviceContextNextGenBase.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include "Atomics.h" -#include "BasicTypes.h" -#include "ReferenceCounters.h" -#include "RefCntAutoPtr.h" -#include "DeviceContextBase.hpp" -#include "RefCntAutoPtr.h" - -namespace Diligent -{ - -/// Base implementation of the device context for next-generation backends. - -template -class DeviceContextNextGenBase : public DeviceContextBase -{ -public: - using TBase = DeviceContextBase; - using DeviceImplType = typename ImplementationTraits::DeviceType; - using ICommandQueueType = typename ImplementationTraits::ICommandQueueType; - - DeviceContextNextGenBase(IReferenceCounters* pRefCounters, - DeviceImplType* pRenderDevice, - Uint32 ContextId, - Uint32 CommandQueueId, - Uint32 NumCommandsToFlush, - bool bIsDeferred) : - // clang-format off - TBase{pRefCounters, pRenderDevice, bIsDeferred}, - m_ContextId {ContextId }, - m_CommandQueueId {CommandQueueId }, - m_NumCommandsToFlush {NumCommandsToFlush}, - m_ContextFrameNumber {0}, - m_SubmittedBuffersCmdQueueMask{bIsDeferred ? 0 : Uint64{1} << Uint64{CommandQueueId}} - // clang-format on - { - } - - ~DeviceContextNextGenBase() - { - } - - virtual ICommandQueueType* LockCommandQueue() override final - { - if (this->m_bIsDeferred) - { - LOG_WARNING_MESSAGE("Deferred contexts have no associated command queues"); - return nullptr; - } - return this->m_pDevice->LockCommandQueue(m_CommandQueueId); - } - - virtual void UnlockCommandQueue() override final - { - if (this->m_bIsDeferred) - { - LOG_WARNING_MESSAGE("Deferred contexts have no associated command queues"); - return; - } - this->m_pDevice->UnlockCommandQueue(m_CommandQueueId); - } - - Uint32 GetCommandQueueId() const - { - return m_CommandQueueId; - } - -protected: - // Should be called at the end of FinishFrame() - void EndFrame() - { - if (this->m_bIsDeferred) - { - // For deferred context, reset submitted cmd queue mask - m_SubmittedBuffersCmdQueueMask = 0; - } - else - { - this->m_pDevice->FlushStaleResources(m_CommandQueueId); - } - Atomics::AtomicIncrement(m_ContextFrameNumber); - } - - const Uint32 m_ContextId; - const Uint32 m_CommandQueueId; - const Uint32 m_NumCommandsToFlush; - Atomics::AtomicInt64 m_ContextFrameNumber; - - // This mask indicates which command queues command buffers from this context were submitted to. - // For immediate context, this will always be 1 << m_CommandQueueId. - // For deferred contexts, this will accumulate bits of the queues to which command buffers - // were submitted to before FinishFrame() was called. This mask is used to release resources - // allocated by the context during the frame when FinishFrame() is called. - Uint64 m_SubmittedBuffersCmdQueueMask = 0; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineNextGenBase/include/DeviceContextNextGenBase.hpp b/Graphics/GraphicsEngineNextGenBase/include/DeviceContextNextGenBase.hpp new file mode 100644 index 00000000..8954e3d4 --- /dev/null +++ b/Graphics/GraphicsEngineNextGenBase/include/DeviceContextNextGenBase.hpp @@ -0,0 +1,125 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "Atomics.h" +#include "BasicTypes.h" +#include "ReferenceCounters.h" +#include "RefCntAutoPtr.h" +#include "DeviceContextBase.hpp" +#include "RefCntAutoPtr.h" + +namespace Diligent +{ + +/// Base implementation of the device context for next-generation backends. + +template +class DeviceContextNextGenBase : public DeviceContextBase +{ +public: + using TBase = DeviceContextBase; + using DeviceImplType = typename ImplementationTraits::DeviceType; + using ICommandQueueType = typename ImplementationTraits::ICommandQueueType; + + DeviceContextNextGenBase(IReferenceCounters* pRefCounters, + DeviceImplType* pRenderDevice, + Uint32 ContextId, + Uint32 CommandQueueId, + Uint32 NumCommandsToFlush, + bool bIsDeferred) : + // clang-format off + TBase{pRefCounters, pRenderDevice, bIsDeferred}, + m_ContextId {ContextId }, + m_CommandQueueId {CommandQueueId }, + m_NumCommandsToFlush {NumCommandsToFlush}, + m_ContextFrameNumber {0}, + m_SubmittedBuffersCmdQueueMask{bIsDeferred ? 0 : Uint64{1} << Uint64{CommandQueueId}} + // clang-format on + { + } + + ~DeviceContextNextGenBase() + { + } + + virtual ICommandQueueType* LockCommandQueue() override final + { + if (this->m_bIsDeferred) + { + LOG_WARNING_MESSAGE("Deferred contexts have no associated command queues"); + return nullptr; + } + return this->m_pDevice->LockCommandQueue(m_CommandQueueId); + } + + virtual void UnlockCommandQueue() override final + { + if (this->m_bIsDeferred) + { + LOG_WARNING_MESSAGE("Deferred contexts have no associated command queues"); + return; + } + this->m_pDevice->UnlockCommandQueue(m_CommandQueueId); + } + + Uint32 GetCommandQueueId() const + { + return m_CommandQueueId; + } + +protected: + // Should be called at the end of FinishFrame() + void EndFrame() + { + if (this->m_bIsDeferred) + { + // For deferred context, reset submitted cmd queue mask + m_SubmittedBuffersCmdQueueMask = 0; + } + else + { + this->m_pDevice->FlushStaleResources(m_CommandQueueId); + } + Atomics::AtomicIncrement(m_ContextFrameNumber); + } + + const Uint32 m_ContextId; + const Uint32 m_CommandQueueId; + const Uint32 m_NumCommandsToFlush; + Atomics::AtomicInt64 m_ContextFrameNumber; + + // This mask indicates which command queues command buffers from this context were submitted to. + // For immediate context, this will always be 1 << m_CommandQueueId. + // For deferred contexts, this will accumulate bits of the queues to which command buffers + // were submitted to before FinishFrame() was called. This mask is used to release resources + // allocated by the context during the frame when FinishFrame() is called. + Uint64 m_SubmittedBuffersCmdQueueMask = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineNextGenBase/include/DynamicHeap.h b/Graphics/GraphicsEngineNextGenBase/include/DynamicHeap.h deleted file mode 100644 index 906a846f..00000000 --- a/Graphics/GraphicsEngineNextGenBase/include/DynamicHeap.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Defines dynamic heap utilities - -#include -#include -#include -#include -#include "VariableSizeAllocationsManager.hpp" -#include "RingBuffer.hpp" - -namespace Diligent -{ - -namespace DynamicHeap -{ - - -// Having global ring buffer shared between all contexts is inconvinient because all contexts -// must share the same frame. Having individual ring bufer per context may result in a lot of unused -// memory. As a result, ring buffer is not currently used for dynamic memory management. -// Instead, every dynamic heap allocates pages from the global dynamic memory manager. -class MasterBlockRingBufferBasedManager -{ -public: - using OffsetType = RingBuffer::OffsetType; - using MasterBlock = RingBuffer::OffsetType; - static constexpr const OffsetType InvalidOffset = RingBuffer::InvalidOffset; - - MasterBlockRingBufferBasedManager(IMemoryAllocator& Allocator, - Uint32 Size) : - m_RingBuffer{Size, Allocator} - {} - - // clang-format off - MasterBlockRingBufferBasedManager (const MasterBlockRingBufferBasedManager&) = delete; - MasterBlockRingBufferBasedManager ( MasterBlockRingBufferBasedManager&&) = delete; - MasterBlockRingBufferBasedManager& operator= (const MasterBlockRingBufferBasedManager&) = delete; - MasterBlockRingBufferBasedManager& operator= ( MasterBlockRingBufferBasedManager&&) = delete; - // clang-format on - - void DiscardMasterBlocks(std::vector& /*Blocks*/, Uint64 FenceValue) - { - std::lock_guard Lock{m_RingBufferMtx}; - m_RingBuffer.FinishCurrentFrame(FenceValue); - } - - void ReleaseStaleBlocks(Uint64 LastCompletedFenceValue) - { - std::lock_guard Lock{m_RingBufferMtx}; - m_RingBuffer.ReleaseCompletedFrames(LastCompletedFenceValue); - } - - OffsetType GetSize() const { return m_RingBuffer.GetMaxSize(); } - OffsetType GetUsedSize() const { return m_RingBuffer.GetUsedSize(); } - -protected: - MasterBlock AllocateMasterBlock(OffsetType SizeInBytes, OffsetType Alignment) - { - std::lock_guard Lock{m_RingBufferMtx}; - return m_RingBuffer.Allocate(SizeInBytes, Alignment); - } - -private: - std::mutex m_RingBufferMtx; - RingBuffer m_RingBuffer; -}; - - -class MasterBlockListBasedManager -{ -public: - using OffsetType = VariableSizeAllocationsManager::OffsetType; - using MasterBlock = VariableSizeAllocationsManager::Allocation; - - MasterBlockListBasedManager(IMemoryAllocator& Allocator, - Uint32 Size) : - m_AllocationsMgr{Size, Allocator} - { -#ifdef DEVELOPMENT - m_MasterBlockCounter = 0; -#endif - } - - // clang-format off - MasterBlockListBasedManager (const MasterBlockListBasedManager&) = delete; - MasterBlockListBasedManager ( MasterBlockListBasedManager&&) = delete; - MasterBlockListBasedManager& operator= (const MasterBlockListBasedManager&) = delete; - MasterBlockListBasedManager& operator= ( MasterBlockListBasedManager&&) = delete; - // clang-format on - - ~MasterBlockListBasedManager() - { - DEV_CHECK_ERR(m_MasterBlockCounter == 0, m_MasterBlockCounter, " master block(s) have not been returned to the manager"); - } - - template - void ReleaseMasterBlocks(std::vector& Blocks, RenderDeviceImplType& Device, Uint64 CmdQueueMask) - { - struct StaleMasterBlock - { - MasterBlock Block; - MasterBlockListBasedManager* Mgr; - - // clang-format off - StaleMasterBlock(MasterBlock&& _Block, MasterBlockListBasedManager* _Mgr)noexcept : - Block {std::move(_Block)}, - Mgr {_Mgr } - { - } - - StaleMasterBlock (const StaleMasterBlock&) = delete; - StaleMasterBlock& operator= (const StaleMasterBlock&) = delete; - StaleMasterBlock& operator= ( StaleMasterBlock&&) = delete; - - StaleMasterBlock(StaleMasterBlock&& rhs)noexcept : - Block {std::move(rhs.Block)}, - Mgr {rhs.Mgr } - { - rhs.Block = MasterBlock{}; - rhs.Mgr = nullptr; - } - // clang-format on - - ~StaleMasterBlock() - { - if (Mgr != nullptr) - { - std::lock_guard Lock{Mgr->m_AllocationsMgrMtx}; -#ifdef DEVELOPMENT - --Mgr->m_MasterBlockCounter; -#endif - Mgr->m_AllocationsMgr.Free(std::move(Block)); - } - } - }; - for (auto& Block : Blocks) - { - DEV_CHECK_ERR(Block.IsValid(), "Attempting to release invalid master block"); - Device.SafeReleaseDeviceObject(StaleMasterBlock{std::move(Block), this}, CmdQueueMask); - } - } - - // clang-format off - OffsetType GetSize() const { return m_AllocationsMgr.GetMaxSize(); } - OffsetType GetUsedSize() const { return m_AllocationsMgr.GetUsedSize();} - // clang-format on - -#ifdef DEVELOPMENT - int32_t GetMasterBlockCounter() const - { - return m_MasterBlockCounter; - } -#endif - -protected: - MasterBlock AllocateMasterBlock(OffsetType SizeInBytes, OffsetType Alignment) - { - std::lock_guard Lock{m_AllocationsMgrMtx}; - auto NewBlock = m_AllocationsMgr.Allocate(SizeInBytes, Alignment); -#ifdef DEVELOPMENT - if (NewBlock.IsValid()) - { - ++m_MasterBlockCounter; - } -#endif - return NewBlock; - } - -private: - std::mutex m_AllocationsMgrMtx; - VariableSizeAllocationsManager m_AllocationsMgr; - -#ifdef DEVELOPMENT - std::atomic_int32_t m_MasterBlockCounter; -#endif -}; - -} // namespace DynamicHeap - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineNextGenBase/include/DynamicHeap.hpp b/Graphics/GraphicsEngineNextGenBase/include/DynamicHeap.hpp new file mode 100644 index 00000000..906a846f --- /dev/null +++ b/Graphics/GraphicsEngineNextGenBase/include/DynamicHeap.hpp @@ -0,0 +1,209 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Defines dynamic heap utilities + +#include +#include +#include +#include +#include "VariableSizeAllocationsManager.hpp" +#include "RingBuffer.hpp" + +namespace Diligent +{ + +namespace DynamicHeap +{ + + +// Having global ring buffer shared between all contexts is inconvinient because all contexts +// must share the same frame. Having individual ring bufer per context may result in a lot of unused +// memory. As a result, ring buffer is not currently used for dynamic memory management. +// Instead, every dynamic heap allocates pages from the global dynamic memory manager. +class MasterBlockRingBufferBasedManager +{ +public: + using OffsetType = RingBuffer::OffsetType; + using MasterBlock = RingBuffer::OffsetType; + static constexpr const OffsetType InvalidOffset = RingBuffer::InvalidOffset; + + MasterBlockRingBufferBasedManager(IMemoryAllocator& Allocator, + Uint32 Size) : + m_RingBuffer{Size, Allocator} + {} + + // clang-format off + MasterBlockRingBufferBasedManager (const MasterBlockRingBufferBasedManager&) = delete; + MasterBlockRingBufferBasedManager ( MasterBlockRingBufferBasedManager&&) = delete; + MasterBlockRingBufferBasedManager& operator= (const MasterBlockRingBufferBasedManager&) = delete; + MasterBlockRingBufferBasedManager& operator= ( MasterBlockRingBufferBasedManager&&) = delete; + // clang-format on + + void DiscardMasterBlocks(std::vector& /*Blocks*/, Uint64 FenceValue) + { + std::lock_guard Lock{m_RingBufferMtx}; + m_RingBuffer.FinishCurrentFrame(FenceValue); + } + + void ReleaseStaleBlocks(Uint64 LastCompletedFenceValue) + { + std::lock_guard Lock{m_RingBufferMtx}; + m_RingBuffer.ReleaseCompletedFrames(LastCompletedFenceValue); + } + + OffsetType GetSize() const { return m_RingBuffer.GetMaxSize(); } + OffsetType GetUsedSize() const { return m_RingBuffer.GetUsedSize(); } + +protected: + MasterBlock AllocateMasterBlock(OffsetType SizeInBytes, OffsetType Alignment) + { + std::lock_guard Lock{m_RingBufferMtx}; + return m_RingBuffer.Allocate(SizeInBytes, Alignment); + } + +private: + std::mutex m_RingBufferMtx; + RingBuffer m_RingBuffer; +}; + + +class MasterBlockListBasedManager +{ +public: + using OffsetType = VariableSizeAllocationsManager::OffsetType; + using MasterBlock = VariableSizeAllocationsManager::Allocation; + + MasterBlockListBasedManager(IMemoryAllocator& Allocator, + Uint32 Size) : + m_AllocationsMgr{Size, Allocator} + { +#ifdef DEVELOPMENT + m_MasterBlockCounter = 0; +#endif + } + + // clang-format off + MasterBlockListBasedManager (const MasterBlockListBasedManager&) = delete; + MasterBlockListBasedManager ( MasterBlockListBasedManager&&) = delete; + MasterBlockListBasedManager& operator= (const MasterBlockListBasedManager&) = delete; + MasterBlockListBasedManager& operator= ( MasterBlockListBasedManager&&) = delete; + // clang-format on + + ~MasterBlockListBasedManager() + { + DEV_CHECK_ERR(m_MasterBlockCounter == 0, m_MasterBlockCounter, " master block(s) have not been returned to the manager"); + } + + template + void ReleaseMasterBlocks(std::vector& Blocks, RenderDeviceImplType& Device, Uint64 CmdQueueMask) + { + struct StaleMasterBlock + { + MasterBlock Block; + MasterBlockListBasedManager* Mgr; + + // clang-format off + StaleMasterBlock(MasterBlock&& _Block, MasterBlockListBasedManager* _Mgr)noexcept : + Block {std::move(_Block)}, + Mgr {_Mgr } + { + } + + StaleMasterBlock (const StaleMasterBlock&) = delete; + StaleMasterBlock& operator= (const StaleMasterBlock&) = delete; + StaleMasterBlock& operator= ( StaleMasterBlock&&) = delete; + + StaleMasterBlock(StaleMasterBlock&& rhs)noexcept : + Block {std::move(rhs.Block)}, + Mgr {rhs.Mgr } + { + rhs.Block = MasterBlock{}; + rhs.Mgr = nullptr; + } + // clang-format on + + ~StaleMasterBlock() + { + if (Mgr != nullptr) + { + std::lock_guard Lock{Mgr->m_AllocationsMgrMtx}; +#ifdef DEVELOPMENT + --Mgr->m_MasterBlockCounter; +#endif + Mgr->m_AllocationsMgr.Free(std::move(Block)); + } + } + }; + for (auto& Block : Blocks) + { + DEV_CHECK_ERR(Block.IsValid(), "Attempting to release invalid master block"); + Device.SafeReleaseDeviceObject(StaleMasterBlock{std::move(Block), this}, CmdQueueMask); + } + } + + // clang-format off + OffsetType GetSize() const { return m_AllocationsMgr.GetMaxSize(); } + OffsetType GetUsedSize() const { return m_AllocationsMgr.GetUsedSize();} + // clang-format on + +#ifdef DEVELOPMENT + int32_t GetMasterBlockCounter() const + { + return m_MasterBlockCounter; + } +#endif + +protected: + MasterBlock AllocateMasterBlock(OffsetType SizeInBytes, OffsetType Alignment) + { + std::lock_guard Lock{m_AllocationsMgrMtx}; + auto NewBlock = m_AllocationsMgr.Allocate(SizeInBytes, Alignment); +#ifdef DEVELOPMENT + if (NewBlock.IsValid()) + { + ++m_MasterBlockCounter; + } +#endif + return NewBlock; + } + +private: + std::mutex m_AllocationsMgrMtx; + VariableSizeAllocationsManager m_AllocationsMgr; + +#ifdef DEVELOPMENT + std::atomic_int32_t m_MasterBlockCounter; +#endif +}; + +} // namespace DynamicHeap + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineNextGenBase/include/RenderDeviceNextGenBase.h b/Graphics/GraphicsEngineNextGenBase/include/RenderDeviceNextGenBase.h deleted file mode 100644 index 8ac8bc18..00000000 --- a/Graphics/GraphicsEngineNextGenBase/include/RenderDeviceNextGenBase.h +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include - -#include "EngineFactory.h" -#include "Atomics.h" -#include "BasicTypes.h" -#include "ReferenceCounters.h" -#include "MemoryAllocator.h" -#include "RefCntAutoPtr.h" -#include "PlatformMisc.h" -#include "ResourceReleaseQueue.hpp" -#include "EngineMemory.h" - -namespace Diligent -{ - -/// Base implementation of the render device for next-generation backends. - -template -class RenderDeviceNextGenBase : public TBase -{ -public: - using typename TBase::DeviceObjectSizes; - - RenderDeviceNextGenBase(IReferenceCounters* pRefCounters, - IMemoryAllocator& RawMemAllocator, - IEngineFactory* pEngineFactory, - size_t CmdQueueCount, - CommandQueueType** Queues, - Uint32 NumDeferredContexts, - const DeviceObjectSizes& ObjectSizes) : - TBase{pRefCounters, RawMemAllocator, pEngineFactory, NumDeferredContexts, ObjectSizes}, - m_CmdQueueCount{CmdQueueCount} - { - m_CommandQueues = ALLOCATE(this->m_RawMemAllocator, "Raw memory for the device command/release queues", CommandQueue, m_CmdQueueCount); - for (size_t q = 0; q < m_CmdQueueCount; ++q) - new (m_CommandQueues + q) CommandQueue(RefCntAutoPtr(Queues[q]), this->m_RawMemAllocator); - } - - ~RenderDeviceNextGenBase() - { - DestroyCommandQueues(); - } - - // The following basic requirement guarantees correctness of resource deallocation: - // - // A resource is never released before the last draw command referencing it is submitted to the command queue - // - - // - // CPU - // Last Reference - // of resource X - // | - // | Submit Cmd Submit Cmd Submit Cmd - // | List N List N+1 List N+2 - // V | | | - // NextFenceValue | * N | N+1 | N+2 | - // - // - // CompletedFenceValue | N-3 | N-2 | N-1 | N | - // . . . . . - // -----------------------------.--------------.---------------.-------------------.----------------.------------- - // . . . . . - // - // GPU | Cmd List N-2 | Cmd List N-1 | Cmd List N | Cmd List N+1 | - // | - // | - // Resource X can - // be released - template ::value>::type> - void SafeReleaseDeviceObject(ObjectType&& Object, Uint64 QueueMask) - { - QueueMask &= GetCommandQueueMask(); - - VERIFY(QueueMask != 0, "At least one bit should be set in the command queue mask"); - if (QueueMask == 0) - return; - - Atomics::Long NumReferences = PlatformMisc::CountOneBits(QueueMask); - auto Wrapper = DynamicStaleResourceWrapper::Create(std::move(Object), NumReferences); - - while (QueueMask != 0) - { - auto QueueIndex = PlatformMisc::GetLSB(QueueMask); - VERIFY_EXPR(QueueIndex < m_CmdQueueCount); - - auto& Queue = m_CommandQueues[QueueIndex]; - // Do not use std::move on wrapper!!! - Queue.ReleaseQueue.SafeReleaseResource(Wrapper, Queue.NextCmdBufferNumber); - QueueMask &= ~(Uint64{1} << Uint64{QueueIndex}); - --NumReferences; - } - VERIFY_EXPR(NumReferences == 0); - - Wrapper.GiveUpOwnership(); - } - - size_t GetCommandQueueCount() const - { - return m_CmdQueueCount; - } - - Uint64 GetCommandQueueMask() const - { - return (m_CmdQueueCount < 64) ? ((Uint64{1} << Uint64{m_CmdQueueCount}) - 1) : ~Uint64{0}; - } - - void PurgeReleaseQueues(bool ForceRelease = false) - { - for (Uint32 q = 0; q < m_CmdQueueCount; ++q) - PurgeReleaseQueue(q, ForceRelease); - } - - void PurgeReleaseQueue(Uint32 QueueIndex, bool ForceRelease = false) - { - VERIFY_EXPR(QueueIndex < m_CmdQueueCount); - auto& Queue = m_CommandQueues[QueueIndex]; - auto CompletedFenceValue = ForceRelease ? std::numeric_limits::max() : Queue.CmdQueue->GetCompletedFenceValue(); - Queue.ReleaseQueue.Purge(CompletedFenceValue); - } - - void IdleCommandQueue(size_t QueueIdx, bool ReleaseResources) - { - VERIFY_EXPR(QueueIdx < m_CmdQueueCount); - auto& Queue = m_CommandQueues[QueueIdx]; - - Uint64 CmdBufferNumber = 0; - Uint64 FenceValue = 0; - { - std::lock_guard Lock{Queue.Mtx}; - - if (ReleaseResources) - { - // Increment command buffer number before idling the queue. - // This will make sure that any resource released while this function - // is running will be associated with the next command buffer submission. - CmdBufferNumber = static_cast(Queue.NextCmdBufferNumber); - Atomics::AtomicIncrement(Queue.NextCmdBufferNumber); - } - - FenceValue = Queue.CmdQueue->WaitForIdle(); - } - - if (ReleaseResources) - { - Queue.ReleaseQueue.DiscardStaleResources(CmdBufferNumber, FenceValue); - Queue.ReleaseQueue.Purge(Queue.CmdQueue->GetCompletedFenceValue()); - } - } - - void IdleAllCommandQueues(bool ReleaseResources) - { - for (size_t q = 0; q < m_CmdQueueCount; ++q) - IdleCommandQueue(q, ReleaseResources); - } - - struct SubmittedCommandBufferInfo - { - Uint64 CmdBufferNumber = 0; - Uint64 FenceValue = 0; - }; - template - SubmittedCommandBufferInfo SubmitCommandBuffer(Uint32 QueueIndex, SubmitDataType& SubmitData, bool DiscardStaleResources) - { - SubmittedCommandBufferInfo CmdBuffInfo; - VERIFY_EXPR(QueueIndex < m_CmdQueueCount); - auto& Queue = m_CommandQueues[QueueIndex]; - - { - std::lock_guard Lock{Queue.Mtx}; - - // Increment command buffer number before submitting the cmd buffer. - // This will make sure that any resource released while this function - // is running will be associated with the next command buffer. - CmdBuffInfo.CmdBufferNumber = static_cast(Queue.NextCmdBufferNumber); - Atomics::AtomicIncrement(Queue.NextCmdBufferNumber); - - CmdBuffInfo.FenceValue = Queue.CmdQueue->Submit(SubmitData); - } - - if (DiscardStaleResources) - { - // The following basic requirement guarantees correctness of resource deallocation: - // - // A resource is never released before the last draw command referencing it is submitted for execution - // - - // Move stale objects into the release queue. - // Note that objects are moved from stale list to release queue based on the cmd buffer number, - // not fence value. This makes sure that basic requirement is met even when the fence value is - // not incremented while executing the command buffer (as is the case with Unity command queue). - - // As long as resources used by deferred contexts are not released before the command list - // is executed through immediate context, this stategy always works. - Queue.ReleaseQueue.DiscardStaleResources(CmdBuffInfo.CmdBufferNumber, CmdBuffInfo.FenceValue); - } - - return CmdBuffInfo; - } - - ResourceReleaseQueue& GetReleaseQueue(Uint32 QueueIndex) - { - VERIFY_EXPR(QueueIndex < m_CmdQueueCount); - return m_CommandQueues[QueueIndex].ReleaseQueue; - } - - const CommandQueueType& GetCommandQueue(Uint32 QueueIndex) const - { - VERIFY_EXPR(QueueIndex < m_CmdQueueCount); - return *m_CommandQueues[QueueIndex].CmdQueue; - } - - virtual Uint64 GetCompletedFenceValue(Uint32 QueueIndex) override final - { - return m_CommandQueues[QueueIndex].CmdQueue->GetCompletedFenceValue(); - } - - virtual Uint64 GetNextFenceValue(Uint32 QueueIndex) override final - { - return m_CommandQueues[QueueIndex].CmdQueue->GetNextFenceValue(); - } - - virtual Bool IsFenceSignaled(Uint32 QueueIndex, Uint64 FenceValue) override final - { - return FenceValue <= GetCompletedFenceValue(QueueIndex); - } - - template - void LockCmdQueueAndRun(Uint32 QueueIndex, TAction Action) - { - VERIFY_EXPR(QueueIndex < m_CmdQueueCount); - auto& Queue = m_CommandQueues[QueueIndex]; - std::lock_guard Lock{Queue.Mtx}; - Action(Queue.CmdQueue); - } - - CommandQueueType* LockCommandQueue(Uint32 QueueIndex) - { - VERIFY_EXPR(QueueIndex < m_CmdQueueCount); - auto& Queue = m_CommandQueues[QueueIndex]; - Queue.Mtx.lock(); - return Queue.CmdQueue; - } - - void UnlockCommandQueue(Uint32 QueueIndex) - { - VERIFY_EXPR(QueueIndex < m_CmdQueueCount); - auto& Queue = m_CommandQueues[QueueIndex]; - Queue.Mtx.unlock(); - } - -protected: - void DestroyCommandQueues() - { - if (m_CommandQueues != nullptr) - { - for (size_t q = 0; q < m_CmdQueueCount; ++q) - { - auto& Queue = m_CommandQueues[q]; - DEV_CHECK_ERR(Queue.ReleaseQueue.GetStaleResourceCount() == 0, "All stale resources must be released before destroying a command queue"); - DEV_CHECK_ERR(Queue.ReleaseQueue.GetPendingReleaseResourceCount() == 0, "All resources must be released before destroying a command queue"); - Queue.~CommandQueue(); - } - this->m_RawMemAllocator.Free(m_CommandQueues); - m_CommandQueues = nullptr; - } - } - - struct CommandQueue - { - CommandQueue(RefCntAutoPtr _CmdQueue, IMemoryAllocator& Allocator) noexcept : - CmdQueue{std::move(_CmdQueue)}, - ReleaseQueue{Allocator} - { - NextCmdBufferNumber = 0; - } - - // clang-format off - CommandQueue (const CommandQueue&) = delete; - CommandQueue ( CommandQueue&&) = delete; - CommandQueue& operator = (const CommandQueue&) = delete; - CommandQueue& operator = ( CommandQueue&&) = delete; - // clang-format on - - std::mutex Mtx; - Atomics::AtomicInt64 NextCmdBufferNumber; - RefCntAutoPtr CmdQueue; - ResourceReleaseQueue ReleaseQueue; - }; - const size_t m_CmdQueueCount = 0; - CommandQueue* m_CommandQueues = nullptr; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineNextGenBase/include/RenderDeviceNextGenBase.hpp b/Graphics/GraphicsEngineNextGenBase/include/RenderDeviceNextGenBase.hpp new file mode 100644 index 00000000..8ac8bc18 --- /dev/null +++ b/Graphics/GraphicsEngineNextGenBase/include/RenderDeviceNextGenBase.hpp @@ -0,0 +1,324 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include + +#include "EngineFactory.h" +#include "Atomics.h" +#include "BasicTypes.h" +#include "ReferenceCounters.h" +#include "MemoryAllocator.h" +#include "RefCntAutoPtr.h" +#include "PlatformMisc.h" +#include "ResourceReleaseQueue.hpp" +#include "EngineMemory.h" + +namespace Diligent +{ + +/// Base implementation of the render device for next-generation backends. + +template +class RenderDeviceNextGenBase : public TBase +{ +public: + using typename TBase::DeviceObjectSizes; + + RenderDeviceNextGenBase(IReferenceCounters* pRefCounters, + IMemoryAllocator& RawMemAllocator, + IEngineFactory* pEngineFactory, + size_t CmdQueueCount, + CommandQueueType** Queues, + Uint32 NumDeferredContexts, + const DeviceObjectSizes& ObjectSizes) : + TBase{pRefCounters, RawMemAllocator, pEngineFactory, NumDeferredContexts, ObjectSizes}, + m_CmdQueueCount{CmdQueueCount} + { + m_CommandQueues = ALLOCATE(this->m_RawMemAllocator, "Raw memory for the device command/release queues", CommandQueue, m_CmdQueueCount); + for (size_t q = 0; q < m_CmdQueueCount; ++q) + new (m_CommandQueues + q) CommandQueue(RefCntAutoPtr(Queues[q]), this->m_RawMemAllocator); + } + + ~RenderDeviceNextGenBase() + { + DestroyCommandQueues(); + } + + // The following basic requirement guarantees correctness of resource deallocation: + // + // A resource is never released before the last draw command referencing it is submitted to the command queue + // + + // + // CPU + // Last Reference + // of resource X + // | + // | Submit Cmd Submit Cmd Submit Cmd + // | List N List N+1 List N+2 + // V | | | + // NextFenceValue | * N | N+1 | N+2 | + // + // + // CompletedFenceValue | N-3 | N-2 | N-1 | N | + // . . . . . + // -----------------------------.--------------.---------------.-------------------.----------------.------------- + // . . . . . + // + // GPU | Cmd List N-2 | Cmd List N-1 | Cmd List N | Cmd List N+1 | + // | + // | + // Resource X can + // be released + template ::value>::type> + void SafeReleaseDeviceObject(ObjectType&& Object, Uint64 QueueMask) + { + QueueMask &= GetCommandQueueMask(); + + VERIFY(QueueMask != 0, "At least one bit should be set in the command queue mask"); + if (QueueMask == 0) + return; + + Atomics::Long NumReferences = PlatformMisc::CountOneBits(QueueMask); + auto Wrapper = DynamicStaleResourceWrapper::Create(std::move(Object), NumReferences); + + while (QueueMask != 0) + { + auto QueueIndex = PlatformMisc::GetLSB(QueueMask); + VERIFY_EXPR(QueueIndex < m_CmdQueueCount); + + auto& Queue = m_CommandQueues[QueueIndex]; + // Do not use std::move on wrapper!!! + Queue.ReleaseQueue.SafeReleaseResource(Wrapper, Queue.NextCmdBufferNumber); + QueueMask &= ~(Uint64{1} << Uint64{QueueIndex}); + --NumReferences; + } + VERIFY_EXPR(NumReferences == 0); + + Wrapper.GiveUpOwnership(); + } + + size_t GetCommandQueueCount() const + { + return m_CmdQueueCount; + } + + Uint64 GetCommandQueueMask() const + { + return (m_CmdQueueCount < 64) ? ((Uint64{1} << Uint64{m_CmdQueueCount}) - 1) : ~Uint64{0}; + } + + void PurgeReleaseQueues(bool ForceRelease = false) + { + for (Uint32 q = 0; q < m_CmdQueueCount; ++q) + PurgeReleaseQueue(q, ForceRelease); + } + + void PurgeReleaseQueue(Uint32 QueueIndex, bool ForceRelease = false) + { + VERIFY_EXPR(QueueIndex < m_CmdQueueCount); + auto& Queue = m_CommandQueues[QueueIndex]; + auto CompletedFenceValue = ForceRelease ? std::numeric_limits::max() : Queue.CmdQueue->GetCompletedFenceValue(); + Queue.ReleaseQueue.Purge(CompletedFenceValue); + } + + void IdleCommandQueue(size_t QueueIdx, bool ReleaseResources) + { + VERIFY_EXPR(QueueIdx < m_CmdQueueCount); + auto& Queue = m_CommandQueues[QueueIdx]; + + Uint64 CmdBufferNumber = 0; + Uint64 FenceValue = 0; + { + std::lock_guard Lock{Queue.Mtx}; + + if (ReleaseResources) + { + // Increment command buffer number before idling the queue. + // This will make sure that any resource released while this function + // is running will be associated with the next command buffer submission. + CmdBufferNumber = static_cast(Queue.NextCmdBufferNumber); + Atomics::AtomicIncrement(Queue.NextCmdBufferNumber); + } + + FenceValue = Queue.CmdQueue->WaitForIdle(); + } + + if (ReleaseResources) + { + Queue.ReleaseQueue.DiscardStaleResources(CmdBufferNumber, FenceValue); + Queue.ReleaseQueue.Purge(Queue.CmdQueue->GetCompletedFenceValue()); + } + } + + void IdleAllCommandQueues(bool ReleaseResources) + { + for (size_t q = 0; q < m_CmdQueueCount; ++q) + IdleCommandQueue(q, ReleaseResources); + } + + struct SubmittedCommandBufferInfo + { + Uint64 CmdBufferNumber = 0; + Uint64 FenceValue = 0; + }; + template + SubmittedCommandBufferInfo SubmitCommandBuffer(Uint32 QueueIndex, SubmitDataType& SubmitData, bool DiscardStaleResources) + { + SubmittedCommandBufferInfo CmdBuffInfo; + VERIFY_EXPR(QueueIndex < m_CmdQueueCount); + auto& Queue = m_CommandQueues[QueueIndex]; + + { + std::lock_guard Lock{Queue.Mtx}; + + // Increment command buffer number before submitting the cmd buffer. + // This will make sure that any resource released while this function + // is running will be associated with the next command buffer. + CmdBuffInfo.CmdBufferNumber = static_cast(Queue.NextCmdBufferNumber); + Atomics::AtomicIncrement(Queue.NextCmdBufferNumber); + + CmdBuffInfo.FenceValue = Queue.CmdQueue->Submit(SubmitData); + } + + if (DiscardStaleResources) + { + // The following basic requirement guarantees correctness of resource deallocation: + // + // A resource is never released before the last draw command referencing it is submitted for execution + // + + // Move stale objects into the release queue. + // Note that objects are moved from stale list to release queue based on the cmd buffer number, + // not fence value. This makes sure that basic requirement is met even when the fence value is + // not incremented while executing the command buffer (as is the case with Unity command queue). + + // As long as resources used by deferred contexts are not released before the command list + // is executed through immediate context, this stategy always works. + Queue.ReleaseQueue.DiscardStaleResources(CmdBuffInfo.CmdBufferNumber, CmdBuffInfo.FenceValue); + } + + return CmdBuffInfo; + } + + ResourceReleaseQueue& GetReleaseQueue(Uint32 QueueIndex) + { + VERIFY_EXPR(QueueIndex < m_CmdQueueCount); + return m_CommandQueues[QueueIndex].ReleaseQueue; + } + + const CommandQueueType& GetCommandQueue(Uint32 QueueIndex) const + { + VERIFY_EXPR(QueueIndex < m_CmdQueueCount); + return *m_CommandQueues[QueueIndex].CmdQueue; + } + + virtual Uint64 GetCompletedFenceValue(Uint32 QueueIndex) override final + { + return m_CommandQueues[QueueIndex].CmdQueue->GetCompletedFenceValue(); + } + + virtual Uint64 GetNextFenceValue(Uint32 QueueIndex) override final + { + return m_CommandQueues[QueueIndex].CmdQueue->GetNextFenceValue(); + } + + virtual Bool IsFenceSignaled(Uint32 QueueIndex, Uint64 FenceValue) override final + { + return FenceValue <= GetCompletedFenceValue(QueueIndex); + } + + template + void LockCmdQueueAndRun(Uint32 QueueIndex, TAction Action) + { + VERIFY_EXPR(QueueIndex < m_CmdQueueCount); + auto& Queue = m_CommandQueues[QueueIndex]; + std::lock_guard Lock{Queue.Mtx}; + Action(Queue.CmdQueue); + } + + CommandQueueType* LockCommandQueue(Uint32 QueueIndex) + { + VERIFY_EXPR(QueueIndex < m_CmdQueueCount); + auto& Queue = m_CommandQueues[QueueIndex]; + Queue.Mtx.lock(); + return Queue.CmdQueue; + } + + void UnlockCommandQueue(Uint32 QueueIndex) + { + VERIFY_EXPR(QueueIndex < m_CmdQueueCount); + auto& Queue = m_CommandQueues[QueueIndex]; + Queue.Mtx.unlock(); + } + +protected: + void DestroyCommandQueues() + { + if (m_CommandQueues != nullptr) + { + for (size_t q = 0; q < m_CmdQueueCount; ++q) + { + auto& Queue = m_CommandQueues[q]; + DEV_CHECK_ERR(Queue.ReleaseQueue.GetStaleResourceCount() == 0, "All stale resources must be released before destroying a command queue"); + DEV_CHECK_ERR(Queue.ReleaseQueue.GetPendingReleaseResourceCount() == 0, "All resources must be released before destroying a command queue"); + Queue.~CommandQueue(); + } + this->m_RawMemAllocator.Free(m_CommandQueues); + m_CommandQueues = nullptr; + } + } + + struct CommandQueue + { + CommandQueue(RefCntAutoPtr _CmdQueue, IMemoryAllocator& Allocator) noexcept : + CmdQueue{std::move(_CmdQueue)}, + ReleaseQueue{Allocator} + { + NextCmdBufferNumber = 0; + } + + // clang-format off + CommandQueue (const CommandQueue&) = delete; + CommandQueue ( CommandQueue&&) = delete; + CommandQueue& operator = (const CommandQueue&) = delete; + CommandQueue& operator = ( CommandQueue&&) = delete; + // clang-format on + + std::mutex Mtx; + Atomics::AtomicInt64 NextCmdBufferNumber; + RefCntAutoPtr CmdQueue; + ResourceReleaseQueue ReleaseQueue; + }; + const size_t m_CmdQueueCount = 0; + CommandQueue* m_CommandQueues = nullptr; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineNextGenBase/src/dummy.cpp b/Graphics/GraphicsEngineNextGenBase/src/dummy.cpp index 5a756046..543f8df9 100644 --- a/Graphics/GraphicsEngineNextGenBase/src/dummy.cpp +++ b/Graphics/GraphicsEngineNextGenBase/src/dummy.cpp @@ -25,4 +25,4 @@ * of the possibility of such damages. */ -#include "RenderDeviceNextGenBase.h" +#include "RenderDeviceNextGenBase.hpp" -- cgit v1.2.3