mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-05 12:46:11 +00:00
Resource Management 5: D3D support for resource allocation.
Refactor existing resource allocators by adding a memory type and memory handle. BUG=dawn:27, dawn:153 Change-Id: I090b6ab40e7eaa0d7ea5ce1e8b760e961be9b559 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/9420 Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
f0b17d00b9
commit
7ffd2346f8
7
BUILD.gn
7
BUILD.gn
@ -204,6 +204,9 @@ source_set("libdawn_native_sources") {
|
||||
"src/dawn_native/RenderPassEncoder.h",
|
||||
"src/dawn_native/RenderPipeline.cpp",
|
||||
"src/dawn_native/RenderPipeline.h",
|
||||
"src/dawn_native/ResourceHeap.h",
|
||||
"src/dawn_native/ResourceMemoryAllocation.cpp",
|
||||
"src/dawn_native/ResourceMemoryAllocation.h",
|
||||
"src/dawn_native/RingBuffer.cpp",
|
||||
"src/dawn_native/RingBuffer.h",
|
||||
"src/dawn_native/Sampler.cpp",
|
||||
@ -239,6 +242,8 @@ source_set("libdawn_native_sources") {
|
||||
"src/dawn_native/d3d12/CommandAllocatorManager.h",
|
||||
"src/dawn_native/d3d12/CommandBufferD3D12.cpp",
|
||||
"src/dawn_native/d3d12/CommandBufferD3D12.h",
|
||||
"src/dawn_native/d3d12/CommittedResourceAllocatorD3D12.cpp",
|
||||
"src/dawn_native/d3d12/CommittedResourceAllocatorD3D12.h",
|
||||
"src/dawn_native/d3d12/ComputePipelineD3D12.cpp",
|
||||
"src/dawn_native/d3d12/ComputePipelineD3D12.h",
|
||||
"src/dawn_native/d3d12/D3D12Info.cpp",
|
||||
@ -260,6 +265,8 @@ source_set("libdawn_native_sources") {
|
||||
"src/dawn_native/d3d12/RenderPipelineD3D12.h",
|
||||
"src/dawn_native/d3d12/ResourceAllocator.cpp",
|
||||
"src/dawn_native/d3d12/ResourceAllocator.h",
|
||||
"src/dawn_native/d3d12/ResourceHeapD3D12.cpp",
|
||||
"src/dawn_native/d3d12/ResourceHeapD3D12.h",
|
||||
"src/dawn_native/d3d12/SamplerD3D12.cpp",
|
||||
"src/dawn_native/d3d12/SamplerD3D12.h",
|
||||
"src/dawn_native/d3d12/ShaderModuleD3D12.cpp",
|
||||
|
@ -36,6 +36,7 @@ namespace dawn_native {
|
||||
class RenderBundleEncoderBase;
|
||||
class RenderPassEncoderBase;
|
||||
class RenderPipelineBase;
|
||||
class ResourceHeapBase;
|
||||
class SamplerBase;
|
||||
class ShaderModuleBase;
|
||||
class StagingBufferBase;
|
||||
|
31
src/dawn_native/ResourceHeap.h
Normal file
31
src/dawn_native/ResourceHeap.h
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2019 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_RESOURCEHEAP_H_
|
||||
#define DAWNNATIVE_RESOURCEHEAP_H_
|
||||
|
||||
#include "dawn_native/Error.h"
|
||||
|
||||
namespace dawn_native {
|
||||
|
||||
// Wrapper for a resource backed by a heap.
|
||||
class ResourceHeapBase {
|
||||
protected:
|
||||
ResourceHeapBase() = default;
|
||||
virtual ~ResourceHeapBase() = default;
|
||||
};
|
||||
|
||||
} // namespace dawn_native
|
||||
|
||||
#endif // DAWNNATIVE_RESOURCEHEAP_H_
|
53
src/dawn_native/ResourceMemoryAllocation.cpp
Normal file
53
src/dawn_native/ResourceMemoryAllocation.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2019 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/ResourceMemoryAllocation.h"
|
||||
#include "common/Assert.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace dawn_native {
|
||||
|
||||
static constexpr uint64_t INVALID_OFFSET = std::numeric_limits<uint64_t>::max();
|
||||
|
||||
ResourceMemoryAllocation::ResourceMemoryAllocation()
|
||||
: mMethod(AllocationMethod::kInvalid), mOffset(INVALID_OFFSET), mResourceHeap(nullptr) {
|
||||
}
|
||||
|
||||
ResourceMemoryAllocation::ResourceMemoryAllocation(uint64_t offset,
|
||||
ResourceHeapBase* resourceHeap,
|
||||
AllocationMethod method)
|
||||
: mMethod(method), mOffset(offset), mResourceHeap(resourceHeap) {
|
||||
}
|
||||
|
||||
ResourceHeapBase* ResourceMemoryAllocation::GetResourceHeap() const {
|
||||
ASSERT(mMethod != AllocationMethod::kInvalid);
|
||||
return mResourceHeap;
|
||||
}
|
||||
|
||||
uint64_t ResourceMemoryAllocation::GetOffset() const {
|
||||
ASSERT(mMethod != AllocationMethod::kInvalid);
|
||||
return mOffset;
|
||||
}
|
||||
|
||||
AllocationMethod ResourceMemoryAllocation::GetAllocationMethod() const {
|
||||
ASSERT(mMethod != AllocationMethod::kInvalid);
|
||||
return mMethod;
|
||||
}
|
||||
|
||||
void ResourceMemoryAllocation::Invalidate() {
|
||||
mResourceHeap = nullptr;
|
||||
mMethod = AllocationMethod::kInvalid;
|
||||
}
|
||||
} // namespace dawn_native
|
60
src/dawn_native/ResourceMemoryAllocation.h
Normal file
60
src/dawn_native/ResourceMemoryAllocation.h
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2018 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_RESOURCEMEMORYALLOCATION_H_
|
||||
#define DAWNNATIVE_RESOURCEMEMORYALLOCATION_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace dawn_native {
|
||||
|
||||
class ResourceHeapBase;
|
||||
|
||||
// Allocation method determines how memory was sub-divided.
|
||||
// Used by the device to get the allocator that was responsible for the allocation.
|
||||
enum class AllocationMethod {
|
||||
|
||||
// Memory not sub-divided.
|
||||
kDirect,
|
||||
|
||||
// Memory sub-divided using one or more blocks of various sizes.
|
||||
kSubAllocated,
|
||||
|
||||
// Memory not allocated or freed.
|
||||
kInvalid
|
||||
};
|
||||
|
||||
// Handle into a resource heap pool.
|
||||
class ResourceMemoryAllocation {
|
||||
public:
|
||||
ResourceMemoryAllocation();
|
||||
ResourceMemoryAllocation(uint64_t offset,
|
||||
ResourceHeapBase* resourceHeap,
|
||||
AllocationMethod method);
|
||||
~ResourceMemoryAllocation() = default;
|
||||
|
||||
ResourceHeapBase* GetResourceHeap() const;
|
||||
uint64_t GetOffset() const;
|
||||
AllocationMethod GetAllocationMethod() const;
|
||||
|
||||
void Invalidate();
|
||||
|
||||
private:
|
||||
AllocationMethod mMethod;
|
||||
uint64_t mOffset;
|
||||
ResourceHeapBase* mResourceHeap;
|
||||
};
|
||||
} // namespace dawn_native
|
||||
|
||||
#endif // DAWNNATIVE_RESOURCEMEMORYALLOCATION_H_
|
@ -73,6 +73,11 @@ namespace dawn_native {
|
||||
using BackendType = typename BackendTraits::RenderPipelineType;
|
||||
};
|
||||
|
||||
template <typename BackendTraits>
|
||||
struct ToBackendTraits<ResourceHeapBase, BackendTraits> {
|
||||
using BackendType = typename BackendTraits::ResourceHeapType;
|
||||
};
|
||||
|
||||
template <typename BackendTraits>
|
||||
struct ToBackendTraits<SamplerBase, BackendTraits> {
|
||||
using BackendType = typename BackendTraits::SamplerType;
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "common/Constants.h"
|
||||
#include "common/Math.h"
|
||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||
#include "dawn_native/d3d12/ResourceAllocator.h"
|
||||
#include "dawn_native/d3d12/ResourceHeapD3D12.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
@ -71,6 +71,9 @@ namespace dawn_native { namespace d3d12 {
|
||||
|
||||
Buffer::Buffer(Device* device, const BufferDescriptor* descriptor)
|
||||
: BufferBase(device, descriptor) {
|
||||
}
|
||||
|
||||
MaybeError Buffer::Initialize() {
|
||||
D3D12_RESOURCE_DESC resourceDescriptor;
|
||||
resourceDescriptor.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
resourceDescriptor.Alignment = 0;
|
||||
@ -105,8 +108,11 @@ namespace dawn_native { namespace d3d12 {
|
||||
mLastUsage = dawn::BufferUsage::CopySrc;
|
||||
}
|
||||
|
||||
mResource =
|
||||
device->GetResourceAllocator()->Allocate(heapType, resourceDescriptor, bufferUsage);
|
||||
DAWN_TRY_ASSIGN(
|
||||
mResourceAllocation,
|
||||
ToBackend(GetDevice())
|
||||
->AllocateMemory(heapType, resourceDescriptor, bufferUsage, D3D12_HEAP_FLAG_NONE));
|
||||
return {};
|
||||
}
|
||||
|
||||
Buffer::~Buffer() {
|
||||
@ -118,8 +124,8 @@ namespace dawn_native { namespace d3d12 {
|
||||
return Align(GetSize(), 256);
|
||||
}
|
||||
|
||||
ComPtr<ID3D12Resource> Buffer::GetD3D12Resource() {
|
||||
return mResource;
|
||||
ComPtr<ID3D12Resource> Buffer::GetD3D12Resource() const {
|
||||
return ToBackend(mResourceAllocation.GetResourceHeap())->GetD3D12Resource();
|
||||
}
|
||||
|
||||
// When true is returned, a D3D12_RESOURCE_BARRIER has been created and must be used in a
|
||||
@ -174,7 +180,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().Get();
|
||||
barrier->Transition.StateBefore = lastState;
|
||||
barrier->Transition.StateAfter = newState;
|
||||
barrier->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
@ -192,7 +198,7 @@ namespace dawn_native { namespace d3d12 {
|
||||
}
|
||||
|
||||
D3D12_GPU_VIRTUAL_ADDRESS Buffer::GetVA() const {
|
||||
return mResource->GetGPUVirtualAddress();
|
||||
return ToBackend(mResourceAllocation.GetResourceHeap())->GetGPUPointer();
|
||||
}
|
||||
|
||||
void Buffer::OnMapCommandSerialFinished(uint32_t mapSerial, void* data, bool isWrite) {
|
||||
@ -210,8 +216,8 @@ namespace dawn_native { namespace d3d12 {
|
||||
|
||||
MaybeError Buffer::MapAtCreationImpl(uint8_t** mappedPointer) {
|
||||
mWrittenMappedRange = {0, GetSize()};
|
||||
ASSERT_SUCCESS(
|
||||
mResource->Map(0, &mWrittenMappedRange, reinterpret_cast<void**>(mappedPointer)));
|
||||
ASSERT_SUCCESS(GetD3D12Resource()->Map(0, &mWrittenMappedRange,
|
||||
reinterpret_cast<void**>(mappedPointer)));
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -219,8 +225,7 @@ namespace dawn_native { namespace d3d12 {
|
||||
mWrittenMappedRange = {};
|
||||
D3D12_RANGE readRange = {0, GetSize()};
|
||||
char* data = nullptr;
|
||||
ASSERT_SUCCESS(mResource->Map(0, &readRange, reinterpret_cast<void**>(&data)));
|
||||
|
||||
ASSERT_SUCCESS(GetD3D12Resource()->Map(0, &readRange, reinterpret_cast<void**>(&data)));
|
||||
// There is no need to transition the resource to a new state: D3D12 seems to make the GPU
|
||||
// writes available when the fence is passed.
|
||||
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapRequestTracker();
|
||||
@ -231,8 +236,8 @@ namespace dawn_native { namespace d3d12 {
|
||||
MaybeError Buffer::MapWriteAsyncImpl(uint32_t serial) {
|
||||
mWrittenMappedRange = {0, GetSize()};
|
||||
char* data = nullptr;
|
||||
ASSERT_SUCCESS(mResource->Map(0, &mWrittenMappedRange, reinterpret_cast<void**>(&data)));
|
||||
|
||||
ASSERT_SUCCESS(
|
||||
GetD3D12Resource()->Map(0, &mWrittenMappedRange, reinterpret_cast<void**>(&data)));
|
||||
// There is no need to transition the resource to a new state: D3D12 seems to make the CPU
|
||||
// writes available on queue submission.
|
||||
MapRequestTracker* tracker = ToBackend(GetDevice())->GetMapRequestTracker();
|
||||
@ -241,14 +246,12 @@ namespace dawn_native { namespace d3d12 {
|
||||
}
|
||||
|
||||
void Buffer::UnmapImpl() {
|
||||
mResource->Unmap(0, &mWrittenMappedRange);
|
||||
ToBackend(GetDevice())->GetResourceAllocator()->Release(mResource);
|
||||
GetD3D12Resource()->Unmap(0, &mWrittenMappedRange);
|
||||
mWrittenMappedRange = {};
|
||||
}
|
||||
|
||||
void Buffer::DestroyImpl() {
|
||||
ToBackend(GetDevice())->GetResourceAllocator()->Release(mResource);
|
||||
mResource = nullptr;
|
||||
ToBackend(GetDevice())->DeallocateMemory(mResourceAllocation);
|
||||
}
|
||||
|
||||
MapRequestTracker::MapRequestTracker(Device* device) : mDevice(device) {
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "common/SerialQueue.h"
|
||||
#include "dawn_native/Buffer.h"
|
||||
|
||||
#include "dawn_native/ResourceMemoryAllocation.h"
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
@ -29,8 +30,10 @@ namespace dawn_native { namespace d3d12 {
|
||||
Buffer(Device* device, const BufferDescriptor* descriptor);
|
||||
~Buffer();
|
||||
|
||||
MaybeError Initialize();
|
||||
|
||||
uint32_t GetD3D12Size() const;
|
||||
ComPtr<ID3D12Resource> GetD3D12Resource();
|
||||
ComPtr<ID3D12Resource> GetD3D12Resource() const;
|
||||
D3D12_GPU_VIRTUAL_ADDRESS GetVA() const;
|
||||
void OnMapCommandSerialFinished(uint32_t mapSerial, void* data, bool isWrite);
|
||||
bool TransitionUsageAndGetResourceBarrier(D3D12_RESOURCE_BARRIER* barrier,
|
||||
@ -48,7 +51,7 @@ namespace dawn_native { namespace d3d12 {
|
||||
bool IsMapWritable() const override;
|
||||
virtual MaybeError MapAtCreationImpl(uint8_t** mappedPointer) override;
|
||||
|
||||
ComPtr<ID3D12Resource> mResource;
|
||||
ResourceMemoryAllocation mResourceAllocation;
|
||||
bool mFixedResourceState = false;
|
||||
dawn::BufferUsage mLastUsage = dawn::BufferUsage::None;
|
||||
Serial mLastUsedSerial = UINT64_MAX;
|
||||
|
52
src/dawn_native/d3d12/CommittedResourceAllocatorD3D12.cpp
Normal file
52
src/dawn_native/d3d12/CommittedResourceAllocatorD3D12.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright 2019 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/CommittedResourceAllocatorD3D12.h"
|
||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||
#include "dawn_native/d3d12/ResourceHeapD3D12.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
CommittedResourceAllocator::CommittedResourceAllocator(Device* device, D3D12_HEAP_TYPE heapType)
|
||||
: mDevice(device), mHeapType(heapType) {
|
||||
}
|
||||
|
||||
ResultOrError<ResourceMemoryAllocation> CommittedResourceAllocator::Allocate(
|
||||
const D3D12_RESOURCE_DESC& resourceDescriptor,
|
||||
D3D12_RESOURCE_STATES initialUsage,
|
||||
D3D12_HEAP_FLAGS heapFlags) {
|
||||
D3D12_HEAP_PROPERTIES heapProperties;
|
||||
heapProperties.Type = mHeapType;
|
||||
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
heapProperties.CreationNodeMask = 0;
|
||||
heapProperties.VisibleNodeMask = 0;
|
||||
|
||||
ComPtr<ID3D12Resource> committedResource;
|
||||
if (FAILED(mDevice->GetD3D12Device()->CreateCommittedResource(
|
||||
&heapProperties, heapFlags, &resourceDescriptor, initialUsage, nullptr,
|
||||
IID_PPV_ARGS(&committedResource)))) {
|
||||
return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate resource");
|
||||
}
|
||||
|
||||
return ResourceMemoryAllocation(
|
||||
/*offset*/ 0, new ResourceHeap(std::move(committedResource)),
|
||||
AllocationMethod::kDirect);
|
||||
}
|
||||
|
||||
void CommittedResourceAllocator::Deallocate(ResourceMemoryAllocation& allocation) {
|
||||
std::unique_ptr<ResourceHeap> resourceHeap(ToBackend(allocation.GetResourceHeap()));
|
||||
mDevice->ReferenceUntilUnused(resourceHeap->GetD3D12Resource());
|
||||
}
|
||||
}} // namespace dawn_native::d3d12
|
47
src/dawn_native/d3d12/CommittedResourceAllocatorD3D12.h
Normal file
47
src/dawn_native/d3d12/CommittedResourceAllocatorD3D12.h
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2019 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_COMMITTEDRESOURCEALLOCATORD3D12_H_
|
||||
#define DAWNNATIVE_D3D12_COMMITTEDRESOURCEALLOCATORD3D12_H_
|
||||
|
||||
#include "common/SerialQueue.h"
|
||||
#include "dawn_native/Error.h"
|
||||
#include "dawn_native/ResourceMemoryAllocation.h"
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
class Device;
|
||||
|
||||
// Wrapper to allocate D3D12 committed resource.
|
||||
// Committed resources are implicitly backed by a D3D12 heap.
|
||||
class CommittedResourceAllocator {
|
||||
public:
|
||||
CommittedResourceAllocator(Device* device, D3D12_HEAP_TYPE heapType);
|
||||
~CommittedResourceAllocator() = default;
|
||||
|
||||
ResultOrError<ResourceMemoryAllocation> Allocate(
|
||||
const D3D12_RESOURCE_DESC& resourceDescriptor,
|
||||
D3D12_RESOURCE_STATES initialUsage,
|
||||
D3D12_HEAP_FLAGS heapFlags);
|
||||
void Deallocate(ResourceMemoryAllocation& allocation);
|
||||
|
||||
private:
|
||||
Device* mDevice;
|
||||
D3D12_HEAP_TYPE mHeapType;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
||||
#endif // DAWNNATIVE_D3D12_COMMITTEDRESOURCEALLOCATORD3D12_H_
|
@ -31,6 +31,7 @@
|
||||
#include "dawn_native/d3d12/QueueD3D12.h"
|
||||
#include "dawn_native/d3d12/RenderPipelineD3D12.h"
|
||||
#include "dawn_native/d3d12/ResourceAllocator.h"
|
||||
#include "dawn_native/d3d12/ResourceHeapD3D12.h"
|
||||
#include "dawn_native/d3d12/SamplerD3D12.h"
|
||||
#include "dawn_native/d3d12/ShaderModuleD3D12.h"
|
||||
#include "dawn_native/d3d12/StagingBufferD3D12.h"
|
||||
@ -110,12 +111,17 @@ namespace dawn_native { namespace d3d12 {
|
||||
}
|
||||
NextSerial();
|
||||
WaitForSerial(mLastSubmittedSerial); // Wait for all in-flight commands to finish executing
|
||||
TickImpl(); // Call tick one last time so resources are cleaned up
|
||||
TickImpl(); // Call tick one last time so resources are cleaned up
|
||||
|
||||
// Free services explicitly so that they can free D3D12 resources before destruction of the
|
||||
// device.
|
||||
mDynamicUploader = nullptr;
|
||||
|
||||
// GPU is no longer executing commands. Existing objects do not get freed until the device
|
||||
// is destroyed. To ensure objects are always released, force the completed serial to be
|
||||
// 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);
|
||||
@ -124,6 +130,8 @@ namespace dawn_native { namespace d3d12 {
|
||||
::CloseHandle(mFenceEvent);
|
||||
}
|
||||
|
||||
mUsedComObjectRefs.ClearUpTo(mCompletedSerial);
|
||||
|
||||
ASSERT(mUsedComObjectRefs.Empty());
|
||||
ASSERT(mPendingCommands.commandList == nullptr);
|
||||
}
|
||||
@ -264,7 +272,9 @@ namespace dawn_native { namespace d3d12 {
|
||||
return new BindGroupLayout(this, descriptor);
|
||||
}
|
||||
ResultOrError<BufferBase*> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
|
||||
return new Buffer(this, descriptor);
|
||||
std::unique_ptr<Buffer> buffer = std::make_unique<Buffer>(this, descriptor);
|
||||
DAWN_TRY(buffer->Initialize());
|
||||
return buffer.release();
|
||||
}
|
||||
CommandBufferBase* Device::CreateCommandBuffer(CommandEncoderBase* encoder,
|
||||
const CommandBufferDescriptor* descriptor) {
|
||||
@ -326,4 +336,48 @@ namespace dawn_native { namespace d3d12 {
|
||||
return {};
|
||||
}
|
||||
|
||||
size_t Device::GetD3D12HeapTypeToIndex(D3D12_HEAP_TYPE heapType) const {
|
||||
ASSERT(heapType > 0);
|
||||
ASSERT(heapType <= kNumHeapTypes);
|
||||
return heapType - 1;
|
||||
}
|
||||
|
||||
void Device::DeallocateMemory(ResourceMemoryAllocation& allocation) {
|
||||
CommittedResourceAllocator* allocator = nullptr;
|
||||
D3D12_HEAP_PROPERTIES heapProp;
|
||||
ToBackend(allocation.GetResourceHeap())
|
||||
->GetD3D12Resource()
|
||||
->GetHeapProperties(&heapProp, nullptr);
|
||||
const size_t heapTypeIndex = GetD3D12HeapTypeToIndex(heapProp.Type);
|
||||
ASSERT(heapTypeIndex < kNumHeapTypes);
|
||||
allocator = mDirectResourceAllocators[heapTypeIndex].get();
|
||||
allocator->Deallocate(allocation);
|
||||
|
||||
// Invalidate the underlying resource heap in case the client accidentally
|
||||
// calls DeallocateMemory again using the same allocation.
|
||||
allocation.Invalidate();
|
||||
}
|
||||
|
||||
ResultOrError<ResourceMemoryAllocation> Device::AllocateMemory(
|
||||
D3D12_HEAP_TYPE heapType,
|
||||
const D3D12_RESOURCE_DESC& resourceDescriptor,
|
||||
D3D12_RESOURCE_STATES initialUsage,
|
||||
D3D12_HEAP_FLAGS heapFlags) {
|
||||
const size_t heapTypeIndex = GetD3D12HeapTypeToIndex(heapType);
|
||||
ASSERT(heapTypeIndex < kNumHeapTypes);
|
||||
|
||||
// Get the direct allocator using a tightly sized heap (aka CreateCommittedResource).
|
||||
CommittedResourceAllocator* allocator = mDirectResourceAllocators[heapTypeIndex].get();
|
||||
if (allocator == nullptr) {
|
||||
mDirectResourceAllocators[heapTypeIndex] =
|
||||
std::make_unique<CommittedResourceAllocator>(this, heapType);
|
||||
allocator = mDirectResourceAllocators[heapTypeIndex].get();
|
||||
}
|
||||
|
||||
ResourceMemoryAllocation allocation;
|
||||
DAWN_TRY_ASSIGN(allocation,
|
||||
allocator->Allocate(resourceDescriptor, initialUsage, heapFlags));
|
||||
|
||||
return allocation;
|
||||
}
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "common/SerialQueue.h"
|
||||
#include "dawn_native/Device.h"
|
||||
#include "dawn_native/d3d12/CommittedResourceAllocatorD3D12.h"
|
||||
#include "dawn_native/d3d12/Forward.h"
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
@ -81,6 +82,14 @@ namespace dawn_native { namespace d3d12 {
|
||||
uint64_t destinationOffset,
|
||||
uint64_t size) override;
|
||||
|
||||
ResultOrError<ResourceMemoryAllocation> AllocateMemory(
|
||||
D3D12_HEAP_TYPE heapType,
|
||||
const D3D12_RESOURCE_DESC& resourceDescriptor,
|
||||
D3D12_RESOURCE_STATES initialUsage,
|
||||
D3D12_HEAP_FLAGS heapFlags);
|
||||
|
||||
void DeallocateMemory(ResourceMemoryAllocation& allocation);
|
||||
|
||||
private:
|
||||
ResultOrError<BindGroupBase*> CreateBindGroupImpl(
|
||||
const BindGroupDescriptor* descriptor) override;
|
||||
@ -104,6 +113,8 @@ namespace dawn_native { namespace d3d12 {
|
||||
TextureBase* texture,
|
||||
const TextureViewDescriptor* descriptor) override;
|
||||
|
||||
size_t GetD3D12HeapTypeToIndex(D3D12_HEAP_TYPE heapType) const;
|
||||
|
||||
Serial mCompletedSerial = 0;
|
||||
Serial mLastSubmittedSerial = 0;
|
||||
ComPtr<ID3D12Fence> mFence;
|
||||
@ -128,6 +139,20 @@ namespace dawn_native { namespace d3d12 {
|
||||
std::unique_ptr<MapRequestTracker> mMapRequestTracker;
|
||||
std::unique_ptr<ResourceAllocator> mResourceAllocator;
|
||||
|
||||
static constexpr uint32_t kNumHeapTypes = 4u; // Number of D3D12_HEAP_TYPE
|
||||
|
||||
static_assert(D3D12_HEAP_TYPE_READBACK <= kNumHeapTypes,
|
||||
"Readback heap type enum exceeds max heap types");
|
||||
static_assert(D3D12_HEAP_TYPE_UPLOAD <= kNumHeapTypes,
|
||||
"Upload heap type enum exceeds max heap types");
|
||||
static_assert(D3D12_HEAP_TYPE_DEFAULT <= kNumHeapTypes,
|
||||
"Default heap type enum exceeds max heap types");
|
||||
static_assert(D3D12_HEAP_TYPE_CUSTOM <= kNumHeapTypes,
|
||||
"Custom heap type enum exceeds max heap types");
|
||||
|
||||
std::array<std::unique_ptr<CommittedResourceAllocator>, kNumHeapTypes>
|
||||
mDirectResourceAllocators;
|
||||
|
||||
dawn_native::PCIInfo mPCIInfo;
|
||||
};
|
||||
|
||||
|
@ -29,6 +29,7 @@ namespace dawn_native { namespace d3d12 {
|
||||
class PipelineLayout;
|
||||
class Queue;
|
||||
class RenderPipeline;
|
||||
class ResourceHeap;
|
||||
class Sampler;
|
||||
class ShaderModule;
|
||||
class StagingBuffer;
|
||||
@ -47,6 +48,7 @@ namespace dawn_native { namespace d3d12 {
|
||||
using PipelineLayoutType = PipelineLayout;
|
||||
using QueueType = Queue;
|
||||
using RenderPipelineType = RenderPipeline;
|
||||
using ResourceHeapType = ResourceHeap;
|
||||
using SamplerType = Sampler;
|
||||
using ShaderModuleType = ShaderModule;
|
||||
using StagingBufferType = StagingBuffer;
|
||||
|
30
src/dawn_native/d3d12/ResourceHeapD3D12.cpp
Normal file
30
src/dawn_native/d3d12/ResourceHeapD3D12.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2019 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/ResourceHeapD3D12.h"
|
||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
ResourceHeap::ResourceHeap(ComPtr<ID3D12Resource> resource) : mResource(resource) {
|
||||
}
|
||||
|
||||
ComPtr<ID3D12Resource> ResourceHeap::GetD3D12Resource() const {
|
||||
return mResource;
|
||||
}
|
||||
|
||||
D3D12_GPU_VIRTUAL_ADDRESS ResourceHeap::GetGPUPointer() const {
|
||||
return mResource->GetGPUVirtualAddress();
|
||||
}
|
||||
}} // namespace dawn_native::d3d12
|
38
src/dawn_native/d3d12/ResourceHeapD3D12.h
Normal file
38
src/dawn_native/d3d12/ResourceHeapD3D12.h
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2019 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_RESOURCEHEAPD3D12_H_
|
||||
#define DAWNNATIVE_D3D12_RESOURCEHEAPD3D12_H_
|
||||
|
||||
#include "dawn_native/ResourceHeap.h"
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
// Wrapper for physical memory used with or without a resource object.
|
||||
class ResourceHeap : public ResourceHeapBase {
|
||||
public:
|
||||
ResourceHeap(ComPtr<ID3D12Resource> resource);
|
||||
|
||||
~ResourceHeap() = default;
|
||||
|
||||
ComPtr<ID3D12Resource> GetD3D12Resource() const;
|
||||
D3D12_GPU_VIRTUAL_ADDRESS GetGPUPointer() const;
|
||||
|
||||
private:
|
||||
ComPtr<ID3D12Resource> mResource;
|
||||
};
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
||||
#endif // DAWNNATIVE_D3D12_RESOURCEHEAPD3D12_H_
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include "dawn_native/d3d12/StagingBufferD3D12.h"
|
||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||
#include "dawn_native/d3d12/ResourceAllocator.h"
|
||||
#include "dawn_native/d3d12/ResourceHeapD3D12.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
@ -36,12 +36,11 @@ namespace dawn_native { namespace d3d12 {
|
||||
resourceDescriptor.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
resourceDescriptor.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
|
||||
mUploadHeap = mDevice->GetResourceAllocator()->Allocate(
|
||||
D3D12_HEAP_TYPE_UPLOAD, resourceDescriptor, D3D12_RESOURCE_STATE_GENERIC_READ);
|
||||
DAWN_TRY_ASSIGN(mUploadHeap, mDevice->AllocateMemory(
|
||||
D3D12_HEAP_TYPE_UPLOAD, resourceDescriptor,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_HEAP_FLAG_NONE));
|
||||
|
||||
// TODO(bryan.bernhart@intel.com): Record the GPU pointer for generic non-upload usage.
|
||||
|
||||
if (FAILED(mUploadHeap->Map(0, nullptr, &mMappedPointer))) {
|
||||
if (FAILED(GetResource()->Map(0, nullptr, &mMappedPointer))) {
|
||||
return DAWN_DEVICE_LOST_ERROR("Unable to map staging buffer.");
|
||||
}
|
||||
|
||||
@ -50,14 +49,14 @@ namespace dawn_native { namespace d3d12 {
|
||||
|
||||
StagingBuffer::~StagingBuffer() {
|
||||
// Invalidate the CPU virtual address & flush cache (if needed).
|
||||
mUploadHeap->Unmap(0, nullptr);
|
||||
GetResource()->Unmap(0, nullptr);
|
||||
mMappedPointer = nullptr;
|
||||
|
||||
mDevice->GetResourceAllocator()->Release(mUploadHeap);
|
||||
mDevice->DeallocateMemory(mUploadHeap);
|
||||
}
|
||||
|
||||
ID3D12Resource* StagingBuffer::GetResource() const {
|
||||
return mUploadHeap.Get();
|
||||
return ToBackend(mUploadHeap.GetResourceHeap())->GetD3D12Resource().Get();
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
@ -15,6 +15,7 @@
|
||||
#ifndef DAWNNATIVE_STAGINGBUFFERD3D12_H_
|
||||
#define DAWNNATIVE_STAGINGBUFFERD3D12_H_
|
||||
|
||||
#include "dawn_native/ResourceMemoryAllocation.h"
|
||||
#include "dawn_native/StagingBuffer.h"
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
@ -33,7 +34,7 @@ namespace dawn_native { namespace d3d12 {
|
||||
|
||||
private:
|
||||
Device* mDevice;
|
||||
ComPtr<ID3D12Resource> mUploadHeap;
|
||||
ResourceMemoryAllocation mUploadHeap;
|
||||
};
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user