Changed the way ProtectedSession is passed. COMPATIBILITY BREAKING!

Using ProtectedSession now requires using custom pools.
Added POOL_DESC::pProtectedSession. Removed Allocator::CreateResource1, AllocateMemory1. Removed parameter pProtectedSession from Allocator::CreateCommittedResource2.
Code mostly by @medranSolus.
This commit is contained in:
Adam Sawicki 2022-01-13 13:14:49 +01:00
parent f78c4fbd38
commit 9c97fcaae0
5 changed files with 138 additions and 365 deletions

View File

@ -126,6 +126,9 @@ If providing your own implementation, you need to implement a subset of std::ato
#define D3D12MA_API
#endif
// Forward declaration if ID3D12ProtectedResourceSession is not defined inside the headers (older SDK, pre ID3D12Device4)
struct ID3D12ProtectedResourceSession;
namespace D3D12MA
{
class D3D12MA_API IUnknownImpl : public IUnknown
@ -468,6 +471,12 @@ struct POOL_DESC
Leave 0 (default) not to impose any additional alignment. If not 0, it must be a power of two.
*/
UINT64 MinAllocationAlignment;
/** \brief Additional parameter allowing pool to create resources with passed protected session.
If not null then all the heaps and committed resources will be created with this parameter.
Valid only if ID3D12Device4 interface is present in current Windows SDK!
*/
ID3D12ProtectedResourceSession* pProtectedSession;
};
/** \brief Custom memory pool
@ -725,27 +734,8 @@ public:
REFIID riidResource,
void** ppvResource);
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
/** \brief Similar to Allocator::CreateResource, but supports additional parameter `pProtectedSession`.
If `pProtectedSession` is not null, current implementation always creates the resource as committed
using `ID3D12Device4::CreateCommittedResource1`.
To work correctly, `ID3D12Device4` interface must be available in the current system. Otherwise, `E_NOINTERFACE` is returned.
*/
HRESULT CreateResource1(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_DESC* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation,
REFIID riidResource,
void** ppvResource);
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
/** \brief Similar to Allocator::CreateResource1, but supports new structure `D3D12_RESOURCE_DESC1`.
/** \brief Similar to Allocator::CreateResource, but supports new structure `D3D12_RESOURCE_DESC1`.
It internally uses `ID3D12Device8::CreateCommittedResource2` or `ID3D12Device8::CreatePlacedResource1`.
@ -756,7 +746,6 @@ public:
const D3D12_RESOURCE_DESC1* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation,
REFIID riidResource,
void** ppvResource);
@ -786,21 +775,6 @@ public:
const D3D12_RESOURCE_ALLOCATION_INFO* pAllocInfo,
Allocation** ppAllocation);
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
/** \brief Similar to Allocator::AllocateMemory, but supports additional parameter `pProtectedSession`.
If `pProtectedSession` is not null, current implementation always creates separate heap
using `ID3D12Device4::CreateHeap1`.
To work correctly, `ID3D12Device4` interface must be available in the current system. Otherwise, `E_NOINTERFACE` is returned.
*/
HRESULT AllocateMemory1(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_ALLOCATION_INFO* pAllocInfo,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation);
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
/** \brief Creates a new resource in place of an existing allocation. This is useful for memory aliasing.
\param pAllocation Existing allocation indicating the memory where the new resource should be created.

View File

@ -66,6 +66,10 @@ typedef std::chrono::high_resolution_clock::duration duration;
throw std::runtime_error(__FILE__ "(" LINE_STRING "): FAILED( " #expr " )"); \
} } while(false)
const uint32_t VENDOR_ID_AMD = 0x1002;
const uint32_t VENDOR_ID_NVIDIA = 0x10DE;
const uint32_t VENDOR_ID_INTEL = 0x8086;
template <typename T>
inline constexpr T CeilDiv(T x, T y)
{

View File

@ -2731,7 +2731,7 @@ protected:
const UINT64 m_Size;
const UINT m_Id;
HRESULT Init();
HRESULT Init(ID3D12ProtectedResourceSession* pProtectedSession);
private:
ID3D12Heap* m_Heap = NULL;
@ -2760,7 +2760,7 @@ public:
UINT64 size,
UINT id);
virtual ~NormalBlock();
HRESULT Init();
HRESULT Init(ID3D12ProtectedResourceSession* pProtectedSession);
BlockVector* GetBlockVector() const { return m_BlockVector; }
@ -2852,7 +2852,8 @@ public:
size_t minBlockCount,
size_t maxBlockCount,
bool explicitBlockSize,
UINT64 minAllocationAlignment);
UINT64 minAllocationAlignment,
ID3D12ProtectedResourceSession* pProtectedSession);
~BlockVector();
HRESULT CreateMinBlocks();
@ -2891,7 +2892,6 @@ public:
const D3D12_RESOURCE_DESC1& resourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation,
REFIID riidResource,
void** ppvResource);
@ -2911,6 +2911,7 @@ private:
const size_t m_MaxBlockCount;
const bool m_ExplicitBlockSize;
const UINT64 m_MinAllocationAlignment;
ID3D12ProtectedResourceSession* const m_ProtectedSession;
/* There can be at most one allocation that is completely empty - a
hysteresis to avoid pessimistic case of alternating creation and destruction
of a VkDeviceMemory. */
@ -2943,7 +2944,9 @@ private:
ALLOCATION_FLAGS allocFlags,
Allocation** pAllocation);
HRESULT CreateBlock(UINT64 blockSize, size_t* pNewBlockIndex);
HRESULT CreateBlock(
UINT64 blockSize,
size_t* pNewBlockIndex);
};
////////////////////////////////////////////////////////////////////////////////
@ -3050,6 +3053,7 @@ struct CommittedAllocationParameters
CommittedAllocationList* m_List = NULL;
D3D12_HEAP_PROPERTIES m_HeapProperties = {};
D3D12_HEAP_FLAGS m_HeapFlags = D3D12_HEAP_FLAG_NONE;
ID3D12ProtectedResourceSession* m_ProtectedSession = NULL;
bool IsValid() const { return m_List != NULL; }
};
@ -3090,25 +3094,12 @@ public:
REFIID riidResource,
void** ppvResource);
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT CreateResource1(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_DESC* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation,
REFIID riidResource,
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);
@ -3119,14 +3110,6 @@ public:
const D3D12_RESOURCE_ALLOCATION_INFO* pAllocInfo,
Allocation** ppAllocation);
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT AllocateMemory1(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_ALLOCATION_INFO* pAllocInfo,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation);
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT CreateAliasingResource(
Allocation* pAllocation,
UINT64 AllocationLocalOffset,
@ -3209,23 +3192,12 @@ private:
D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE *pOptimizedClearValue,
Allocation** ppAllocation, REFIID riidResource, void** ppvResource);
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT AllocateCommittedResource1(
const CommittedAllocationParameters& committedAllocParams,
UINT64 resourceSize, bool withinBudget,
const D3D12_RESOURCE_DESC* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE *pOptimizedClearValue,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation, REFIID riidResource, void** ppvResource);
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
HRESULT AllocateCommittedResource2(
const CommittedAllocationParameters& committedAllocParams,
UINT64 resourceSize, bool withinBudget,
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__
@ -3236,14 +3208,6 @@ private:
const D3D12_RESOURCE_ALLOCATION_INFO& allocInfo, bool withinBudget,
Allocation** ppAllocation);
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT AllocateHeap1(
const CommittedAllocationParameters& committedAllocParams,
const D3D12_RESOURCE_ALLOCATION_INFO& allocInfo, bool withinBudget,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation);
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
template<typename D3D12_RESOURCE_DESC_T>
HRESULT CalcAllocationParams(const ALLOCATION_DESC& allocDesc, UINT64 allocSize,
const D3D12_RESOURCE_DESC_T* resDesc, // Optional
@ -3924,9 +3888,9 @@ NormalBlock::~NormalBlock()
}
}
HRESULT NormalBlock::Init()
HRESULT NormalBlock::Init(ID3D12ProtectedResourceSession* pProtectedSession)
{
HRESULT hr = MemoryBlock::Init();
HRESULT hr = MemoryBlock::Init(pProtectedSession);
if(FAILED(hr))
{
return hr;
@ -3973,7 +3937,7 @@ MemoryBlock::~MemoryBlock()
}
}
HRESULT MemoryBlock::Init()
HRESULT MemoryBlock::Init(ID3D12ProtectedResourceSession* pProtectedSession)
{
D3D12MA_ASSERT(m_Heap == NULL && m_Size > 0);
@ -3983,7 +3947,12 @@ HRESULT MemoryBlock::Init()
heapDesc.Alignment = HeapFlagsToAlignment(m_HeapFlags);
heapDesc.Flags = m_HeapFlags;
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT hr = m_Allocator->GetDevice4()->CreateHeap1(&heapDesc, pProtectedSession, D3D12MA_IID_PPV_ARGS(&m_Heap));
#else
D3D12MA_ASSERT(pProtectedSession == NULL);
HRESULT hr = m_Allocator->GetDevice()->CreateHeap(&heapDesc, D3D12MA_IID_PPV_ARGS(&m_Heap));
#endif
if(SUCCEEDED(hr))
{
m_Allocator->m_Budget.m_BlockBytes[HeapTypeToIndex(m_HeapProps.Type)] += m_Size;
@ -4073,7 +4042,8 @@ BlockVector::BlockVector(
size_t minBlockCount,
size_t maxBlockCount,
bool explicitBlockSize,
UINT64 minAllocationAlignment) :
UINT64 minAllocationAlignment,
ID3D12ProtectedResourceSession* pProtectedSession) :
m_hAllocator(hAllocator),
m_HeapProps(heapProps),
m_HeapFlags(heapFlags),
@ -4082,6 +4052,7 @@ BlockVector::BlockVector(
m_MaxBlockCount(maxBlockCount),
m_ExplicitBlockSize(explicitBlockSize),
m_MinAllocationAlignment(minAllocationAlignment),
m_ProtectedSession(pProtectedSession),
m_HasEmptyBlock(false),
m_Blocks(hAllocator->GetAllocs()),
m_NextBlockId(0)
@ -4393,13 +4364,10 @@ HRESULT BlockVector::CreateResource2(
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)
{
@ -4523,7 +4491,9 @@ HRESULT BlockVector::AllocateFromBlock(
return E_OUTOFMEMORY;
}
HRESULT BlockVector::CreateBlock(UINT64 blockSize, size_t* pNewBlockIndex)
HRESULT BlockVector::CreateBlock(
UINT64 blockSize,
size_t* pNewBlockIndex)
{
NormalBlock* const pBlock = D3D12MA_NEW(m_hAllocator->GetAllocs(), NormalBlock)(
m_hAllocator,
@ -4532,7 +4502,7 @@ HRESULT BlockVector::CreateBlock(UINT64 blockSize, size_t* pNewBlockIndex)
m_HeapFlags,
blockSize,
m_NextBlockId++);
HRESULT hr = pBlock->Init();
HRESULT hr = pBlock->Init(m_ProtectedSession);
if(FAILED(hr))
{
D3D12MA_DELETE(m_hAllocator->GetAllocs(), pBlock);
@ -4614,17 +4584,19 @@ PoolPimpl::PoolPimpl(AllocatorPimpl* allocator, const POOL_DESC& desc) :
{
const bool explicitBlockSize = desc.BlockSize != 0;
const UINT64 preferredBlockSize = explicitBlockSize ? desc.BlockSize : D3D12MA_DEFAULT_BLOCK_SIZE;
D3D12_HEAP_FLAGS heapFlags = desc.HeapFlags;
UINT maxBlockCount = desc.MaxBlockCount != 0 ? desc.MaxBlockCount : UINT_MAX;
#ifndef __ID3D12Device4_INTERFACE_DEFINED__
D3D12MA_ASSERT(m_Desc.pProtectedSession == NULL);
#endif
m_BlockVector = D3D12MA_NEW(allocator->GetAllocs(), BlockVector)(
allocator, desc.HeapProperties, heapFlags,
allocator, desc.HeapProperties, desc.HeapFlags,
preferredBlockSize,
desc.MinBlockCount, maxBlockCount,
explicitBlockSize,
D3D12MA_MAX(desc.MinAllocationAlignment, (UINT64)D3D12MA_DEBUG_ALIGNMENT));
D3D12MA_MAX(desc.MinAllocationAlignment, (UINT64)D3D12MA_DEBUG_ALIGNMENT),
desc.pProtectedSession);
}
HRESULT PoolPimpl::Init()
@ -4819,7 +4791,8 @@ HRESULT AllocatorPimpl::Init(const ALLOCATOR_DESC& desc)
0, // minBlockCount
SIZE_MAX, // maxBlockCount
false, // explicitBlockSize
D3D12MA_DEBUG_ALIGNMENT); // minAllocationAlignment
D3D12MA_DEBUG_ALIGNMENT, // minAllocationAlignment
NULL); // pProtectedSession
// No need to call m_pBlockVectors[i]->CreateMinBlocks here, becase minBlockCount is 0.
}
@ -4940,64 +4913,12 @@ HRESULT AllocatorPimpl::CreateResource(
return hr;
}
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT AllocatorPimpl::CreateResource1(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_DESC* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState,
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation,
REFIID riidResource,
void** ppvResource)
{
// Fall back to old implementation
if(pProtectedSession == NULL)
{
return CreateResource(pAllocDesc, pResourceDesc, InitialResourceState, pOptimizedClearValue, ppAllocation, riidResource, ppvResource);
}
*ppAllocation = NULL;
if(ppvResource)
{
*ppvResource = NULL;
}
D3D12_RESOURCE_DESC 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_DESC>(*pAllocDesc, resAllocInfo.SizeInBytes,
pResourceDesc,
blockVector, committedAllocationParams, preferCommitted);
if(FAILED(hr))
return hr;
const bool withinBudget = (pAllocDesc->Flags & ALLOCATION_FLAG_WITHIN_BUDGET) != 0;
// In current implementation it must always be allocated as committed.
if(committedAllocationParams.IsValid())
{
return AllocateCommittedResource1(committedAllocationParams,
resAllocInfo.SizeInBytes, withinBudget, &finalResourceDesc,
InitialResourceState, pOptimizedClearValue,
pProtectedSession, ppAllocation, riidResource, ppvResource);
}
else
return E_INVALIDARG;
}
#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)
@ -5028,16 +4949,13 @@ HRESULT AllocatorPimpl::CreateResource2(
if(FAILED(hr))
return hr;
if(pProtectedSession != NULL)
blockVector = NULL; // Must be committed allocation.
const bool withinBudget = (pAllocDesc->Flags & ALLOCATION_FLAG_WITHIN_BUDGET) != 0;
hr = E_INVALIDARG;
if(committedAllocationParams.IsValid() && preferCommitted)
{
hr = AllocateCommittedResource2(committedAllocationParams,
resAllocInfo.SizeInBytes, withinBudget,&finalResourceDesc,
InitialResourceState, pOptimizedClearValue, pProtectedSession,
InitialResourceState, pOptimizedClearValue,
ppAllocation, riidResource, ppvResource);
if(SUCCEEDED(hr))
return hr;
@ -5046,7 +4964,7 @@ HRESULT AllocatorPimpl::CreateResource2(
{
hr = blockVector->CreateResource2(resAllocInfo.SizeInBytes, resAllocInfo.Alignment,
*pAllocDesc, finalResourceDesc,
InitialResourceState, pOptimizedClearValue, pProtectedSession,
InitialResourceState, pOptimizedClearValue,
ppAllocation, riidResource, ppvResource);
if(SUCCEEDED(hr))
return hr;
@ -5055,7 +4973,7 @@ HRESULT AllocatorPimpl::CreateResource2(
{
hr = AllocateCommittedResource2(committedAllocationParams,
resAllocInfo.SizeInBytes, withinBudget,&finalResourceDesc,
InitialResourceState, pOptimizedClearValue, pProtectedSession,
InitialResourceState, pOptimizedClearValue,
ppAllocation, riidResource, ppvResource);
if(SUCCEEDED(hr))
return hr;
@ -5104,42 +5022,6 @@ HRESULT AllocatorPimpl::AllocateMemory(
return hr;
}
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT AllocatorPimpl::AllocateMemory1(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_ALLOCATION_INFO* pAllocInfo,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation)
{
// Fall back to old implementation
if(pProtectedSession == NULL)
{
return AllocateMemory(pAllocDesc, pAllocInfo, ppAllocation);
}
*ppAllocation = NULL;
BlockVector* blockVector = NULL;
CommittedAllocationParameters committedAllocationParams = {};
bool preferCommitted = false;
HRESULT hr = CalcAllocationParams<D3D12_RESOURCE_DESC>(*pAllocDesc, pAllocInfo->SizeInBytes,
NULL, // pResDesc
blockVector, committedAllocationParams, preferCommitted);
if(FAILED(hr))
return hr;
const bool withinBudget = (pAllocDesc->Flags & ALLOCATION_FLAG_WITHIN_BUDGET) != 0;
// In current implementation it must always be allocated as separate CreateHeap1.
if(committedAllocationParams.IsValid())
{
return AllocateHeap1(committedAllocationParams,
*pAllocInfo, withinBudget, pProtectedSession, ppAllocation);
}
else
return E_INVALIDARG;
}
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT AllocatorPimpl::CreateAliasingResource(
Allocation* pAllocation,
UINT64 AllocationLocalOffset,
@ -5201,67 +5083,33 @@ HRESULT AllocatorPimpl::AllocateCommittedResource(
}
ID3D12Resource* res = NULL;
HRESULT hr = m_Device->CreateCommittedResource(
&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, 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, wasZeroInitialized);
alloc->InitCommitted(committedAllocParams.m_List);
alloc->SetResource(res, pResourceDesc);
*ppAllocation = alloc;
committedAllocParams.m_List->Register(alloc);
const UINT heapTypeIndex = HeapTypeToIndex(committedAllocParams.m_HeapProperties.Type);
m_Budget.AddCommittedAllocation(heapTypeIndex, resourceSize);
}
else
{
res->Release();
}
}
return hr;
}
/* 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]
*/
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT AllocatorPimpl::AllocateCommittedResource1(
const CommittedAllocationParameters& committedAllocParams,
UINT64 resourceSize, bool withinBudget,
const D3D12_RESOURCE_DESC* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE *pOptimizedClearValue,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation, REFIID riidResource, void** ppvResource)
{
D3D12MA_ASSERT(committedAllocParams.IsValid());
if(m_Device4 == NULL)
{
return E_NOINTERFACE;
}
if(withinBudget &&
!NewAllocationWithinBudget(committedAllocParams.m_HeapProperties.Type, resourceSize))
{
return E_OUTOFMEMORY;
}
ID3D12Resource* res = NULL;
HRESULT hr = m_Device4->CreateCommittedResource1(
&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]
committedAllocParams.m_HeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS,
pResourceDesc, InitialResourceState,
pOptimizedClearValue, pProtectedSession, D3D12MA_IID_PPV_ARGS(&res));
pOptimizedClearValue, committedAllocParams.m_ProtectedSession, D3D12MA_IID_PPV_ARGS(&res));
#else
D3D12MA_ASSERT(committedAllocParams.m_ProtectedSession == NULL);
HRESULT hr = m_Device->CreateCommittedResource(
&committedAllocParams.m_HeapProperties,
committedAllocParams.m_HeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS,
pResourceDesc, InitialResourceState,
pOptimizedClearValue, D3D12MA_IID_PPV_ARGS(&res));
#endif
if(SUCCEEDED(hr))
{
if(ppvResource != NULL)
@ -5289,7 +5137,6 @@ HRESULT AllocatorPimpl::AllocateCommittedResource1(
}
return hr;
}
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
HRESULT AllocatorPimpl::AllocateCommittedResource2(
@ -5297,7 +5144,6 @@ HRESULT AllocatorPimpl::AllocateCommittedResource2(
UINT64 resourceSize, bool withinBudget,
const D3D12_RESOURCE_DESC1* pResourceDesc,
D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE *pOptimizedClearValue,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation, REFIID riidResource, void** ppvResource)
{
D3D12MA_ASSERT(committedAllocParams.IsValid());
@ -5318,7 +5164,7 @@ HRESULT AllocatorPimpl::AllocateCommittedResource2(
&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, pProtectedSession, D3D12MA_IID_PPV_ARGS(&res));
pOptimizedClearValue, committedAllocParams.m_ProtectedSession, D3D12MA_IID_PPV_ARGS(&res));
if(SUCCEEDED(hr))
{
if(ppvResource != NULL)
@ -5370,50 +5216,15 @@ HRESULT AllocatorPimpl::AllocateHeap(
heapDesc.Flags = committedAllocParams.m_HeapFlags;
ID3D12Heap* heap = nullptr;
HRESULT hr = m_Device->CreateHeap(&heapDesc, D3D12MA_IID_PPV_ARGS(&heap));
if(SUCCEEDED(hr))
{
const BOOL wasZeroInitialized = TRUE;
(*ppAllocation) = m_AllocationObjectAllocator.Allocate(this, allocInfo.SizeInBytes, wasZeroInitialized);
(*ppAllocation)->InitHeap(committedAllocParams.m_List, heap);
committedAllocParams.m_List->Register(*ppAllocation);
const UINT heapTypeIndex = HeapTypeToIndex(committedAllocParams.m_HeapProperties.Type);
m_Budget.AddCommittedAllocation(heapTypeIndex, allocInfo.SizeInBytes);
}
return hr;
}
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT AllocatorPimpl::AllocateHeap1(
const CommittedAllocationParameters& committedAllocParams,
const D3D12_RESOURCE_ALLOCATION_INFO& allocInfo, bool withinBudget,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation)
{
D3D12MA_ASSERT(committedAllocParams.IsValid());
*ppAllocation = nullptr;
if(m_Device4 == NULL)
{
return E_NOINTERFACE;
}
if(withinBudget &&
!NewAllocationWithinBudget(committedAllocParams.m_HeapProperties.Type, allocInfo.SizeInBytes))
{
return E_OUTOFMEMORY;
}
D3D12_HEAP_DESC heapDesc = {};
heapDesc.SizeInBytes = allocInfo.SizeInBytes;
heapDesc.Properties = committedAllocParams.m_HeapProperties;
heapDesc.Alignment = allocInfo.Alignment;
heapDesc.Flags = committedAllocParams.m_HeapFlags;
ID3D12Heap* heap = nullptr;
HRESULT hr = m_Device4->CreateHeap1(&heapDesc, pProtectedSession, D3D12MA_IID_PPV_ARGS(&heap));
HRESULT hr = m_Device4->CreateHeap1(&heapDesc, committedAllocParams.m_ProtectedSession, D3D12MA_IID_PPV_ARGS(&heap));
#else
D3D12MA_ASSERT(committedAllocParams.m_ProtectedSession == NULL);
HRESULT hr = m_Device->CreateHeap(&heapDesc, D3D12MA_IID_PPV_ARGS(&heap));
#endif
if(SUCCEEDED(hr))
{
const BOOL wasZeroInitialized = TRUE;
@ -5426,7 +5237,6 @@ HRESULT AllocatorPimpl::AllocateHeap1(
}
return hr;
}
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
template<typename D3D12_RESOURCE_DESC_T>
HRESULT AllocatorPimpl::CalcAllocationParams(const ALLOCATION_DESC& allocDesc, UINT64 allocSize,
@ -5443,6 +5253,7 @@ HRESULT AllocatorPimpl::CalcAllocationParams(const ALLOCATION_DESC& allocDesc, U
outBlockVector = pool->GetBlockVector();
outCommittedAllocationParams.m_ProtectedSession = pool->GetDesc().pProtectedSession;
outCommittedAllocationParams.m_HeapProperties = pool->GetDesc().HeapProperties;
outCommittedAllocationParams.m_HeapFlags = pool->GetDesc().HeapFlags;
outCommittedAllocationParams.m_List = pool->GetCommittedAllocationList();
@ -6379,34 +6190,12 @@ HRESULT Allocator::CreateResource(
return m_Pimpl->CreateResource(pAllocDesc, pResourceDesc, InitialResourceState, pOptimizedClearValue, ppAllocation, riidResource, ppvResource);
}
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT Allocator::CreateResource1(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_DESC* 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::CreateResource1.");
return E_INVALIDARG;
}
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
return m_Pimpl->CreateResource1(pAllocDesc, pResourceDesc, InitialResourceState, pOptimizedClearValue, pProtectedSession, ppAllocation, riidResource, ppvResource);
}
#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)
@ -6417,7 +6206,7 @@ HRESULT Allocator::CreateResource2(
return E_INVALIDARG;
}
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
return m_Pimpl->CreateResource2(pAllocDesc, pResourceDesc, InitialResourceState, pOptimizedClearValue, pProtectedSession, ppAllocation, riidResource, ppvResource);
return m_Pimpl->CreateResource2(pAllocDesc, pResourceDesc, InitialResourceState, pOptimizedClearValue, ppAllocation, riidResource, ppvResource);
}
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
@ -6450,23 +6239,6 @@ HRESULT Allocator::AllocateMemory(
return m_Pimpl->AllocateMemory(pAllocDesc, pAllocInfo, ppAllocation);
}
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT Allocator::AllocateMemory1(
const ALLOCATION_DESC* pAllocDesc,
const D3D12_RESOURCE_ALLOCATION_INFO* pAllocInfo,
ID3D12ProtectedResourceSession *pProtectedSession,
Allocation** ppAllocation)
{
if(!ValidateAllocateMemoryParameters(pAllocDesc, pAllocInfo, ppAllocation))
{
D3D12MA_ASSERT(0 && "Invalid arguments passed to Allocator::AllocateMemory1.");
return E_INVALIDARG;
}
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
return m_Pimpl->AllocateMemory1(pAllocDesc, pAllocInfo, pProtectedSession, ppAllocation);
}
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT Allocator::CreateAliasingResource(
Allocation* pAllocation,
UINT64 AllocationLocalOffset,

View File

@ -90,6 +90,7 @@ static float g_TimeDelta;
static DXGIUsage* g_DXGIUsage;
static ComPtr<ID3D12Device> g_Device;
DXGI_ADAPTER_DESC1 g_AdapterDesc;
static ComPtr<D3D12MA::Allocator> g_Allocator;
static ComPtr<IDXGISwapChain3> g_SwapChain; // swapchain used to switch between render targets
@ -513,10 +514,6 @@ ComPtr<IDXGIAdapter1> DXGIUsage::CreateAdapter(const GPUSelection& GPUSelection)
return adapter;
}
static const uint32_t VENDOR_ID_AMD = 0x1002;
static const uint32_t VENDOR_ID_NVIDIA = 0x10DE;
static const uint32_t VENDOR_ID_INTEL = 0x8086;
static const wchar_t* VendorIDToStr(uint32_t vendorID)
{
switch(vendorID)
@ -566,17 +563,15 @@ static std::wstring SizeToStr(size_t size)
static void PrintAdapterInformation(IDXGIAdapter1* adapter)
{
DXGI_ADAPTER_DESC1 adapterDesc = {};
adapter->GetDesc1(&adapterDesc);
wprintf(L"DXGI_ADAPTER_DESC1:\n");
wprintf(L" Description = %s\n", adapterDesc.Description);
wprintf(L" VendorId = 0x%X (%s)\n", adapterDesc.VendorId, VendorIDToStr(adapterDesc.VendorId));
wprintf(L" DeviceId = 0x%X\n", adapterDesc.DeviceId);
wprintf(L" SubSysId = 0x%X\n", adapterDesc.SubSysId);
wprintf(L" Revision = 0x%X\n", adapterDesc.Revision);
wprintf(L" DedicatedVideoMemory = %zu B (%s)\n", adapterDesc.DedicatedVideoMemory, SizeToStr(adapterDesc.DedicatedVideoMemory).c_str());
wprintf(L" DedicatedSystemMemory = %zu B (%s)\n", adapterDesc.DedicatedSystemMemory, SizeToStr(adapterDesc.DedicatedSystemMemory).c_str());
wprintf(L" SharedSystemMemory = %zu B (%s)\n", adapterDesc.SharedSystemMemory, SizeToStr(adapterDesc.SharedSystemMemory).c_str());
wprintf(L" Description = %s\n", g_AdapterDesc.Description);
wprintf(L" VendorId = 0x%X (%s)\n", g_AdapterDesc.VendorId, VendorIDToStr(g_AdapterDesc.VendorId));
wprintf(L" DeviceId = 0x%X\n", g_AdapterDesc.DeviceId);
wprintf(L" SubSysId = 0x%X\n", g_AdapterDesc.SubSysId);
wprintf(L" Revision = 0x%X\n", g_AdapterDesc.Revision);
wprintf(L" DedicatedVideoMemory = %zu B (%s)\n", g_AdapterDesc.DedicatedVideoMemory, SizeToStr(g_AdapterDesc.DedicatedVideoMemory).c_str());
wprintf(L" DedicatedSystemMemory = %zu B (%s)\n", g_AdapterDesc.DedicatedSystemMemory, SizeToStr(g_AdapterDesc.DedicatedSystemMemory).c_str());
wprintf(L" SharedSystemMemory = %zu B (%s)\n", g_AdapterDesc.SharedSystemMemory, SizeToStr(g_AdapterDesc.SharedSystemMemory).c_str());
const D3D12_FEATURE_DATA_D3D12_OPTIONS& options = g_Allocator->GetD3D12Options();
wprintf(L"D3D12_FEATURE_DATA_D3D12_OPTIONS:\n");
@ -630,6 +625,8 @@ static void InitD3D() // initializes direct3d 12
ComPtr<IDXGIAdapter1> adapter = g_DXGIUsage->CreateAdapter(g_CommandLineParameters.m_GPUSelection);
CHECK_BOOL(adapter);
CHECK_HR(adapter->GetDesc1(&g_AdapterDesc));
// Must be done before D3D12 device is created.
if(ENABLE_DEBUG_LAYER)
{

View File

@ -25,6 +25,7 @@
#include <thread>
extern ID3D12GraphicsCommandList* BeginCommandList();
extern DXGI_ADAPTER_DESC1 g_AdapterDesc;
extern void EndCommandList(ID3D12GraphicsCommandList* cmdList);
static constexpr UINT64 MEGABYTE = 1024 * 1024;
@ -1613,6 +1614,7 @@ static bool IsProtectedResourceSessionSupported(const TestContext& ctx)
return support.Support > D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE;
}
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
static void TestDevice4(const TestContext& ctx)
{
wprintf(L"Test ID3D12Device4\n");
@ -1641,32 +1643,54 @@ static void TestDevice4(const TestContext& ctx)
return;
}
// Create a buffer
D3D12MA::POOL_DESC poolDesc = {};
poolDesc.HeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
poolDesc.pProtectedSession = session.Get();
poolDesc.MinAllocationAlignment = 0;
poolDesc.HeapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
ComPtr<D3D12MA::Pool> pool;
hr = ctx.allocator->CreatePool(&poolDesc, &pool);
if(FAILED(hr))
{
wprintf(L"Failed to create custom pool.\n");
return;
}
D3D12_RESOURCE_DESC resourceDesc;
FillResourceDescForBuffer(resourceDesc, 1024);
for(UINT testIndex = 0; testIndex < 2; ++testIndex)
{
// Create a buffer
D3D12MA::ALLOCATION_DESC allocDesc = {};
allocDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
allocDesc.CustomPool = pool.Get();
if(testIndex == 0)
allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED;
ComPtr<D3D12MA::Allocation> bufAlloc;
ComPtr<ID3D12Resource> bufRes;
CHECK_HR(ctx.allocator->CreateResource1(&allocDesc, &resourceDesc,
CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resourceDesc,
D3D12_RESOURCE_STATE_COMMON, NULL,
session.Get(), &bufAlloc, IID_PPV_ARGS(&bufRes)));
&bufAlloc, IID_PPV_ARGS(&bufRes)));
CHECK_BOOL(bufAlloc && bufAlloc->GetResource() == bufRes.Get());
// Make sure it's (not) committed.
CHECK_BOOL((bufAlloc->GetHeap() == NULL) == (testIndex == 0));
// Create a heap
// Temporarily commented out as it caues BSOD on RTX2080Ti driver 461.40.
#if 0
// Allocate memory/heap
// Temporarily disabled on NVIDIA as it causes BSOD on RTX2080Ti driver 461.40.
if(g_AdapterDesc.VendorId != VENDOR_ID_NVIDIA)
{
D3D12_RESOURCE_ALLOCATION_INFO heapAllocInfo = {
D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT * 100, // SizeInBytes
D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT * 2, // SizeInBytes
D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, // Alignment
};
CHECK_HR(ctx.allocator->AllocateMemory1(&allocDesc, &heapAllocInfo, session, &alloc));
AllocationUniquePtr heapAllocPtr{alloc};
#endif
ComPtr<D3D12MA::Allocation> memAlloc;
CHECK_HR(ctx.allocator->AllocateMemory(&allocDesc, &heapAllocInfo, &memAlloc));
CHECK_BOOL(memAlloc->GetHeap());
}
}
}
#endif // #ifdef __ID3D12Device4_INTERFACE_DEFINED__
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
static void TestDevice8(const TestContext& ctx)
@ -1688,7 +1712,7 @@ static void TestDevice8(const TestContext& ctx)
ComPtr<D3D12MA::Allocation> allocPtr0;
ComPtr<ID3D12Resource> res0;
CHECK_HR(ctx.allocator->CreateResource2(&allocDesc, &resourceDesc,
D3D12_RESOURCE_STATE_COMMON, NULL, NULL,
D3D12_RESOURCE_STATE_COMMON, NULL,
&allocPtr0, IID_PPV_ARGS(&res0)));
CHECK_BOOL(allocPtr0->GetHeap() == NULL);
@ -1699,7 +1723,7 @@ static void TestDevice8(const TestContext& ctx)
ComPtr<D3D12MA::Allocation> allocPtr1;
ComPtr<ID3D12Resource> res1;
CHECK_HR(ctx.allocator->CreateResource2(&allocDesc, &resourceDesc,
D3D12_RESOURCE_STATE_COMMON, NULL, NULL,
D3D12_RESOURCE_STATE_COMMON, NULL,
&allocPtr1, IID_PPV_ARGS(&res1)));
CHECK_BOOL(allocPtr1->GetHeap()!= NULL);
}
@ -1729,7 +1753,9 @@ static void TestGroupBasics(const TestContext& ctx)
TestTransfer(ctx);
TestZeroInitialized(ctx);
TestMultithreading(ctx);
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
TestDevice4(ctx);
#endif
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
TestDevice8(ctx);
#endif