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:
Bryan Bernhart 2019-10-22 21:01:11 +00:00 committed by Commit Bot service account
parent 7b3cc35cb6
commit c833c0c592
9 changed files with 26 additions and 155 deletions

View File

@ -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",

View File

@ -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"

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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_

View File

@ -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);
}

View File

@ -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;