From 7642634a62a151295badb7a6e31414473df5c036 Mon Sep 17 00:00:00 2001 From: Adam Sawicki Date: Mon, 26 Jul 2021 21:18:52 +0200 Subject: [PATCH] BREAKING CHANGE: Made all public classes COM-compatible - inheriting from IUnknown, reference counting --- src/D3D12MemAlloc.cpp | 55 ++++++++---- src/D3D12MemAlloc.h | 78 ++++++++++------- src/D3D12Sample.cpp | 6 +- src/Tests.cpp | 199 +++++++++++++++--------------------------- 4 files changed, 155 insertions(+), 183 deletions(-) diff --git a/src/D3D12MemAlloc.cpp b/src/D3D12MemAlloc.cpp index 54b8522..b6efe6b 100644 --- a/src/D3D12MemAlloc.cpp +++ b/src/D3D12MemAlloc.cpp @@ -31,7 +31,6 @@ #include #include -#include #include #include #include @@ -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 -#endif - -#ifndef D3D12MA_ATOMIC_UINT64 - #define D3D12MA_ATOMIC_UINT64 std::atomic -#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 diff --git a/src/D3D12MemAlloc.h b/src/D3D12MemAlloc.h index a6007cc..e96e624 100644 --- a/src/D3D12MemAlloc.h +++ b/src/D3D12MemAlloc.h @@ -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 +#endif + +#ifndef D3D12MA_ATOMIC_UINT32 + #define D3D12MA_ATOMIC_UINT32 std::atomic +#endif + +#ifndef D3D12MA_ATOMIC_UINT64 + #define D3D12MA_ATOMIC_UINT64 std::atomic +#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 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**); diff --git a/src/D3D12Sample.cpp b/src/D3D12Sample.cpp index 6bdb3bf..b7baee3 100644 --- a/src/D3D12Sample.cpp +++ b/src/D3D12Sample.cpp @@ -90,7 +90,7 @@ static float g_TimeDelta; static DXGIUsage* g_DXGIUsage; static ComPtr g_Device; -static D3D12MA::Allocator* g_Allocator; +static ComPtr g_Allocator; static ComPtr g_SwapChain; // swapchain used to switch between render targets static ComPtr 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); } diff --git a/src/Tests.cpp b/src/Tests.cpp index 1ffcb6e..5177545 100644 --- a/src/Tests.cpp +++ b/src/Tests.cpp @@ -29,33 +29,17 @@ extern void EndCommandList(ID3D12GraphicsCommandList* cmdList); static constexpr UINT64 MEGABYTE = 1024 * 1024; -template -struct D3d12maObjDeleter -{ - void operator()(T* obj) const - { - if(obj) - { - obj->Release(); - } - } -}; - -typedef std::unique_ptr> AllocationUniquePtr; -typedef std::unique_ptr> PoolUniquePtr; -typedef std::unique_ptr> VirtualBlockUniquePtr; - struct ResourceWithAllocation { ComPtr resource; - AllocationUniquePtr allocation; + ComPtr 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 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 alloc; ComPtr pageable; CHECK_HR(ctx.allocator->CreateResource( &allocDesc, @@ -563,8 +535,6 @@ static void TestOtherComInterface(const TestContext& ctx) ComPtr 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 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 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 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 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 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 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 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 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 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 pool; + CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool)); - std::vector allocations; + std::vector> 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 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 alloc; CHECK_HR( ctx.allocator->AllocateMemory(&allocDesc, &finalAllocInfo, &alloc) ); CHECK_BOOL(alloc != NULL && alloc->GetHeap() != NULL); - ID3D12Resource* res1 = NULL; + ComPtr 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 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 bufAlloc; ComPtr 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 allocPtr0; ComPtr 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 allocPtr1; ComPtr 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)