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>
This commit is contained in:
parent
7b3cc35cb6
commit
c833c0c592
2
BUILD.gn
2
BUILD.gn
|
@ -291,8 +291,6 @@ source_set("libdawn_native_sources") {
|
|||
"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",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 @@ namespace dawn_native { namespace d3d12 {
|
|||
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 @@ namespace dawn_native { namespace d3d12 {
|
|||
// 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 @@ namespace dawn_native { namespace d3d12 {
|
|||
return mMapRequestTracker.get();
|
||||
}
|
||||
|
||||
ResourceAllocator* Device::GetResourceAllocator() const {
|
||||
return mResourceAllocator.get();
|
||||
}
|
||||
|
||||
CommandAllocatorManager* Device::GetCommandAllocatorManager() const {
|
||||
return mCommandAllocatorManager.get();
|
||||
}
|
||||
|
@ -212,7 +202,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
// as it enqueued resources to be released.
|
||||
mDynamicUploader->Deallocate(mCompletedSerial);
|
||||
|
||||
mResourceAllocator->Tick(mCompletedSerial);
|
||||
mResourceAllocatorManager->Tick(mCompletedSerial);
|
||||
DAWN_TRY(mCommandAllocatorManager->Tick(mCompletedSerial));
|
||||
mDescriptorHeapAllocator->Deallocate(mCompletedSerial);
|
||||
|
|
|
@ -31,7 +31,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
class DescriptorHeapAllocator;
|
||||
class MapRequestTracker;
|
||||
class PlatformFunctions;
|
||||
class ResourceAllocator;
|
||||
class ResourceAllocatorManager;
|
||||
|
||||
#define ASSERT_SUCCESS(hr) \
|
||||
|
@ -64,7 +63,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
DescriptorHeapAllocator* GetDescriptorHeapAllocator() const;
|
||||
MapRequestTracker* GetMapRequestTracker() const;
|
||||
ResourceAllocator* GetResourceAllocator() const;
|
||||
CommandAllocatorManager* GetCommandAllocatorManager() const;
|
||||
|
||||
const PlatformFunctions* GetFunctions() const;
|
||||
|
@ -147,7 +145,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
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;
|
||||
|
|
|
@ -32,9 +32,11 @@ namespace dawn_native { namespace d3d12 {
|
|||
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;
|
||||
|
|
|
@ -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
|
|
@ -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_
|
|
@ -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 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
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 @@ namespace dawn_native { namespace d3d12 {
|
|||
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 @@ namespace dawn_native { namespace d3d12 {
|
|||
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 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
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 @@ namespace dawn_native { namespace d3d12 {
|
|||
}
|
||||
|
||||
ID3D12Resource* Texture::GetD3D12Resource() const {
|
||||
return mResource.Get();
|
||||
return mResourceAllocation.GetD3D12Resource().Get();
|
||||
}
|
||||
|
||||
UINT16 Texture::GetDepthOrArraySize() {
|
||||
|
@ -476,7 +482,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
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 @@ namespace dawn_native { namespace d3d12 {
|
|||
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 @@ namespace dawn_native { namespace d3d12 {
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -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 @@ namespace dawn_native { namespace d3d12 {
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue