diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2017-05-20 21:00:37 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2017-05-20 21:00:37 +0000 |
| commit | 109a75aac22463802f03dfc6588951ed0b04892a (patch) | |
| tree | 51e121c71b7e8d30bab1eb400e21497677797a03 /Graphics/GraphicsTools | |
| parent | Resolved conflicts (diff) | |
| download | DiligentCore-109a75aac22463802f03dfc6588951ed0b04892a.tar.gz DiligentCore-109a75aac22463802f03dfc6588951ed0b04892a.zip | |
Merge from dev branch
Diffstat (limited to 'Graphics/GraphicsTools')
10 files changed, 140 insertions, 64 deletions
diff --git a/Graphics/GraphicsTools/include/BasicShaderSourceStreamFactory.h b/Graphics/GraphicsTools/include/BasicShaderSourceStreamFactory.h index 86e2650b..24e87df5 100644 --- a/Graphics/GraphicsTools/include/BasicShaderSourceStreamFactory.h +++ b/Graphics/GraphicsTools/include/BasicShaderSourceStreamFactory.h @@ -1,4 +1,4 @@ -/* Copyright 2015-2016 Egor Yusov +/* Copyright 2015-2017 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsTools/include/GraphicsUtilities.h b/Graphics/GraphicsTools/include/GraphicsUtilities.h index 6e6b34f6..f13684fd 100644 --- a/Graphics/GraphicsTools/include/GraphicsUtilities.h +++ b/Graphics/GraphicsTools/include/GraphicsUtilities.h @@ -1,4 +1,4 @@ -/* Copyright 2015-2016 Egor Yusov +/* Copyright 2015-2017 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsTools/include/RingBuffer.h b/Graphics/GraphicsTools/include/RingBuffer.h index ee2b7d6c..8c4119ac 100644 --- a/Graphics/GraphicsTools/include/RingBuffer.h +++ b/Graphics/GraphicsTools/include/RingBuffer.h @@ -1,4 +1,4 @@ -/* Copyright 2015-2016 Egor Yusov +/* Copyright 2015-2017 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,12 +39,21 @@ namespace Diligent { public: typedef size_t OffsetType; - typedef std::pair<Uint64,OffsetType> FrameNumOffsetPair; - + struct FrameTailAttribs + { + FrameTailAttribs(Uint64 fn, OffsetType off, OffsetType sz) : + FrameNum(fn), + Offset(off), + Size(sz) + {} + Uint64 FrameNum; + OffsetType Offset; + OffsetType Size; + }; static const OffsetType InvalidOffset = static_cast<OffsetType>(-1); RingBuffer(OffsetType MaxSize, IMemoryAllocator &Allocator) : - m_CompletedFrameTails(0, FrameNumOffsetPair(), STD_ALLOCATOR_RAW_MEM(FrameNumOffsetPair, Allocator, "Allocator for vector<FrameNumOffsetPair>" )), + m_CompletedFrameTails(0, FrameTailAttribs(0,0,0), STD_ALLOCATOR_RAW_MEM(FrameTailAttribs, Allocator, "Allocator for vector<FrameNumOffsetPair>" )), m_MaxSize(MaxSize) {} @@ -53,12 +62,19 @@ namespace Diligent m_Head(rhs.m_Head), m_Tail(rhs.m_Tail), m_MaxSize(rhs.m_MaxSize), - m_UsedSize(rhs.m_UsedSize) + m_UsedSize(rhs.m_UsedSize), + m_CurrFrameSize(rhs.m_CurrFrameSize) { rhs.m_Head = 0; rhs.m_Tail = 0; rhs.m_MaxSize = 0; rhs.m_UsedSize = 0; + rhs.m_CurrFrameSize = 0; + } + + ~RingBuffer() + { + VERIFY(m_UsedSize==0, "All space in the ring buffer must be released") } RingBuffer& operator = (RingBuffer&& rhs) @@ -68,11 +84,13 @@ namespace Diligent m_Tail = rhs.m_Tail; m_MaxSize = rhs.m_MaxSize; m_UsedSize = rhs.m_UsedSize; + m_CurrFrameSize = rhs.m_CurrFrameSize; rhs.m_MaxSize = 0; rhs.m_Head = 0; rhs.m_Tail = 0; rhs.m_UsedSize = 0; + rhs.m_CurrFrameSize = 0; return *this; } @@ -99,12 +117,15 @@ namespace Diligent auto Offset = m_Tail; m_Tail += Size; m_UsedSize += Size; + m_CurrFrameSize += Size; return Offset; } else if(Size <= m_Head) { // Allocate from the beginning of the buffer - m_UsedSize += (m_MaxSize - m_Tail) + Size; + OffsetType AddSize = (m_MaxSize - m_Tail) + Size; + m_UsedSize += AddSize; + m_CurrFrameSize += AddSize; m_Tail = Size; return 0; } @@ -119,54 +140,33 @@ namespace Diligent auto Offset = m_Tail; m_Tail += Size; m_UsedSize += Size; + m_CurrFrameSize += Size; return Offset; } return InvalidOffset; } + // FrameNum is the number of the frame (or command list) in which the tail + // could have been referenced last time + // See http://diligentgraphics.com/diligent-engine/architecture/d3d12/managing-resource-lifetimes/ void FinishCurrentFrame(Uint64 FrameNum) { - m_CompletedFrameTails.push_back(std::make_pair(FrameNum, m_Tail) ); + m_CompletedFrameTails.emplace_back(FrameNum, m_Tail, m_CurrFrameSize); + m_CurrFrameSize = 0; } + // NumCompletedFrames is the number of completed frames (or command lists) + // See http://diligentgraphics.com/diligent-engine/architecture/d3d12/managing-resource-lifetimes/ void ReleaseCompletedFrames(Uint64 NumCompletedFrames) { - while(!m_CompletedFrameTails.empty() && m_CompletedFrameTails.front().first < NumCompletedFrames) + // Command list is completed when its number is strictly less than the number of completed frames + while(!m_CompletedFrameTails.empty() && m_CompletedFrameTails.front().FrameNum < NumCompletedFrames) { - auto &OldestFrameTail = m_CompletedFrameTails.front().second; - if( m_UsedSize > 0 ) - { - if (OldestFrameTail > m_Head) - { - // m_Head OldestFrameTail MaxSize - // | | | - // [ xxxxxxxxxxxxxxxxxxxxx ] - // - // - VERIFY_EXPR(m_UsedSize >= OldestFrameTail - m_Head); - m_UsedSize -= OldestFrameTail - m_Head; - } - else - { - // OldestFrameTail m_Head MaxSize - // | | | - // [xxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx] - // - - // - // m_Head,OldestFrameTail MaxSize - // | | - // [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx] - // - // - // - VERIFY_EXPR(m_UsedSize >= (m_MaxSize - m_Head) + OldestFrameTail); - m_UsedSize -= (m_MaxSize - m_Head); - m_UsedSize -= OldestFrameTail; - } - } - m_Head = OldestFrameTail; + const auto &OldestFrameTail = m_CompletedFrameTails.front(); + VERIFY_EXPR(OldestFrameTail.Size <= m_MaxSize); + m_UsedSize -= OldestFrameTail.Size; + m_Head = OldestFrameTail.Offset; m_CompletedFrameTails.pop_front(); } } @@ -177,10 +177,61 @@ namespace Diligent OffsetType GetUsedSize()const{return m_UsedSize;} private: - std::deque< FrameNumOffsetPair, STDAllocatorRawMem<FrameNumOffsetPair> > m_CompletedFrameTails; + // Consider the following scenario for 1024 buffer: + // Allocate(512) + // + // h t m + // |xxxxx| | + + // FinishCurrentFrame(0) + // + // t0 + // h t m + // |xxxxx| | + + // ReleaseCompletedFrames(1) + // + // h + // t m + // | | | + + // FinishCurrentFrame(1) + // + // t1 + // h + // t m + // | | | + + // Allocate(512) + // + // t1 t + // h m + // | |xxxxx| + + // Allocate(512) + // + // t + // t1 + // h m + // |xxxxx|xxxxx| + + // FinishCurrentFrame(2) + // + // t + // t1 + // t2 + // h m + // |xxxxx|xxxxx| + + // At this point there will be two tails in the queue, both at 512. m_UsedSize will be 0. When + // ReleaseCompletedFrames(2) is called, there wil be no way to find out if the current frame is 0 + // or the entire buffer if we don't store the frame size + + std::deque< FrameTailAttribs, STDAllocatorRawMem<FrameTailAttribs> > m_CompletedFrameTails; OffsetType m_Head = 0; OffsetType m_Tail = 0; OffsetType m_MaxSize = 0; OffsetType m_UsedSize = 0; + OffsetType m_CurrFrameSize = 0; }; } diff --git a/Graphics/GraphicsTools/include/ShaderMacroHelper.h b/Graphics/GraphicsTools/include/ShaderMacroHelper.h index f64c2349..1beec624 100644 --- a/Graphics/GraphicsTools/include/ShaderMacroHelper.h +++ b/Graphics/GraphicsTools/include/ShaderMacroHelper.h @@ -1,4 +1,4 @@ -/* Copyright 2015-2016 Egor Yusov +/* Copyright 2015-2017 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsTools/include/VariableSizeAllocationsManager.h b/Graphics/GraphicsTools/include/VariableSizeAllocationsManager.h index c415d82e..17381758 100644 --- a/Graphics/GraphicsTools/include/VariableSizeAllocationsManager.h +++ b/Graphics/GraphicsTools/include/VariableSizeAllocationsManager.h @@ -21,6 +21,9 @@ * of the possibility of such damages. */ +// Helper class that handles free memory block management to accommodate variable-size allocation requests +// See http://diligentgraphics.com/diligent-engine/architecture/d3d12/variable-size-memory-allocations-manager/ + #pragma once #include <map> @@ -298,7 +301,11 @@ namespace Diligent VERIFY_EXPR(BlockIt->first >= 0 && BlockIt->first + BlockIt->second.Size <= m_MaxSize); VERIFY_EXPR(BlockIt == BlockIt->second.OrderBySizeIt->second); VERIFY_EXPR(BlockIt->second.Size == BlockIt->second.OrderBySizeIt->first); - VERIFY(PrevBlockIt == m_FreeBlocksByOffset.end() || BlockIt->first > PrevBlockIt->first + PrevBlockIt->second.Size, "Not merged adjacent or overlapping blocks detected" ); + // 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; PrevBlockIt = BlockIt; diff --git a/Graphics/GraphicsTools/include/VariableSizeGPUAllocationsManager.h b/Graphics/GraphicsTools/include/VariableSizeGPUAllocationsManager.h index 4804338a..b1cb9693 100644 --- a/Graphics/GraphicsTools/include/VariableSizeGPUAllocationsManager.h +++ b/Graphics/GraphicsTools/include/VariableSizeGPUAllocationsManager.h @@ -21,6 +21,10 @@ * of the possibility of such damages. */ + +// An GPU-tailored extension of the basic variable-size allocations manager +// See http://diligentgraphics.com/diligent-engine/architecture/d3d12/variable-size-memory-allocations-manager/ + #pragma once #include <deque> @@ -29,60 +33,74 @@ 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 { private: - struct FreedAllocationInfo + struct StaleAllocationAttribs { OffsetType Offset; OffsetType Size; - Uint64 FrameNumber; - FreedAllocationInfo(OffsetType _Offset, OffsetType _Size, Uint64 _FrameNumber) : - Offset(_Offset), Size(_Size), FrameNumber(_FrameNumber) + Uint64 CmdListNumber; + StaleAllocationAttribs(OffsetType _Offset, OffsetType _Size, Uint64 _CmdListNumber) : + Offset(_Offset), Size(_Size), CmdListNumber(_CmdListNumber) {} }; public: VariableSizeGPUAllocationsManager(OffsetType MaxSize, IMemoryAllocator &Allocator) : VariableSizeAllocationsManager(MaxSize, Allocator), - m_StaleAllocations(0, FreedAllocationInfo(0,0,0), STD_ALLOCATOR_RAW_MEM(FreedAllocationInfo, Allocator, "Allocator for deque< FreedAllocationInfo>" )) + m_StaleAllocations(0, StaleAllocationAttribs(0,0,0), STD_ALLOCATOR_RAW_MEM(StaleAllocationAttribs, Allocator, "Allocator for deque<StaleAllocationAttribs>" )) {} ~VariableSizeGPUAllocationsManager() { VERIFY(m_StaleAllocations.empty(), "Not all stale allocations released"); + VERIFY(m_StaleAllocationsSize == 0, "Not all stale allocations released") } // = default causes compiler error when instantiating std::vector::emplace_back() in Visual Studio 2015 (Version 14.0.23107.0 D14REL) VariableSizeGPUAllocationsManager(VariableSizeGPUAllocationsManager&& rhs) : VariableSizeAllocationsManager(std::move(rhs)), - m_StaleAllocations(std::move(rhs.m_StaleAllocations)) + m_StaleAllocations(std::move(rhs.m_StaleAllocations)), + m_StaleAllocationsSize(rhs.m_StaleAllocationsSize) { + rhs.m_StaleAllocationsSize = 0; } - VariableSizeGPUAllocationsManager& operator = (VariableSizeGPUAllocationsManager&& rhs) = default; + VariableSizeGPUAllocationsManager& operator = (VariableSizeGPUAllocationsManager&& rhs) = delete; VariableSizeGPUAllocationsManager(const VariableSizeGPUAllocationsManager&) = delete; VariableSizeGPUAllocationsManager& operator = (const VariableSizeGPUAllocationsManager&) = delete; - void Free(OffsetType Offset, OffsetType Size, Uint64 FrameNumber) + void Free(OffsetType Offset, OffsetType Size, Uint64 CmdListNumber) { // Do not release the block immediately, but add // it to the queue instead - m_StaleAllocations.emplace_back(Offset, Size, FrameNumber); + m_StaleAllocations.emplace_back(Offset, Size, CmdListNumber); + m_StaleAllocationsSize += Size; } - void ReleaseCompletedFrames(Uint64 NumCompletedFrames) + // Releases stale allocation from completed command lists + // The method takes the NUMBER of completed cmd lists (N) + // and releases all allocations whose number n < N + // (n == N is NOT released) + void ReleaseStaleAllocations(Uint64 NumCompletedCmdLists) { - // Free all allocations from the beginning of the queue that belong to completed frames - while(!m_StaleAllocations.empty() && m_StaleAllocations.front().FrameNumber < NumCompletedFrames) + // Free all allocations from the beginning of the queue that belong to completed command lists + while(!m_StaleAllocations.empty() && m_StaleAllocations.front().CmdListNumber < NumCompletedCmdLists) { auto &OldestAllocation = m_StaleAllocations.front(); VariableSizeAllocationsManager::Free(OldestAllocation.Offset, OldestAllocation.Size); - m_StaleAllocations.pop_front(); + m_StaleAllocationsSize -= OldestAllocation.Size; + m_StaleAllocations.pop_front(); } } + size_t GetStaleAllocationsSize()const { return m_StaleAllocationsSize; } + private: - std::deque< FreedAllocationInfo, STDAllocatorRawMem<FreedAllocationInfo> > m_StaleAllocations; + std::deque< StaleAllocationAttribs, STDAllocatorRawMem<StaleAllocationAttribs> > m_StaleAllocations; + size_t m_StaleAllocationsSize = 0; }; } diff --git a/Graphics/GraphicsTools/include/pch.h b/Graphics/GraphicsTools/include/pch.h index 41fa3c3b..690233d1 100644 --- a/Graphics/GraphicsTools/include/pch.h +++ b/Graphics/GraphicsTools/include/pch.h @@ -1,4 +1,4 @@ -/* Copyright 2015-2016 Egor Yusov +/* Copyright 2015-2017 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsTools/src/BasicShaderSourceStreamFactory.cpp b/Graphics/GraphicsTools/src/BasicShaderSourceStreamFactory.cpp index e15635e8..6c1db669 100644 --- a/Graphics/GraphicsTools/src/BasicShaderSourceStreamFactory.cpp +++ b/Graphics/GraphicsTools/src/BasicShaderSourceStreamFactory.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015-2016 Egor Yusov +/* Copyright 2015-2017 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsTools/src/GraphicsUtilities.cpp b/Graphics/GraphicsTools/src/GraphicsUtilities.cpp index f3a7d873..e0ae1dce 100644 --- a/Graphics/GraphicsTools/src/GraphicsUtilities.cpp +++ b/Graphics/GraphicsTools/src/GraphicsUtilities.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015-2016 Egor Yusov +/* Copyright 2015-2017 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/Graphics/GraphicsTools/src/pch.cpp b/Graphics/GraphicsTools/src/pch.cpp index 997e0f4a..d5f45c6a 100644 --- a/Graphics/GraphicsTools/src/pch.cpp +++ b/Graphics/GraphicsTools/src/pch.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015-2016 Egor Yusov +/* Copyright 2015-2017 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. |
