mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator.git
synced 2024-11-21 19:50:05 +00:00
BREAKING CHANGE: Made all public classes COM-compatible - inheriting from IUnknown, reference counting
This commit is contained in:
parent
0f44bf40bf
commit
7642634a62
@ -31,7 +31,6 @@
|
||||
|
||||
#include <combaseapi.h>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <cstdlib>
|
||||
@ -239,17 +238,6 @@ static inline void D3D12MA_SWAP(T& a, T& b)
|
||||
#define D3D12MA_RW_MUTEX RWMutex
|
||||
#endif
|
||||
|
||||
/*
|
||||
If providing your own implementation, you need to implement a subset of std::atomic.
|
||||
*/
|
||||
#ifndef D3D12MA_ATOMIC_UINT32
|
||||
#define D3D12MA_ATOMIC_UINT32 std::atomic<UINT>
|
||||
#endif
|
||||
|
||||
#ifndef D3D12MA_ATOMIC_UINT64
|
||||
#define D3D12MA_ATOMIC_UINT64 std::atomic<UINT64>
|
||||
#endif
|
||||
|
||||
/*
|
||||
Returns true if given number is a power of two.
|
||||
T must be unsigned integer number or signed integer but always nonnegative.
|
||||
@ -2846,6 +2834,7 @@ struct CommittedAllocationParameters
|
||||
class AllocatorPimpl
|
||||
{
|
||||
public:
|
||||
std::atomic_uint32_t m_RefCount = 1;
|
||||
CurrentBudgetData m_Budget;
|
||||
|
||||
AllocatorPimpl(const ALLOCATION_CALLBACKS& allocationCallbacks, const ALLOCATOR_DESC& desc);
|
||||
@ -4473,7 +4462,7 @@ void PoolPimpl::FreeName()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Public class Pool implementation
|
||||
|
||||
void Pool::Release()
|
||||
void Pool::ReleaseThis()
|
||||
{
|
||||
if(this == NULL)
|
||||
{
|
||||
@ -5862,6 +5851,38 @@ void AllocatorPimpl::WriteBudgetToJson(JsonWriter& json, const Budget& budget)
|
||||
json.EndObject();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Public but internal class IUnknownImpl implementation
|
||||
|
||||
HRESULT STDMETHODCALLTYPE IUnknownImpl::QueryInterface(REFIID riid, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject)
|
||||
{
|
||||
if(ppvObject == NULL)
|
||||
return E_POINTER;
|
||||
if(riid == IID_IUnknown)
|
||||
{
|
||||
++m_RefCount;
|
||||
*ppvObject = this;
|
||||
return S_OK;
|
||||
}
|
||||
*ppvObject = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE IUnknownImpl::AddRef()
|
||||
{
|
||||
return ++m_RefCount;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE IUnknownImpl::Release()
|
||||
{
|
||||
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
|
||||
|
||||
const uint32_t newRefCount = --m_RefCount;
|
||||
if(newRefCount == 0)
|
||||
ReleaseThis();
|
||||
return newRefCount;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Public class Allocation implementation
|
||||
|
||||
@ -5893,7 +5914,7 @@ void Allocation::PackedData::SetTextureLayout(D3D12_TEXTURE_LAYOUT textureLayout
|
||||
m_TextureLayout = u;
|
||||
}
|
||||
|
||||
void Allocation::Release()
|
||||
void Allocation::ReleaseThis()
|
||||
{
|
||||
if(this == NULL)
|
||||
{
|
||||
@ -6063,7 +6084,7 @@ Allocator::~Allocator()
|
||||
D3D12MA_DELETE(m_Pimpl->GetAllocs(), m_Pimpl);
|
||||
}
|
||||
|
||||
void Allocator::Release()
|
||||
void Allocator::ReleaseThis()
|
||||
{
|
||||
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
|
||||
|
||||
@ -6072,8 +6093,6 @@ void Allocator::Release()
|
||||
D3D12MA_DELETE(allocationCallbacksCopy, this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const D3D12_FEATURE_DATA_D3D12_OPTIONS& Allocator::GetD3D12Options() const
|
||||
{
|
||||
return m_Pimpl->GetD3D12Options();
|
||||
@ -6325,7 +6344,7 @@ VirtualBlock::~VirtualBlock()
|
||||
D3D12MA_DELETE(m_Pimpl->m_AllocationCallbacks, m_Pimpl);
|
||||
}
|
||||
|
||||
void VirtualBlock::Release()
|
||||
void VirtualBlock::ReleaseThis()
|
||||
{
|
||||
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
|
||||
|
||||
|
@ -728,6 +728,36 @@ may get their alignment 4K and their size a multiply of 4K instead of 64K.
|
||||
// To be used with MAKE_HRESULT to define custom error codes.
|
||||
#define FACILITY_D3D12MA 3542
|
||||
|
||||
/*
|
||||
If providing your own implementation, you need to implement a subset of std::atomic.
|
||||
*/
|
||||
#if !defined(D3D12MA_ATOMIC_UINT32) || !defined(D3D12MA_ATOMIC_UINT64)
|
||||
#include <atomic>
|
||||
#endif
|
||||
|
||||
#ifndef D3D12MA_ATOMIC_UINT32
|
||||
#define D3D12MA_ATOMIC_UINT32 std::atomic<UINT>
|
||||
#endif
|
||||
|
||||
#ifndef D3D12MA_ATOMIC_UINT64
|
||||
#define D3D12MA_ATOMIC_UINT64 std::atomic<UINT64>
|
||||
#endif
|
||||
|
||||
namespace D3D12MA
|
||||
{
|
||||
class IUnknownImpl : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject);
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef();
|
||||
virtual ULONG STDMETHODCALLTYPE Release();
|
||||
protected:
|
||||
virtual void ReleaseThis() { delete this; }
|
||||
private:
|
||||
D3D12MA_ATOMIC_UINT32 m_RefCount = 1;
|
||||
};
|
||||
} // namespace D3D12MA
|
||||
|
||||
/// \endcond
|
||||
|
||||
namespace D3D12MA
|
||||
@ -847,16 +877,9 @@ To retrieve this information, use methods of this class.
|
||||
The object also remembers `ID3D12Resource` and "owns" a reference to it,
|
||||
so it calls `%Release()` on the resource when destroyed.
|
||||
*/
|
||||
class Allocation
|
||||
class Allocation : public IUnknownImpl
|
||||
{
|
||||
public:
|
||||
/** \brief Deletes this object.
|
||||
|
||||
This function must be used instead of destructor, which is private.
|
||||
There is no reference counting involved.
|
||||
*/
|
||||
void Release();
|
||||
|
||||
/** \brief Returns offset in bytes from the start of memory heap.
|
||||
|
||||
You usually don't need to use this offset. If you create a buffer or a texture together with the allocation using function
|
||||
@ -925,6 +948,9 @@ public:
|
||||
*/
|
||||
BOOL WasZeroInitialized() const { return m_PackedData.WasZeroInitialized(); }
|
||||
|
||||
protected:
|
||||
virtual void ReleaseThis();
|
||||
|
||||
private:
|
||||
friend class AllocatorPimpl;
|
||||
friend class BlockVector;
|
||||
@ -1066,16 +1092,9 @@ pools - creating resources in default pool is sufficient.
|
||||
|
||||
To create custom pool, fill D3D12MA::POOL_DESC and call D3D12MA::Allocator::CreatePool.
|
||||
*/
|
||||
class Pool
|
||||
class Pool : public IUnknownImpl
|
||||
{
|
||||
public:
|
||||
/** \brief Deletes pool object, frees D3D12 heaps (memory blocks) managed by it. Allocations and resources must already be released!
|
||||
|
||||
It doesn't delete allocations and resources created in this pool. They must be all
|
||||
released before calling this function!
|
||||
*/
|
||||
void Release();
|
||||
|
||||
/** \brief Returns copy of parameters of the pool.
|
||||
|
||||
These are the same parameters as passed to D3D12MA::Allocator::CreatePool.
|
||||
@ -1103,6 +1122,9 @@ public:
|
||||
*/
|
||||
LPCWSTR GetName() const;
|
||||
|
||||
protected:
|
||||
virtual void ReleaseThis();
|
||||
|
||||
private:
|
||||
friend class Allocator;
|
||||
friend class AllocatorPimpl;
|
||||
@ -1258,16 +1280,9 @@ Call method Allocator::Release to destroy it.
|
||||
It is recommended to create just one object of this type per `ID3D12Device` object,
|
||||
right after Direct3D 12 is initialized and keep it alive until before Direct3D device is destroyed.
|
||||
*/
|
||||
class Allocator
|
||||
class Allocator : public IUnknownImpl
|
||||
{
|
||||
public:
|
||||
/** \brief Deletes this object.
|
||||
|
||||
This function must be used instead of destructor, which is private.
|
||||
There is no reference counting involved.
|
||||
*/
|
||||
void Release();
|
||||
|
||||
/// Returns cached options retrieved from D3D12 device.
|
||||
const D3D12_FEATURE_DATA_D3D12_OPTIONS& GetD3D12Options() const;
|
||||
/** \brief Returns true if `D3D12_FEATURE_DATA_ARCHITECTURE1::UMA` was found to be true.
|
||||
@ -1469,6 +1484,9 @@ public:
|
||||
/// Frees memory of a string returned from Allocator::BuildStatsString.
|
||||
void FreeStatsString(WCHAR* pStatsString) const;
|
||||
|
||||
protected:
|
||||
virtual void ReleaseThis();
|
||||
|
||||
private:
|
||||
friend HRESULT CreateAllocator(const ALLOCATOR_DESC*, Allocator**);
|
||||
template<typename T> friend void D3D12MA_DELETE(const ALLOCATION_CALLBACKS&, T*);
|
||||
@ -1540,16 +1558,11 @@ sub-allocation regions inside a single GPU buffer.
|
||||
|
||||
To create this object, fill in D3D12MA::VIRTUAL_BLOCK_DESC and call CreateVirtualBlock().
|
||||
To destroy it, call its method VirtualBlock::Release().
|
||||
You need to free all the allocations within this block or call Clear() before destroying it.
|
||||
*/
|
||||
class VirtualBlock
|
||||
class VirtualBlock : public IUnknownImpl
|
||||
{
|
||||
public:
|
||||
/** \brief Destroys this object and frees it from memory.
|
||||
|
||||
You need to free all the allocations within this block or call Clear() before destroying it.
|
||||
*/
|
||||
void Release();
|
||||
|
||||
/** \brief Returns true if the block is empty - contains 0 allocations.
|
||||
*/
|
||||
BOOL IsEmpty() const;
|
||||
@ -1585,6 +1598,9 @@ public:
|
||||
/** \brief Frees memory of a string returned from VirtualBlock::BuildStatsString.
|
||||
*/
|
||||
void FreeStatsString(WCHAR* pStatsString) const;
|
||||
|
||||
protected:
|
||||
virtual void ReleaseThis();
|
||||
|
||||
private:
|
||||
friend HRESULT CreateVirtualBlock(const VIRTUAL_BLOCK_DESC*, VirtualBlock**);
|
||||
|
@ -90,7 +90,7 @@ static float g_TimeDelta;
|
||||
|
||||
static DXGIUsage* g_DXGIUsage;
|
||||
static ComPtr<ID3D12Device> g_Device;
|
||||
static D3D12MA::Allocator* g_Allocator;
|
||||
static ComPtr<D3D12MA::Allocator> g_Allocator;
|
||||
|
||||
static ComPtr<IDXGISwapChain3> g_SwapChain; // swapchain used to switch between render targets
|
||||
static ComPtr<ID3D12CommandQueue> g_CommandQueue; // container for command lists
|
||||
@ -1575,7 +1575,7 @@ void Cleanup() // release com ojects and clean up memory
|
||||
g_Fences[i].Reset();
|
||||
}
|
||||
|
||||
g_Allocator->Release(); g_Allocator = nullptr;
|
||||
g_Allocator.Reset();
|
||||
if(ENABLE_CPU_ALLOCATION_CALLBACKS)
|
||||
{
|
||||
assert(g_CpuAllocationCount.load() == 0);
|
||||
@ -1592,7 +1592,7 @@ static void ExecuteTests()
|
||||
TestContext ctx = {};
|
||||
ctx.allocationCallbacks = &g_AllocationCallbacks;
|
||||
ctx.device = g_Device.Get();
|
||||
ctx.allocator = g_Allocator;
|
||||
ctx.allocator = g_Allocator.Get();
|
||||
ctx.allocatorFlags = g_AllocatorFlags;
|
||||
Test(ctx);
|
||||
}
|
||||
|
199
src/Tests.cpp
199
src/Tests.cpp
@ -29,33 +29,17 @@ extern void EndCommandList(ID3D12GraphicsCommandList* cmdList);
|
||||
|
||||
static constexpr UINT64 MEGABYTE = 1024 * 1024;
|
||||
|
||||
template<typename T>
|
||||
struct D3d12maObjDeleter
|
||||
{
|
||||
void operator()(T* obj) const
|
||||
{
|
||||
if(obj)
|
||||
{
|
||||
obj->Release();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::unique_ptr<D3D12MA::Allocation, D3d12maObjDeleter<D3D12MA::Allocation>> AllocationUniquePtr;
|
||||
typedef std::unique_ptr<D3D12MA::Pool, D3d12maObjDeleter<D3D12MA::Pool>> PoolUniquePtr;
|
||||
typedef std::unique_ptr<D3D12MA::VirtualBlock, D3d12maObjDeleter<D3D12MA::VirtualBlock>> VirtualBlockUniquePtr;
|
||||
|
||||
struct ResourceWithAllocation
|
||||
{
|
||||
ComPtr<ID3D12Resource> resource;
|
||||
AllocationUniquePtr allocation;
|
||||
ComPtr<D3D12MA::Allocation> allocation;
|
||||
UINT64 size = UINT64_MAX;
|
||||
UINT dataSeed = 0;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
resource.Reset();
|
||||
allocation.reset();
|
||||
allocation.Reset();
|
||||
size = UINT64_MAX;
|
||||
dataSeed = 0;
|
||||
}
|
||||
@ -139,14 +123,12 @@ static void TestVirtualBlocks(const TestContext& ctx)
|
||||
|
||||
// # Create block 16 MB
|
||||
|
||||
VirtualBlockUniquePtr block;
|
||||
VirtualBlock* blockPtr = nullptr;
|
||||
ComPtr<D3D12MA::VirtualBlock> block;
|
||||
VIRTUAL_BLOCK_DESC blockDesc = {};
|
||||
blockDesc.pAllocationCallbacks = ctx.allocationCallbacks;
|
||||
blockDesc.Size = blockSize;
|
||||
CHECK_HR( CreateVirtualBlock(&blockDesc, &blockPtr) );
|
||||
CHECK_BOOL( blockPtr );
|
||||
block.reset(blockPtr);
|
||||
CHECK_HR( CreateVirtualBlock(&blockDesc, &block) );
|
||||
CHECK_BOOL( block );
|
||||
|
||||
// # Allocate 8 MB
|
||||
|
||||
@ -322,16 +304,14 @@ static void TestCommittedResourcesAndJson(const TestContext& ctx)
|
||||
{
|
||||
const bool receiveExplicitResource = i < 2;
|
||||
|
||||
D3D12MA::Allocation* alloc = nullptr;
|
||||
CHECK_HR( ctx.allocator->CreateResource(
|
||||
&allocDesc,
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
NULL,
|
||||
&alloc,
|
||||
&resources[i].allocation,
|
||||
__uuidof(ID3D12Resource),
|
||||
receiveExplicitResource ? (void**)&resources[i].resource : NULL));
|
||||
resources[i].allocation.reset(alloc);
|
||||
|
||||
if(receiveExplicitResource)
|
||||
{
|
||||
@ -385,10 +365,8 @@ static void TestCustomHeapFlags(const TestContext& ctx)
|
||||
resAllocInfo.SizeInBytes = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
resAllocInfo.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
|
||||
D3D12MA::Allocation* alloc = nullptr;
|
||||
CHECK_HR( ctx.allocator->AllocateMemory(&allocDesc, &resAllocInfo, &alloc) );
|
||||
ResourceWithAllocation res;
|
||||
res.allocation.reset(alloc);
|
||||
CHECK_HR( ctx.allocator->AllocateMemory(&allocDesc, &resAllocInfo, &res.allocation) );
|
||||
|
||||
// Must be created as separate allocation.
|
||||
CHECK_BOOL( res.allocation->GetOffset() == 0 );
|
||||
@ -414,15 +392,13 @@ static void TestCustomHeapFlags(const TestContext& ctx)
|
||||
allocDesc.ExtraHeapFlags = D3D12_HEAP_FLAG_SHARED | D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER; // Extra flags.
|
||||
|
||||
ResourceWithAllocation res;
|
||||
D3D12MA::Allocation* alloc = nullptr;
|
||||
CHECK_HR( ctx.allocator->CreateResource(
|
||||
&allocDesc,
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
NULL,
|
||||
&alloc,
|
||||
&res.allocation,
|
||||
IID_PPV_ARGS(&res.resource)) );
|
||||
res.allocation.reset(alloc);
|
||||
|
||||
// Must be created as committed.
|
||||
CHECK_BOOL( res.allocation->GetHeap() == NULL );
|
||||
@ -445,7 +421,6 @@ static void TestPlacedResources(const TestContext& ctx)
|
||||
D3D12_RESOURCE_DESC resourceDesc;
|
||||
FillResourceDescForBuffer(resourceDesc, bufSize);
|
||||
|
||||
D3D12MA::Allocation* alloc = nullptr;
|
||||
for(UINT i = 0; i < count; ++i)
|
||||
{
|
||||
CHECK_HR( ctx.allocator->CreateResource(
|
||||
@ -453,9 +428,8 @@ static void TestPlacedResources(const TestContext& ctx)
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
NULL,
|
||||
&alloc,
|
||||
&resources[i].allocation,
|
||||
IID_PPV_ARGS(&resources[i].resource)) );
|
||||
resources[i].allocation.reset(alloc);
|
||||
|
||||
// Make sure it doesn't have implicit heap.
|
||||
if(!alwaysCommitted)
|
||||
@ -505,10 +479,9 @@ static void TestPlacedResources(const TestContext& ctx)
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
NULL,
|
||||
&alloc,
|
||||
&textureRes.allocation,
|
||||
IID_PPV_ARGS(&textureRes.resource)) );
|
||||
textureRes.allocation.reset(alloc);
|
||||
|
||||
|
||||
// Additionally create an MSAA render target to see if no error occurs due to bad handling of Resource Tier.
|
||||
resourceDesc = {};
|
||||
resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||
@ -528,9 +501,8 @@ static void TestPlacedResources(const TestContext& ctx)
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
NULL,
|
||||
&alloc,
|
||||
&renderTargetRes.allocation,
|
||||
IID_PPV_ARGS(&renderTargetRes.resource)) );
|
||||
renderTargetRes.allocation.reset(alloc);
|
||||
}
|
||||
|
||||
static void TestOtherComInterface(const TestContext& ctx)
|
||||
@ -549,7 +521,7 @@ static void TestOtherComInterface(const TestContext& ctx)
|
||||
allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED;
|
||||
}
|
||||
|
||||
D3D12MA::Allocation* alloc = nullptr;
|
||||
ComPtr<D3D12MA::Allocation> alloc;
|
||||
ComPtr<ID3D12Pageable> pageable;
|
||||
CHECK_HR(ctx.allocator->CreateResource(
|
||||
&allocDesc,
|
||||
@ -563,8 +535,6 @@ static void TestOtherComInterface(const TestContext& ctx)
|
||||
ComPtr<ID3D12Device> device;
|
||||
CHECK_HR(pageable->GetDevice(IID_PPV_ARGS(&device)));
|
||||
CHECK_BOOL(device.Get() == ctx.device);
|
||||
|
||||
alloc->Release();
|
||||
}
|
||||
}
|
||||
|
||||
@ -586,11 +556,8 @@ static void TestCustomPools(const TestContext& ctx)
|
||||
poolDesc.MinBlockCount = 1;
|
||||
poolDesc.MaxBlockCount = 2;
|
||||
|
||||
D3D12MA::Pool* poolPtr;
|
||||
CHECK_HR( ctx.allocator->CreatePool(&poolDesc, &poolPtr) );
|
||||
PoolUniquePtr pool{poolPtr};
|
||||
|
||||
D3D12MA::Allocation* allocPtr;
|
||||
ComPtr<D3D12MA::Pool> pool;
|
||||
CHECK_HR( ctx.allocator->CreatePool(&poolDesc, &pool) );
|
||||
|
||||
// # Validate stats for empty pool
|
||||
|
||||
@ -610,7 +577,7 @@ static void TestCustomPools(const TestContext& ctx)
|
||||
// # Create buffers 2x 5 MB
|
||||
|
||||
D3D12MA::ALLOCATION_DESC allocDesc = {};
|
||||
allocDesc.CustomPool = pool.get();
|
||||
allocDesc.CustomPool = pool.Get();
|
||||
allocDesc.ExtraHeapFlags = (D3D12_HEAP_FLAGS)0xCDCDCDCD; // Should be ignored.
|
||||
allocDesc.HeapType = (D3D12_HEAP_TYPE)0xCDCDCDCD; // Should be ignored.
|
||||
|
||||
@ -618,15 +585,14 @@ static void TestCustomPools(const TestContext& ctx)
|
||||
D3D12_RESOURCE_DESC resDesc;
|
||||
FillResourceDescForBuffer(resDesc, BUFFER_SIZE);
|
||||
|
||||
AllocationUniquePtr allocs[4];
|
||||
ComPtr<D3D12MA::Allocation> allocs[4];
|
||||
for(uint32_t i = 0; i < 2; ++i)
|
||||
{
|
||||
CHECK_HR( ctx.allocator->CreateResource(&allocDesc, &resDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
NULL, // pOptimizedClearValue
|
||||
&allocPtr,
|
||||
&allocs[i],
|
||||
__uuidof(ID3D12Resource), NULL) ); // riidResource, ppvResource
|
||||
allocs[i].reset(allocPtr);
|
||||
}
|
||||
|
||||
// # Validate pool stats now
|
||||
@ -654,10 +620,11 @@ static void TestCustomPools(const TestContext& ctx)
|
||||
allocDesc.Flags = i == 0 ?
|
||||
D3D12MA::ALLOCATION_FLAG_NEVER_ALLOCATE:
|
||||
D3D12MA::ALLOCATION_FLAG_COMMITTED;
|
||||
ComPtr<D3D12MA::Allocation> alloc;
|
||||
const HRESULT hr = ctx.allocator->CreateResource(&allocDesc, &resDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
NULL, // pOptimizedClearValue
|
||||
&allocPtr,
|
||||
&alloc,
|
||||
__uuidof(ID3D12Resource), NULL); // riidResource, ppvResource
|
||||
CHECK_BOOL( FAILED(hr) );
|
||||
}
|
||||
@ -667,15 +634,16 @@ static void TestCustomPools(const TestContext& ctx)
|
||||
allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NONE;
|
||||
for(uint32_t i = 2; i < 5; ++i)
|
||||
{
|
||||
ComPtr<D3D12MA::Allocation> alloc;
|
||||
HRESULT hr = ctx.allocator->CreateResource(&allocDesc, &resDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
NULL, // pOptimizedClearValue
|
||||
&allocPtr,
|
||||
&alloc,
|
||||
__uuidof(ID3D12Resource), NULL); // riidResource, ppvResource
|
||||
if(i < 4)
|
||||
{
|
||||
CHECK_HR( hr );
|
||||
allocs[i].reset(allocPtr);
|
||||
allocs[i] = std::move(alloc);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -691,19 +659,18 @@ static void TestCustomPools(const TestContext& ctx)
|
||||
|
||||
// # Make room, AllocateMemory, CreateAliasingResource
|
||||
|
||||
allocs[3].reset();
|
||||
allocs[0].reset();
|
||||
allocs[3].Reset();
|
||||
allocs[0].Reset();
|
||||
|
||||
D3D12_RESOURCE_ALLOCATION_INFO resAllocInfo = {};
|
||||
resAllocInfo.SizeInBytes = 5 * MEGABYTE;
|
||||
resAllocInfo.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
|
||||
CHECK_HR( ctx.allocator->AllocateMemory(&allocDesc, &resAllocInfo, &allocPtr) );
|
||||
allocs[0].reset(allocPtr);
|
||||
CHECK_HR( ctx.allocator->AllocateMemory(&allocDesc, &resAllocInfo, &allocs[0]) );
|
||||
|
||||
resDesc.Width = 1 * MEGABYTE;
|
||||
ComPtr<ID3D12Resource> res;
|
||||
CHECK_HR( ctx.allocator->CreateAliasingResource(allocs[0].get(),
|
||||
CHECK_HR( ctx.allocator->CreateAliasingResource(allocs[0].Get(),
|
||||
0, // AllocationLocalOffset
|
||||
&resDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
@ -724,27 +691,24 @@ static void TestCustomPool_MinAllocationAlignment(const TestContext& ctx)
|
||||
poolDesc.HeapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
|
||||
poolDesc.MinAllocationAlignment = MIN_ALIGNMENT;
|
||||
|
||||
D3D12MA::Pool* poolPtr;
|
||||
CHECK_HR( ctx.allocator->CreatePool(&poolDesc, &poolPtr) );
|
||||
PoolUniquePtr pool{poolPtr};
|
||||
ComPtr<D3D12MA::Pool> pool;
|
||||
CHECK_HR( ctx.allocator->CreatePool(&poolDesc, &pool) );
|
||||
|
||||
D3D12MA::Allocation* allocPtr;
|
||||
D3D12MA::ALLOCATION_DESC allocDesc = {};
|
||||
allocDesc.CustomPool = pool.get();
|
||||
allocDesc.CustomPool = pool.Get();
|
||||
|
||||
D3D12_RESOURCE_DESC resDesc;
|
||||
FillResourceDescForBuffer(resDesc, BUFFER_SIZE);
|
||||
|
||||
AllocationUniquePtr allocs[BUFFER_COUNT];
|
||||
ComPtr<D3D12MA::Allocation> allocs[BUFFER_COUNT];
|
||||
for(size_t i = 0; i < BUFFER_COUNT; ++i)
|
||||
{
|
||||
CHECK_HR( ctx.allocator->CreateResource(&allocDesc, &resDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
NULL, // pOptimizedClearValue
|
||||
&allocPtr,
|
||||
&allocs[i],
|
||||
IID_NULL, NULL) ); // riidResource, ppvResource
|
||||
allocs[i].reset(allocPtr);
|
||||
CHECK_BOOL(allocPtr->GetOffset() % MIN_ALIGNMENT == 0);
|
||||
CHECK_BOOL(allocs[i]->GetOffset() % MIN_ALIGNMENT == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -762,25 +726,23 @@ static HRESULT TestCustomHeap(const TestContext& ctx, const D3D12_HEAP_PROPERTIE
|
||||
|
||||
const UINT64 BUFFER_SIZE = 1 * MEGABYTE;
|
||||
|
||||
D3D12MA::Pool* poolPtr;
|
||||
HRESULT hr = ctx.allocator->CreatePool(&poolDesc, &poolPtr);
|
||||
PoolUniquePtr pool{poolPtr};
|
||||
ComPtr<D3D12MA::Pool> pool;
|
||||
HRESULT hr = ctx.allocator->CreatePool(&poolDesc, &pool);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
D3D12MA::ALLOCATION_DESC allocDesc = {};
|
||||
allocDesc.CustomPool = pool.get();
|
||||
allocDesc.CustomPool = pool.Get();
|
||||
|
||||
D3D12_RESOURCE_DESC resDesc;
|
||||
FillResourceDescForBuffer(resDesc, BUFFER_SIZE);
|
||||
|
||||
// Pool already allocated a block. We don't expect CreatePlacedResource to fail.
|
||||
D3D12MA::Allocation* allocPtr;
|
||||
ComPtr<D3D12MA::Allocation> alloc;
|
||||
CHECK_HR( ctx.allocator->CreateResource(&allocDesc, &resDesc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
NULL, // pOptimizedClearValue
|
||||
&allocPtr,
|
||||
&alloc,
|
||||
__uuidof(ID3D12Resource), NULL) ); // riidResource, ppvResource
|
||||
AllocationUniquePtr alloc{allocPtr};
|
||||
|
||||
D3D12MA::Stats globalStatsCurr = {};
|
||||
ctx.allocator->CalculateStats(&globalStatsCurr);
|
||||
@ -840,11 +802,10 @@ static void TestStandardCustomCommittedPlaced(const TestContext& ctx)
|
||||
poolDesc.HeapProperties.Type = heapType;
|
||||
poolDesc.HeapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
|
||||
|
||||
D3D12MA::Pool* poolPtr;
|
||||
CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &poolPtr));
|
||||
PoolUniquePtr pool{poolPtr};
|
||||
ComPtr<D3D12MA::Pool> pool;
|
||||
CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));
|
||||
|
||||
std::vector<AllocationUniquePtr> allocations;
|
||||
std::vector<ComPtr<D3D12MA::Allocation>> allocations;
|
||||
|
||||
D3D12MA::Stats statsBeg = {};
|
||||
D3D12MA::StatInfo poolStatInfoBeg = {};
|
||||
@ -867,7 +828,7 @@ static void TestStandardCustomCommittedPlaced(const TestContext& ctx)
|
||||
D3D12MA::ALLOCATION_DESC allocDesc = {};
|
||||
if(useCustomPool)
|
||||
{
|
||||
allocDesc.CustomPool = pool.get();
|
||||
allocDesc.CustomPool = pool.Get();
|
||||
allocDesc.HeapType = (D3D12_HEAP_TYPE)0xCDCDCDCD; // Should be ignored.
|
||||
allocDesc.ExtraHeapFlags = (D3D12_HEAP_FLAGS)0xCDCDCDCD; // Should be ignored.
|
||||
}
|
||||
@ -878,7 +839,7 @@ static void TestStandardCustomCommittedPlaced(const TestContext& ctx)
|
||||
if(neverAllocate)
|
||||
allocDesc.Flags |= D3D12MA::ALLOCATION_FLAG_NEVER_ALLOCATE;
|
||||
|
||||
D3D12MA::Allocation* allocPtr = NULL;
|
||||
ComPtr<D3D12MA::Allocation> allocPtr = NULL;
|
||||
HRESULT hr = ctx.allocator->CreateResource(&allocDesc, &resDesc,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
NULL, // pOptimizedClearValue
|
||||
@ -886,7 +847,7 @@ static void TestStandardCustomCommittedPlaced(const TestContext& ctx)
|
||||
CHECK_BOOL(SUCCEEDED(hr) == (allocPtr != NULL));
|
||||
if(allocPtr)
|
||||
{
|
||||
allocations.push_back(AllocationUniquePtr{allocPtr});
|
||||
allocations.push_back(allocPtr);
|
||||
if(useCustomPool)
|
||||
++poolAllocCount;
|
||||
}
|
||||
@ -956,13 +917,13 @@ static void TestAliasingMemory(const TestContext& ctx)
|
||||
allocDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
|
||||
allocDesc.ExtraHeapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES;
|
||||
|
||||
D3D12MA::Allocation* alloc = NULL;
|
||||
ComPtr<D3D12MA::Allocation> alloc;
|
||||
CHECK_HR( ctx.allocator->AllocateMemory(&allocDesc, &finalAllocInfo, &alloc) );
|
||||
CHECK_BOOL(alloc != NULL && alloc->GetHeap() != NULL);
|
||||
|
||||
ID3D12Resource* res1 = NULL;
|
||||
ComPtr<ID3D12Resource> res1;
|
||||
CHECK_HR( ctx.allocator->CreateAliasingResource(
|
||||
alloc,
|
||||
alloc.Get(),
|
||||
0, // AllocationLocalOffset
|
||||
&resDesc1,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
@ -970,9 +931,9 @@ static void TestAliasingMemory(const TestContext& ctx)
|
||||
IID_PPV_ARGS(&res1)) );
|
||||
CHECK_BOOL(res1 != NULL);
|
||||
|
||||
ID3D12Resource* res2 = NULL;
|
||||
ComPtr<ID3D12Resource> res2;
|
||||
CHECK_HR( ctx.allocator->CreateAliasingResource(
|
||||
alloc,
|
||||
alloc.Get(),
|
||||
0, // AllocationLocalOffset
|
||||
&resDesc2,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
@ -981,10 +942,6 @@ static void TestAliasingMemory(const TestContext& ctx)
|
||||
CHECK_BOOL(res2 != NULL);
|
||||
|
||||
// You can use res1 and res2, but not at the same time!
|
||||
|
||||
res2->Release();
|
||||
res1->Release();
|
||||
alloc->Release();
|
||||
}
|
||||
|
||||
static void TestMapping(const TestContext& ctx)
|
||||
@ -1003,15 +960,13 @@ static void TestMapping(const TestContext& ctx)
|
||||
|
||||
for(UINT i = 0; i < count; ++i)
|
||||
{
|
||||
D3D12MA::Allocation* alloc = nullptr;
|
||||
CHECK_HR( ctx.allocator->CreateResource(
|
||||
&allocDesc,
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
NULL,
|
||||
&alloc,
|
||||
&resources[i].allocation,
|
||||
IID_PPV_ARGS(&resources[i].resource)) );
|
||||
resources[i].allocation.reset(alloc);
|
||||
|
||||
void* mappedPtr = NULL;
|
||||
CHECK_HR( resources[i].resource->Map(0, &EMPTY_RANGE, &mappedPtr) );
|
||||
@ -1082,15 +1037,13 @@ static void TestStats(const TestContext& ctx)
|
||||
{
|
||||
if(i == count / 2)
|
||||
allocDesc.Flags |= D3D12MA::ALLOCATION_FLAG_COMMITTED;
|
||||
D3D12MA::Allocation* alloc = nullptr;
|
||||
CHECK_HR( ctx.allocator->CreateResource(
|
||||
&allocDesc,
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
NULL,
|
||||
&alloc,
|
||||
&resources[i].allocation,
|
||||
IID_PPV_ARGS(&resources[i].resource)) );
|
||||
resources[i].allocation.reset(alloc);
|
||||
}
|
||||
|
||||
D3D12MA::Stats endStats = {};
|
||||
@ -1153,33 +1106,29 @@ static void TestTransfer(const TestContext& ctx)
|
||||
// Create 3 sets of resources.
|
||||
for(UINT i = 0; i < count; ++i)
|
||||
{
|
||||
D3D12MA::Allocation* alloc = nullptr;
|
||||
CHECK_HR( ctx.allocator->CreateResource(
|
||||
&allocDescUpload,
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
NULL,
|
||||
&alloc,
|
||||
&resourcesUpload[i].allocation,
|
||||
IID_PPV_ARGS(&resourcesUpload[i].resource)) );
|
||||
resourcesUpload[i].allocation.reset(alloc);
|
||||
|
||||
CHECK_HR( ctx.allocator->CreateResource(
|
||||
&allocDescDefault,
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
NULL,
|
||||
&alloc,
|
||||
&resourcesDefault[i].allocation,
|
||||
IID_PPV_ARGS(&resourcesDefault[i].resource)) );
|
||||
resourcesDefault[i].allocation.reset(alloc);
|
||||
|
||||
CHECK_HR( ctx.allocator->CreateResource(
|
||||
&allocDescReadback,
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
NULL,
|
||||
&alloc,
|
||||
&resourcesReadback[i].allocation,
|
||||
IID_PPV_ARGS(&resourcesReadback[i].resource)) );
|
||||
resourcesReadback[i].allocation.reset(alloc);
|
||||
}
|
||||
|
||||
// Map and fill data in UPLOAD.
|
||||
@ -1241,7 +1190,6 @@ static void TestZeroInitialized(const TestContext& ctx)
|
||||
wprintf(L"Test zero initialized\n");
|
||||
|
||||
const UINT64 bufSize = 128ull * 1024;
|
||||
D3D12MA::Allocation* alloc = nullptr;
|
||||
|
||||
D3D12_RESOURCE_DESC resourceDesc;
|
||||
FillResourceDescForBuffer(resourceDesc, bufSize);
|
||||
@ -1257,9 +1205,8 @@ static void TestZeroInitialized(const TestContext& ctx)
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
NULL,
|
||||
&alloc,
|
||||
&bufUpload.allocation,
|
||||
IID_PPV_ARGS(&bufUpload.resource)) );
|
||||
bufUpload.allocation.reset(alloc);
|
||||
|
||||
{
|
||||
void* mappedPtr = nullptr;
|
||||
@ -1279,9 +1226,8 @@ static void TestZeroInitialized(const TestContext& ctx)
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
NULL,
|
||||
&alloc,
|
||||
&bufReadback.allocation,
|
||||
IID_PPV_ARGS(&bufReadback.resource)) );
|
||||
bufReadback.allocation.reset(alloc);
|
||||
|
||||
auto CheckBufferData = [&](const ResourceWithAllocation& buf)
|
||||
{
|
||||
@ -1323,9 +1269,8 @@ static void TestZeroInitialized(const TestContext& ctx)
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_COPY_SOURCE,
|
||||
NULL,
|
||||
&alloc,
|
||||
&bufDefault.allocation,
|
||||
IID_PPV_ARGS(&bufDefault.resource)) );
|
||||
bufDefault.allocation.reset(alloc);
|
||||
|
||||
wprintf(L" Committed: ");
|
||||
CheckBufferData(bufDefault);
|
||||
@ -1347,9 +1292,8 @@ static void TestZeroInitialized(const TestContext& ctx)
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_COPY_SOURCE,
|
||||
NULL,
|
||||
&alloc,
|
||||
&bufDefault.allocation,
|
||||
IID_PPV_ARGS(&bufDefault.resource)) );
|
||||
bufDefault.allocation.reset(alloc);
|
||||
|
||||
// 2. Check it
|
||||
|
||||
@ -1413,15 +1357,13 @@ static void TestMultithreading(const TestContext& ctx)
|
||||
D3D12_RESOURCE_DESC resourceDesc;
|
||||
FillResourceDescForBuffer(resourceDesc, res.size);
|
||||
|
||||
D3D12MA::Allocation* alloc = nullptr;
|
||||
CHECK_HR( ctx.allocator->CreateResource(
|
||||
&allocDesc,
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
NULL,
|
||||
&alloc,
|
||||
&res.allocation,
|
||||
IID_PPV_ARGS(&res.resource)) );
|
||||
res.allocation.reset(alloc);
|
||||
|
||||
void* mappedPtr = nullptr;
|
||||
CHECK_HR( res.resource->Map(0, &EMPTY_RANGE, &mappedPtr) );
|
||||
@ -1458,15 +1400,13 @@ static void TestMultithreading(const TestContext& ctx)
|
||||
D3D12_RESOURCE_DESC resourceDesc;
|
||||
FillResourceDescForBuffer(resourceDesc, res.size);
|
||||
|
||||
D3D12MA::Allocation* alloc = nullptr;
|
||||
CHECK_HR( ctx.allocator->CreateResource(
|
||||
&allocDesc,
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
NULL,
|
||||
&alloc,
|
||||
&res.allocation,
|
||||
IID_PPV_ARGS(&res.resource)) );
|
||||
res.allocation.reset(alloc);
|
||||
|
||||
void* mappedPtr = nullptr;
|
||||
CHECK_HR( res.resource->Map(0, NULL, &mappedPtr) );
|
||||
@ -1556,12 +1496,11 @@ static void TestDevice4(const TestContext& ctx)
|
||||
D3D12MA::ALLOCATION_DESC allocDesc = {};
|
||||
allocDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
|
||||
|
||||
D3D12MA::Allocation* alloc = nullptr;
|
||||
ComPtr<D3D12MA::Allocation> bufAlloc;
|
||||
ComPtr<ID3D12Resource> bufRes;
|
||||
CHECK_HR(ctx.allocator->CreateResource1(&allocDesc, &resourceDesc,
|
||||
D3D12_RESOURCE_STATE_COMMON, NULL,
|
||||
session.Get(), &alloc, IID_PPV_ARGS(&bufRes)));
|
||||
AllocationUniquePtr bufAllocPtr{alloc};
|
||||
session.Get(), &bufAlloc, IID_PPV_ARGS(&bufRes)));
|
||||
|
||||
// Create a heap
|
||||
// Temporarily commented out as it caues BSOD on RTX2080Ti driver 461.40.
|
||||
@ -1592,25 +1531,23 @@ static void TestDevice8(const TestContext& ctx)
|
||||
allocDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
|
||||
allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED;
|
||||
|
||||
D3D12MA::Allocation* alloc0 = nullptr;
|
||||
ComPtr<D3D12MA::Allocation> allocPtr0;
|
||||
ComPtr<ID3D12Resource> res0;
|
||||
CHECK_HR(ctx.allocator->CreateResource2(&allocDesc, &resourceDesc,
|
||||
D3D12_RESOURCE_STATE_COMMON, NULL, NULL,
|
||||
&alloc0, IID_PPV_ARGS(&res0)));
|
||||
AllocationUniquePtr allocPtr0{alloc0};
|
||||
CHECK_BOOL(alloc0->GetHeap() == NULL);
|
||||
&allocPtr0, IID_PPV_ARGS(&res0)));
|
||||
CHECK_BOOL(allocPtr0->GetHeap() == NULL);
|
||||
|
||||
// Create a placed buffer
|
||||
|
||||
allocDesc.Flags &= ~D3D12MA::ALLOCATION_FLAG_COMMITTED;
|
||||
|
||||
D3D12MA::Allocation* alloc1 = nullptr;
|
||||
ComPtr<D3D12MA::Allocation> allocPtr1;
|
||||
ComPtr<ID3D12Resource> res1;
|
||||
CHECK_HR(ctx.allocator->CreateResource2(&allocDesc, &resourceDesc,
|
||||
D3D12_RESOURCE_STATE_COMMON, NULL, NULL,
|
||||
&alloc1, IID_PPV_ARGS(&res1)));
|
||||
AllocationUniquePtr allocPtr1{alloc1};
|
||||
CHECK_BOOL(alloc1->GetHeap()!= NULL);
|
||||
&allocPtr1, IID_PPV_ARGS(&res1)));
|
||||
CHECK_BOOL(allocPtr1->GetHeap()!= NULL);
|
||||
}
|
||||
|
||||
static void TestGroupVirtual(const TestContext& ctx)
|
||||
|
Loading…
Reference in New Issue
Block a user