mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator.git
synced 2024-11-24 21:10:11 +00:00
Removed Pool::SetMinBytes, Allocator::SetDefaultHeapMinBytes (compatibility breaking!)
More refactoring. Added private enum ResourceClass.
This commit is contained in:
parent
b2c5183078
commit
49fb8acf85
@ -687,6 +687,42 @@ static UINT GetBitsPerPixel(DXGI_FORMAT format)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const D3D12_HEAP_FLAGS RESOURCE_CLASS_HEAP_FLAGS =
|
||||||
|
D3D12_HEAP_FLAG_DENY_BUFFERS | D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES | D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES;
|
||||||
|
|
||||||
|
enum class ResourceClass
|
||||||
|
{
|
||||||
|
Unknown, Buffer, Non_RT_DS_Texture, RT_DS_Texture
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename D3D12_RESOURCE_DESC_T>
|
||||||
|
static inline ResourceClass ResourceDescToResourceClass(const D3D12_RESOURCE_DESC_T& resDesc)
|
||||||
|
{
|
||||||
|
if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||||
|
return ResourceClass::Buffer;
|
||||||
|
// Else: it's surely a texture.
|
||||||
|
const bool isRenderTargetOrDepthStencil =
|
||||||
|
(resDesc.Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)) != 0;
|
||||||
|
return isRenderTargetOrDepthStencil ? ResourceClass::RT_DS_Texture : ResourceClass::Non_RT_DS_Texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ResourceClass HeapFlagsToResourceClass(D3D12_HEAP_FLAGS heapFlags)
|
||||||
|
{
|
||||||
|
const bool allowBuffers = (heapFlags & D3D12_HEAP_FLAG_DENY_BUFFERS ) == 0;
|
||||||
|
const bool allowRtDsTextures = (heapFlags & D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES ) == 0;
|
||||||
|
const bool allowNonRtDsTextures = (heapFlags & D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES) == 0;
|
||||||
|
|
||||||
|
const uint8_t allowedGroupCount = (allowBuffers ? 1 : 0) + (allowRtDsTextures ? 1 : 0) + (allowNonRtDsTextures ? 1 : 0);
|
||||||
|
if(allowedGroupCount != 1)
|
||||||
|
return ResourceClass::Unknown;
|
||||||
|
|
||||||
|
if(allowRtDsTextures)
|
||||||
|
return ResourceClass::RT_DS_Texture;
|
||||||
|
if(allowNonRtDsTextures)
|
||||||
|
return ResourceClass::Non_RT_DS_Texture;
|
||||||
|
return ResourceClass::Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
// This algorithm is overly conservative.
|
// This algorithm is overly conservative.
|
||||||
template<typename D3D12_RESOURCE_DESC_T>
|
template<typename D3D12_RESOURCE_DESC_T>
|
||||||
static bool CanUseSmallAlignment(const D3D12_RESOURCE_DESC_T& resourceDesc)
|
static bool CanUseSmallAlignment(const D3D12_RESOURCE_DESC_T& resourceDesc)
|
||||||
@ -728,13 +764,6 @@ static bool CanUseSmallAlignment(const D3D12_RESOURCE_DESC_T& resourceDesc)
|
|||||||
return tileCount <= 16;
|
return tileCount <= 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
static D3D12_HEAP_FLAGS GetExtraHeapFlagsToIgnore()
|
|
||||||
{
|
|
||||||
D3D12_HEAP_FLAGS result =
|
|
||||||
D3D12_HEAP_FLAG_DENY_BUFFERS | D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES | D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool IsHeapTypeStandard(D3D12_HEAP_TYPE type)
|
static inline bool IsHeapTypeStandard(D3D12_HEAP_TYPE type)
|
||||||
{
|
{
|
||||||
return type == D3D12_HEAP_TYPE_DEFAULT ||
|
return type == D3D12_HEAP_TYPE_DEFAULT ||
|
||||||
@ -2644,8 +2673,6 @@ public:
|
|||||||
void** ppvResource);
|
void** ppvResource);
|
||||||
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||||
|
|
||||||
HRESULT SetMinBytes(UINT64 minBytes);
|
|
||||||
|
|
||||||
void AddStats(StatInfo& outStats);
|
void AddStats(StatInfo& outStats);
|
||||||
void AddStats(Stats& outStats);
|
void AddStats(Stats& outStats);
|
||||||
|
|
||||||
@ -2659,7 +2686,6 @@ private:
|
|||||||
const size_t m_MinBlockCount;
|
const size_t m_MinBlockCount;
|
||||||
const size_t m_MaxBlockCount;
|
const size_t m_MaxBlockCount;
|
||||||
const bool m_ExplicitBlockSize;
|
const bool m_ExplicitBlockSize;
|
||||||
UINT64 m_MinBytes;
|
|
||||||
/* There can be at most one allocation that is completely empty - a
|
/* There can be at most one allocation that is completely empty - a
|
||||||
hysteresis to avoid pessimistic case of alternating creation and destruction
|
hysteresis to avoid pessimistic case of alternating creation and destruction
|
||||||
of a VkDeviceMemory. */
|
of a VkDeviceMemory. */
|
||||||
@ -2754,8 +2780,6 @@ public:
|
|||||||
const POOL_DESC& GetDesc() const { return m_Desc; }
|
const POOL_DESC& GetDesc() const { return m_Desc; }
|
||||||
BlockVector* GetBlockVector() { return m_BlockVector; }
|
BlockVector* GetBlockVector() { return m_BlockVector; }
|
||||||
|
|
||||||
HRESULT SetMinBytes(UINT64 minBytes) { return m_BlockVector->SetMinBytes(minBytes); }
|
|
||||||
|
|
||||||
void CalculateStats(StatInfo& outStats);
|
void CalculateStats(StatInfo& outStats);
|
||||||
|
|
||||||
void SetName(LPCWSTR Name);
|
void SetName(LPCWSTR Name);
|
||||||
@ -2865,11 +2889,6 @@ public:
|
|||||||
REFIID riidResource,
|
REFIID riidResource,
|
||||||
void** ppvResource);
|
void** ppvResource);
|
||||||
|
|
||||||
HRESULT SetDefaultHeapMinBytes(
|
|
||||||
D3D12_HEAP_TYPE heapType,
|
|
||||||
D3D12_HEAP_FLAGS heapFlags,
|
|
||||||
UINT64 minBytes);
|
|
||||||
|
|
||||||
// Unregisters allocation from the collection of dedicated allocations.
|
// Unregisters allocation from the collection of dedicated allocations.
|
||||||
// Allocation object must be deleted externally afterwards.
|
// Allocation object must be deleted externally afterwards.
|
||||||
void FreeCommittedMemory(Allocation* allocation);
|
void FreeCommittedMemory(Allocation* allocation);
|
||||||
@ -2934,11 +2953,6 @@ private:
|
|||||||
|
|
||||||
CommittedAllocationList m_CommittedAllocations[STANDARD_HEAP_TYPE_COUNT];
|
CommittedAllocationList m_CommittedAllocations[STANDARD_HEAP_TYPE_COUNT];
|
||||||
|
|
||||||
// # Used only when ResourceHeapTier = 1
|
|
||||||
UINT64 m_DefaultPoolTier1MinBytes[DEFAULT_POOL_MAX_COUNT]; // Default 0
|
|
||||||
UINT64 m_DefaultPoolHeapTypeMinBytes[HEAP_TYPE_COUNT]; // Default UINT64_MAX, meaning not set
|
|
||||||
D3D12MA_RW_MUTEX m_DefaultPoolMinBytesMutex;
|
|
||||||
|
|
||||||
// Allocates and registers new committed resource with implicit heap, as dedicated allocation.
|
// Allocates and registers new committed resource with implicit heap, as dedicated allocation.
|
||||||
// Creates and returns Allocation object.
|
// Creates and returns Allocation object.
|
||||||
HRESULT AllocateCommittedResource(
|
HRESULT AllocateCommittedResource(
|
||||||
@ -3027,18 +3041,8 @@ private:
|
|||||||
8: D3D12_HEAP_TYPE_READBACK + texture RT or DS
|
8: D3D12_HEAP_TYPE_READBACK + texture RT or DS
|
||||||
*/
|
*/
|
||||||
UINT CalcDefaultPoolCount() const;
|
UINT CalcDefaultPoolCount() const;
|
||||||
template<typename D3D12_RESOURCE_DESC_T>
|
// Returns UINT32_MAX if index cannot be calculcated.
|
||||||
UINT CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, const D3D12_RESOURCE_DESC_T& resourceDesc) const;
|
UINT CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, ResourceClass resourceClass) const;
|
||||||
// This one returns UINT32_MAX if nonstandard heap flags are used and index cannot be calculcated.
|
|
||||||
static UINT CalcDefaultPoolIndex(D3D12_HEAP_TYPE heapType, D3D12_HEAP_FLAGS heapFlags, bool supportsResourceHeapTier2);
|
|
||||||
UINT CalcDefaultPoolIndex(D3D12_HEAP_TYPE heapType, D3D12_HEAP_FLAGS heapFlags) const
|
|
||||||
{
|
|
||||||
return CalcDefaultPoolIndex(heapType, heapFlags, SupportsResourceHeapTier2());
|
|
||||||
}
|
|
||||||
UINT CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc) const
|
|
||||||
{
|
|
||||||
return CalcDefaultPoolIndex(allocDesc.HeapType, allocDesc.ExtraHeapFlags);
|
|
||||||
}
|
|
||||||
void CalcDefaultPoolParams(D3D12_HEAP_TYPE& outHeapType, D3D12_HEAP_FLAGS& outHeapFlags, UINT index) const;
|
void CalcDefaultPoolParams(D3D12_HEAP_TYPE& outHeapType, D3D12_HEAP_FLAGS& outHeapFlags, UINT index) const;
|
||||||
|
|
||||||
// Registers Pool object in m_Pools.
|
// Registers Pool object in m_Pools.
|
||||||
@ -3860,7 +3864,6 @@ BlockVector::BlockVector(
|
|||||||
m_MinBlockCount(minBlockCount),
|
m_MinBlockCount(minBlockCount),
|
||||||
m_MaxBlockCount(maxBlockCount),
|
m_MaxBlockCount(maxBlockCount),
|
||||||
m_ExplicitBlockSize(explicitBlockSize),
|
m_ExplicitBlockSize(explicitBlockSize),
|
||||||
m_MinBytes(0),
|
|
||||||
m_HasEmptyBlock(false),
|
m_HasEmptyBlock(false),
|
||||||
m_Blocks(hAllocator->GetAllocs()),
|
m_Blocks(hAllocator->GetAllocs()),
|
||||||
m_NextBlockId(0)
|
m_NextBlockId(0)
|
||||||
@ -4084,8 +4087,7 @@ void BlockVector::Free(Allocation* hAllocation)
|
|||||||
{
|
{
|
||||||
// Already has empty Allocation. We don't want to have two, so delete this one.
|
// Already has empty Allocation. We don't want to have two, so delete this one.
|
||||||
if((m_HasEmptyBlock || budgetExceeded) &&
|
if((m_HasEmptyBlock || budgetExceeded) &&
|
||||||
blockCount > m_MinBlockCount &&
|
blockCount > m_MinBlockCount)
|
||||||
sumBlockSize - pBlock->m_pMetadata->GetSize() >= m_MinBytes)
|
|
||||||
{
|
{
|
||||||
pBlockToDelete = pBlock;
|
pBlockToDelete = pBlock;
|
||||||
Remove(pBlock);
|
Remove(pBlock);
|
||||||
@ -4101,8 +4103,7 @@ void BlockVector::Free(Allocation* hAllocation)
|
|||||||
else if(m_HasEmptyBlock && blockCount > m_MinBlockCount)
|
else if(m_HasEmptyBlock && blockCount > m_MinBlockCount)
|
||||||
{
|
{
|
||||||
NormalBlock* pLastBlock = m_Blocks.back();
|
NormalBlock* pLastBlock = m_Blocks.back();
|
||||||
if(pLastBlock->m_pMetadata->IsEmpty() &&
|
if(pLastBlock->m_pMetadata->IsEmpty())
|
||||||
sumBlockSize - pLastBlock->m_pMetadata->GetSize() >= m_MinBytes)
|
|
||||||
{
|
{
|
||||||
pBlockToDelete = pLastBlock;
|
pBlockToDelete = pLastBlock;
|
||||||
m_Blocks.pop_back();
|
m_Blocks.pop_back();
|
||||||
@ -4328,89 +4329,6 @@ HRESULT BlockVector::CreateBlock(UINT64 blockSize, size_t* pNewBlockIndex)
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT BlockVector::SetMinBytes(UINT64 minBytes)
|
|
||||||
{
|
|
||||||
MutexLockWrite lock(m_Mutex, m_hAllocator->UseMutex());
|
|
||||||
|
|
||||||
if(minBytes == m_MinBytes)
|
|
||||||
{
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
UINT64 sumBlockSize = CalcSumBlockSize();
|
|
||||||
size_t blockCount = m_Blocks.size();
|
|
||||||
|
|
||||||
// New minBytes is smaller - may be able to free some blocks.
|
|
||||||
if(minBytes < m_MinBytes)
|
|
||||||
{
|
|
||||||
m_HasEmptyBlock = false; // Will recalculate this value from scratch.
|
|
||||||
for(size_t blockIndex = blockCount; blockIndex--; )
|
|
||||||
{
|
|
||||||
NormalBlock* const block = m_Blocks[blockIndex];
|
|
||||||
const UINT64 size = block->m_pMetadata->GetSize();
|
|
||||||
const bool isEmpty = block->m_pMetadata->IsEmpty();
|
|
||||||
if(isEmpty &&
|
|
||||||
sumBlockSize - size >= minBytes &&
|
|
||||||
blockCount - 1 >= m_MinBlockCount)
|
|
||||||
{
|
|
||||||
D3D12MA_DELETE(m_hAllocator->GetAllocs(), block);
|
|
||||||
m_Blocks.remove(blockIndex);
|
|
||||||
sumBlockSize -= size;
|
|
||||||
--blockCount;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(isEmpty)
|
|
||||||
{
|
|
||||||
m_HasEmptyBlock = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// New minBytes is larger - may need to allocate some blocks.
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const UINT64 minBlockSize = m_PreferredBlockSize >> NEW_BLOCK_SIZE_SHIFT_MAX;
|
|
||||||
while(SUCCEEDED(hr) && sumBlockSize < minBytes)
|
|
||||||
{
|
|
||||||
if(blockCount < m_MaxBlockCount)
|
|
||||||
{
|
|
||||||
UINT64 newBlockSize = m_PreferredBlockSize;
|
|
||||||
if(!m_ExplicitBlockSize)
|
|
||||||
{
|
|
||||||
if(sumBlockSize + newBlockSize > minBytes)
|
|
||||||
{
|
|
||||||
newBlockSize = minBytes - sumBlockSize;
|
|
||||||
}
|
|
||||||
// Next one would be the last block to create and its size would be smaller than
|
|
||||||
// the smallest block size we want to use here, so make this one smaller.
|
|
||||||
else if(blockCount + 1 < m_MaxBlockCount &&
|
|
||||||
sumBlockSize + newBlockSize + minBlockSize > minBytes)
|
|
||||||
{
|
|
||||||
newBlockSize -= minBlockSize + sumBlockSize + m_PreferredBlockSize - minBytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = CreateBlock(newBlockSize, NULL);
|
|
||||||
if(SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
m_HasEmptyBlock = true;
|
|
||||||
sumBlockSize += newBlockSize;
|
|
||||||
++blockCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hr = E_INVALIDARG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_MinBytes = minBytes;
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockVector::AddStats(StatInfo& outStats)
|
void BlockVector::AddStats(StatInfo& outStats)
|
||||||
{
|
{
|
||||||
MutexLockRead lock(m_Mutex, m_hAllocator->UseMutex());
|
MutexLockRead lock(m_Mutex, m_hAllocator->UseMutex());
|
||||||
@ -4561,11 +4479,6 @@ POOL_DESC Pool::GetDesc() const
|
|||||||
return m_Pimpl->GetDesc();
|
return m_Pimpl->GetDesc();
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT Pool::SetMinBytes(UINT64 minBytes)
|
|
||||||
{
|
|
||||||
return m_Pimpl->SetMinBytes(minBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pool::CalculateStats(StatInfo* pStats)
|
void Pool::CalculateStats(StatInfo* pStats)
|
||||||
{
|
{
|
||||||
D3D12MA_ASSERT(pStats);
|
D3D12MA_ASSERT(pStats);
|
||||||
@ -4615,12 +4528,6 @@ AllocatorPimpl::AllocatorPimpl(const ALLOCATION_CALLBACKS& allocationCallbacks,
|
|||||||
ZeroMemory(&m_D3D12Architecture, sizeof(m_D3D12Architecture));
|
ZeroMemory(&m_D3D12Architecture, sizeof(m_D3D12Architecture));
|
||||||
|
|
||||||
ZeroMemory(m_BlockVectors, sizeof(m_BlockVectors));
|
ZeroMemory(m_BlockVectors, sizeof(m_BlockVectors));
|
||||||
ZeroMemory(m_DefaultPoolTier1MinBytes, sizeof(m_DefaultPoolTier1MinBytes));
|
|
||||||
|
|
||||||
for(UINT i = 0; i < HEAP_TYPE_COUNT; ++i)
|
|
||||||
{
|
|
||||||
m_DefaultPoolHeapTypeMinBytes[i] = UINT64_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(UINT i = 0; i < STANDARD_HEAP_TYPE_COUNT; ++i)
|
for(UINT i = 0; i < STANDARD_HEAP_TYPE_COUNT; ++i)
|
||||||
{
|
{
|
||||||
@ -4790,7 +4697,8 @@ HRESULT AllocatorPimpl::CreateResource(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const UINT defaultPoolIndex = CalcDefaultPoolIndex(*pAllocDesc, finalResourceDesc);
|
const ResourceClass resourceClass = ResourceDescToResourceClass(finalResourceDesc);
|
||||||
|
const UINT defaultPoolIndex = CalcDefaultPoolIndex(*pAllocDesc, resourceClass);
|
||||||
const bool requireCommittedMemory = defaultPoolIndex == UINT32_MAX;
|
const bool requireCommittedMemory = defaultPoolIndex == UINT32_MAX;
|
||||||
if(requireCommittedMemory)
|
if(requireCommittedMemory)
|
||||||
{
|
{
|
||||||
@ -4969,7 +4877,8 @@ HRESULT AllocatorPimpl::CreateResource2(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const UINT defaultPoolIndex = CalcDefaultPoolIndex(*pAllocDesc, finalResourceDesc);
|
const ResourceClass resourceClass = ResourceDescToResourceClass(finalResourceDesc);
|
||||||
|
const UINT defaultPoolIndex = CalcDefaultPoolIndex(*pAllocDesc, resourceClass);
|
||||||
requireCommittedMemory = requireCommittedMemory || defaultPoolIndex == UINT32_MAX;
|
requireCommittedMemory = requireCommittedMemory || defaultPoolIndex == UINT32_MAX;
|
||||||
if(requireCommittedMemory)
|
if(requireCommittedMemory)
|
||||||
{
|
{
|
||||||
@ -5154,71 +5063,6 @@ HRESULT AllocatorPimpl::CreateAliasingResource(
|
|||||||
ppvResource);
|
ppvResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT AllocatorPimpl::SetDefaultHeapMinBytes(
|
|
||||||
D3D12_HEAP_TYPE heapType,
|
|
||||||
D3D12_HEAP_FLAGS heapFlags,
|
|
||||||
UINT64 minBytes)
|
|
||||||
{
|
|
||||||
if(!IsHeapTypeStandard(heapType))
|
|
||||||
{
|
|
||||||
D3D12MA_ASSERT(0 && "Allocator::SetDefaultHeapMinBytes: Invalid heapType passed.");
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(SupportsResourceHeapTier2())
|
|
||||||
{
|
|
||||||
if(heapFlags != D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES &&
|
|
||||||
heapFlags != D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS &&
|
|
||||||
heapFlags != D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES &&
|
|
||||||
heapFlags != D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES)
|
|
||||||
{
|
|
||||||
D3D12MA_ASSERT(0 && "Allocator::SetDefaultHeapMinBytes: Invalid heapFlags passed.");
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT64 newMinBytes = UINT64_MAX;
|
|
||||||
|
|
||||||
{
|
|
||||||
MutexLockWrite lock(m_DefaultPoolMinBytesMutex, m_UseMutex);
|
|
||||||
|
|
||||||
if(heapFlags == D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES)
|
|
||||||
{
|
|
||||||
m_DefaultPoolHeapTypeMinBytes[HeapTypeToIndex(heapType)] = minBytes;
|
|
||||||
newMinBytes = minBytes;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const UINT defaultPoolTier1Index = CalcDefaultPoolIndex(heapType, heapFlags, false);
|
|
||||||
m_DefaultPoolTier1MinBytes[defaultPoolTier1Index] = minBytes;
|
|
||||||
|
|
||||||
newMinBytes = m_DefaultPoolHeapTypeMinBytes[HeapTypeToIndex(heapType)];
|
|
||||||
if(newMinBytes == UINT64_MAX)
|
|
||||||
{
|
|
||||||
newMinBytes = m_DefaultPoolTier1MinBytes[CalcDefaultPoolIndex(heapType, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS, false)] +
|
|
||||||
m_DefaultPoolTier1MinBytes[CalcDefaultPoolIndex(heapType, D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, false)] +
|
|
||||||
m_DefaultPoolTier1MinBytes[CalcDefaultPoolIndex(heapType, D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES, false)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const UINT defaultPoolIndex = CalcDefaultPoolIndex(heapType, D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES);
|
|
||||||
return m_BlockVectors[defaultPoolIndex]->SetMinBytes(newMinBytes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(heapFlags != D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS &&
|
|
||||||
heapFlags != D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES &&
|
|
||||||
heapFlags != D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES)
|
|
||||||
{
|
|
||||||
D3D12MA_ASSERT(0 && "Allocator::SetDefaultHeapMinBytes: Invalid heapFlags passed.");
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
const UINT defaultPoolIndex = CalcDefaultPoolIndex(heapType, heapFlags);
|
|
||||||
return m_BlockVectors[defaultPoolIndex]->SetMinBytes(minBytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename D3D12_RESOURCE_DESC_T>
|
template<typename D3D12_RESOURCE_DESC_T>
|
||||||
bool AllocatorPimpl::PrefersCommittedAllocation(const D3D12_RESOURCE_DESC_T& resourceDesc)
|
bool AllocatorPimpl::PrefersCommittedAllocation(const D3D12_RESOURCE_DESC_T& resourceDesc)
|
||||||
{
|
{
|
||||||
@ -5553,10 +5397,9 @@ HRESULT AllocatorPimpl::CalcAllocationParams(const ALLOCATION_DESC& allocDesc, U
|
|||||||
|
|
||||||
if(allocDesc.CustomPool != NULL)
|
if(allocDesc.CustomPool != NULL)
|
||||||
{
|
{
|
||||||
if((allocDesc.Flags & ALLOCATION_FLAG_COMMITTED) == 0)
|
PoolPimpl* const pool = allocDesc.CustomPool->m_Pimpl;
|
||||||
{
|
outBlockVector = pool->GetBlockVector();
|
||||||
outBlockVector = allocDesc.CustomPool->m_Pimpl->GetBlockVector();
|
outCommittedAllocationList = &pool->m_CommittedAllocations;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -5564,32 +5407,49 @@ HRESULT AllocatorPimpl::CalcAllocationParams(const ALLOCATION_DESC& allocDesc, U
|
|||||||
{
|
{
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
if((allocDesc.Flags & ALLOCATION_FLAG_NEVER_ALLOCATE) == 0)
|
|
||||||
|
outCommittedAllocationList = &m_CommittedAllocations[HeapTypeToIndex(allocDesc.HeapType)];
|
||||||
|
|
||||||
|
const ResourceClass resourceClass = (resDesc != NULL) ?
|
||||||
|
ResourceDescToResourceClass(*resDesc) : HeapFlagsToResourceClass(allocDesc.ExtraHeapFlags);
|
||||||
|
const UINT defaultPoolIndex = CalcDefaultPoolIndex(allocDesc, resourceClass);
|
||||||
|
if(defaultPoolIndex != UINT32_MAX)
|
||||||
{
|
{
|
||||||
outCommittedAllocationList = &m_CommittedAllocations[HeapTypeToIndex(allocDesc.HeapType)];
|
outBlockVector = m_BlockVectors[defaultPoolIndex];
|
||||||
}
|
const UINT64 preferredBlockSize = outBlockVector->GetPreferredBlockSize();
|
||||||
if(!m_AlwaysCommitted &&
|
if(allocSize > preferredBlockSize)
|
||||||
(allocDesc.Flags & ALLOCATION_FLAG_COMMITTED) == 0)
|
|
||||||
{
|
|
||||||
const UINT defaultPoolIndex = CalcDefaultPoolIndex(allocDesc);
|
|
||||||
if(defaultPoolIndex != UINT32_MAX)
|
|
||||||
{
|
{
|
||||||
outBlockVector = m_BlockVectors[defaultPoolIndex];
|
outBlockVector = NULL;
|
||||||
const UINT64 preferredBlockSize = outBlockVector->GetPreferredBlockSize();
|
}
|
||||||
if(allocSize > preferredBlockSize)
|
else if(allocSize > preferredBlockSize / 2)
|
||||||
{
|
{
|
||||||
outBlockVector = NULL;
|
// Heuristics: Allocate committed memory if requested size if greater than half of preferred block size.
|
||||||
}
|
outPreferCommitted = true;
|
||||||
else if(allocSize > preferredBlockSize / 2)
|
|
||||||
{
|
|
||||||
// Heuristics: Allocate committed memory if requested size if greater than half of preferred block size.
|
|
||||||
outPreferCommitted = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const D3D12_HEAP_FLAGS extraHeapFlags = allocDesc.ExtraHeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS;
|
||||||
|
if(outBlockVector != NULL && extraHeapFlags != 0)
|
||||||
|
{
|
||||||
|
outBlockVector = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(resDesc != NULL && PrefersCommittedAllocation(*resDesc))
|
|
||||||
|
if((allocDesc.Flags & ALLOCATION_FLAG_COMMITTED) != 0 ||
|
||||||
|
m_AlwaysCommitted)
|
||||||
|
{
|
||||||
|
outBlockVector = NULL;
|
||||||
|
}
|
||||||
|
if((allocDesc.Flags & ALLOCATION_FLAG_NEVER_ALLOCATE) != 0)
|
||||||
|
{
|
||||||
|
outCommittedAllocationList = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(resDesc != NULL && !outPreferCommitted && PrefersCommittedAllocation(*resDesc))
|
||||||
|
{
|
||||||
outPreferCommitted = true;
|
outPreferCommitted = true;
|
||||||
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5605,10 +5465,9 @@ UINT AllocatorPimpl::CalcDefaultPoolCount() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename D3D12_RESOURCE_DESC_T>
|
UINT AllocatorPimpl::CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, ResourceClass resourceClass) const
|
||||||
UINT AllocatorPimpl::CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, const D3D12_RESOURCE_DESC_T& resourceDesc) const
|
|
||||||
{
|
{
|
||||||
const D3D12_HEAP_FLAGS extraHeapFlags = allocDesc.ExtraHeapFlags & ~GetExtraHeapFlagsToIgnore();
|
const D3D12_HEAP_FLAGS extraHeapFlags = allocDesc.ExtraHeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS;
|
||||||
if(extraHeapFlags != 0)
|
if(extraHeapFlags != 0)
|
||||||
{
|
{
|
||||||
return UINT32_MAX;
|
return UINT32_MAX;
|
||||||
@ -5623,66 +5482,22 @@ UINT AllocatorPimpl::CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, cons
|
|||||||
default: D3D12MA_ASSERT(0);
|
default: D3D12MA_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!SupportsResourceHeapTier2())
|
if(SupportsResourceHeapTier2())
|
||||||
|
return poolIndex;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
poolIndex *= 3;
|
switch(resourceClass)
|
||||||
if(resourceDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER)
|
|
||||||
{
|
|
||||||
++poolIndex;
|
|
||||||
const bool isRenderTargetOrDepthStencil =
|
|
||||||
(resourceDesc.Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)) != 0;
|
|
||||||
if(isRenderTargetOrDepthStencil)
|
|
||||||
{
|
|
||||||
++poolIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return poolIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT AllocatorPimpl::CalcDefaultPoolIndex(D3D12_HEAP_TYPE heapType, D3D12_HEAP_FLAGS heapFlags, bool supportsResourceHeapTier2)
|
|
||||||
{
|
|
||||||
const D3D12_HEAP_FLAGS extraHeapFlags = heapFlags & ~GetExtraHeapFlagsToIgnore();
|
|
||||||
if(extraHeapFlags != 0)
|
|
||||||
{
|
|
||||||
return UINT32_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT poolIndex = UINT_MAX;
|
|
||||||
switch(heapType)
|
|
||||||
{
|
|
||||||
case D3D12_HEAP_TYPE_DEFAULT: poolIndex = 0; break;
|
|
||||||
case D3D12_HEAP_TYPE_UPLOAD: poolIndex = 1; break;
|
|
||||||
case D3D12_HEAP_TYPE_READBACK: poolIndex = 2; break;
|
|
||||||
default: D3D12MA_ASSERT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!supportsResourceHeapTier2)
|
|
||||||
{
|
|
||||||
poolIndex *= 3;
|
|
||||||
|
|
||||||
const bool allowBuffers = (heapFlags & D3D12_HEAP_FLAG_DENY_BUFFERS) == 0;
|
|
||||||
const bool allowRtDsTextures = (heapFlags & D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES) == 0;
|
|
||||||
const bool allowNonRtDsTextures = (heapFlags & D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES) == 0;
|
|
||||||
|
|
||||||
const uint8_t allowedGroupCount = (allowBuffers ? 1 : 0) + (allowRtDsTextures ? 1 : 0) + (allowNonRtDsTextures ? 1 : 0);
|
|
||||||
if(allowedGroupCount != 1)
|
|
||||||
{
|
{
|
||||||
|
case ResourceClass::Buffer:
|
||||||
|
return poolIndex * 3;
|
||||||
|
case ResourceClass::Non_RT_DS_Texture:
|
||||||
|
return poolIndex * 3 + 1;
|
||||||
|
case ResourceClass::RT_DS_Texture:
|
||||||
|
return poolIndex * 3 + 2;
|
||||||
|
default:
|
||||||
return UINT32_MAX;
|
return UINT32_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!allowBuffers)
|
|
||||||
{
|
|
||||||
++poolIndex;
|
|
||||||
if(allowRtDsTextures)
|
|
||||||
{
|
|
||||||
++poolIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return poolIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AllocatorPimpl::CalcDefaultPoolParams(D3D12_HEAP_TYPE& outHeapType, D3D12_HEAP_FLAGS& outHeapFlags, UINT index) const
|
void AllocatorPimpl::CalcDefaultPoolParams(D3D12_HEAP_TYPE& outHeapType, D3D12_HEAP_FLAGS& outHeapFlags, UINT index) const
|
||||||
@ -6597,15 +6412,6 @@ HRESULT Allocator::CreatePool(
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT Allocator::SetDefaultHeapMinBytes(
|
|
||||||
D3D12_HEAP_TYPE heapType,
|
|
||||||
D3D12_HEAP_FLAGS heapFlags,
|
|
||||||
UINT64 minBytes)
|
|
||||||
{
|
|
||||||
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
|
|
||||||
return m_Pimpl->SetDefaultHeapMinBytes(heapType, heapFlags, minBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Allocator::SetCurrentFrameIndex(UINT frameIndex)
|
void Allocator::SetCurrentFrameIndex(UINT frameIndex)
|
||||||
{
|
{
|
||||||
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
|
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
|
||||||
|
@ -40,7 +40,6 @@ Documentation of all members: D3D12MemAlloc.h
|
|||||||
- [Mapping memory](@ref quick_start_mapping_memory)
|
- [Mapping memory](@ref quick_start_mapping_memory)
|
||||||
- \subpage custom_pools
|
- \subpage custom_pools
|
||||||
- \subpage resource_aliasing
|
- \subpage resource_aliasing
|
||||||
- \subpage reserving_memory
|
|
||||||
- \subpage virtual_allocator
|
- \subpage virtual_allocator
|
||||||
- \subpage configuration
|
- \subpage configuration
|
||||||
- [Custom CPU memory allocator](@ref custom_memory_allocator)
|
- [Custom CPU memory allocator](@ref custom_memory_allocator)
|
||||||
@ -413,43 +412,6 @@ Additional considerations:
|
|||||||
Otherwise they must be placed in different memory heap types, and thus aliasing them is not possible.
|
Otherwise they must be placed in different memory heap types, and thus aliasing them is not possible.
|
||||||
|
|
||||||
|
|
||||||
\page reserving_memory Reserving minimum amount of memory
|
|
||||||
|
|
||||||
The library automatically allocates and frees memory heaps.
|
|
||||||
It also applies some hysteresis so that it doesn't allocate and free entire heap
|
|
||||||
when you repeatedly create and release a single resource.
|
|
||||||
However, if you want to make sure certain number of bytes is always allocated as heaps in a specific pool,
|
|
||||||
you can use functions designed for this purpose:
|
|
||||||
|
|
||||||
- For default heaps use D3D12MA::Allocator::SetDefaultHeapMinBytes.
|
|
||||||
- For custom heaps use D3D12MA::Pool::SetMinBytes.
|
|
||||||
|
|
||||||
Default is 0. You can change this parameter any time.
|
|
||||||
Setting it to higher value may cause new heaps to be allocated.
|
|
||||||
If this allocation fails, the function returns appropriate error code, but the parameter remains set to the new value.
|
|
||||||
Setting it to lower value may cause some empty heaps to be released.
|
|
||||||
|
|
||||||
You can always call D3D12MA::Allocator::SetDefaultHeapMinBytes for 3 sets of heap flags separately:
|
|
||||||
`D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS`, `D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES`, `D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES`.
|
|
||||||
When ResourceHeapTier = 2, so that all types of resourced are kept together,
|
|
||||||
these 3 values as simply summed up to calculate minimum amount of bytes for default pool with certain heap type.
|
|
||||||
Alternatively, when ResourceHeapTier = 2, you can call this function with
|
|
||||||
`D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES` = 0. This will set a single value for the default pool and
|
|
||||||
will override the sum of those three.
|
|
||||||
|
|
||||||
Reservation of minimum number of bytes interacts correctly with
|
|
||||||
D3D12MA::POOL_DESC::MinBlockCount and D3D12MA::POOL_DESC::MaxBlockCount.
|
|
||||||
For example, free blocks (heaps) of a custom pool will be released only when
|
|
||||||
their number doesn't fall below `MinBlockCount` and their sum size doesn't fall below `MinBytes`.
|
|
||||||
|
|
||||||
Some restrictions apply:
|
|
||||||
|
|
||||||
- Setting `MinBytes` doesn't interact with memory budget. The allocator tries
|
|
||||||
to create additional heaps when necessary without checking if they will exceed the budget.
|
|
||||||
- Resources created as committed don't count into the number of bytes compared with `MinBytes` set.
|
|
||||||
Only placed resources are considered.
|
|
||||||
|
|
||||||
|
|
||||||
\page virtual_allocator Virtual allocator
|
\page virtual_allocator Virtual allocator
|
||||||
|
|
||||||
As an extra feature, the core allocation algorithm of the library is exposed through a simple and convenient API of "virtual allocator".
|
As an extra feature, the core allocation algorithm of the library is exposed through a simple and convenient API of "virtual allocator".
|
||||||
@ -1096,12 +1058,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
POOL_DESC GetDesc() const;
|
POOL_DESC GetDesc() const;
|
||||||
|
|
||||||
/** \brief Sets the minimum number of bytes that should always be allocated (reserved) in this pool.
|
|
||||||
|
|
||||||
See also: \subpage reserving_memory.
|
|
||||||
*/
|
|
||||||
HRESULT SetMinBytes(UINT64 minBytes);
|
|
||||||
|
|
||||||
/** \brief Retrieves statistics from the current state of this pool.
|
/** \brief Retrieves statistics from the current state of this pool.
|
||||||
*/
|
*/
|
||||||
void CalculateStats(StatInfo* pStats);
|
void CalculateStats(StatInfo* pStats);
|
||||||
@ -1457,20 +1413,6 @@ public:
|
|||||||
const POOL_DESC* pPoolDesc,
|
const POOL_DESC* pPoolDesc,
|
||||||
Pool** ppPool);
|
Pool** ppPool);
|
||||||
|
|
||||||
/** \brief Sets the minimum number of bytes that should always be allocated (reserved) in a specific default pool.
|
|
||||||
|
|
||||||
\param heapType Must be one of: `D3D12_HEAP_TYPE_DEFAULT`, `D3D12_HEAP_TYPE_UPLOAD`, `D3D12_HEAP_TYPE_READBACK`.
|
|
||||||
\param heapFlags Must be one of: `D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS`, `D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES`,
|
|
||||||
`D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES`. If ResourceHeapTier = 2, it can also be `D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES`.
|
|
||||||
\param minBytes Minimum number of bytes to keep allocated.
|
|
||||||
|
|
||||||
See also: \subpage reserving_memory.
|
|
||||||
*/
|
|
||||||
HRESULT SetDefaultHeapMinBytes(
|
|
||||||
D3D12_HEAP_TYPE heapType,
|
|
||||||
D3D12_HEAP_FLAGS heapFlags,
|
|
||||||
UINT64 minBytes);
|
|
||||||
|
|
||||||
/** \brief Sets the index of the current frame.
|
/** \brief Sets the index of the current frame.
|
||||||
|
|
||||||
This function is used to set the frame index in the allocator when a new game frame begins.
|
This function is used to set the frame index in the allocator when a new game frame begins.
|
||||||
|
@ -606,22 +606,6 @@ static void TestCustomPools(const TestContext& ctx)
|
|||||||
pool->SetName(NAME);
|
pool->SetName(NAME);
|
||||||
CHECK_BOOL( wcscmp(pool->GetName(), NAME) == 0 );
|
CHECK_BOOL( wcscmp(pool->GetName(), NAME) == 0 );
|
||||||
|
|
||||||
// # SetMinBytes
|
|
||||||
|
|
||||||
CHECK_HR( pool->SetMinBytes(15 * MEGABYTE) );
|
|
||||||
pool->CalculateStats(&poolStats);
|
|
||||||
CHECK_BOOL( poolStats.BlockCount == 2 );
|
|
||||||
CHECK_BOOL( poolStats.AllocationCount == 0 );
|
|
||||||
CHECK_BOOL( poolStats.UsedBytes == 0 );
|
|
||||||
CHECK_BOOL( poolStats.UnusedBytes == poolStats.BlockCount * poolDesc.BlockSize );
|
|
||||||
|
|
||||||
CHECK_HR( pool->SetMinBytes(0) );
|
|
||||||
pool->CalculateStats(&poolStats);
|
|
||||||
CHECK_BOOL( poolStats.BlockCount == 1 );
|
|
||||||
CHECK_BOOL( poolStats.AllocationCount == 0 );
|
|
||||||
CHECK_BOOL( poolStats.UsedBytes == 0 );
|
|
||||||
CHECK_BOOL( poolStats.UnusedBytes == poolStats.BlockCount * poolDesc.BlockSize );
|
|
||||||
|
|
||||||
// # Create buffers 2x 5 MB
|
// # Create buffers 2x 5 MB
|
||||||
|
|
||||||
D3D12MA::ALLOCATION_DESC allocDesc = {};
|
D3D12MA::ALLOCATION_DESC allocDesc = {};
|
||||||
@ -806,26 +790,6 @@ static void TestCustomHeaps(const TestContext& ctx)
|
|||||||
CHECK_HR(hr);
|
CHECK_HR(hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TestDefaultPoolMinBytes(const TestContext& ctx)
|
|
||||||
{
|
|
||||||
D3D12MA::Stats stats;
|
|
||||||
ctx.allocator->CalculateStats(&stats);
|
|
||||||
const UINT64 gpuAllocatedBefore = stats.HeapType[0].UsedBytes + stats.HeapType[0].UnusedBytes;
|
|
||||||
|
|
||||||
const UINT64 gpuAllocatedMin = gpuAllocatedBefore * 105 / 100;
|
|
||||||
CHECK_HR( ctx.allocator->SetDefaultHeapMinBytes(D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS, CeilDiv(gpuAllocatedMin, 3ull)) );
|
|
||||||
CHECK_HR( ctx.allocator->SetDefaultHeapMinBytes(D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, CeilDiv(gpuAllocatedMin, 3ull)) );
|
|
||||||
CHECK_HR( ctx.allocator->SetDefaultHeapMinBytes(D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES, CeilDiv(gpuAllocatedMin, 3ull)) );
|
|
||||||
|
|
||||||
ctx.allocator->CalculateStats(&stats);
|
|
||||||
const UINT64 gpuAllocatedAfter = stats.HeapType[0].UsedBytes + stats.HeapType[0].UnusedBytes;
|
|
||||||
CHECK_BOOL(gpuAllocatedAfter >= gpuAllocatedMin);
|
|
||||||
|
|
||||||
CHECK_HR( ctx.allocator->SetDefaultHeapMinBytes(D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS, 0) );
|
|
||||||
CHECK_HR( ctx.allocator->SetDefaultHeapMinBytes(D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, 0) );
|
|
||||||
CHECK_HR( ctx.allocator->SetDefaultHeapMinBytes(D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES, 0) );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void TestAliasingMemory(const TestContext& ctx)
|
static void TestAliasingMemory(const TestContext& ctx)
|
||||||
{
|
{
|
||||||
wprintf(L"Test aliasing memory\n");
|
wprintf(L"Test aliasing memory\n");
|
||||||
@ -1526,7 +1490,6 @@ static void TestGroupBasics(const TestContext& ctx)
|
|||||||
TestOtherComInterface(ctx);
|
TestOtherComInterface(ctx);
|
||||||
TestCustomPools(ctx);
|
TestCustomPools(ctx);
|
||||||
TestCustomHeaps(ctx);
|
TestCustomHeaps(ctx);
|
||||||
TestDefaultPoolMinBytes(ctx);
|
|
||||||
TestAliasingMemory(ctx);
|
TestAliasingMemory(ctx);
|
||||||
TestMapping(ctx);
|
TestMapping(ctx);
|
||||||
TestStats(ctx);
|
TestStats(ctx);
|
||||||
|
Loading…
Reference in New Issue
Block a user