diff --git a/.github/workflows/.patches/dawn.diff b/.github/workflows/.patches/dawn.diff index 36fb7dee9..0c3087c1b 100644 --- a/.github/workflows/.patches/dawn.diff +++ b/.github/workflows/.patches/dawn.diff @@ -1,39 +1,8 @@ -From 432dc113fe27f5b0b4f027cad368e30af66db994 Mon Sep 17 00:00:00 2001 -From: Bryan Bernhart -Date: Tue, 15 Feb 2022 17:25:29 -0800 -Subject: [PATCH] Use GPGMM for D3D12 backend. +commit ca55e3cf88e274008722f31e35941bade2b8f4cf +Author: Brandon Jones +Date: Fri Oct 21 16:07:38 2022 -0700 -Change-Id: I47708462a1d9dd0166120c3a6af93451aae54a07 ---- - .gitignore | 1 + - DEPS | 4 + - build_overrides/dawn.gni | 1 + - build_overrides/gpgmm.gni | 16 +++ - scripts/dawn_overrides_with_defaults.gni | 5 +- - src/dawn/native/BUILD.gn | 15 ++- - src/dawn/native/Device.cpp | 1 + - src/dawn/native/Toggles.cpp | 8 ++ - src/dawn/native/Toggles.h | 2 + - src/dawn/native/d3d12/AdapterD3D12.cpp | 4 + - src/dawn/native/d3d12/BufferD3D12.cpp | 52 ++++---- - src/dawn/native/d3d12/BufferD3D12.h | 7 +- - src/dawn/native/d3d12/CommandBufferD3D12.cpp | 9 +- - .../native/d3d12/CommandRecordingContext.cpp | 26 ++-- - .../native/d3d12/CommandRecordingContext.h | 5 +- - src/dawn/native/d3d12/D3D12Backend.cpp | 10 +- - src/dawn/native/d3d12/DeviceD3D12.cpp | 124 +++++++++++++++--- - src/dawn/native/d3d12/DeviceD3D12.h | 20 +-- - .../ShaderVisibleDescriptorAllocatorD3D12.cpp | 78 ++++++----- - .../ShaderVisibleDescriptorAllocatorD3D12.h | 11 +- - src/dawn/native/d3d12/StagingBufferD3D12.cpp | 22 +--- - src/dawn/native/d3d12/StagingBufferD3D12.h | 4 +- - src/dawn/native/d3d12/TextureD3D12.cpp | 43 +++--- - src/dawn/native/d3d12/TextureD3D12.h | 4 +- - src/dawn/native/d3d12/UtilsD3D12.cpp | 11 ++ - src/dawn/native/d3d12/UtilsD3D12.h | 2 + - .../tests/white_box/D3D12ResidencyTests.cpp | 17 +-- - 27 files changed, 336 insertions(+), 166 deletions(-) - create mode 100644 build_overrides/gpgmm.gni + [PATCH] Use GPGMM for D3D12 backend. diff --git a/.gitignore b/.gitignore index a66733d04..9e2f720a6 100644 @@ -74,28 +43,6 @@ index 6440625c5..ef3784630 100644 # Optional path to a one-liner version file. Default is empty path indicating # that git should be used to figure out the version. -diff --git a/build_overrides/gpgmm.gni b/build_overrides/gpgmm.gni -new file mode 100644 -index 000000000..b41f6a9db ---- /dev/null -+++ b/build_overrides/gpgmm.gni -@@ -0,0 +1,16 @@ -+# Copyright 2021 The Dawn Authors -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); -+# you may not use this file except in compliance with the License. -+# You may obtain a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, -+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+# See the License for the specific language governing permissions and -+# limitations under the License. -+ -+# The paths to GPGMM's dependencies -+gpgmm_vk_loader_dir = "//third_party/vulkan-deps/vulkan-loader/src" diff --git a/scripts/dawn_overrides_with_defaults.gni b/scripts/dawn_overrides_with_defaults.gni index bbe79e18c..3fd68fc73 100644 --- a/scripts/dawn_overrides_with_defaults.gni @@ -212,7 +159,7 @@ index e23830e89..144ea3e22 100644 // Create a retrieval filter with a deny list to suppress messages. diff --git a/src/dawn/native/d3d12/BufferD3D12.cpp b/src/dawn/native/d3d12/BufferD3D12.cpp -index 0488fce6a..88e8f9cc4 100644 +index 0488fce6a..21b6f7eca 100644 --- a/src/dawn/native/d3d12/BufferD3D12.cpp +++ b/src/dawn/native/d3d12/BufferD3D12.cpp @@ -153,9 +153,15 @@ MaybeError Buffer::Initialize(bool mappedAtCreation) { @@ -531,7 +478,7 @@ index 05ddd6b4c..acf1b659d 100644 AdapterDiscoveryOptions::AdapterDiscoveryOptions() diff --git a/src/dawn/native/d3d12/DeviceD3D12.cpp b/src/dawn/native/d3d12/DeviceD3D12.cpp -index 214fa67f8..4f0d60c6f 100644 +index 214fa67f8..d909d4d2a 100644 --- a/src/dawn/native/d3d12/DeviceD3D12.cpp +++ b/src/dawn/native/d3d12/DeviceD3D12.cpp @@ -132,8 +132,43 @@ MaybeError Device::Initialize(const DeviceDescriptor* descriptor) { @@ -773,7 +720,7 @@ index 0373cf9d8..4cea643f8 100644 static constexpr uint32_t kMaxSamplerDescriptorsPerBindGroup = 3 * kMaxSamplersPerShaderStage; static constexpr uint32_t kMaxViewDescriptorsPerBindGroup = diff --git a/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp b/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp -index fe99a63ac..6cc22c93e 100644 +index fe99a63ac..353e47b82 100644 --- a/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp +++ b/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp @@ -93,7 +93,8 @@ ShaderVisibleDescriptorAllocator::ShaderVisibleDescriptorAllocator( @@ -786,7 +733,7 @@ index fe99a63ac..6cc22c93e 100644 ASSERT(heapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || heapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); } -@@ -140,31 +141,38 @@ void ShaderVisibleDescriptorAllocator::Tick(ExecutionSerial completedSerial) { +@@ -140,31 +141,23 @@ void ShaderVisibleDescriptorAllocator::Tick(ExecutionSerial completedSerial) { ResultOrError> ShaderVisibleDescriptorAllocator::AllocateHeap(uint32_t descriptorCount) const { @@ -808,43 +755,31 @@ index fe99a63ac..6cc22c93e 100644 - DAWN_TRY(CheckOutOfMemoryHRESULT(mDevice->GetD3D12Device()->CreateDescriptorHeap( - &heapDescriptor, IID_PPV_ARGS(&d3d12DescriptorHeap)), - "ID3D12Device::CreateDescriptorHeap")); -+ heapDesc.SizeInBytes = mSizeIncrement * descriptorCount; -+ heapDesc.MemorySegmentGroup = DXGI_MEMORY_SEGMENT_GROUP_LOCAL; -+ -+ auto createHeapFn = [&](ID3D12Pageable** ppPageableOut) -> HRESULT { -+ ComPtr d3d12DescriptorHeap; -+ D3D12_DESCRIPTOR_HEAP_DESC heapDescriptor; -+ heapDescriptor.Type = mHeapType; -+ heapDescriptor.NumDescriptors = descriptorCount; -+ heapDescriptor.Flags = GetD3D12HeapFlags(mHeapType); -+ heapDescriptor.NodeMask = 0; -+ HRESULT hr = mDevice->GetD3D12Device()->CreateDescriptorHeap( -+ &heapDescriptor, IID_PPV_ARGS(&d3d12DescriptorHeap)); -+ if (FAILED(hr)) { -+ return hr; -+ } - +- - std::unique_ptr descriptorHeap = - std::make_unique(std::move(d3d12DescriptorHeap), kSize); -+ *ppPageableOut = d3d12DescriptorHeap.Detach(); -+ return S_OK; -+ }; - +- - // We must track the allocation in the LRU when it is created, otherwise the residency - // manager will see the allocation as non-resident in the later call to LockAllocation. - mDevice->GetResidencyManager()->TrackResidentAllocation(descriptorHeap.get()); -+ ComPtr descriptorHeap; -+ DAWN_TRY( -+ CheckOutOfMemoryHRESULT(gpgmm::d3d12::CreateHeap(heapDesc, mDevice->GetResidencyManager(), -+ createHeapFn, &descriptorHeap), -+ "Unable to create descriptor heap")); - +- - return std::move(descriptorHeap); ++ heapDesc.SizeInBytes = mSizeIncrement * descriptorCount; ++ heapDesc.MemorySegmentGroup = DXGI_MEMORY_SEGMENT_GROUP_LOCAL; ++ ++ CreateHeapCallback callback(mDevice->GetD3D12Device(), descriptorCount, mHeapType); ++ ComPtr descriptorHeap; ++ DAWN_TRY(CheckOutOfMemoryHRESULT( ++ gpgmm::d3d12::CreateHeap(heapDesc, mDevice->GetResidencyManager(), ++ CreateHeapCallback::CreateHeapCallbackWrapper, &callback, ++ &descriptorHeap), ++ "Unable to create descriptor heap")); ++ + return std::make_unique(std::move(descriptorHeap)); } // Creates a GPU descriptor heap that manages descriptors in a FIFO queue. -@@ -174,7 +182,9 @@ MaybeError ShaderVisibleDescriptorAllocator::AllocateAndSwitchShaderVisibleHeap( +@@ -174,7 +167,9 @@ MaybeError ShaderVisibleDescriptorAllocator::AllocateAndSwitchShaderVisibleHeap( // The first phase increasingly grows a small heap in binary sizes for light users while the // second phase pool-allocates largest sized heaps for heavy users. if (mHeap != nullptr) { @@ -855,7 +790,7 @@ index fe99a63ac..6cc22c93e 100644 const uint32_t maxDescriptorCount = GetD3D12ShaderVisibleHeapMaxSize( mHeapType, mDevice->IsToggleEnabled(Toggle::UseD3D12SmallShaderVisibleHeapForTesting)); -@@ -200,7 +210,10 @@ MaybeError ShaderVisibleDescriptorAllocator::AllocateAndSwitchShaderVisibleHeap( +@@ -200,7 +195,10 @@ MaybeError ShaderVisibleDescriptorAllocator::AllocateAndSwitchShaderVisibleHeap( DAWN_TRY_ASSIGN(descriptorHeap, AllocateHeap(mDescriptorCount)); } @@ -867,7 +802,7 @@ index fe99a63ac..6cc22c93e 100644 // Create a FIFO buffer from the recently created heap. mHeap = std::move(descriptorHeap); -@@ -227,12 +240,12 @@ uint64_t ShaderVisibleDescriptorAllocator::GetShaderVisiblePoolSizeForTesting() +@@ -227,12 +225,12 @@ uint64_t ShaderVisibleDescriptorAllocator::GetShaderVisiblePoolSizeForTesting() } bool ShaderVisibleDescriptorAllocator::IsShaderVisibleHeapLockedResidentForTesting() const { @@ -882,7 +817,7 @@ index fe99a63ac..6cc22c93e 100644 } bool ShaderVisibleDescriptorAllocator::IsAllocationStillValid( -@@ -243,13 +256,18 @@ bool ShaderVisibleDescriptorAllocator::IsAllocationStillValid( +@@ -243,13 +241,46 @@ bool ShaderVisibleDescriptorAllocator::IsAllocationStillValid( allocation.GetHeapSerial() == mHeapSerial); } @@ -905,10 +840,38 @@ index fe99a63ac..6cc22c93e 100644 +gpgmm::d3d12::IHeap* ShaderVisibleDescriptorHeap::GetHeap() const { + return mDescriptorHeap.Get(); } ++ ++CreateHeapCallback::CreateHeapCallback(ID3D12Device* device, ++ uint32_t descriptorCount, ++ D3D12_DESCRIPTOR_HEAP_TYPE heapType) ++ : mDevice(device), mDescriptorCount(descriptorCount), mHeapType(heapType) {} ++ ++// static ++HRESULT CreateHeapCallback::CreateHeapCallbackWrapper(void* context, ++ ID3D12Pageable** ppPageableOut) { ++ CreateHeapCallback* callback = static_cast(context); ++ return callback->CreateHeap(ppPageableOut); ++} ++ ++HRESULT CreateHeapCallback::CreateHeap(ID3D12Pageable** ppPageableOut) { ++ ComPtr d3d12DescriptorHeap; ++ D3D12_DESCRIPTOR_HEAP_DESC heapDescriptor; ++ heapDescriptor.Type = mHeapType; ++ heapDescriptor.NumDescriptors = mDescriptorCount; ++ heapDescriptor.Flags = GetD3D12HeapFlags(mHeapType); ++ heapDescriptor.NodeMask = 0; ++ HRESULT hr = mDevice->CreateDescriptorHeap(&heapDescriptor, IID_PPV_ARGS(&d3d12DescriptorHeap)); ++ if (FAILED(hr)) { ++ return hr; ++ } ++ ++ *ppPageableOut = d3d12DescriptorHeap.Detach(); ++ return S_OK; ++} + } // namespace dawn::native::d3d12 diff --git a/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.h b/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.h -index cf09f9d50..e76561d2c 100644 +index cf09f9d50..f22684f27 100644 --- a/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.h +++ b/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.h @@ -24,6 +24,8 @@ @@ -938,15 +901,32 @@ index cf09f9d50..e76561d2c 100644 }; class ShaderVisibleDescriptorAllocator { -@@ -99,6 +102,8 @@ class ShaderVisibleDescriptorAllocator { +@@ -99,7 +102,25 @@ class ShaderVisibleDescriptorAllocator { // The descriptor count is the current size of the heap in number of descriptors. // This is stored on the allocator to avoid extra conversions. uint32_t mDescriptorCount = 0; + + bool mResidencyManagementEnabled = false; ++}; ++ ++class CreateHeapCallback { ++ public: ++ CreateHeapCallback(ID3D12Device* device, ++ uint32_t descriptorCount, ++ D3D12_DESCRIPTOR_HEAP_TYPE heapType); ++ static HRESULT CreateHeapCallbackWrapper(void* context, ID3D12Pageable** ppPageableOut); ++ ++ private: ++ HRESULT CreateHeap(ID3D12Pageable** ppPageableOut); ++ ++ ID3D12Device* mDevice; ++ uint32_t mDescriptorCount; ++ D3D12_DESCRIPTOR_HEAP_TYPE mHeapType; }; ++ } // namespace dawn::native::d3d12 + #endif // SRC_DAWN_NATIVE_D3D12_SHADERVISIBLEDESCRIPTORALLOCATORD3D12_H_ diff --git a/src/dawn/native/d3d12/StagingBufferD3D12.cpp b/src/dawn/native/d3d12/StagingBufferD3D12.cpp index edaa2cff4..7753c25cf 100644 --- a/src/dawn/native/d3d12/StagingBufferD3D12.cpp @@ -1231,6 +1211,3 @@ index 6298d82f4..912bdb608 100644 - D3D12Backend({"use_d3d12_small_shader_visible_heap"})); + D3D12Backend({"use_d3d12_small_shader_visible_heap", + "use_d3d12_small_residency_budget"})); --- -2.23.0.windows.1 - diff --git a/README.md b/README.md index 887b8ff1e..609f90c21 100644 --- a/README.md +++ b/README.md @@ -69,13 +69,10 @@ shaderVisibleHeap.SizeInBytes = kHeapSize; shaderVisibleHeap.MemorySegmentGroup = DXGI_MEMORY_SEGMENT_GROUP_LOCAL; ComPtr descriptorHeap; -gpgmm::d3d12::CreateHeap(shaderVisibleHeap, residencyManager, - [&](ID3D12Pageable** ppPageableOut) -> HRESULT { - ComPtr heap; - mDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&heap)); - *ppPageableOut = heap.Detach(); - return S_OK; -}, &descriptorHeap); +CreateHeapContext createHeapContext(heapDesc); +gpgmm::d3d12::CreateHeap(shaderVisibleHeap, residencyManager, + createHeapContext, &CreateHeapContext::CreateHeapCallbackWrapper, + &descriptorHeap); // Shader-visible heaps should be locked or always resident. residency->LockHeap(descriptorHeap.get()); diff --git a/include/gpgmm_d3d12.h b/include/gpgmm_d3d12.h index 19d659838..5977c0a6c 100644 --- a/include/gpgmm_d3d12.h +++ b/include/gpgmm_d3d12.h @@ -181,7 +181,8 @@ namespace gpgmm::d3d12 { }; \endcode */ - using CreateHeapFn = std::function; + + using CreateHeapFn = HRESULT (*)(void* context, ID3D12Pageable** ppPageableOut); GPGMM_INTERFACE IResidencyManager; @@ -210,12 +211,38 @@ namespace gpgmm::d3d12 { @param descriptor A reference to HEAP_DESC structure that describes the heap. @param pResidencyManager A pointer to the ResidencyManager used to manage this heap. @param createHeapFn A callback function which creates a ID3D12Pageable derived type. + @param createHeapFnContext A pointer to a class designed to implement the actual heap creation + function and store any necessary variables. @param[out] ppHeapOut Pointer to a memory block that receives a pointer to the heap. + + Example call showing the usage of createHeapFn and createHeapFnContext: + + CreateHeap(descriptor, pResidencyManager, CallbackContext:CallbackWrapper, + reinterpret_cast(callbackContext), ppHeapOut); + + Example Callback Context Class: + + class CallbackContext { + public: + CallbackContext(); + CreateHeap(void *context, ID3D12Pageable** ppPageableOut); + static CallbackWrapper(ID3D12Pageable** ppPageableOut); + private: + (Declare variables needed for heap creation here) + } + + Example Implementation of CallbackWrapper: + + HRESULT CallbackContext:CallbackWrapper(void* context, ID3D12Pageable** ppPageableOut) { + CallbackContext* callbackContext = reinterpret_cast(context); + return callbackContext->CreateHeap(ppPageableOut); + } */ GPGMM_EXPORT HRESULT CreateHeap(const HEAP_DESC& descriptor, IResidencyManager* const pResidencyManager, - CreateHeapFn&& createHeapFn, + CreateHeapFn createHeapFn, + void* createHeapFnContext, IHeap** ppHeapOut); /** \brief Represents a list of heaps which will be "made resident" upon executing a diff --git a/src/gpgmm/d3d12/HeapD3D12.cpp b/src/gpgmm/d3d12/HeapD3D12.cpp index fb286d979..9502a978c 100644 --- a/src/gpgmm/d3d12/HeapD3D12.cpp +++ b/src/gpgmm/d3d12/HeapD3D12.cpp @@ -58,15 +58,18 @@ namespace gpgmm::d3d12 { HRESULT CreateHeap(const HEAP_DESC& descriptor, IResidencyManager* const pResidencyManager, - CreateHeapFn&& createHeapFn, + CreateHeapFn createHeapFn, + void* createHeapFnContext, IHeap** ppHeapOut) { - return Heap::CreateHeap(descriptor, pResidencyManager, std::move(createHeapFn), ppHeapOut); + return Heap::CreateHeap(descriptor, pResidencyManager, createHeapFn, createHeapFnContext, + ppHeapOut); } // static HRESULT Heap::CreateHeap(const HEAP_DESC& descriptor, IResidencyManager* const pResidencyManager, - CreateHeapFn&& createHeapFn, + CreateHeapFn createHeapFn, + void* createHeapFnContext, IHeap** ppHeapOut) { const bool isResidencyDisabled = (pResidencyManager == nullptr); @@ -79,7 +82,7 @@ namespace gpgmm::d3d12 { } ComPtr pageable; - ReturnIfFailed(createHeapFn(&pageable)); + ReturnIfFailed(createHeapFn(createHeapFnContext, &pageable)); // Pageable-based type is required for residency-managed heaps. if (pageable == nullptr) { diff --git a/src/gpgmm/d3d12/HeapD3D12.h b/src/gpgmm/d3d12/HeapD3D12.h index fc281ddf1..06b2ea152 100644 --- a/src/gpgmm/d3d12/HeapD3D12.h +++ b/src/gpgmm/d3d12/HeapD3D12.h @@ -34,7 +34,8 @@ namespace gpgmm::d3d12 { public: static HRESULT CreateHeap(const HEAP_DESC& descriptor, IResidencyManager* const pResidencyManager, - CreateHeapFn&& createHeapFn, + CreateHeapFn createHeapFn, + void* createHeapFnContext, IHeap** ppHeapOut); ~Heap() override; diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp index 284725770..be44c4f01 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp @@ -1242,18 +1242,12 @@ namespace gpgmm::d3d12 { resourceHeapDesc.SizeInBytes = resourceInfo.SizeInBytes; resourceHeapDesc.Alignment = resourceInfo.Alignment; - IHeap* resourceHeap = nullptr; - ReturnIfFailed(Heap::CreateHeap( - resourceHeapDesc, /*residencyManager*/ nullptr, - [&](ID3D12Pageable** ppPageableOut) -> HRESULT { - ComPtr pageable; - resource.As(&pageable); - - *ppPageableOut = pageable.Detach(); + ImportResourceCallbackContext importResourceCallbackContext(resource); - return S_OK; - }, - &resourceHeap)); + IHeap* resourceHeap = nullptr; + ReturnIfFailed(Heap::CreateHeap(resourceHeapDesc, /*residencyManager*/ nullptr, + ImportResourceCallbackContext::CreateHeapWrapper, + &importResourceCallbackContext, &resourceHeap)); const uint64_t& allocationSize = resourceInfo.SizeInBytes; mStats.UsedMemoryUsage += allocationSize; @@ -1267,9 +1261,9 @@ namespace gpgmm::d3d12 { allocationDesc.OffsetFromResource = 0; if (ppResourceAllocationOut != nullptr){ - *ppResourceAllocationOut = - new ResourceAllocation(allocationDesc, nullptr, this, static_cast(resourceHeap), - nullptr, std::move(resource)); + *ppResourceAllocationOut = new ResourceAllocation(allocationDesc, nullptr, this, + static_cast(resourceHeap), + nullptr, std::move(resource)); } return S_OK; @@ -1326,30 +1320,13 @@ namespace gpgmm::d3d12 { // Since residency is per heap, every committed resource is wrapped in a heap object. IHeap* resourceHeap = nullptr; ComPtr committedResource; + CreateCommittedResourceCallbackContext callbackContext( + mDevice.Get(), committedResource, &heapProperties, heapFlags, resourceDescriptor, + clearValue, initialResourceState); - ReturnIfFailed(Heap::CreateHeap( - resourceHeapDesc, mResidencyManager.Get(), - [&](ID3D12Pageable** ppPageableOut) -> HRESULT { - // Resource heap flags must be inferred by the resource descriptor and cannot be - // explicitly provided to CreateCommittedResource. - heapFlags &= ~(D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES | - D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES | D3D12_HEAP_FLAG_DENY_BUFFERS); - - // Non-custom heaps are not allowed to have the pool-specified. - if (heapProperties.Type != D3D12_HEAP_TYPE_CUSTOM) { - heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - } - - ReturnIfFailed(mDevice->CreateCommittedResource( - &heapProperties, heapFlags, resourceDescriptor, initialResourceState, - clearValue, IID_PPV_ARGS(&committedResource))); - - ComPtr pageable; - ReturnIfFailed(committedResource.As(&pageable)); - *ppPageableOut = pageable.Detach(); - return S_OK; - }, - &resourceHeap)); + ReturnIfFailed(Heap::CreateHeap(resourceHeapDesc, mResidencyManager.Get(), + CreateCommittedResourceCallbackContext::CreateHeapWrapper, + &callbackContext, &resourceHeap)); if (commitedResourceOut != nullptr) { *commitedResourceOut = committedResource.Detach(); @@ -1488,4 +1465,74 @@ namespace gpgmm::d3d12 { return E_INVALIDARG; } + ImportResourceCallbackContext::ImportResourceCallbackContext(ComPtr resource) + : mResource(resource) { + } + + // static + HRESULT ImportResourceCallbackContext::CreateHeapWrapper(void* pContext, + ID3D12Pageable** ppPageableOut) { + ImportResourceCallbackContext* importResourceCallbackContext = + static_cast(pContext); + + return importResourceCallbackContext->CreateHeap(ppPageableOut); + } + + HRESULT ImportResourceCallbackContext::CreateHeap(ID3D12Pageable** ppPageableOut) { + ComPtr pageable; + ReturnIfFailed(mResource.As(&pageable)); + + *ppPageableOut = pageable.Detach(); + + return S_OK; + } + + CreateCommittedResourceCallbackContext::CreateCommittedResourceCallbackContext( + ID3D12Device* device, + ComPtr resource, + D3D12_HEAP_PROPERTIES* heapProperties, + D3D12_HEAP_FLAGS heapFlags, + const D3D12_RESOURCE_DESC* resourceDescriptor, + const D3D12_CLEAR_VALUE* clearValue, + D3D12_RESOURCE_STATES initialResourceState) + : mClearValue(clearValue), + mDevice(device), + mInitialResourceState(initialResourceState), + mHeapFlags(heapFlags), + mHeapProperties(heapProperties), + mResource(resource), + mResourceDescriptor(resourceDescriptor) { + } + + // static + HRESULT CreateCommittedResourceCallbackContext::CreateHeapWrapper( + void* pContext, + ID3D12Pageable** ppPageableOut) { + CreateCommittedResourceCallbackContext* createCommittedResourceCallbackContext = + static_cast(pContext); + + return createCommittedResourceCallbackContext->CreateHeap(ppPageableOut); + } + + HRESULT CreateCommittedResourceCallbackContext::CreateHeap(ID3D12Pageable** ppPageableOut) { + // Resource heap flags must be inferred by the resource descriptor and cannot be + // explicitly provided to CreateCommittedResource. + mHeapFlags &= ~(D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES | + D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES | D3D12_HEAP_FLAG_DENY_BUFFERS); + + // Non-custom heaps are not allowed to have the pool-specified. + if (mHeapProperties->Type != D3D12_HEAP_TYPE_CUSTOM) { + mHeapProperties->MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + } + + ReturnIfFailed(mDevice->CreateCommittedResource(mHeapProperties, mHeapFlags, + mResourceDescriptor, mInitialResourceState, + mClearValue, IID_PPV_ARGS(&mResource))); + + ComPtr pageable; + ReturnIfFailed(mResource.As(&pageable)); + *ppPageableOut = pageable.Detach(); + return S_OK; + } + } // namespace gpgmm::d3d12 diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.h b/src/gpgmm/d3d12/ResourceAllocatorD3D12.h index cb16a5224..933d63fc6 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.h +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.h @@ -35,6 +35,41 @@ namespace gpgmm::d3d12 { class ResidencyManager; class ResourceAllocation; + class ImportResourceCallbackContext { + public: + ImportResourceCallbackContext(ComPtr resource); + static HRESULT CreateHeapWrapper(void* pContext, ID3D12Pageable** ppPageableOut); + + private: + HRESULT CreateHeap(ID3D12Pageable** ppPageableOut); + + ComPtr mResource; + }; + + class CreateCommittedResourceCallbackContext { + public: + CreateCommittedResourceCallbackContext(ID3D12Device* device, + ComPtr resource, + D3D12_HEAP_PROPERTIES* heapProperties, + D3D12_HEAP_FLAGS heapFlags, + const D3D12_RESOURCE_DESC* resourceDescriptor, + const D3D12_CLEAR_VALUE* clearValue, + D3D12_RESOURCE_STATES initialResourceState); + + static HRESULT CreateHeapWrapper(void* pContext, ID3D12Pageable** ppPageableOut); + + private: + HRESULT CreateHeap(ID3D12Pageable** ppPageableOut); + + const D3D12_CLEAR_VALUE* mClearValue; + ID3D12Device* mDevice; + D3D12_RESOURCE_STATES mInitialResourceState; + D3D12_HEAP_FLAGS mHeapFlags; + D3D12_HEAP_PROPERTIES* mHeapProperties; + ComPtr mResource; + const D3D12_RESOURCE_DESC* mResourceDescriptor; + }; + class ResourceAllocator final : public IUnknownImpl, public IResourceAllocator, public MemoryAllocator { diff --git a/src/gpgmm/d3d12/ResourceHeapAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceHeapAllocatorD3D12.cpp index c19cc102e..33f37b386 100644 --- a/src/gpgmm/d3d12/ResourceHeapAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceHeapAllocatorD3D12.cpp @@ -62,29 +62,17 @@ namespace gpgmm::d3d12 { mHeapProperties.MemoryPoolPreference, mResidencyManager->IsUMA()); } + D3D12_HEAP_DESC heapDesc = {}; + heapDesc.Properties = mHeapProperties; + heapDesc.SizeInBytes = resourceHeapDesc.SizeInBytes; + heapDesc.Alignment = resourceHeapDesc.Alignment; + heapDesc.Flags = mHeapFlags; + + CreateResourceHeapCallbackContext createResourceHeapCallbackContext(mDevice, &heapDesc); IHeap* resourceHeap = nullptr; - if (FAILED(Heap::CreateHeap( - resourceHeapDesc, mResidencyManager, - [&](ID3D12Pageable** ppPageableOut) -> HRESULT { - D3D12_HEAP_DESC heapDesc = {}; - heapDesc.Properties = mHeapProperties; - heapDesc.SizeInBytes = resourceHeapDesc.SizeInBytes; - heapDesc.Alignment = resourceHeapDesc.Alignment; - heapDesc.Flags = mHeapFlags; - - // Non-custom heaps are not allowed to have the pool-specified. - if (heapDesc.Properties.Type != D3D12_HEAP_TYPE_CUSTOM) { - heapDesc.Properties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - } - - ComPtr heap; - ReturnIfFailed(mDevice->CreateHeap(&heapDesc, IID_PPV_ARGS(&heap))); - - *ppPageableOut = heap.Detach(); - - return S_OK; - }, - &resourceHeap))) { + if (FAILED(Heap::CreateHeap(resourceHeapDesc, mResidencyManager, + CreateResourceHeapCallbackContext::CreateHeapWrapper, + &createResourceHeapCallbackContext, &resourceHeap))) { return {}; } @@ -116,4 +104,31 @@ namespace gpgmm::d3d12 { return "ResourceHeapAllocator"; } + CreateResourceHeapCallbackContext::CreateResourceHeapCallbackContext(ID3D12Device* device, + D3D12_HEAP_DESC* heapDesc) + : mDevice(device), mHeapDesc(heapDesc) { + } + + HRESULT CreateResourceHeapCallbackContext::CreateHeapWrapper(void* pContext, + ID3D12Pageable** ppPageableOut) { + CreateResourceHeapCallbackContext* createResourceHeapCallbackContext = + static_cast(pContext); + + return createResourceHeapCallbackContext->CreateHeap(ppPageableOut); + } + + HRESULT CreateResourceHeapCallbackContext::CreateHeap(ID3D12Pageable** ppPageableOut) { + // Non-custom heaps are not allowed to have the pool-specified. + if (mHeapDesc->Properties.Type != D3D12_HEAP_TYPE_CUSTOM) { + mHeapDesc->Properties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + } + + ComPtr heap; + ReturnIfFailed(mDevice->CreateHeap(mHeapDesc, IID_PPV_ARGS(&heap))); + + *ppPageableOut = heap.Detach(); + + return S_OK; + } + } // namespace gpgmm::d3d12 diff --git a/src/gpgmm/d3d12/ResourceHeapAllocatorD3D12.h b/src/gpgmm/d3d12/ResourceHeapAllocatorD3D12.h index 393e5e3d4..737cb54c5 100644 --- a/src/gpgmm/d3d12/ResourceHeapAllocatorD3D12.h +++ b/src/gpgmm/d3d12/ResourceHeapAllocatorD3D12.h @@ -23,6 +23,18 @@ namespace gpgmm::d3d12 { class ResidencyManager; + class CreateResourceHeapCallbackContext { + public: + CreateResourceHeapCallbackContext(ID3D12Device* device, D3D12_HEAP_DESC* heapDesc); + static HRESULT CreateHeapWrapper(void* pContext, ID3D12Pageable** ppPageableOut); + + private: + HRESULT CreateHeap(ID3D12Pageable** ppPageableOut); + + ID3D12Device* mDevice; + D3D12_HEAP_DESC* mHeapDesc; + }; + // Wrapper to allocate a D3D12 heap for resources of any type. class ResourceHeapAllocator final : public MemoryAllocator { public: diff --git a/src/mvi/gpgmm_d3d12.cpp b/src/mvi/gpgmm_d3d12.cpp index 3e7c253a4..adf337574 100644 --- a/src/mvi/gpgmm_d3d12.cpp +++ b/src/mvi/gpgmm_d3d12.cpp @@ -75,10 +75,11 @@ namespace gpgmm::d3d12 { // static HRESULT Heap::CreateHeap(const HEAP_DESC& descriptor, IResidencyManager* const pResidencyManager, - CreateHeapFn&& createHeapFn, + CreateHeapFn createHeapFn, + void* context, IHeap** ppHeapOut) { Microsoft::WRL::ComPtr pageable; - ReturnIfFailed(createHeapFn(&pageable)); + ReturnIfFailed(createHeapFn(context, &pageable)); if (ppHeapOut != nullptr) { *ppHeapOut = new Heap(pageable, descriptor, (pResidencyManager == nullptr)); @@ -355,22 +356,13 @@ namespace gpgmm::d3d12 { resourceHeapDesc.SizeInBytes = resourceInfo.SizeInBytes; resourceHeapDesc.Alignment = resourceInfo.Alignment; - ReturnIfFailed(Heap::CreateHeap( - resourceHeapDesc, mResidencyManager.Get(), - [&](ID3D12Pageable** ppPageableOut) -> HRESULT { - D3D12_HEAP_PROPERTIES heapProperties = {}; - heapProperties.Type = allocationDescriptor.HeapType; + CreateCommittedResourceCallbackContext callbackContext( + mDevice.Get(), allocationDescriptor, committedResource, &resourceDescriptor, + pClearValue, initialResourceState); - ReturnIfFailed(mDevice->CreateCommittedResource( - &heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDescriptor, - initialResourceState, pClearValue, IID_PPV_ARGS(&committedResource))); - - Microsoft::WRL::ComPtr pageable; - ReturnIfFailed(committedResource.As(&pageable)); - *ppPageableOut = pageable.Detach(); - return S_OK; - }, - &resourceHeap)); + ReturnIfFailed(Heap::CreateHeap(resourceHeapDesc, mResidencyManager.Get(), + CreateCommittedResourceCallbackContext::CreateHeapWrapper, + &callbackContext, &resourceHeap)); const uint64_t allocationSize = resourceHeapDesc.SizeInBytes; mStats.UsedMemoryUsage += allocationSize; @@ -433,4 +425,41 @@ namespace gpgmm::d3d12 { return IUnknownImpl::Release(); } + CreateCommittedResourceCallbackContext::CreateCommittedResourceCallbackContext( + ID3D12Device* device, + ALLOCATION_DESC allocationDescriptor, + Microsoft::WRL::ComPtr resource, + const D3D12_RESOURCE_DESC* resourceDescriptor, + const D3D12_CLEAR_VALUE* clearValue, + D3D12_RESOURCE_STATES initialResourceState) + : mDevice(device), + mAllocationDescriptor(allocationDescriptor), + mClearValue(clearValue), + mResource(resource), + mResourceDescriptor(resourceDescriptor) { + } + + HRESULT CreateCommittedResourceCallbackContext::CreateHeap(ID3D12Pageable** ppPageableOut) { + D3D12_HEAP_PROPERTIES heapProperties = {}; + heapProperties.Type = mAllocationDescriptor.HeapType; + + ReturnIfFailed(mDevice->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, + mResourceDescriptor, mInitialResourceState, + mClearValue, IID_PPV_ARGS(&mResource))); + + Microsoft::WRL::ComPtr pageable; + ReturnIfFailed(mResource.As(&pageable)); + *ppPageableOut = pageable.Detach(); + return S_OK; + } + + HRESULT CreateCommittedResourceCallbackContext::CreateHeapWrapper( + void* context, + ID3D12Pageable** ppPageableOut) { + CreateCommittedResourceCallbackContext* createCommittedResourceCallbackContext = + static_cast(context); + + return createCommittedResourceCallbackContext->CreateHeap(ppPageableOut); + } + } // namespace gpgmm::d3d12 diff --git a/src/mvi/gpgmm_d3d12.h b/src/mvi/gpgmm_d3d12.h index 78e52fa4c..822694c10 100644 --- a/src/mvi/gpgmm_d3d12.h +++ b/src/mvi/gpgmm_d3d12.h @@ -64,7 +64,8 @@ namespace gpgmm::d3d12 { public: static HRESULT CreateHeap(const HEAP_DESC& descriptor, IResidencyManager* const pResidencyManager, - CreateHeapFn&& createHeapFn, + CreateHeapFn createHeapFn, + void* context, IHeap** ppHeapOut); // IHeap interface @@ -172,6 +173,27 @@ namespace gpgmm::d3d12 { Microsoft::WRL::ComPtr mResource; }; + class CreateCommittedResourceCallbackContext { + public: + CreateCommittedResourceCallbackContext(ID3D12Device* device, + ALLOCATION_DESC allocationDescriptor, + Microsoft::WRL::ComPtr resource, + const D3D12_RESOURCE_DESC* resourceDescriptor, + const D3D12_CLEAR_VALUE* clearValue, + D3D12_RESOURCE_STATES initialResourceState); + static HRESULT CreateHeapWrapper(void* context, ID3D12Pageable** ppPageableOut); + + private: + HRESULT CreateHeap(ID3D12Pageable** ppPageableOut); + + ID3D12Device* mDevice; + ALLOCATION_DESC mAllocationDescriptor; + const D3D12_CLEAR_VALUE* mClearValue; + D3D12_RESOURCE_STATES mInitialResourceState; + Microsoft::WRL::ComPtr mResource; + const D3D12_RESOURCE_DESC* mResourceDescriptor; + }; + class ResourceAllocator final : public MemoryAllocator, public IUnknownImpl, public IResourceAllocator { diff --git a/src/tests/capture_replay_tests/D3D12EventTraceReplay.cpp b/src/tests/capture_replay_tests/D3D12EventTraceReplay.cpp index 6e7e01091..a33e7f210 100644 --- a/src/tests/capture_replay_tests/D3D12EventTraceReplay.cpp +++ b/src/tests/capture_replay_tests/D3D12EventTraceReplay.cpp @@ -19,6 +19,7 @@ #include "gpgmm/common/TraceEventPhase.h" #include "gpgmm/d3d12/CapsD3D12.h" #include "gpgmm/d3d12/ErrorD3D12.h" +#include "gpgmm/d3d12/ResourceHeapAllocatorD3D12.h" #include "gpgmm/d3d12/UtilsD3D12.h" #include "gpgmm/utils/Log.h" #include "gpgmm/utils/PlatformTime.h" @@ -539,25 +540,23 @@ class D3D12EventTraceReplay : public D3D12TestBase, public CaptureReplayTestWith .Get(); ASSERT_NE(residencyManager, nullptr); + D3D12_HEAP_FLAGS heapFlags = + static_cast(args["Heap"]["Flags"].asInt()); + + D3D12_HEAP_DESC heapDesc = {}; + heapDesc.Properties = heapProperties; + heapDesc.SizeInBytes = resourceHeapDesc.SizeInBytes; + heapDesc.Alignment = resourceHeapDesc.Alignment; + heapDesc.Flags = heapFlags; + + CreateResourceHeapCallbackContext createHeapContext(mDevice.Get(), + &heapDesc); + ComPtr resourceHeap; - ASSERT_SUCCEEDED(CreateHeap( - resourceHeapDesc, residencyManager, - [&](ID3D12Pageable** ppPageableOut) -> HRESULT { - D3D12_HEAP_DESC heapDesc = {}; - heapDesc.Properties = heapProperties; - heapDesc.SizeInBytes = resourceHeapDesc.SizeInBytes; - heapDesc.Alignment = resourceHeapDesc.Alignment; - heapDesc.Flags = - static_cast(args["Heap"]["Flags"].asInt()); - - ComPtr heap; - ReturnIfFailed(mDevice->CreateHeap(&heapDesc, IID_PPV_ARGS(&heap))); - - *ppPageableOut = heap.Detach(); - - return S_OK; - }, - &resourceHeap)); + ASSERT_SUCCEEDED( + CreateHeap(resourceHeapDesc, residencyManager, + CreateResourceHeapCallbackContext::CreateHeapWrapper, + &createHeapContext, &resourceHeap)); playbackContext.CurrentHeapWithoutID = std::move(resourceHeap); diff --git a/src/tests/end2end/D3D12ResidencyManagerTests.cpp b/src/tests/end2end/D3D12ResidencyManagerTests.cpp index e68660cd6..791926bd7 100644 --- a/src/tests/end2end/D3D12ResidencyManagerTests.cpp +++ b/src/tests/end2end/D3D12ResidencyManagerTests.cpp @@ -16,6 +16,7 @@ #include "gpgmm/common/SizeClass.h" #include "gpgmm/d3d12/CapsD3D12.h" +#include "gpgmm/d3d12/ResourceHeapAllocatorD3D12.h" #include "gpgmm/d3d12/UtilsD3D12.h" #include @@ -75,6 +76,46 @@ class D3D12ResidencyManagerTests : public D3D12TestBase, public ::testing::Test return (segment.Budget > segment.CurrentUsage) ? (segment.Budget - segment.CurrentUsage) : 0; } + + class CreateDescHeapCallbackContext { + public: + CreateDescHeapCallbackContext(ID3D12Device* device, D3D12_DESCRIPTOR_HEAP_DESC descHeapDesc) + : mDevice(device), mDescHeapDesc(descHeapDesc) { + } + static HRESULT CreateHeapWrapper(void* pContext, ID3D12Pageable** ppPageableOut) { + CreateDescHeapCallbackContext* createDescHeapCallbackContext = + static_cast(pContext); + return createDescHeapCallbackContext->CreateHeap(ppPageableOut); + } + + private: + HRESULT CreateHeap(ID3D12Pageable** ppPageableOut) { + ComPtr heap; + if (FAILED(mDevice->CreateDescriptorHeap(&mDescHeapDesc, IID_PPV_ARGS(&heap)))) { + return E_FAIL; + } + *ppPageableOut = heap.Detach(); + return S_OK; + } + ID3D12Device* mDevice; + D3D12_DESCRIPTOR_HEAP_DESC mDescHeapDesc; + }; + + class BadCreateHeapCallbackContext { + public: + BadCreateHeapCallbackContext() { + } + static HRESULT CreateHeapWrapper(void* pContext, ID3D12Pageable** ppPageableOut) { + BadCreateHeapCallbackContext* badCreateHeapCallbackContext = + static_cast(pContext); + return badCreateHeapCallbackContext->CreateHeap(ppPageableOut); + } + + private: + HRESULT CreateHeap(ID3D12Pageable** ppPageableOut) { + return S_OK; + } + }; }; TEST_F(D3D12ResidencyManagerTests, CreateResourceHeapNotResident) { @@ -95,26 +136,17 @@ TEST_F(D3D12ResidencyManagerTests, CreateResourceHeapNotResident) { resourceHeapAlwaysInBudgetDesc.MemorySegmentGroup = DXGI_MEMORY_SEGMENT_GROUP_LOCAL; resourceHeapAlwaysInBudgetDesc.Flags |= HEAP_FLAG_ALWAYS_IN_BUDGET; - auto createHeapNotResidentFn = [&](ID3D12Pageable** ppPageableOut) -> HRESULT { - D3D12_HEAP_DESC heapDesc = {}; - heapDesc.Properties = heapProperties; - heapDesc.SizeInBytes = kHeapSize; - - // Assume tier 1, which all adapters support. - heapDesc.Flags |= D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS; - - heapDesc.Flags |= D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT; + D3D12_HEAP_DESC heapDesc; + heapDesc.Properties = heapProperties; + heapDesc.SizeInBytes = kHeapSize; + heapDesc.Flags |= D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS; + heapDesc.Flags |= D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT; - ComPtr heap; - if (FAILED(mDevice->CreateHeap(&heapDesc, IID_PPV_ARGS(&heap)))) { - return E_FAIL; - } - *ppPageableOut = heap.Detach(); - return S_OK; - }; + CreateResourceHeapCallbackContext createHeapContext(mDevice.Get(), &heapDesc); ASSERT_FAILED(CreateHeap(resourceHeapAlwaysInBudgetDesc, residencyManager.Get(), - createHeapNotResidentFn, nullptr)); + CreateResourceHeapCallbackContext::CreateHeapWrapper, + &createHeapContext, nullptr)); } TEST_F(D3D12ResidencyManagerTests, CreateResourceHeap) { @@ -134,31 +166,26 @@ TEST_F(D3D12ResidencyManagerTests, CreateResourceHeap) { // Assume tier 1, which all adapters support. heapDesc.Flags |= D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS; - auto createHeapFn = [&](ID3D12Pageable** ppPageableOut) -> HRESULT { - ComPtr heap; - if (FAILED(mDevice->CreateHeap(&heapDesc, IID_PPV_ARGS(&heap)))) { - return E_FAIL; - } - *ppPageableOut = heap.Detach(); - return S_OK; - }; - - auto badCreateHeapFn = [&](ID3D12Pageable** ppPageableOut) -> HRESULT { - // No pageable set should E_FAIL. - return S_OK; - }; + CreateResourceHeapCallbackContext createHeapContext(mDevice.Get(), &heapDesc); + BadCreateHeapCallbackContext badCreateHeapCallbackContext; HEAP_DESC resourceHeapDesc = {}; resourceHeapDesc.SizeInBytes = kHeapSize; resourceHeapDesc.MemorySegmentGroup = DXGI_MEMORY_SEGMENT_GROUP_LOCAL; - ASSERT_FAILED(CreateHeap(resourceHeapDesc, residencyManager.Get(), badCreateHeapFn, nullptr)); + ASSERT_FAILED(CreateHeap(resourceHeapDesc, residencyManager.Get(), + BadCreateHeapCallbackContext::CreateHeapWrapper, + &badCreateHeapCallbackContext, nullptr)); - ASSERT_SUCCEEDED(CreateHeap(resourceHeapDesc, residencyManager.Get(), createHeapFn, nullptr)); + ASSERT_SUCCEEDED(CreateHeap(resourceHeapDesc, residencyManager.Get(), + CreateResourceHeapCallbackContext::CreateHeapWrapper, + &createHeapContext, nullptr)); // Create a resource heap without residency. ComPtr resourceHeap; - ASSERT_SUCCEEDED(CreateHeap(resourceHeapDesc, nullptr, createHeapFn, &resourceHeap)); + ASSERT_SUCCEEDED(CreateHeap(resourceHeapDesc, nullptr, + CreateResourceHeapCallbackContext::CreateHeapWrapper, + &createHeapContext, &resourceHeap)); // Ensure the unmanaged resource heap state is always unknown. Even though D3D12 implicitly // creates heaps as resident, untrack resource heaps would never transition out from @@ -167,8 +194,9 @@ TEST_F(D3D12ResidencyManagerTests, CreateResourceHeap) { EXPECT_EQ(resourceHeap->GetInfo().IsLocked, false); // Create a resource heap with residency. - ASSERT_SUCCEEDED( - CreateHeap(resourceHeapDesc, residencyManager.Get(), createHeapFn, &resourceHeap)); + ASSERT_SUCCEEDED(CreateHeap(resourceHeapDesc, residencyManager.Get(), + CreateResourceHeapCallbackContext::CreateHeapWrapper, + &createHeapContext, &resourceHeap)); ASSERT_NE(resourceHeap, nullptr); EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_STATUS_CURRENT_RESIDENT); @@ -217,18 +245,12 @@ TEST_F(D3D12ResidencyManagerTests, CreateDescriptorHeap) { heapDesc.NumDescriptors * mDevice->GetDescriptorHandleIncrementSize(heapDesc.Type); descriptorHeapDesc.MemorySegmentGroup = DXGI_MEMORY_SEGMENT_GROUP_LOCAL; - auto createHeapFn = [&](ID3D12Pageable** ppPageableOut) -> HRESULT { - ComPtr heap; - if (FAILED(mDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&heap)))) { - return E_FAIL; - } - *ppPageableOut = heap.Detach(); - return S_OK; - }; + CreateDescHeapCallbackContext createDescHeapCallbackContext(mDevice.Get(), heapDesc); ComPtr descriptorHeap; - ASSERT_SUCCEEDED( - CreateHeap(descriptorHeapDesc, residencyManager.Get(), createHeapFn, &descriptorHeap)); + ASSERT_SUCCEEDED(CreateHeap(descriptorHeapDesc, residencyManager.Get(), + CreateDescHeapCallbackContext::CreateHeapWrapper, + &createDescHeapCallbackContext, &descriptorHeap)); EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_STATUS_UNKNOWN); EXPECT_EQ(descriptorHeap->GetInfo().IsLocked, false);