summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsTools
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2017-05-20 21:00:37 +0000
committerEgor Yusov <egor.yusov@gmail.com>2017-05-20 21:00:37 +0000
commit109a75aac22463802f03dfc6588951ed0b04892a (patch)
tree51e121c71b7e8d30bab1eb400e21497677797a03 /Graphics/GraphicsTools
parentResolved conflicts (diff)
downloadDiligentCore-109a75aac22463802f03dfc6588951ed0b04892a.tar.gz
DiligentCore-109a75aac22463802f03dfc6588951ed0b04892a.zip
Merge from dev branch
Diffstat (limited to 'Graphics/GraphicsTools')
-rw-r--r--Graphics/GraphicsTools/include/BasicShaderSourceStreamFactory.h2
-rw-r--r--Graphics/GraphicsTools/include/GraphicsUtilities.h2
-rw-r--r--Graphics/GraphicsTools/include/RingBuffer.h135
-rw-r--r--Graphics/GraphicsTools/include/ShaderMacroHelper.h2
-rw-r--r--Graphics/GraphicsTools/include/VariableSizeAllocationsManager.h9
-rw-r--r--Graphics/GraphicsTools/include/VariableSizeGPUAllocationsManager.h46
-rw-r--r--Graphics/GraphicsTools/include/pch.h2
-rw-r--r--Graphics/GraphicsTools/src/BasicShaderSourceStreamFactory.cpp2
-rw-r--r--Graphics/GraphicsTools/src/GraphicsUtilities.cpp2
-rw-r--r--Graphics/GraphicsTools/src/pch.cpp2
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.