add support of ID3D12Device10::CreateCommittedResource3, ID3D12Device8::CreatePlacedResource2 and perhaps all possible future versions of them

This commit is contained in:
ruslan_kutdusov 2022-07-24 00:53:20 +03:00
parent f0458801c4
commit c2c78fe042
3 changed files with 534 additions and 317 deletions

View File

@ -1157,7 +1157,26 @@ public:
Allocation** ppAllocation,
REFIID riidResource,
void** ppvResource);
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
/** \brief Similar to Allocator::CreateResource2, but there are initial layout instead of state and
castable formats list
It internally uses `ID3D12Device10::CreateCommittedResource3` or `ID3D12Device10::CreatePlacedResource2`.
To work correctly, `ID3D12Device10` interface must be available in the current system. Otherwise, `E_NOINTERFACE` is returned.
*/
HRESULT CreateResource3(const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_DESC1* pResourceDesc,
D3D12_BARRIER_LAYOUT InitialLayout,
const D3D12_CLEAR_VALUE* pOptimizedClearValue,
UINT32 NumCastableFormats,
DXGI_FORMAT* pCastableFormats,
Allocation** ppAllocation,
REFIID riidResource,
void** ppvResource);
#endif // #ifdef __ID3D12Device10_INTERFACE_DEFINED__
/** \brief Allocates memory without creating any resource placed in it.
@ -1214,6 +1233,41 @@ public:
REFIID riidResource,
void** ppvResource);
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
/** \brief Similar to Allocator::CreateAliasingResource, but supports new structure `D3D12_RESOURCE_DESC1`.
It internally uses `ID3D12Device8::CreatePlacedResource1`.
To work correctly, `ID3D12Device8` interface must be available in the current system. Otherwise, `E_NOINTERFACE` is returned.
*/
HRESULT CreateAliasingResource1(Allocation* pAllocation,
UINT64 AllocationLocalOffset,
const D3D12_RESOURCE_DESC1* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE* pOptimizedClearValue,
REFIID riidResource,
void** ppvResource);
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
/** \brief Similar to Allocator::CreateAliasingResource1, but there are initial layout instead of state and
castable formats list
It internally uses `ID3D12Device10::CreatePlacedResource2`.
To work correctly, `ID3D12Device10` interface must be available in the current system. Otherwise, `E_NOINTERFACE` is returned.
*/
HRESULT CreateAliasingResource2(Allocation* pAllocation,
UINT64 AllocationLocalOffset,
const D3D12_RESOURCE_DESC1* pResourceDesc,
D3D12_BARRIER_LAYOUT InitialLayout,
const D3D12_CLEAR_VALUE* pOptimizedClearValue,
UINT32 NumCastableFormats,
DXGI_FORMAT* pCastableFormats,
REFIID riidResource,
void** ppvResource);
#endif // #ifdef __ID3D12Device10_INTERFACE_DEFINED__
/** \brief Creates custom pool.
*/
HRESULT CreatePool(

View File

@ -5950,6 +5950,83 @@ struct CommittedAllocationParameters
};
#endif // _D3D12M_COMMITTED_ALLOCATION_PARAMETERS
// Simple variant data structure to hold all possible variations of ID3D12Device*::CreateCommittedResource* and ID3D12Device*::CreatePlacedResource* arguments
struct CREATE_RESOURCE_PARAMS
{
CREATE_RESOURCE_PARAMS() = delete;
CREATE_RESOURCE_PARAMS(
const D3D12_RESOURCE_DESC* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE* pOptimizedClearValue)
: variant(VARIANT_WITH_STATE)
, pResourceDesc(pResourceDesc)
, InitialResourceState(InitialResourceState)
, pOptimizedClearValue(pOptimizedClearValue)
{
}
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
CREATE_RESOURCE_PARAMS(
const D3D12_RESOURCE_DESC1* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE* pOptimizedClearValue)
: variant(VARIANT_WITH_STATE_AND_DESC1)
, pResourceDesc1(pResourceDesc)
, InitialResourceState(InitialResourceState)
, pOptimizedClearValue(pOptimizedClearValue)
{
}
#endif
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
CREATE_RESOURCE_PARAMS(
const D3D12_RESOURCE_DESC1* pResourceDesc,
D3D12_BARRIER_LAYOUT InitialLayout,
const D3D12_CLEAR_VALUE* pOptimizedClearValue,
UINT32 NumCastableFormats,
DXGI_FORMAT* pCastableFormats)
: variant(VARIANT_WITH_LAYOUT)
, pResourceDesc1(pResourceDesc)
, InitialLayout(InitialLayout)
, pOptimizedClearValue(pOptimizedClearValue)
, NumCastableFormats(NumCastableFormats)
, pCastableFormats(pCastableFormats)
{
}
#endif
enum VARIANT
{
VARIANT_INVALID = 0,
VARIANT_WITH_STATE,
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
VARIANT_WITH_STATE_AND_DESC1,
#endif
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
VARIANT_WITH_LAYOUT
#endif
};
VARIANT variant = VARIANT_INVALID;
union
{
const D3D12_RESOURCE_DESC* pResourceDesc;
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
const D3D12_RESOURCE_DESC1* pResourceDesc1;
#endif
};
union
{
D3D12_RESOURCE_STATES InitialResourceState;
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
D3D12_BARRIER_LAYOUT InitialLayout;
#endif
};
const D3D12_CLEAR_VALUE* pOptimizedClearValue;
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
UINT32 NumCastableFormats;
DXGI_FORMAT* pCastableFormats;
#endif
};
#ifndef _D3D12MA_BLOCK_VECTOR
/*
Sequence of NormalBlock. Represents memory blocks allocated for a specific
@ -6003,26 +6080,11 @@ public:
UINT64 size,
UINT64 alignment,
const ALLOCATION_DESC& allocDesc,
const D3D12_RESOURCE_DESC& resourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
const CREATE_RESOURCE_PARAMS& createParams,
Allocation** ppAllocation,
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,
Allocation** ppAllocation,
REFIID riidResource,
void** ppvResource);
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
void AddStatistics(Statistics& inoutStats);
void AddDetailedStatistics(DetailedStatistics& inoutStats);
@ -6402,32 +6464,24 @@ public:
UINT HeapPropertiesToMemorySegmentGroup(const D3D12_HEAP_PROPERTIES& heapProps) const;
UINT64 GetMemoryCapacity(UINT memorySegmentGroup) const;
HRESULT CreateResource(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_DESC* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
Allocation** ppAllocation,
HRESULT CreatePlacedResourceWrap(
ID3D12Heap *pHeap,
UINT64 HeapOffset,
const CREATE_RESOURCE_PARAMS& createParams,
REFIID riidResource,
void** ppvResource);
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
HRESULT CreateResource2(
HRESULT CreateResource(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_DESC1* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
const CREATE_RESOURCE_PARAMS& createParams,
Allocation** ppAllocation,
REFIID riidResource,
void** ppvResource);
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
HRESULT CreateAliasingResource(
Allocation* pAllocation,
UINT64 AllocationLocalOffset,
const D3D12_RESOURCE_DESC* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
const CREATE_RESOURCE_PARAMS& createParams,
REFIID riidResource,
void** ppvResource);
@ -6468,6 +6522,9 @@ private:
#endif
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
ID3D12Device8* m_Device8 = NULL; // AddRef, optional
#endif
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
ID3D12Device10* m_Device10 = NULL; // AddRef, optional
#endif
IDXGIAdapter* m_Adapter; // AddRef
#if D3D12MA_DXGI_1_4
@ -6499,19 +6556,9 @@ private:
HRESULT AllocateCommittedResource(
const CommittedAllocationParameters& committedAllocParams,
UINT64 resourceSize, bool withinBudget, void* pPrivateData,
const D3D12_RESOURCE_DESC* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE *pOptimizedClearValue,
const CREATE_RESOURCE_PARAMS& createParams,
Allocation** ppAllocation, REFIID riidResource, void** ppvResource);
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
HRESULT AllocateCommittedResource2(
const CommittedAllocationParameters& committedAllocParams,
UINT64 resourceSize, bool withinBudget, void* pPrivateData,
const D3D12_RESOURCE_DESC1* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE *pOptimizedClearValue,
Allocation** ppAllocation, REFIID riidResource, void** ppvResource);
#endif
// Allocates and registers new heap without any resources placed in it, as dedicated allocation.
// Creates and returns Allocation object.
HRESULT AllocateHeap(
@ -6602,6 +6649,10 @@ HRESULT AllocatorPimpl::Init(const ALLOCATOR_DESC& desc)
}
#endif
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
m_Device->QueryInterface(D3D12MA_IID_PPV_ARGS(&m_Device10));
#endif
HRESULT hr = m_Adapter->GetDesc(&m_AdapterDesc);
if (FAILED(hr))
{
@ -6738,16 +6789,60 @@ UINT64 AllocatorPimpl::GetMemoryCapacity(UINT memorySegmentGroup) const
}
}
HRESULT AllocatorPimpl::CreatePlacedResourceWrap(
ID3D12Heap *pHeap,
UINT64 HeapOffset,
const CREATE_RESOURCE_PARAMS& createParams,
REFIID riidResource,
void** ppvResource)
{
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
if (createParams.variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_LAYOUT)
{
if (!m_Device10)
{
return E_NOINTERFACE;
}
return m_Device10->CreatePlacedResource2(pHeap, HeapOffset,
createParams.pResourceDesc1, createParams.InitialLayout,
createParams.pOptimizedClearValue, createParams.NumCastableFormats,
createParams.pCastableFormats, riidResource, ppvResource);
} else
#endif
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
if (createParams.variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE_AND_DESC1)
{
if (!m_Device8)
{
return E_NOINTERFACE;
}
return m_Device8->CreatePlacedResource1(pHeap, HeapOffset,
createParams.pResourceDesc1, createParams.InitialResourceState,
createParams.pOptimizedClearValue, riidResource, ppvResource);
} else
#endif
if (createParams.variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE)
{
return m_Device->CreatePlacedResource(pHeap, HeapOffset,
createParams.pResourceDesc, createParams.InitialResourceState,
createParams.pOptimizedClearValue, riidResource, ppvResource);
}
else
{
D3D12MA_ASSERT(0);
return E_INVALIDARG;
}
}
HRESULT AllocatorPimpl::CreateResource(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_DESC* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE* pOptimizedClearValue,
const CREATE_RESOURCE_PARAMS& createParams,
Allocation** ppAllocation,
REFIID riidResource,
void** ppvResource)
{
D3D12MA_ASSERT(pAllocDesc && pResourceDesc && ppAllocation);
D3D12MA_ASSERT(pAllocDesc && createParams.pResourceDesc && ppAllocation);
*ppAllocation = NULL;
if (ppvResource)
@ -6755,8 +6850,47 @@ HRESULT AllocatorPimpl::CreateResource(
*ppvResource = NULL;
}
D3D12_RESOURCE_DESC finalResourceDesc = *pResourceDesc;
D3D12_RESOURCE_ALLOCATION_INFO resAllocInfo = GetResourceAllocationInfo(finalResourceDesc);
CREATE_RESOURCE_PARAMS finalCreateParams = createParams;
D3D12_RESOURCE_DESC finalResourceDesc;
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
D3D12_RESOURCE_DESC1 finalResourceDesc1;
#endif
D3D12_RESOURCE_ALLOCATION_INFO resAllocInfo;
if (createParams.variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE)
{
finalResourceDesc = *createParams.pResourceDesc;
finalCreateParams.pResourceDesc = &finalResourceDesc;
resAllocInfo = GetResourceAllocationInfo(finalResourceDesc);
}
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
else if (createParams.variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE_AND_DESC1)
{
if (!m_Device8)
{
return E_NOINTERFACE;
}
finalResourceDesc1 = *createParams.pResourceDesc1;
finalCreateParams.pResourceDesc1 = &finalResourceDesc1;
resAllocInfo = GetResourceAllocationInfo(finalResourceDesc1);
}
#endif
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
else if (createParams.variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_LAYOUT)
{
if (!m_Device10)
{
return E_NOINTERFACE;
}
finalResourceDesc1 = *createParams.pResourceDesc1;
finalCreateParams.pResourceDesc1 = &finalResourceDesc1;
resAllocInfo = GetResourceAllocationInfo(finalResourceDesc1);
}
#endif
else
{
D3D12MA_ASSERT(0);
return E_INVALIDARG;
}
D3D12MA_ASSERT(IsPow2(resAllocInfo.Alignment));
D3D12MA_ASSERT(resAllocInfo.SizeInBytes > 0);
@ -6764,7 +6898,7 @@ HRESULT AllocatorPimpl::CreateResource(
CommittedAllocationParameters committedAllocationParams = {};
bool preferCommitted = false;
HRESULT hr = CalcAllocationParams<D3D12_RESOURCE_DESC>(*pAllocDesc, resAllocInfo.SizeInBytes,
pResourceDesc,
createParams.pResourceDesc,
blockVector, committedAllocationParams, preferCommitted);
if (FAILED(hr))
return hr;
@ -6775,16 +6909,14 @@ HRESULT AllocatorPimpl::CreateResource(
{
hr = AllocateCommittedResource(committedAllocationParams,
resAllocInfo.SizeInBytes, withinBudget, pAllocDesc->pPrivateData,
&finalResourceDesc, InitialResourceState, pOptimizedClearValue,
ppAllocation, riidResource, ppvResource);
finalCreateParams, ppAllocation, riidResource, ppvResource);
if (SUCCEEDED(hr))
return hr;
}
if (blockVector != NULL)
{
hr = blockVector->CreateResource(resAllocInfo.SizeInBytes, resAllocInfo.Alignment,
*pAllocDesc, finalResourceDesc,
InitialResourceState, pOptimizedClearValue,
*pAllocDesc, finalCreateParams,
ppAllocation, riidResource, ppvResource);
if (SUCCEEDED(hr))
return hr;
@ -6793,83 +6925,13 @@ HRESULT AllocatorPimpl::CreateResource(
{
hr = AllocateCommittedResource(committedAllocationParams,
resAllocInfo.SizeInBytes, withinBudget, pAllocDesc->pPrivateData,
&finalResourceDesc, InitialResourceState, pOptimizedClearValue,
ppAllocation, riidResource, ppvResource);
finalCreateParams, ppAllocation, riidResource, ppvResource);
if (SUCCEEDED(hr))
return hr;
}
return hr;
}
#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,
Allocation** ppAllocation,
REFIID riidResource,
void** ppvResource)
{
D3D12MA_ASSERT(pAllocDesc && pResourceDesc && ppAllocation);
*ppAllocation = NULL;
if (ppvResource)
{
*ppvResource = NULL;
}
if (m_Device8 == NULL)
{
return E_NOINTERFACE;
}
D3D12_RESOURCE_DESC1 finalResourceDesc = *pResourceDesc;
D3D12_RESOURCE_ALLOCATION_INFO resAllocInfo = GetResourceAllocationInfo(finalResourceDesc);
D3D12MA_ASSERT(IsPow2(resAllocInfo.Alignment));
D3D12MA_ASSERT(resAllocInfo.SizeInBytes > 0);
BlockVector* blockVector = NULL;
CommittedAllocationParameters committedAllocationParams = {};
bool preferCommitted = false;
HRESULT hr = CalcAllocationParams<D3D12_RESOURCE_DESC1>(*pAllocDesc, resAllocInfo.SizeInBytes,
pResourceDesc,
blockVector, committedAllocationParams, preferCommitted);
if (FAILED(hr))
return hr;
const bool withinBudget = (pAllocDesc->Flags & ALLOCATION_FLAG_WITHIN_BUDGET) != 0;
hr = E_INVALIDARG;
if (committedAllocationParams.IsValid() && preferCommitted)
{
hr = AllocateCommittedResource2(committedAllocationParams,
resAllocInfo.SizeInBytes, withinBudget, pAllocDesc->pPrivateData,
&finalResourceDesc, InitialResourceState, pOptimizedClearValue,
ppAllocation, riidResource, ppvResource);
if (SUCCEEDED(hr))
return hr;
}
if (blockVector != NULL)
{
hr = blockVector->CreateResource2(resAllocInfo.SizeInBytes, resAllocInfo.Alignment,
*pAllocDesc, finalResourceDesc,
InitialResourceState, pOptimizedClearValue,
ppAllocation, riidResource, ppvResource);
if (SUCCEEDED(hr))
return hr;
}
if (committedAllocationParams.IsValid() && !preferCommitted)
{
hr = AllocateCommittedResource2(committedAllocationParams,
resAllocInfo.SizeInBytes, withinBudget, pAllocDesc->pPrivateData,
&finalResourceDesc, InitialResourceState, pOptimizedClearValue,
ppAllocation, riidResource, ppvResource);
if (SUCCEEDED(hr))
return hr;
}
return hr;
}
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
HRESULT AllocatorPimpl::AllocateMemory(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_ALLOCATION_INFO* pAllocInfo,
@ -6913,16 +6975,53 @@ HRESULT AllocatorPimpl::AllocateMemory(
HRESULT AllocatorPimpl::CreateAliasingResource(
Allocation* pAllocation,
UINT64 AllocationLocalOffset,
const D3D12_RESOURCE_DESC* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE* pOptimizedClearValue,
const CREATE_RESOURCE_PARAMS& createParams,
REFIID riidResource,
void** ppvResource)
{
*ppvResource = NULL;
D3D12_RESOURCE_DESC resourceDesc2 = *pResourceDesc;
D3D12_RESOURCE_ALLOCATION_INFO resAllocInfo = GetResourceAllocationInfo(resourceDesc2);
CREATE_RESOURCE_PARAMS finalCreateParams = createParams;
D3D12_RESOURCE_DESC finalResourceDesc;
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
D3D12_RESOURCE_DESC1 finalResourceDesc1;
#endif
D3D12_RESOURCE_ALLOCATION_INFO resAllocInfo;
if (createParams.variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE)
{
finalResourceDesc = *createParams.pResourceDesc;
finalCreateParams.pResourceDesc = &finalResourceDesc;
resAllocInfo = GetResourceAllocationInfo(finalResourceDesc);
}
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
else if (createParams.variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE_AND_DESC1)
{
if (!m_Device8)
{
return E_NOINTERFACE;
}
finalResourceDesc1 = *createParams.pResourceDesc1;
finalCreateParams.pResourceDesc1 = &finalResourceDesc1;
resAllocInfo = GetResourceAllocationInfo(finalResourceDesc1);
}
#endif
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
else if (createParams.variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_LAYOUT)
{
if (!m_Device10)
{
return E_NOINTERFACE;
}
finalResourceDesc1 = *createParams.pResourceDesc1;
finalCreateParams.pResourceDesc1 = &finalResourceDesc1;
resAllocInfo = GetResourceAllocationInfo(finalResourceDesc1);
}
#endif
else
{
D3D12MA_ASSERT(0);
return E_INVALIDARG;
}
D3D12MA_ASSERT(IsPow2(resAllocInfo.Alignment));
D3D12MA_ASSERT(resAllocInfo.SizeInBytes > 0);
@ -6938,14 +7037,7 @@ HRESULT AllocatorPimpl::CreateAliasingResource(
return E_INVALIDARG;
}
return m_Device->CreatePlacedResource(
existingHeap,
newOffset,
&resourceDesc2,
InitialResourceState,
pOptimizedClearValue,
riidResource,
ppvResource);
return CreatePlacedResourceWrap(existingHeap, newOffset, finalCreateParams, riidResource, ppvResource);
}
void AllocatorPimpl::FreeCommittedMemory(Allocation* allocation)
@ -7509,8 +7601,7 @@ bool AllocatorPimpl::PrefersCommittedAllocation(const D3D12_RESOURCE_DESC_T& res
HRESULT AllocatorPimpl::AllocateCommittedResource(
const CommittedAllocationParameters& committedAllocParams,
UINT64 resourceSize, bool withinBudget, void* pPrivateData,
const D3D12_RESOURCE_DESC* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE* pOptimizedClearValue,
const CREATE_RESOURCE_PARAMS& createParams,
Allocation** ppAllocation, REFIID riidResource, void** ppvResource)
{
D3D12MA_ASSERT(committedAllocParams.IsValid());
@ -7526,16 +7617,15 @@ HRESULT AllocatorPimpl::AllocateCommittedResource(
hr = AllocateHeap(committedAllocParams, heapAllocInfo, withinBudget, pPrivateData, ppAllocation);
if (SUCCEEDED(hr))
{
hr = m_Device->CreatePlacedResource((*ppAllocation)->GetHeap(), 0,
pResourceDesc, InitialResourceState,
pOptimizedClearValue, D3D12MA_IID_PPV_ARGS(&res));
hr = CreatePlacedResourceWrap((*ppAllocation)->GetHeap(), 0,
createParams, D3D12MA_IID_PPV_ARGS(&res));
if (SUCCEEDED(hr))
{
if (ppvResource != NULL)
hr = res->QueryInterface(riidResource, ppvResource);
if (SUCCEEDED(hr))
{
(*ppAllocation)->SetResourcePointer(res, pResourceDesc);
(*ppAllocation)->SetResourcePointer(res, createParams.pResourceDesc);
return hr;
}
res->Release();
@ -7561,28 +7651,69 @@ HRESULT AllocatorPimpl::AllocateCommittedResource(
*
* [ STATE_CREATION ERROR #640: CREATERESOURCEANDHEAP_INVALIDHEAPMISCFLAGS]
*/
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
if (m_Device4)
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
if (createParams.variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_LAYOUT)
{
hr = m_Device4->CreateCommittedResource1(
if (!m_Device10)
{
return E_NOINTERFACE;
}
hr = m_Device10->CreateCommittedResource3(
&committedAllocParams.m_HeapProperties,
committedAllocParams.m_HeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS,
pResourceDesc, InitialResourceState,
pOptimizedClearValue, committedAllocParams.m_ProtectedSession, D3D12MA_IID_PPV_ARGS(&res));
createParams.pResourceDesc1, createParams.InitialLayout,
createParams.pOptimizedClearValue, committedAllocParams.m_ProtectedSession,
createParams.NumCastableFormats, createParams.pCastableFormats,
D3D12MA_IID_PPV_ARGS(&res));
} else
#endif
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
if (createParams.variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE_AND_DESC1)
{
if (!m_Device8)
{
return E_NOINTERFACE;
}
hr = m_Device8->CreateCommittedResource2(
&committedAllocParams.m_HeapProperties,
committedAllocParams.m_HeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS,
createParams.pResourceDesc1, createParams.InitialResourceState,
createParams.pOptimizedClearValue, committedAllocParams.m_ProtectedSession,
D3D12MA_IID_PPV_ARGS(&res));
} else
#endif
if (createParams.variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE)
{
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
if (m_Device4)
{
hr = m_Device4->CreateCommittedResource1(
&committedAllocParams.m_HeapProperties,
committedAllocParams.m_HeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS,
createParams.pResourceDesc, createParams.InitialResourceState,
createParams.pOptimizedClearValue, committedAllocParams.m_ProtectedSession,
D3D12MA_IID_PPV_ARGS(&res));
}
else
#endif
{
if (committedAllocParams.m_ProtectedSession == NULL)
{
hr = m_Device->CreateCommittedResource(
&committedAllocParams.m_HeapProperties,
committedAllocParams.m_HeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS,
createParams.pResourceDesc, createParams.InitialResourceState,
createParams.pOptimizedClearValue, D3D12MA_IID_PPV_ARGS(&res));
}
else
hr = E_NOINTERFACE;
}
}
else
#endif
{
if (committedAllocParams.m_ProtectedSession == NULL)
{
hr = m_Device->CreateCommittedResource(
&committedAllocParams.m_HeapProperties,
committedAllocParams.m_HeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS,
pResourceDesc, InitialResourceState,
pOptimizedClearValue, D3D12MA_IID_PPV_ARGS(&res));
}
else
hr = E_NOINTERFACE;
D3D12MA_ASSERT(0);
return E_INVALIDARG;
}
if (SUCCEEDED(hr))
@ -7594,9 +7725,9 @@ HRESULT AllocatorPimpl::AllocateCommittedResource(
if (SUCCEEDED(hr))
{
const BOOL wasZeroInitialized = TRUE;
Allocation* alloc = m_AllocationObjectAllocator.Allocate(this, resourceSize, pResourceDesc->Alignment, wasZeroInitialized);
Allocation* alloc = m_AllocationObjectAllocator.Allocate(this, resourceSize, createParams.pResourceDesc->Alignment, wasZeroInitialized);
alloc->InitCommitted(committedAllocParams.m_List);
alloc->SetResourcePointer(res, pResourceDesc);
alloc->SetResourcePointer(res, createParams.pResourceDesc);
alloc->SetPrivateData(pPrivateData);
*ppAllocation = alloc;
@ -7615,93 +7746,6 @@ HRESULT AllocatorPimpl::AllocateCommittedResource(
return hr;
}
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
HRESULT AllocatorPimpl::AllocateCommittedResource2(
const CommittedAllocationParameters& committedAllocParams,
UINT64 resourceSize, bool withinBudget, void* pPrivateData,
const D3D12_RESOURCE_DESC1* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE* pOptimizedClearValue,
Allocation** ppAllocation, REFIID riidResource, void** ppvResource)
{
D3D12MA_ASSERT(committedAllocParams.IsValid());
if (m_Device8 == NULL)
{
return E_NOINTERFACE;
}
HRESULT hr;
ID3D12Resource* res = NULL;
// Allocate aliasing memory with explicit heap
if (committedAllocParams.m_CanAlias)
{
D3D12_RESOURCE_ALLOCATION_INFO heapAllocInfo = {};
heapAllocInfo.SizeInBytes = resourceSize;
heapAllocInfo.Alignment = HeapFlagsToAlignment(committedAllocParams.m_HeapFlags, m_MsaaAlwaysCommitted);
hr = AllocateHeap(committedAllocParams, heapAllocInfo, withinBudget, pPrivateData, ppAllocation);
if (SUCCEEDED(hr))
{
hr = m_Device8->CreatePlacedResource1((*ppAllocation)->GetHeap(), 0,
pResourceDesc, InitialResourceState,
pOptimizedClearValue, D3D12MA_IID_PPV_ARGS(&res));
if (SUCCEEDED(hr))
{
if (ppvResource != NULL)
hr = res->QueryInterface(riidResource, ppvResource);
if (SUCCEEDED(hr))
{
(*ppAllocation)->SetResourcePointer(res, pResourceDesc);
return hr;
}
res->Release();
}
FreeHeapMemory(*ppAllocation);
}
return hr;
}
if (withinBudget &&
!NewAllocationWithinBudget(committedAllocParams.m_HeapProperties.Type, resourceSize))
{
return E_OUTOFMEMORY;
}
hr = m_Device8->CreateCommittedResource2(
&committedAllocParams.m_HeapProperties,
committedAllocParams.m_HeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS, // D3D12 ERROR: ID3D12Device::CreateCommittedResource: When creating a committed resource, D3D12_HEAP_FLAGS must not have either D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES, D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES, nor D3D12_HEAP_FLAG_DENY_BUFFERS set. These flags will be set automatically to correspond with the committed resource type. [ STATE_CREATION ERROR #640: CREATERESOURCEANDHEAP_INVALIDHEAPMISCFLAGS]
pResourceDesc, InitialResourceState,
pOptimizedClearValue, committedAllocParams.m_ProtectedSession, D3D12MA_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, resourceSize, pResourceDesc->Alignment, wasZeroInitialized);
alloc->InitCommitted(committedAllocParams.m_List);
alloc->SetResourcePointer(res, pResourceDesc);
alloc->SetPrivateData(pPrivateData);
*ppAllocation = alloc;
committedAllocParams.m_List->Register(alloc);
const UINT memSegmentGroup = HeapPropertiesToMemorySegmentGroup(committedAllocParams.m_HeapProperties);
m_Budget.AddBlock(memSegmentGroup, resourceSize);
m_Budget.AddAllocation(memSegmentGroup, resourceSize);
}
else
{
res->Release();
}
}
return hr;
}
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
HRESULT AllocatorPimpl::AllocateHeap(
const CommittedAllocationParameters& committedAllocParams,
const D3D12_RESOURCE_ALLOCATION_INFO& allocInfo, bool withinBudget,
@ -8411,9 +8455,7 @@ HRESULT BlockVector::CreateResource(
UINT64 size,
UINT64 alignment,
const ALLOCATION_DESC& allocDesc,
const D3D12_RESOURCE_DESC& resourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE* pOptimizedClearValue,
const CREATE_RESOURCE_PARAMS& createParams,
Allocation** ppAllocation,
REFIID riidResource,
void** ppvResource)
@ -8422,12 +8464,10 @@ HRESULT BlockVector::CreateResource(
if (SUCCEEDED(hr))
{
ID3D12Resource* res = NULL;
hr = m_hAllocator->GetDevice()->CreatePlacedResource(
hr = m_hAllocator->CreatePlacedResourceWrap(
(*ppAllocation)->m_Placed.block->GetHeap(),
(*ppAllocation)->GetOffset(),
&resourceDesc,
InitialResourceState,
pOptimizedClearValue,
createParams,
D3D12MA_IID_PPV_ARGS(&res));
if (SUCCEEDED(hr))
{
@ -8437,7 +8477,7 @@ HRESULT BlockVector::CreateResource(
}
if (SUCCEEDED(hr))
{
(*ppAllocation)->SetResourcePointer(res, &resourceDesc);
(*ppAllocation)->SetResourcePointer(res, createParams.pResourceDesc);
}
else
{
@ -8453,60 +8493,6 @@ HRESULT BlockVector::CreateResource(
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,
Allocation** ppAllocation,
REFIID riidResource,
void** ppvResource)
{
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,
D3D12MA_IID_PPV_ARGS(&res));
if (SUCCEEDED(hr))
{
if (ppvResource != NULL)
{
hr = res->QueryInterface(riidResource, ppvResource);
}
if (SUCCEEDED(hr))
{
(*ppAllocation)->SetResourcePointer(res, &resourceDesc);
}
else
{
res->Release();
SAFE_RELEASE(*ppAllocation);
}
}
else
{
SAFE_RELEASE(*ppAllocation);
}
}
return hr;
}
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
void BlockVector::AddStatistics(Statistics& inoutStats)
{
MutexLockRead lock(m_Mutex, m_hAllocator->UseMutex());
@ -9961,7 +9947,12 @@ HRESULT Allocator::CreateResource(
return E_INVALIDARG;
}
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
return m_Pimpl->CreateResource(pAllocDesc, pResourceDesc, InitialResourceState, pOptimizedClearValue, ppAllocation, riidResource, ppvResource);
return m_Pimpl->CreateResource(
pAllocDesc,
CREATE_RESOURCE_PARAMS(pResourceDesc, InitialResourceState, pOptimizedClearValue),
ppAllocation,
riidResource,
ppvResource);
}
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
@ -9980,10 +9971,42 @@ HRESULT Allocator::CreateResource2(
return E_INVALIDARG;
}
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
return m_Pimpl->CreateResource2(pAllocDesc, pResourceDesc, InitialResourceState, pOptimizedClearValue, ppAllocation, riidResource, ppvResource);
return m_Pimpl->CreateResource(
pAllocDesc,
CREATE_RESOURCE_PARAMS(pResourceDesc, InitialResourceState, pOptimizedClearValue),
ppAllocation,
riidResource,
ppvResource);
}
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
HRESULT Allocator::CreateResource3(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_DESC1* pResourceDesc,
D3D12_BARRIER_LAYOUT InitialLayout,
const D3D12_CLEAR_VALUE* pOptimizedClearValue,
UINT32 NumCastableFormats,
DXGI_FORMAT* pCastableFormats,
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->CreateResource(
pAllocDesc,
CREATE_RESOURCE_PARAMS(pResourceDesc, InitialLayout, pOptimizedClearValue, NumCastableFormats, pCastableFormats),
ppAllocation,
riidResource,
ppvResource);
}
#endif // #ifdef __ID3D12Device10_INTERFACE_DEFINED__
HRESULT Allocator::AllocateMemory(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_ALLOCATION_INFO* pAllocInfo,
@ -10013,9 +10036,66 @@ HRESULT Allocator::CreateAliasingResource(
return E_INVALIDARG;
}
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
return m_Pimpl->CreateAliasingResource(pAllocation, AllocationLocalOffset, pResourceDesc, InitialResourceState, pOptimizedClearValue, riidResource, ppvResource);
return m_Pimpl->CreateAliasingResource(
pAllocation,
AllocationLocalOffset,
CREATE_RESOURCE_PARAMS(pResourceDesc, InitialResourceState, pOptimizedClearValue),
riidResource,
ppvResource);
}
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
HRESULT Allocator::CreateAliasingResource1(
Allocation* pAllocation,
UINT64 AllocationLocalOffset,
const D3D12_RESOURCE_DESC1* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE* pOptimizedClearValue,
REFIID riidResource,
void** ppvResource)
{
if (!pAllocation || !pResourceDesc || !ppvResource)
{
D3D12MA_ASSERT(0 && "Invalid arguments passed to Allocator::CreateAliasingResource.");
return E_INVALIDARG;
}
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
return m_Pimpl->CreateAliasingResource(
pAllocation,
AllocationLocalOffset,
CREATE_RESOURCE_PARAMS(pResourceDesc, InitialResourceState, pOptimizedClearValue),
riidResource,
ppvResource);
}
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
HRESULT Allocator::CreateAliasingResource2(
Allocation* pAllocation,
UINT64 AllocationLocalOffset,
const D3D12_RESOURCE_DESC1* pResourceDesc,
D3D12_BARRIER_LAYOUT InitialLayout,
const D3D12_CLEAR_VALUE* pOptimizedClearValue,
UINT32 NumCastableFormats,
DXGI_FORMAT* pCastableFormats,
REFIID riidResource,
void** ppvResource)
{
if (!pAllocation || !pResourceDesc || !ppvResource)
{
D3D12MA_ASSERT(0 && "Invalid arguments passed to Allocator::CreateAliasingResource.");
return E_INVALIDARG;
}
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
return m_Pimpl->CreateAliasingResource(
pAllocation,
AllocationLocalOffset,
CREATE_RESOURCE_PARAMS(pResourceDesc, InitialLayout, pOptimizedClearValue, NumCastableFormats, pCastableFormats),
riidResource,
ppvResource);
}
#endif // #ifdef __ID3D12Device10_INTERFACE_DEFINED__
HRESULT Allocator::CreatePool(
const POOL_DESC* pPoolDesc,
Pool** ppPool)

View File

@ -2820,19 +2820,99 @@ static void TestDevice8(const TestContext& ctx)
&allocPtr0, IID_PPV_ARGS(&res0)));
CHECK_BOOL(allocPtr0->GetHeap() == NULL);
// Create a placed buffer
// Create a heap and placed buffer in it
allocDesc.Flags &= ~D3D12MA::ALLOCATION_FLAG_COMMITTED;
allocDesc.Flags |= D3D12MA::ALLOCATION_FLAG_CAN_ALIAS;
ComPtr<D3D12MA::Allocation> allocPtr1;
ComPtr<ID3D12Resource> res1;
CHECK_HR(ctx.allocator->CreateResource2(&allocDesc, &resourceDesc,
D3D12_RESOURCE_STATE_COMMON, NULL,
&allocPtr1, IID_PPV_ARGS(&res1)));
CHECK_BOOL(allocPtr1->GetHeap()!= NULL);
CHECK_BOOL(allocPtr1->GetHeap() != NULL);
// Create a placed buffer
allocDesc.Flags &= ~D3D12MA::ALLOCATION_FLAG_COMMITTED;
ComPtr<D3D12MA::Allocation> allocPtr2;
ComPtr<ID3D12Resource> res2;
CHECK_HR(ctx.allocator->CreateResource2(&allocDesc, &resourceDesc,
D3D12_RESOURCE_STATE_COMMON, NULL,
&allocPtr2, IID_PPV_ARGS(&res2)));
CHECK_BOOL(allocPtr2->GetHeap()!= NULL);
// Create an aliasing buffer
ComPtr<ID3D12Resource> res3;
CHECK_HR(ctx.allocator->CreateAliasingResource1(allocPtr2.Get(), 0, &resourceDesc,
D3D12_RESOURCE_STATE_COMMON, NULL,
IID_PPV_ARGS(&res3)));
}
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
static void TestDevice10(const TestContext& ctx)
{
wprintf(L"Test ID3D12Device10\n");
ComPtr<ID3D12Device10> dev10;
CHECK_HR(ctx.device->QueryInterface(IID_PPV_ARGS(&dev10)));
D3D12_RESOURCE_DESC1 resourceDesc = {};
resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
resourceDesc.Alignment = 0;
resourceDesc.Width = 1920;
resourceDesc.Height = 1080;
resourceDesc.DepthOrArraySize = 1;
resourceDesc.MipLevels = 1;
resourceDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
resourceDesc.SampleDesc.Count = 1;
resourceDesc.SampleDesc.Quality = 0;
resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
// Create a committed texture
D3D12MA::ALLOCATION_DESC allocDesc = {};
allocDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED;
ComPtr<D3D12MA::Allocation> allocPtr0;
ComPtr<ID3D12Resource> res0;
CHECK_HR(ctx.allocator->CreateResource3(&allocDesc, &resourceDesc,
D3D12_BARRIER_LAYOUT_UNDEFINED, NULL, 0, NULL,
&allocPtr0, IID_PPV_ARGS(&res0)));
CHECK_BOOL(allocPtr0->GetHeap() == NULL);
// Create a heap and placed texture in it
allocDesc.Flags |= D3D12MA::ALLOCATION_FLAG_CAN_ALIAS;
ComPtr<D3D12MA::Allocation> allocPtr1;
ComPtr<ID3D12Resource> res1;
CHECK_HR(ctx.allocator->CreateResource3(&allocDesc, &resourceDesc,
D3D12_BARRIER_LAYOUT_UNDEFINED, NULL, 0, NULL,
&allocPtr1, IID_PPV_ARGS(&res1)));
CHECK_BOOL(allocPtr1->GetHeap() != NULL);
// Create a placed texture
allocDesc.Flags &= ~D3D12MA::ALLOCATION_FLAG_COMMITTED;
ComPtr<D3D12MA::Allocation> allocPtr2;
ComPtr<ID3D12Resource> res2;
CHECK_HR(ctx.allocator->CreateResource3(&allocDesc, &resourceDesc,
D3D12_BARRIER_LAYOUT_UNDEFINED, NULL, 0, NULL,
&allocPtr2, IID_PPV_ARGS(&res2)));
CHECK_BOOL(allocPtr2->GetHeap() != NULL);
// Create an aliasing texture
ComPtr<ID3D12Resource> res3;
CHECK_HR(ctx.allocator->CreateAliasingResource2(allocPtr2.Get(), 0, &resourceDesc,
D3D12_BARRIER_LAYOUT_UNDEFINED, NULL, 0, NULL,
IID_PPV_ARGS(&res3)));
}
#endif // #ifdef __ID3D12Device10_INTERFACE_DEFINED__
static void TestVirtualBlocks(const TestContext& ctx)
{
wprintf(L"Test virtual blocks\n");
@ -4095,6 +4175,9 @@ static void TestGroupBasics(const TestContext& ctx)
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
TestDevice8(ctx);
#endif
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
TestDevice10(ctx);
#endif
FILE* file;
fopen_s(&file, "Results.csv", "w");