diff --git a/include/D3D12MemAlloc.h b/include/D3D12MemAlloc.h index a85c1f5..c8a7988 100644 --- a/include/D3D12MemAlloc.h +++ b/include/D3D12MemAlloc.h @@ -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. diff --git a/src/Common.h b/src/Common.h index 0f6d356..f2c42aa 100644 --- a/src/Common.h +++ b/src/Common.h @@ -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 inline constexpr T CeilDiv(T x, T y) { diff --git a/src/D3D12MemAlloc.cpp b/src/D3D12MemAlloc.cpp index 7655e72..e0d52ae 100644 --- a/src/D3D12MemAlloc.cpp +++ b/src/D3D12MemAlloc.cpp @@ -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 HRESULT CalcAllocationParams(const ALLOCATION_DESC& allocDesc, UINT64 allocSize, const D3D12_RESOURCE_DESC_T* resDesc, // Optional @@ -3924,14 +3888,14 @@ NormalBlock::~NormalBlock() } } -HRESULT NormalBlock::Init() +HRESULT NormalBlock::Init(ID3D12ProtectedResourceSession* pProtectedSession) { - HRESULT hr = MemoryBlock::Init(); + HRESULT hr = MemoryBlock::Init(pProtectedSession); if(FAILED(hr)) { return hr; } - + m_pMetadata = D3D12MA_NEW(m_Allocator->GetAllocs(), BlockMetadata_Generic)(&m_Allocator->GetAllocs(), false); m_pMetadata->Init(m_Size); @@ -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(*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(*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 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, diff --git a/src/D3D12Sample.cpp b/src/D3D12Sample.cpp index 699d5dc..f9dc855 100644 --- a/src/D3D12Sample.cpp +++ b/src/D3D12Sample.cpp @@ -90,6 +90,7 @@ static float g_TimeDelta; static DXGIUsage* g_DXGIUsage; static ComPtr g_Device; +DXGI_ADAPTER_DESC1 g_AdapterDesc; static ComPtr g_Allocator; static ComPtr g_SwapChain; // swapchain used to switch between render targets @@ -513,10 +514,6 @@ ComPtr 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 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) { diff --git a/src/Tests.cpp b/src/Tests.cpp index 8b011cc..b373d6e 100644 --- a/src/Tests.cpp +++ b/src/Tests.cpp @@ -25,6 +25,7 @@ #include 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 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); - D3D12MA::ALLOCATION_DESC allocDesc = {}; - allocDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT; + for(UINT testIndex = 0; testIndex < 2; ++testIndex) + { + // Create a buffer + D3D12MA::ALLOCATION_DESC allocDesc = {}; + allocDesc.CustomPool = pool.Get(); + if(testIndex == 0) + allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED; + ComPtr bufAlloc; + ComPtr bufRes; + CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resourceDesc, + D3D12_RESOURCE_STATE_COMMON, NULL, + &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)); - ComPtr bufAlloc; - ComPtr bufRes; - CHECK_HR(ctx.allocator->CreateResource1(&allocDesc, &resourceDesc, - D3D12_RESOURCE_STATE_COMMON, NULL, - session.Get(), &bufAlloc, IID_PPV_ARGS(&bufRes))); - - // Create a heap - // Temporarily commented out as it caues BSOD on RTX2080Ti driver 461.40. -#if 0 - D3D12_RESOURCE_ALLOCATION_INFO heapAllocInfo = { - D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT * 100, // SizeInBytes - D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, // Alignment - }; - - CHECK_HR(ctx.allocator->AllocateMemory1(&allocDesc, &heapAllocInfo, session, &alloc)); - AllocationUniquePtr heapAllocPtr{alloc}; -#endif + // 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 * 2, // SizeInBytes + D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, // Alignment + }; + ComPtr 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 allocPtr0; ComPtr 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 allocPtr1; ComPtr 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