Added Allocator::CreateResource2
diff --git a/src/D3D12MemAlloc.cpp b/src/D3D12MemAlloc.cpp
index a7ab321..396819b 100644
--- a/src/D3D12MemAlloc.cpp
+++ b/src/D3D12MemAlloc.cpp
@@ -688,7 +688,8 @@
}
// This algorithm is overly conservative.
-static bool CanUseSmallAlignment(const D3D12_RESOURCE_DESC& resourceDesc)
+template<typename D3D12_RESOURCE_DESC_T>
+static bool CanUseSmallAlignment(const D3D12_RESOURCE_DESC_T& resourceDesc)
{
if(resourceDesc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D)
return false;
@@ -2356,6 +2357,20 @@
REFIID riidResource,
void** ppvResource);
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+ HRESULT CreateResource2(
+ UINT64 size,
+ UINT64 alignment,
+ const ALLOCATION_DESC& allocDesc,
+ const D3D12_RESOURCE_DESC1& resourceDesc,
+ D3D12_RESOURCE_STATES InitialResourceState,
+ const D3D12_CLEAR_VALUE *pOptimizedClearValue,
+ ID3D12ProtectedResourceSession *pProtectedSession,
+ Allocation** ppAllocation,
+ REFIID riidResource,
+ void** ppvResource);
+#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
+
HRESULT SetMinBytes(UINT64 minBytes);
void AddStats(StatInfo& outStats);
@@ -2465,6 +2480,9 @@
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
ID3D12Device4* GetDevice4() const { return m_Device4; }
#endif
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+ ID3D12Device8* GetDevice8() const { return m_Device8; }
+#endif
// Shortcut for "Allocation Callbacks", because this function is called so often.
const ALLOCATION_CALLBACKS& GetAllocs() const { return m_AllocationCallbacks; }
const D3D12_FEATURE_DATA_D3D12_OPTIONS& GetD3D12Options() const { return m_D3D12Options; }
@@ -2494,6 +2512,18 @@
void** ppvResource);
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+ HRESULT CreateResource2(
+ const ALLOCATION_DESC* pAllocDesc,
+ const D3D12_RESOURCE_DESC1* pResourceDesc,
+ D3D12_RESOURCE_STATES InitialResourceState,
+ const D3D12_CLEAR_VALUE *pOptimizedClearValue,
+ ID3D12ProtectedResourceSession *pProtectedSession,
+ Allocation** ppAllocation,
+ REFIID riidResource,
+ void** ppvResource);
+#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
+
HRESULT AllocateMemory(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_ALLOCATION_INFO* pAllocInfo,
@@ -2552,7 +2582,8 @@
Heuristics that decides whether a resource should better be placed in its own,
dedicated allocation (committed resource rather than placed resource).
*/
- static bool PrefersCommittedAllocation(const D3D12_RESOURCE_DESC& resourceDesc);
+ template<typename D3D12_RESOURCE_DESC_T>
+ static bool PrefersCommittedAllocation(const D3D12_RESOURCE_DESC_T& resourceDesc);
const bool m_UseMutex;
const bool m_AlwaysCommitted;
@@ -2560,6 +2591,9 @@
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
ID3D12Device4* m_Device4 = NULL; // AddRef, optional
#endif
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+ ID3D12Device8* m_Device8 = NULL; // AddRef, optional
+#endif
IDXGIAdapter* m_Adapter; // AddRef
#if D3D12MA_DXGI_1_4
IDXGIAdapter3* m_Adapter3 = NULL; // AddRef, optional
@@ -2612,6 +2646,19 @@
void** ppvResource);
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+ HRESULT AllocateCommittedResource2(
+ const ALLOCATION_DESC* pAllocDesc,
+ const D3D12_RESOURCE_DESC1* pResourceDesc,
+ const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
+ D3D12_RESOURCE_STATES InitialResourceState,
+ const D3D12_CLEAR_VALUE *pOptimizedClearValue,
+ ID3D12ProtectedResourceSession *pProtectedSession,
+ Allocation** ppAllocation,
+ REFIID riidResource,
+ void** ppvResource);
+#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
+
// Allocates and registers new heap without any resources placed in it, as dedicated allocation.
// Creates and returns Allocation object.
HRESULT AllocateHeap(
@@ -2644,7 +2691,8 @@
8: D3D12_HEAP_TYPE_READBACK + texture RT or DS
*/
UINT CalcDefaultPoolCount() const;
- UINT CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, const D3D12_RESOURCE_DESC& resourceDesc) const;
+ template<typename D3D12_RESOURCE_DESC_T>
+ UINT CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, const D3D12_RESOURCE_DESC_T& resourceDesc) 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
@@ -2669,7 +2717,13 @@
HRESULT UpdateD3D12Budget();
- D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfo(D3D12_RESOURCE_DESC& inOutResourceDesc) const;
+ D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfoNative(const D3D12_RESOURCE_DESC& resourceDesc) const;
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+ D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfoNative(const D3D12_RESOURCE_DESC1& resourceDesc) const;
+#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
+
+ template<typename D3D12_RESOURCE_DESC_T>
+ D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfo(D3D12_RESOURCE_DESC_T& inOutResourceDesc) const;
// Writes object { } with data of given budget.
static void WriteBudgetToJson(JsonWriter& json, const Budget& budget);
@@ -3707,6 +3761,63 @@
return hr;
}
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+HRESULT BlockVector::CreateResource2(
+ UINT64 size,
+ UINT64 alignment,
+ const ALLOCATION_DESC& allocDesc,
+ const D3D12_RESOURCE_DESC1& resourceDesc,
+ D3D12_RESOURCE_STATES InitialResourceState,
+ const D3D12_CLEAR_VALUE *pOptimizedClearValue,
+ ID3D12ProtectedResourceSession *pProtectedSession,
+ Allocation** ppAllocation,
+ REFIID riidResource,
+ void** ppvResource)
+{
+ D3D12MA_ASSERT(pProtectedSession == NULL && "Should never get here. pProtectedSession != NULL currently requires committed resources.");
+
+ ID3D12Device8* const device8 = m_hAllocator->GetDevice8();
+ if(device8 == NULL)
+ {
+ return E_NOINTERFACE;
+ }
+
+ HRESULT hr = Allocate(size, alignment, allocDesc, 1, ppAllocation);
+ if(SUCCEEDED(hr))
+ {
+ ID3D12Resource* res = NULL;
+ hr = device8->CreatePlacedResource1(
+ (*ppAllocation)->m_Placed.block->GetHeap(),
+ (*ppAllocation)->GetOffset(),
+ &resourceDesc,
+ InitialResourceState,
+ pOptimizedClearValue,
+ IID_PPV_ARGS(&res));
+ if(SUCCEEDED(hr))
+ {
+ if(ppvResource != NULL)
+ {
+ hr = res->QueryInterface(riidResource, ppvResource);
+ }
+ if(SUCCEEDED(hr))
+ {
+ (*ppAllocation)->SetResource(res, &resourceDesc);
+ }
+ else
+ {
+ res->Release();
+ SAFE_RELEASE(*ppAllocation);
+ }
+ }
+ else
+ {
+ SAFE_RELEASE(*ppAllocation);
+ }
+ }
+ return hr;
+}
+#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
+
UINT64 BlockVector::CalcSumBlockSize() const
{
UINT64 result = 0;
@@ -4147,6 +4258,10 @@
m_Device->QueryInterface<ID3D12Device4>(&m_Device4);
#endif
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+ m_Device->QueryInterface<ID3D12Device8>(&m_Device8);
+#endif
+
HRESULT hr = m_Adapter->GetDesc(&m_AdapterDesc);
if(FAILED(hr))
{
@@ -4189,6 +4304,9 @@
AllocatorPimpl::~AllocatorPimpl()
{
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+ SAFE_RELEASE(m_Device8);
+#endif
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
SAFE_RELEASE(m_Device4);
#endif
@@ -4414,6 +4532,146 @@
}
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+HRESULT AllocatorPimpl::CreateResource2(
+ const ALLOCATION_DESC* pAllocDesc,
+ const D3D12_RESOURCE_DESC1* pResourceDesc,
+ D3D12_RESOURCE_STATES InitialResourceState,
+ const D3D12_CLEAR_VALUE *pOptimizedClearValue,
+ ID3D12ProtectedResourceSession *pProtectedSession,
+ Allocation** ppAllocation,
+ REFIID riidResource,
+ void** ppvResource)
+{
+ *ppAllocation = NULL;
+ if(ppvResource)
+ {
+ *ppvResource = NULL;
+ }
+
+ if(m_Device8 == NULL)
+ {
+ return E_NOINTERFACE;
+ }
+
+ if(pAllocDesc->CustomPool == NULL)
+ {
+ if(!IsHeapTypeValid(pAllocDesc->HeapType))
+ {
+ return E_INVALIDARG;
+ }
+ }
+
+ ALLOCATION_DESC finalAllocDesc = *pAllocDesc;
+
+ D3D12_RESOURCE_DESC1 finalResourceDesc = *pResourceDesc;
+ D3D12_RESOURCE_ALLOCATION_INFO resAllocInfo = GetResourceAllocationInfo(finalResourceDesc);
+ resAllocInfo.Alignment = D3D12MA_MAX<UINT64>(resAllocInfo.Alignment, D3D12MA_DEBUG_ALIGNMENT);
+ D3D12MA_ASSERT(IsPow2(resAllocInfo.Alignment));
+ D3D12MA_ASSERT(resAllocInfo.SizeInBytes > 0);
+
+ bool requireCommittedMemory = pProtectedSession != NULL || (finalAllocDesc.Flags & ALLOCATION_FLAG_COMMITTED) != 0;
+
+ if(pAllocDesc->CustomPool != NULL)
+ {
+ if(requireCommittedMemory)
+ {
+ return E_INVALIDARG;
+ }
+
+ BlockVector* blockVector = pAllocDesc->CustomPool->m_Pimpl->GetBlockVector();
+ D3D12MA_ASSERT(blockVector);
+ return blockVector->CreateResource2(
+ resAllocInfo.SizeInBytes,
+ resAllocInfo.Alignment,
+ finalAllocDesc,
+ finalResourceDesc,
+ InitialResourceState,
+ pOptimizedClearValue,
+ pProtectedSession,
+ ppAllocation,
+ riidResource,
+ ppvResource);
+ }
+ else
+ {
+ const UINT defaultPoolIndex = CalcDefaultPoolIndex(*pAllocDesc, finalResourceDesc);
+ requireCommittedMemory = requireCommittedMemory || defaultPoolIndex == UINT32_MAX;
+ if(requireCommittedMemory)
+ {
+ return AllocateCommittedResource2(
+ &finalAllocDesc,
+ &finalResourceDesc,
+ resAllocInfo,
+ InitialResourceState,
+ pOptimizedClearValue,
+ pProtectedSession,
+ ppAllocation,
+ riidResource,
+ ppvResource);
+ }
+
+ BlockVector* const blockVector = m_BlockVectors[defaultPoolIndex];
+ D3D12MA_ASSERT(blockVector);
+
+ const UINT64 preferredBlockSize = blockVector->GetPreferredBlockSize();
+ bool preferCommittedMemory =
+ m_AlwaysCommitted ||
+ PrefersCommittedAllocation(finalResourceDesc) ||
+ // Heuristics: Allocate committed memory if requested size if greater than half of preferred block size.
+ resAllocInfo.SizeInBytes > preferredBlockSize / 2;
+ if(preferCommittedMemory &&
+ (finalAllocDesc.Flags & ALLOCATION_FLAG_NEVER_ALLOCATE) == 0)
+ {
+ finalAllocDesc.Flags |= ALLOCATION_FLAG_COMMITTED;
+ }
+
+ if((finalAllocDesc.Flags & ALLOCATION_FLAG_COMMITTED) != 0)
+ {
+ return AllocateCommittedResource2(
+ &finalAllocDesc,
+ &finalResourceDesc,
+ resAllocInfo,
+ InitialResourceState,
+ pOptimizedClearValue,
+ pProtectedSession,
+ ppAllocation,
+ riidResource,
+ ppvResource);
+ }
+ else
+ {
+ HRESULT hr = blockVector->CreateResource2(
+ resAllocInfo.SizeInBytes,
+ resAllocInfo.Alignment,
+ finalAllocDesc,
+ finalResourceDesc,
+ InitialResourceState,
+ pOptimizedClearValue,
+ pProtectedSession,
+ ppAllocation,
+ riidResource,
+ ppvResource);
+ if(SUCCEEDED(hr))
+ {
+ return hr;
+ }
+
+ return AllocateCommittedResource2(
+ &finalAllocDesc,
+ &finalResourceDesc,
+ resAllocInfo,
+ InitialResourceState,
+ pOptimizedClearValue,
+ pProtectedSession,
+ ppAllocation,
+ riidResource,
+ ppvResource);
+ }
+ }
+}
+#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
+
HRESULT AllocatorPimpl::AllocateMemory(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_ALLOCATION_INFO* pAllocInfo,
@@ -4619,7 +4877,8 @@
}
}
-bool AllocatorPimpl::PrefersCommittedAllocation(const D3D12_RESOURCE_DESC& resourceDesc)
+template<typename D3D12_RESOURCE_DESC_T>
+bool AllocatorPimpl::PrefersCommittedAllocation(const D3D12_RESOURCE_DESC_T& resourceDesc)
{
// Intentional. It may change in the future.
return false;
@@ -4759,6 +5018,77 @@
}
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+HRESULT AllocatorPimpl::AllocateCommittedResource2(
+ const ALLOCATION_DESC* pAllocDesc,
+ const D3D12_RESOURCE_DESC1* pResourceDesc,
+ const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
+ D3D12_RESOURCE_STATES InitialResourceState,
+ const D3D12_CLEAR_VALUE *pOptimizedClearValue,
+ ID3D12ProtectedResourceSession *pProtectedSession,
+ Allocation** ppAllocation,
+ REFIID riidResource,
+ void** ppvResource)
+{
+ if(m_Device8 == NULL)
+ {
+ return E_NOINTERFACE;
+ }
+
+ if((pAllocDesc->Flags & ALLOCATION_FLAG_NEVER_ALLOCATE) != 0)
+ {
+ return E_OUTOFMEMORY;
+ }
+
+ if((pAllocDesc->Flags & ALLOCATION_FLAG_WITHIN_BUDGET) != 0)
+ {
+ Budget budget = {};
+ GetBudgetForHeapType(budget, pAllocDesc->HeapType);
+ if(budget.UsageBytes + resAllocInfo.SizeInBytes > budget.BudgetBytes)
+ {
+ return E_OUTOFMEMORY;
+ }
+ }
+
+ D3D12_HEAP_PROPERTIES heapProps = {};
+ heapProps.Type = pAllocDesc->HeapType;
+
+ const D3D12_HEAP_FLAGS heapFlags = pAllocDesc->ExtraHeapFlags;
+
+ ID3D12Resource* res = NULL;
+ HRESULT hr = m_Device8->CreateCommittedResource2(
+ &heapProps, heapFlags, pResourceDesc, InitialResourceState,
+ pOptimizedClearValue, pProtectedSession, IID_PPV_ARGS(&res));
+ if(SUCCEEDED(hr))
+ {
+ if(ppvResource != NULL)
+ {
+ hr = res->QueryInterface(riidResource, ppvResource);
+ }
+ if(SUCCEEDED(hr))
+ {
+ const BOOL wasZeroInitialized = TRUE;
+ Allocation* alloc = m_AllocationObjectAllocator.Allocate(this, resAllocInfo.SizeInBytes, wasZeroInitialized);
+ alloc->InitCommitted(pAllocDesc->HeapType);
+ alloc->SetResource(res, pResourceDesc);
+
+ *ppAllocation = alloc;
+
+ RegisterCommittedAllocation(*ppAllocation, pAllocDesc->HeapType);
+
+ const UINT heapTypeIndex = HeapTypeToIndex(pAllocDesc->HeapType);
+ m_Budget.AddAllocation(heapTypeIndex, resAllocInfo.SizeInBytes);
+ m_Budget.m_BlockBytes[heapTypeIndex] += resAllocInfo.SizeInBytes;
+ }
+ else
+ {
+ res->Release();
+ }
+ }
+ return hr;
+}
+#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
+
HRESULT AllocatorPimpl::AllocateHeap(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_ALLOCATION_INFO& allocInfo,
@@ -4871,7 +5201,8 @@
}
}
-UINT AllocatorPimpl::CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, const D3D12_RESOURCE_DESC& resourceDesc) const
+template<typename D3D12_RESOURCE_DESC_T>
+UINT AllocatorPimpl::CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, const D3D12_RESOURCE_DESC_T& resourceDesc) const
{
const D3D12_HEAP_FLAGS extraHeapFlags = allocDesc.ExtraHeapFlags & ~GetExtraHeapFlagsToIgnore();
if(extraHeapFlags != 0)
@@ -5434,7 +5765,22 @@
#endif
}
-D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfo(D3D12_RESOURCE_DESC& inOutResourceDesc) const
+D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfoNative(const D3D12_RESOURCE_DESC& resourceDesc) const
+{
+ return m_Device->GetResourceAllocationInfo(0, 1, &resourceDesc);
+}
+
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfoNative(const D3D12_RESOURCE_DESC1& resourceDesc) const
+{
+ D3D12MA_ASSERT(m_Device8 != NULL);
+ D3D12_RESOURCE_ALLOCATION_INFO1 info1Unused;
+ return m_Device8->GetResourceAllocationInfo2(0, 1, &resourceDesc, &info1Unused);
+}
+#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
+
+template<typename D3D12_RESOURCE_DESC_T>
+D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfo(D3D12_RESOURCE_DESC_T& inOutResourceDesc) const
{
/* Optional optimization: Microsoft documentation says:
https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-getresourceallocationinfo
@@ -5469,7 +5815,7 @@
D3D12_SMALL_MSAA_RESOURCE_PLACEMENT_ALIGNMENT :
D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT;
inOutResourceDesc.Alignment = smallAlignmentToTry;
- const D3D12_RESOURCE_ALLOCATION_INFO smallAllocInfo = m_Device->GetResourceAllocationInfo(0, 1, &inOutResourceDesc);
+ const D3D12_RESOURCE_ALLOCATION_INFO smallAllocInfo = GetResourceAllocationInfoNative(inOutResourceDesc);
// Check if alignment requested has been granted.
if(smallAllocInfo.Alignment == smallAlignmentToTry)
{
@@ -5479,7 +5825,7 @@
}
#endif // #if D3D12MA_USE_SMALL_RESOURCE_PLACEMENT_ALIGNMENT
- return m_Device->GetResourceAllocationInfo(0, 1, &inOutResourceDesc);
+ return GetResourceAllocationInfoNative(inOutResourceDesc);
}
void AllocatorPimpl::WriteBudgetToJson(JsonWriter& json, const Budget& budget)
@@ -5642,7 +5988,8 @@
m_Heap.heap = heap;
}
-void Allocation::SetResource(ID3D12Resource* resource, const D3D12_RESOURCE_DESC* pResourceDesc)
+template<typename D3D12_RESOURCE_DESC_T>
+void Allocation::SetResource(ID3D12Resource* resource, const D3D12_RESOURCE_DESC_T* pResourceDesc)
{
D3D12MA_ASSERT(m_Resource == NULL && pResourceDesc);
m_Resource = resource;
@@ -5749,6 +6096,27 @@
}
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+HRESULT Allocator::CreateResource2(
+ const ALLOCATION_DESC* pAllocDesc,
+ const D3D12_RESOURCE_DESC1* pResourceDesc,
+ D3D12_RESOURCE_STATES InitialResourceState,
+ const D3D12_CLEAR_VALUE *pOptimizedClearValue,
+ ID3D12ProtectedResourceSession *pProtectedSession,
+ Allocation** ppAllocation,
+ REFIID riidResource,
+ void** ppvResource)
+{
+ if(!pAllocDesc || !pResourceDesc || !ppAllocation)
+ {
+ D3D12MA_ASSERT(0 && "Invalid arguments passed to Allocator::CreateResource2.");
+ return E_INVALIDARG;
+ }
+ D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
+ return m_Pimpl->CreateResource2(pAllocDesc, pResourceDesc, InitialResourceState, pOptimizedClearValue, pProtectedSession, ppAllocation, riidResource, ppvResource);
+}
+#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
+
HRESULT Allocator::AllocateMemory(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_ALLOCATION_INFO* pAllocInfo,
diff --git a/src/D3D12MemAlloc.h b/src/D3D12MemAlloc.h
index 2e82763..4ba288d 100644
--- a/src/D3D12MemAlloc.h
+++ b/src/D3D12MemAlloc.h
@@ -954,7 +954,8 @@
void InitCommitted(D3D12_HEAP_TYPE heapType);
void InitPlaced(UINT64 offset, UINT64 alignment, NormalBlock* block);
void InitHeap(D3D12_HEAP_TYPE heapType, ID3D12Heap* heap);
- void SetResource(ID3D12Resource* resource, const D3D12_RESOURCE_DESC* pResourceDesc);
+ template<typename D3D12_RESOURCE_DESC_T>
+ void SetResource(ID3D12Resource* resource, const D3D12_RESOURCE_DESC_T* pResourceDesc);
void FreeName();
D3D12MA_CLASS_NO_COPY(Allocation)
@@ -1276,6 +1277,24 @@
void** ppvResource);
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
+#ifdef __ID3D12Device8_INTERFACE_DEFINED__
+ /** \brief Similar to Allocator::CreateResource1, but supports new structure `D3D12_RESOURCE_DESC1`.
+
+ It internally uses `ID3D12Device8::CreateCommittedResource2` or `ID3D12Device8::CreatePlacedResource1`.
+
+ To work correctly, `ID3D12Device8` interface must be available in the current system. Otherwise, `E_NOINTERFACE` is returned.
+ */
+ HRESULT CreateResource2(
+ const ALLOCATION_DESC* pAllocDesc,
+ const D3D12_RESOURCE_DESC1* pResourceDesc,
+ D3D12_RESOURCE_STATES InitialResourceState,
+ const D3D12_CLEAR_VALUE *pOptimizedClearValue,
+ ID3D12ProtectedResourceSession *pProtectedSession,
+ Allocation** ppAllocation,
+ REFIID riidResource,
+ void** ppvResource);
+#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
+
/** \brief Allocates memory without creating any resource placed in it.
This function is similar to `ID3D12Device::CreateHeap`, but it may really assign
diff --git a/src/Doxyfile b/src/Doxyfile
index 81f5850..6dae76d 100644
--- a/src/Doxyfile
+++ b/src/Doxyfile
@@ -2201,7 +2201,7 @@
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-PREDEFINED = __ID3D12Device4_INTERFACE_DEFINED__
+PREDEFINED = __ID3D12Device4_INTERFACE_DEFINED__ __ID3D12Device8_INTERFACE_DEFINED__
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
diff --git a/src/Tests.cpp b/src/Tests.cpp
index c075834..cda2e3a 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -61,7 +61,8 @@
}
};
-static void FillResourceDescForBuffer(D3D12_RESOURCE_DESC& outResourceDesc, UINT64 size)
+template<typename D3D12_RESOURCE_DESC_T>
+static void FillResourceDescForBuffer(D3D12_RESOURCE_DESC_T& outResourceDesc, UINT64 size)
{
outResourceDesc = {};
outResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
@@ -1370,7 +1371,43 @@
CHECK_HR(ctx.allocator->AllocateMemory1(&allocDesc, &heapAllocInfo, session, &alloc));
AllocationUniquePtr heapAllocPtr{alloc};
+}
+static void TestDevice8(const TestContext& ctx)
+{
+ wprintf(L"Test ID3D12Device8\n");
+
+ CComPtr<ID3D12Device8> dev8;
+ CHECK_HR(ctx.device->QueryInterface(&dev8));
+
+ D3D12_RESOURCE_DESC1 resourceDesc;
+ FillResourceDescForBuffer(resourceDesc, 1024 * 1024);
+
+ // Create a committed buffer
+
+ D3D12MA::ALLOCATION_DESC allocDesc = {};
+ allocDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
+ allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED;
+
+ D3D12MA::Allocation* alloc0 = nullptr;
+ CComPtr<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);
+
+ // Create a placed buffer
+
+ allocDesc.Flags &= ~D3D12MA::ALLOCATION_FLAG_COMMITTED;
+
+ D3D12MA::Allocation* alloc1 = nullptr;
+ CComPtr<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);
}
static void TestGroupVirtual(const TestContext& ctx)
@@ -1394,6 +1431,7 @@
TestZeroInitialized(ctx);
TestMultithreading(ctx);
TestDevice4(ctx);
+ TestDevice8(ctx);
}
void Test(const TestContext& ctx)