diff --git a/include/gpgmm_d3d12.h b/include/gpgmm_d3d12.h index 78c89b6b..8077c376 100644 --- a/include/gpgmm_d3d12.h +++ b/include/gpgmm_d3d12.h @@ -1052,6 +1052,19 @@ namespace gpgmm::d3d12 { allocation. */ UINT64 ReleaseSizeInBytes; + + /** \brief Additional resource flags to apply for any resource created by this resource + allocator. + + Alternatively, resource flags can be applied at allocation-time so long as + RESOURCE_ALLOCATION_FLAG_ALLOW_SUBALLOCATE_WITHIN_RESOURCE was not specified. + + For a list of available options, please read: + https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_resource_flags + + Optional parameter. When unspecified, no additional flags would be applied. + */ + D3D12_RESOURCE_FLAGS ExtraRequiredResourceFlags; }; /** \enum RESOURCE_ALLOCATION_FLAGS diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp index 389bbdf6..e2ca2036 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp @@ -598,6 +598,7 @@ namespace gpgmm::d3d12 { mResidencyManager(pResidencyManager), mCaps(std::move(caps)), mResourceHeapTier(descriptor.ResourceHeapTier), + mExtraRequiredResourceFlags(descriptor.ExtraRequiredResourceFlags), mIsAlwaysCommitted(descriptor.Flags & RESOURCE_ALLOCATOR_FLAG_ALWAYS_COMMITTED), mIsAlwaysCreatedInBudget(descriptor.Flags & RESOURCE_ALLOCATOR_FLAG_ALWAYS_IN_BUDGET), mFlushEventBuffersOnDestruct(descriptor.RecordOptions.EventScope & @@ -706,9 +707,9 @@ namespace gpgmm::d3d12 { } if (IsBuffersAllowed(heapFlags, mResourceHeapTier)) { - mSmallBufferAllocatorOfType[resourceHeapTypeIndex] = - CreateSmallBufferAllocator(descriptor, heapFlags, heapProperties, heapInfo, - GetInitialResourceState(heapType)); + mSmallBufferAllocatorOfType[resourceHeapTypeIndex] = CreateSmallBufferAllocator( + descriptor, heapFlags, heapProperties, heapInfo, mExtraRequiredResourceFlags, + GetInitialResourceState(heapType)); } else { mSmallBufferAllocatorOfType[resourceHeapTypeIndex] = new SentinelMemoryAllocator; } @@ -824,9 +825,10 @@ namespace gpgmm::d3d12 { D3D12_HEAP_FLAGS heapFlags, const D3D12_HEAP_PROPERTIES& heapProperties, const HEAP_ALLOCATION_INFO& heapInfo, + D3D12_RESOURCE_FLAGS resourceFlags, D3D12_RESOURCE_STATES initialResourceState) { ScopedRef smallBufferOnlyAllocator(new BufferAllocator( - this, heapProperties, heapFlags, D3D12_RESOURCE_FLAG_NONE, initialResourceState)); + this, heapProperties, heapFlags, resourceFlags, initialResourceState)); ScopedRef pooledOrNonPooledAllocator = CreatePoolAllocator(descriptor.PoolAlgorithm, heapInfo, @@ -1134,6 +1136,7 @@ namespace gpgmm::d3d12 { D3D12_RESOURCE_DESC newResourceDesc = resourceDescriptor; newResourceDesc.Alignment = resourceInfo.Alignment; + newResourceDesc.Flags |= mExtraRequiredResourceFlags; // If the heap type was not specified, infer it using the initial resource state. D3D12_HEAP_TYPE heapType = allocationDescriptor.HeapType; diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.h b/src/gpgmm/d3d12/ResourceAllocatorD3D12.h index 973b2a04..bcec2eca 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.h +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.h @@ -102,6 +102,7 @@ namespace gpgmm::d3d12 { D3D12_HEAP_FLAGS heapFlags, const D3D12_HEAP_PROPERTIES& heapProperties, const HEAP_ALLOCATION_INFO& heapInfo, + D3D12_RESOURCE_FLAGS resourceFlags, D3D12_RESOURCE_STATES initialResourceState); ScopedRef CreatePoolAllocator( @@ -157,6 +158,7 @@ namespace gpgmm::d3d12 { std::unique_ptr mCaps; const D3D12_RESOURCE_HEAP_TIER mResourceHeapTier; + const D3D12_RESOURCE_FLAGS mExtraRequiredResourceFlags; const bool mIsAlwaysCommitted; const bool mIsAlwaysCreatedInBudget; const bool mFlushEventBuffersOnDestruct; diff --git a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp index fc22ce45..bfc5f4e6 100644 --- a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp +++ b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp @@ -704,6 +704,23 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBuffer) { {}, CreateBasicBufferDesc(kBufferOf4MBAllocationSize + 1), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, nullptr)); } + + // Create a UAV buffer that that ALLOW_UAV flags applied. + { + RESOURCE_ALLOCATOR_DESC uavAllocatorDesc = CreateBasicAllocatorDesc(); + uavAllocatorDesc.ExtraRequiredResourceFlags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + + ComPtr uavResourceAllocator; + ASSERT_SUCCEEDED(CreateResourceAllocator(uavAllocatorDesc, mDevice.Get(), mAdapter.Get(), + &uavResourceAllocator, nullptr)); + + ComPtr uavBuffer; + ASSERT_SUCCEEDED(uavResourceAllocator->CreateResource( + {}, CreateBasicBufferDesc(kBufferOf4MBAllocationSize), + D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, &uavBuffer)); + + EXPECT_EQ(uavBuffer->GetResource()->GetDesc().Flags, uavAllocatorDesc.ExtraRequiredResourceFlags); + } } TEST_F(D3D12ResourceAllocatorTests, GetResourceAllocator) {