D3D12: Enable sub-allocation for MSAA and non-MSAA textures.
Updates TextureD3D to use the allocation handle and
defaults to using MSAA heaps.
BUG=dawn:27
Change-Id: I2318bb8d068df86364cb2ebc433f4737e9e121aa
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/12580
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
diff --git a/BUILD.gn b/BUILD.gn
index 2e9eff0..3606ba7 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -291,8 +291,6 @@
"src/dawn_native/d3d12/QueueD3D12.h",
"src/dawn_native/d3d12/RenderPipelineD3D12.cpp",
"src/dawn_native/d3d12/RenderPipelineD3D12.h",
- "src/dawn_native/d3d12/ResourceAllocator.cpp",
- "src/dawn_native/d3d12/ResourceAllocator.h",
"src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp",
"src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.h",
"src/dawn_native/d3d12/ResourceHeapAllocationD3D12.cpp",
diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.cpp b/src/dawn_native/d3d12/CommandBufferD3D12.cpp
index 301ac97..f1431db 100644
--- a/src/dawn_native/d3d12/CommandBufferD3D12.cpp
+++ b/src/dawn_native/d3d12/CommandBufferD3D12.cpp
@@ -29,7 +29,6 @@
#include "dawn_native/d3d12/PipelineLayoutD3D12.h"
#include "dawn_native/d3d12/PlatformFunctions.h"
#include "dawn_native/d3d12/RenderPipelineD3D12.h"
-#include "dawn_native/d3d12/ResourceAllocator.h"
#include "dawn_native/d3d12/SamplerD3D12.h"
#include "dawn_native/d3d12/TextureCopySplitter.h"
#include "dawn_native/d3d12/TextureD3D12.h"
diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp
index 2cc42ec..40097bf 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn_native/d3d12/DeviceD3D12.cpp
@@ -31,7 +31,6 @@
#include "dawn_native/d3d12/PlatformFunctions.h"
#include "dawn_native/d3d12/QueueD3D12.h"
#include "dawn_native/d3d12/RenderPipelineD3D12.h"
-#include "dawn_native/d3d12/ResourceAllocator.h"
#include "dawn_native/d3d12/ResourceAllocatorManagerD3D12.h"
#include "dawn_native/d3d12/SamplerD3D12.h"
#include "dawn_native/d3d12/ShaderModuleD3D12.h"
@@ -72,7 +71,6 @@
mCommandAllocatorManager = std::make_unique<CommandAllocatorManager>(this);
mDescriptorHeapAllocator = std::make_unique<DescriptorHeapAllocator>(this);
mMapRequestTracker = std::make_unique<MapRequestTracker>(this);
- mResourceAllocator = std::make_unique<ResourceAllocator>(this);
mResourceAllocatorManager = std::make_unique<ResourceAllocatorManager>(this);
DAWN_TRY(NextSerial());
@@ -125,10 +123,6 @@
// MAX.
mCompletedSerial = std::numeric_limits<Serial>::max();
- // Releasing the uploader enqueues buffers to be released.
- // Call Tick() again to clear them before releasing the allocator.
- mResourceAllocator->Tick(mCompletedSerial);
-
if (mFenceEvent != nullptr) {
::CloseHandle(mFenceEvent);
}
@@ -175,10 +169,6 @@
return mMapRequestTracker.get();
}
- ResourceAllocator* Device::GetResourceAllocator() const {
- return mResourceAllocator.get();
- }
-
CommandAllocatorManager* Device::GetCommandAllocatorManager() const {
return mCommandAllocatorManager.get();
}
@@ -212,7 +202,6 @@
// as it enqueued resources to be released.
mDynamicUploader->Deallocate(mCompletedSerial);
- mResourceAllocator->Tick(mCompletedSerial);
mResourceAllocatorManager->Tick(mCompletedSerial);
DAWN_TRY(mCommandAllocatorManager->Tick(mCompletedSerial));
mDescriptorHeapAllocator->Deallocate(mCompletedSerial);
diff --git a/src/dawn_native/d3d12/DeviceD3D12.h b/src/dawn_native/d3d12/DeviceD3D12.h
index 98ae4f1..4aa27ff 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.h
+++ b/src/dawn_native/d3d12/DeviceD3D12.h
@@ -31,7 +31,6 @@
class DescriptorHeapAllocator;
class MapRequestTracker;
class PlatformFunctions;
- class ResourceAllocator;
class ResourceAllocatorManager;
#define ASSERT_SUCCESS(hr) \
@@ -64,7 +63,6 @@
DescriptorHeapAllocator* GetDescriptorHeapAllocator() const;
MapRequestTracker* GetMapRequestTracker() const;
- ResourceAllocator* GetResourceAllocator() const;
CommandAllocatorManager* GetCommandAllocatorManager() const;
const PlatformFunctions* GetFunctions() const;
@@ -147,7 +145,6 @@
std::unique_ptr<CommandAllocatorManager> mCommandAllocatorManager;
std::unique_ptr<DescriptorHeapAllocator> mDescriptorHeapAllocator;
std::unique_ptr<MapRequestTracker> mMapRequestTracker;
- std::unique_ptr<ResourceAllocator> mResourceAllocator;
std::unique_ptr<ResourceAllocatorManager> mResourceAllocatorManager;
dawn_native::PCIInfo mPCIInfo;
diff --git a/src/dawn_native/d3d12/HeapAllocatorD3D12.cpp b/src/dawn_native/d3d12/HeapAllocatorD3D12.cpp
index 8cd5640..59507ab 100644
--- a/src/dawn_native/d3d12/HeapAllocatorD3D12.cpp
+++ b/src/dawn_native/d3d12/HeapAllocatorD3D12.cpp
@@ -32,9 +32,11 @@
heapDesc.Properties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
heapDesc.Properties.CreationNodeMask = 0;
heapDesc.Properties.VisibleNodeMask = 0;
- // MSAA vs non-MSAA resources have separate heap alignments.
- // TODO(bryan.bernhart@intel.com): Support heap creation containing MSAA resources.
- heapDesc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
+ // It is preferred to use a size that is a multiple of the alignment.
+ // However, MSAA heaps are always aligned to 4MB instead of 64KB. This means
+ // if the heap size is too small, the VMM would fragment.
+ // TODO(bryan.bernhart@intel.com): Consider having MSAA vs non-MSAA heaps.
+ heapDesc.Alignment = D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT;
heapDesc.Flags = mHeapFlags;
ComPtr<ID3D12Heap> heap;
diff --git a/src/dawn_native/d3d12/ResourceAllocator.cpp b/src/dawn_native/d3d12/ResourceAllocator.cpp
deleted file mode 100644
index e2822e6..0000000
--- a/src/dawn_native/d3d12/ResourceAllocator.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2017 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.
-
-#include "dawn_native/d3d12/ResourceAllocator.h"
-
-#include "dawn_native/d3d12/DeviceD3D12.h"
-
-namespace dawn_native { namespace d3d12 {
-
- namespace {
- static constexpr D3D12_HEAP_PROPERTIES kDefaultHeapProperties = {
- D3D12_HEAP_TYPE_DEFAULT, D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_MEMORY_POOL_UNKNOWN, 0,
- 0};
-
- static constexpr D3D12_HEAP_PROPERTIES kUploadHeapProperties = {
- D3D12_HEAP_TYPE_UPLOAD, D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_MEMORY_POOL_UNKNOWN, 0,
- 0};
-
- static constexpr D3D12_HEAP_PROPERTIES kReadbackHeapProperties = {
- D3D12_HEAP_TYPE_READBACK, D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_MEMORY_POOL_UNKNOWN, 0,
- 0};
- } // namespace
-
- ResourceAllocator::ResourceAllocator(Device* device) : mDevice(device) {
- }
-
- ComPtr<ID3D12Resource> ResourceAllocator::Allocate(
- D3D12_HEAP_TYPE heapType,
- const D3D12_RESOURCE_DESC& resourceDescriptor,
- D3D12_RESOURCE_STATES initialUsage) {
- const D3D12_HEAP_PROPERTIES* heapProperties = nullptr;
- switch (heapType) {
- case D3D12_HEAP_TYPE_DEFAULT:
- heapProperties = &kDefaultHeapProperties;
- break;
- case D3D12_HEAP_TYPE_UPLOAD:
- heapProperties = &kUploadHeapProperties;
- break;
- case D3D12_HEAP_TYPE_READBACK:
- heapProperties = &kReadbackHeapProperties;
- break;
- default:
- UNREACHABLE();
- }
-
- ComPtr<ID3D12Resource> resource;
-
- // TODO(enga@google.com): Use CreatePlacedResource
- ASSERT_SUCCESS(mDevice->GetD3D12Device()->CreateCommittedResource(
- heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDescriptor, initialUsage, nullptr,
- IID_PPV_ARGS(&resource)));
-
- return resource;
- }
-
- void ResourceAllocator::Release(ComPtr<ID3D12Resource> resource) {
- // Resources may still be in use on the GPU. Enqueue them so that we hold onto them until
- // GPU execution has completed
- mReleasedResources.Enqueue(resource, mDevice->GetPendingCommandSerial());
- }
-
- void ResourceAllocator::Tick(uint64_t lastCompletedSerial) {
- mReleasedResources.ClearUpTo(lastCompletedSerial);
- }
-
-}} // namespace dawn_native::d3d12
diff --git a/src/dawn_native/d3d12/ResourceAllocator.h b/src/dawn_native/d3d12/ResourceAllocator.h
deleted file mode 100644
index 9311db6..0000000
--- a/src/dawn_native/d3d12/ResourceAllocator.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 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.
-
-#ifndef DAWNNATIVE_D3D12_RESOURCEALLOCATIONMANAGER_H_
-#define DAWNNATIVE_D3D12_RESOURCEALLOCATIONMANAGER_H_
-
-#include "dawn_native/d3d12/d3d12_platform.h"
-
-#include "common/SerialQueue.h"
-
-namespace dawn_native { namespace d3d12 {
-
- class Device;
-
- class ResourceAllocator {
- public:
- ResourceAllocator(Device* device);
-
- ComPtr<ID3D12Resource> Allocate(D3D12_HEAP_TYPE heapType,
- const D3D12_RESOURCE_DESC& resourceDescriptor,
- D3D12_RESOURCE_STATES initialUsage);
- void Release(ComPtr<ID3D12Resource> resource);
- void Tick(uint64_t lastCompletedSerial);
-
- private:
- Device* mDevice;
-
- SerialQueue<ComPtr<ID3D12Resource>> mReleasedResources;
- };
-
-}} // namespace dawn_native::d3d12
-
-#endif // DAWNNATIVE_D3D12_RESOURCEALLOCATIONMANAGER_H_
diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp
index bcb3c39..9caf2f3 100644
--- a/src/dawn_native/d3d12/TextureD3D12.cpp
+++ b/src/dawn_native/d3d12/TextureD3D12.cpp
@@ -22,7 +22,7 @@
#include "dawn_native/d3d12/D3D12Error.h"
#include "dawn_native/d3d12/DescriptorHeapAllocator.h"
#include "dawn_native/d3d12/DeviceD3D12.h"
-#include "dawn_native/d3d12/ResourceAllocator.h"
+#include "dawn_native/d3d12/ResourceAllocatorManagerD3D12.h"
#include "dawn_native/d3d12/StagingBufferD3D12.h"
#include "dawn_native/d3d12/TextureCopySplitter.h"
#include "dawn_native/d3d12/UtilsD3D12.h"
@@ -313,7 +313,10 @@
mAcquireMutexKey = acquireMutexKey;
mDxgiKeyedMutex = std::move(dxgiKeyedMutex);
- mResource = std::move(d3d12Resource);
+
+ AllocationInfo info;
+ info.mMethod = AllocationMethod::kDirect;
+ mResourceAllocation = {info, 0, std::move(d3d12Resource)};
SetIsSubresourceContentInitialized(true, 0, descriptor->mipLevelCount, 0,
descriptor->arrayLayerCount);
@@ -340,10 +343,10 @@
resourceDescriptor.Flags =
D3D12ResourceFlags(GetUsage(), GetFormat(), IsMultisampledTexture());
- mResource = ToBackend(GetDevice())
- ->GetResourceAllocator()
- ->Allocate(D3D12_HEAP_TYPE_DEFAULT, resourceDescriptor,
- D3D12_RESOURCE_STATE_COMMON);
+ DAWN_TRY_ASSIGN(mResourceAllocation,
+ ToBackend(GetDevice())
+ ->AllocateMemory(D3D12_HEAP_TYPE_DEFAULT, resourceDescriptor,
+ D3D12_RESOURCE_STATE_COMMON));
Device* device = ToBackend(GetDevice());
@@ -361,8 +364,11 @@
Texture::Texture(Device* device,
const TextureDescriptor* descriptor,
ComPtr<ID3D12Resource> nativeTexture)
- : TextureBase(device, descriptor, TextureState::OwnedExternal),
- mResource(std::move(nativeTexture)) {
+ : TextureBase(device, descriptor, TextureState::OwnedExternal) {
+ AllocationInfo info;
+ info.mMethod = AllocationMethod::kDirect;
+ mResourceAllocation = {info, 0, std::move(nativeTexture)};
+
SetIsSubresourceContentInitialized(true, 0, descriptor->mipLevelCount, 0,
descriptor->arrayLayerCount);
}
@@ -373,7 +379,7 @@
void Texture::DestroyImpl() {
Device* device = ToBackend(GetDevice());
- device->GetResourceAllocator()->Release(std::move(mResource));
+ device->DeallocateMemory(mResourceAllocation);
if (mDxgiKeyedMutex != nullptr) {
mDxgiKeyedMutex->ReleaseSync(mAcquireMutexKey + 1);
@@ -386,7 +392,7 @@
}
ID3D12Resource* Texture::GetD3D12Resource() const {
- return mResource.Get();
+ return mResourceAllocation.GetD3D12Resource().Get();
}
UINT16 Texture::GetDepthOrArraySize() {
@@ -476,7 +482,7 @@
barrier->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier->Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
- barrier->Transition.pResource = mResource.Get();
+ barrier->Transition.pResource = GetD3D12Resource();
barrier->Transition.StateBefore = lastState;
barrier->Transition.StateAfter = newState;
barrier->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
@@ -570,7 +576,7 @@
D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1));
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = dsvHeap.GetCPUHandle(0);
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = GetDSVDescriptor(baseMipLevel);
- device->GetD3D12Device()->CreateDepthStencilView(mResource.Get(), &dsvDesc,
+ device->GetD3D12Device()->CreateDepthStencilView(GetD3D12Resource(), &dsvDesc,
dsvHandle);
D3D12_CLEAR_FLAGS clearFlags = {};
@@ -597,7 +603,7 @@
for (uint32_t i = baseMipLevel; i < baseMipLevel + levelCount; i++) {
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc =
GetRTVDescriptor(i, baseArrayLayer, layerCount);
- device->GetD3D12Device()->CreateRenderTargetView(mResource.Get(), &rtvDesc,
+ device->GetD3D12Device()->CreateRenderTargetView(GetD3D12Resource(), &rtvDesc,
rtvHandle);
commandList->ClearRenderTargetView(rtvHandle, clearColorRGBA, 0, nullptr);
}
diff --git a/src/dawn_native/d3d12/TextureD3D12.h b/src/dawn_native/d3d12/TextureD3D12.h
index adfe4d1..1e10df9 100644
--- a/src/dawn_native/d3d12/TextureD3D12.h
+++ b/src/dawn_native/d3d12/TextureD3D12.h
@@ -18,6 +18,7 @@
#include "common/Serial.h"
#include "dawn_native/Texture.h"
+#include "dawn_native/d3d12/ResourceHeapAllocationD3D12.h"
#include "dawn_native/d3d12/d3d12_platform.h"
namespace dawn_native { namespace d3d12 {
@@ -86,7 +87,7 @@
D3D12_RESOURCE_BARRIER* barrier,
D3D12_RESOURCE_STATES newState);
- ComPtr<ID3D12Resource> mResource;
+ ResourceHeapAllocation mResourceAllocation;
D3D12_RESOURCE_STATES mLastState = D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_COMMON;
Serial mLastUsedSerial = UINT64_MAX;