Descriptor Residency 1: Add Pageable and ShaderVisibleDescriptorHeap
Refactors ShaderVisibleDescriptorAllocator to use d3d12::Heap to represent ID3D12DescriptorHeaps. Bug: dawn:193 Change-Id: If0a9df0bc138c4d6f1ad110750ab1e6e8084b80f Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/20960 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
949f1e45f1
commit
9b54466be4
|
@ -312,6 +312,8 @@ source_set("dawn_native_sources") {
|
|||
"d3d12/HeapD3D12.h",
|
||||
"d3d12/NativeSwapChainImplD3D12.cpp",
|
||||
"d3d12/NativeSwapChainImplD3D12.h",
|
||||
"d3d12/PageableD3D12.cpp",
|
||||
"d3d12/PageableD3D12.h",
|
||||
"d3d12/PipelineLayoutD3D12.cpp",
|
||||
"d3d12/PipelineLayoutD3D12.h",
|
||||
"d3d12/PlatformFunctions.cpp",
|
||||
|
|
|
@ -193,6 +193,8 @@ if (DAWN_ENABLE_D3D12)
|
|||
"d3d12/HeapD3D12.h"
|
||||
"d3d12/NativeSwapChainImplD3D12.cpp"
|
||||
"d3d12/NativeSwapChainImplD3D12.h"
|
||||
"d3d12/PageableD3D12.cpp"
|
||||
"d3d12/PageableD3D12.h"
|
||||
"d3d12/PipelineLayoutD3D12.cpp"
|
||||
"d3d12/PipelineLayoutD3D12.h"
|
||||
"d3d12/PlatformFunctions.cpp"
|
||||
|
|
|
@ -16,16 +16,8 @@
|
|||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
Heap::Heap(ComPtr<ID3D12Pageable> d3d12Pageable, MemorySegment memorySegment, uint64_t size)
|
||||
: mD3d12Pageable(std::move(d3d12Pageable)), mMemorySegment(memorySegment), mSize(size) {
|
||||
}
|
||||
|
||||
Heap::~Heap() {
|
||||
// When a heap is destroyed, it no longer resides in resident memory, so we must evict
|
||||
// it from the LRU cache. If this heap is not manually removed from the LRU-cache, the
|
||||
// ResidencyManager will attempt to use it after it has been deallocated.
|
||||
if (IsInResidencyLRUCache()) {
|
||||
RemoveFromList();
|
||||
}
|
||||
: Pageable(std::move(d3d12Pageable), memorySegment, size) {
|
||||
mD3d12Pageable.As(&mD3d12Heap);
|
||||
}
|
||||
|
||||
// This function should only be used when mD3D12Pageable was initialized from a
|
||||
|
@ -33,58 +25,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
// ID3D12Pageable was initially created as an ID3D12Resource (i.e. DirectAllocation), then
|
||||
// use GetD3D12Pageable().
|
||||
ID3D12Heap* Heap::GetD3D12Heap() const {
|
||||
ComPtr<ID3D12Heap> heap;
|
||||
HRESULT result = mD3d12Pageable.As(&heap);
|
||||
ASSERT(SUCCEEDED(result));
|
||||
return heap.Get();
|
||||
}
|
||||
|
||||
ID3D12Pageable* Heap::GetD3D12Pageable() const {
|
||||
return mD3d12Pageable.Get();
|
||||
}
|
||||
|
||||
MemorySegment Heap::GetMemorySegment() const {
|
||||
return mMemorySegment;
|
||||
}
|
||||
|
||||
Serial Heap::GetLastUsage() const {
|
||||
return mLastUsage;
|
||||
}
|
||||
|
||||
void Heap::SetLastUsage(Serial serial) {
|
||||
mLastUsage = serial;
|
||||
}
|
||||
|
||||
uint64_t Heap::GetLastSubmission() const {
|
||||
return mLastSubmission;
|
||||
}
|
||||
|
||||
void Heap::SetLastSubmission(Serial serial) {
|
||||
mLastSubmission = serial;
|
||||
}
|
||||
|
||||
uint64_t Heap::GetSize() const {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
bool Heap::IsInResidencyLRUCache() const {
|
||||
return IsInList();
|
||||
}
|
||||
|
||||
void Heap::IncrementResidencyLock() {
|
||||
mResidencyLockRefCount++;
|
||||
}
|
||||
|
||||
void Heap::DecrementResidencyLock() {
|
||||
mResidencyLockRefCount--;
|
||||
}
|
||||
|
||||
bool Heap::IsResidencyLocked() const {
|
||||
if (mResidencyLockRefCount == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return mD3d12Heap.Get();
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::d3d12
|
|
@ -15,67 +15,25 @@
|
|||
#ifndef DAWNNATIVE_D3D12_HEAPD3D12_H_
|
||||
#define DAWNNATIVE_D3D12_HEAPD3D12_H_
|
||||
|
||||
#include "common/LinkedList.h"
|
||||
#include "common/Serial.h"
|
||||
#include "dawn_native/D3D12Backend.h"
|
||||
#include "dawn_native/ResourceHeap.h"
|
||||
#include "dawn_native/d3d12/PageableD3D12.h"
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
class Device;
|
||||
|
||||
// This class is used to represent heap allocations, but also serves as a node within the
|
||||
// ResidencyManager's LRU cache. This node is inserted into the LRU-cache when it is first
|
||||
// allocated, and any time it is scheduled to be used by the GPU. This node is removed from the
|
||||
// LRU cache when it is evicted from resident memory due to budget constraints, or when the heap
|
||||
// is destroyed.
|
||||
class Heap : public ResourceHeapBase, public LinkNode<Heap> {
|
||||
// This class is used to represent ID3D12Heap allocations, as well as an implicit heap
|
||||
// representing a directly allocated resource. It inherits from Pageable because each Heap must
|
||||
// be represented in the ResidencyManager.
|
||||
class Heap : public ResourceHeapBase, public Pageable {
|
||||
public:
|
||||
Heap(ComPtr<ID3D12Pageable> d3d12Pageable, MemorySegment memorySegment, uint64_t size);
|
||||
~Heap();
|
||||
|
||||
ID3D12Heap* GetD3D12Heap() const;
|
||||
ID3D12Pageable* GetD3D12Pageable() const;
|
||||
MemorySegment GetMemorySegment() const;
|
||||
|
||||
// We set mLastRecordingSerial to denote the serial this heap was last recorded to be used.
|
||||
// We must check this serial against the current serial when recording heap usages to ensure
|
||||
// we do not process residency for this heap multiple times.
|
||||
Serial GetLastUsage() const;
|
||||
void SetLastUsage(Serial serial);
|
||||
|
||||
// The residency manager must know the last serial that any portion of the heap was
|
||||
// submitted to be used so that we can ensure this heap stays resident in memory at least
|
||||
// until that serial has completed.
|
||||
uint64_t GetLastSubmission() const;
|
||||
void SetLastSubmission(Serial serial);
|
||||
|
||||
uint64_t GetSize() const;
|
||||
|
||||
bool IsInResidencyLRUCache() const;
|
||||
|
||||
// In some scenarios, such as async buffer mapping, we must lock residency to ensure the
|
||||
// heap cannot be evicted. Because multiple buffers may be mapped in a single heap, we must
|
||||
// track the number of resources currently locked.
|
||||
void IncrementResidencyLock();
|
||||
void DecrementResidencyLock();
|
||||
bool IsResidencyLocked() const;
|
||||
|
||||
private:
|
||||
ComPtr<ID3D12Pageable> mD3d12Pageable;
|
||||
MemorySegment mMemorySegment;
|
||||
// mLastUsage denotes the last time this heap was recorded for use.
|
||||
Serial mLastUsage = 0;
|
||||
// mLastSubmission denotes the last time this heap was submitted to the GPU. Note that
|
||||
// although this variable often contains the same value as mLastUsage, it can differ in some
|
||||
// situations. When some asynchronous APIs (like SetSubData) are called, mLastUsage is
|
||||
// updated upon the call, but the backend operation is deferred until the next submission
|
||||
// to the GPU. This makes mLastSubmission unique from mLastUsage, and allows us to
|
||||
// accurately identify when heaps are evictable.
|
||||
Serial mLastSubmission = 0;
|
||||
uint32_t mResidencyLockRefCount = 0;
|
||||
uint64_t mSize = 0;
|
||||
ComPtr<ID3D12Heap> mD3d12Heap;
|
||||
};
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright 2020 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/PageableD3D12.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
Pageable::Pageable(ComPtr<ID3D12Pageable> d3d12Pageable,
|
||||
MemorySegment memorySegment,
|
||||
uint64_t size)
|
||||
: mD3d12Pageable(std::move(d3d12Pageable)), mMemorySegment(memorySegment), mSize(size) {
|
||||
}
|
||||
|
||||
// When a pageable is destroyed, it no longer resides in resident memory, so we must evict
|
||||
// it from the LRU cache. If this heap is not manually removed from the LRU-cache, the
|
||||
// ResidencyManager will attempt to use it after it has been deallocated.
|
||||
Pageable::~Pageable() {
|
||||
if (IsInResidencyLRUCache()) {
|
||||
RemoveFromList();
|
||||
}
|
||||
}
|
||||
|
||||
ID3D12Pageable* Pageable::GetD3D12Pageable() const {
|
||||
return mD3d12Pageable.Get();
|
||||
}
|
||||
|
||||
Serial Pageable::GetLastUsage() const {
|
||||
return mLastUsage;
|
||||
}
|
||||
|
||||
void Pageable::SetLastUsage(Serial serial) {
|
||||
mLastUsage = serial;
|
||||
}
|
||||
|
||||
uint64_t Pageable::GetLastSubmission() const {
|
||||
return mLastSubmission;
|
||||
}
|
||||
|
||||
void Pageable::SetLastSubmission(Serial serial) {
|
||||
mLastSubmission = serial;
|
||||
}
|
||||
|
||||
MemorySegment Pageable::GetMemorySegment() const {
|
||||
return mMemorySegment;
|
||||
}
|
||||
|
||||
uint64_t Pageable::GetSize() const {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
bool Pageable::IsInResidencyLRUCache() const {
|
||||
return IsInList();
|
||||
}
|
||||
|
||||
void Pageable::IncrementResidencyLock() {
|
||||
mResidencyLockRefCount++;
|
||||
}
|
||||
|
||||
void Pageable::DecrementResidencyLock() {
|
||||
mResidencyLockRefCount--;
|
||||
}
|
||||
|
||||
bool Pageable::IsResidencyLocked() const {
|
||||
return mResidencyLockRefCount != 0;
|
||||
}
|
||||
}} // namespace dawn_native::d3d12
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright 2020 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_PAGEABLED3D12_H_
|
||||
#define DAWNNATIVE_D3D12_PAGEABLED3D12_H_
|
||||
|
||||
#include "common/LinkedList.h"
|
||||
#include "common/Serial.h"
|
||||
#include "dawn_native/D3D12Backend.h"
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
// This class is used to represent ID3D12Pageable allocations, and also serves as a node within
|
||||
// the ResidencyManager's LRU cache. This node is inserted into the LRU-cache when it is first
|
||||
// allocated, and any time it is scheduled to be used by the GPU. This node is removed from the
|
||||
// LRU cache when it is evicted from resident memory due to budget constraints, or when the
|
||||
// pageable allocation is released.
|
||||
class Pageable : public LinkNode<Pageable> {
|
||||
public:
|
||||
Pageable(ComPtr<ID3D12Pageable> d3d12Pageable, MemorySegment memorySegment, uint64_t size);
|
||||
~Pageable();
|
||||
|
||||
ID3D12Pageable* GetD3D12Pageable() const;
|
||||
|
||||
// We set mLastRecordingSerial to denote the serial this pageable was last recorded to be
|
||||
// used. We must check this serial against the current serial when recording usages to
|
||||
// ensure we do not process residency for this pageable multiple times.
|
||||
Serial GetLastUsage() const;
|
||||
void SetLastUsage(Serial serial);
|
||||
|
||||
// The residency manager must know the last serial that any portion of the pageable was
|
||||
// submitted to be used so that we can ensure this pageable stays resident in memory at
|
||||
// least until that serial has completed.
|
||||
uint64_t GetLastSubmission() const;
|
||||
void SetLastSubmission(Serial serial);
|
||||
|
||||
MemorySegment GetMemorySegment() const;
|
||||
|
||||
uint64_t GetSize() const;
|
||||
|
||||
bool IsInResidencyLRUCache() const;
|
||||
|
||||
// In some scenarios, such as async buffer mapping or descriptor heaps, we must lock
|
||||
// residency to ensure the pageable cannot be evicted. Because multiple buffers may be
|
||||
// mapped in a single heap, we must track the number of resources currently locked.
|
||||
void IncrementResidencyLock();
|
||||
void DecrementResidencyLock();
|
||||
bool IsResidencyLocked() const;
|
||||
|
||||
protected:
|
||||
ComPtr<ID3D12Pageable> mD3d12Pageable;
|
||||
|
||||
private:
|
||||
// mLastUsage denotes the last time this pageable was recorded for use.
|
||||
Serial mLastUsage = 0;
|
||||
// mLastSubmission denotes the last time this pageable was submitted to the GPU. Note that
|
||||
// although this variable often contains the same value as mLastUsage, it can differ in some
|
||||
// situations. When some asynchronous APIs (like SetSubData) are called, mLastUsage is
|
||||
// updated upon the call, but the backend operation is deferred until the next submission
|
||||
// to the GPU. This makes mLastSubmission unique from mLastUsage, and allows us to
|
||||
// accurately identify when a pageable can be evicted.
|
||||
Serial mLastSubmission = 0;
|
||||
MemorySegment mMemorySegment;
|
||||
uint32_t mResidencyLockRefCount = 0;
|
||||
uint64_t mSize = 0;
|
||||
};
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
||||
#endif
|
|
@ -144,12 +144,12 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
// Removes a heap from the LRU and returns the least recently used heap when possible. Returns
|
||||
// nullptr when nothing further can be evicted.
|
||||
ResultOrError<Heap*> ResidencyManager::RemoveSingleEntryFromLRU(
|
||||
ResultOrError<Pageable*> ResidencyManager::RemoveSingleEntryFromLRU(
|
||||
MemorySegmentInfo* memorySegment) {
|
||||
ASSERT(!memorySegment->lruCache.empty());
|
||||
Heap* heap = memorySegment->lruCache.head()->value();
|
||||
Pageable* pageable = memorySegment->lruCache.head()->value();
|
||||
|
||||
Serial lastSubmissionSerial = heap->GetLastSubmission();
|
||||
Serial lastSubmissionSerial = pageable->GetLastSubmission();
|
||||
|
||||
// If the next candidate for eviction was inserted into the LRU during the current serial,
|
||||
// it is because more memory is being used in a single command list than is available.
|
||||
|
@ -164,8 +164,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
DAWN_TRY(mDevice->WaitForSerial(lastSubmissionSerial));
|
||||
}
|
||||
|
||||
heap->RemoveFromList();
|
||||
return heap;
|
||||
pageable->RemoveFromList();
|
||||
return pageable;
|
||||
}
|
||||
|
||||
MaybeError ResidencyManager::EnsureCanAllocate(uint64_t allocationSize,
|
||||
|
@ -197,16 +197,16 @@ namespace dawn_native { namespace d3d12 {
|
|||
uint64_t sizeNeededToBeUnderBudget = memoryUsageAfterMakeResident - memorySegment->budget;
|
||||
uint64_t sizeEvicted = 0;
|
||||
while (sizeEvicted < sizeNeededToBeUnderBudget) {
|
||||
Heap* heap;
|
||||
DAWN_TRY_ASSIGN(heap, RemoveSingleEntryFromLRU(memorySegment));
|
||||
Pageable* pageable;
|
||||
DAWN_TRY_ASSIGN(pageable, RemoveSingleEntryFromLRU(memorySegment));
|
||||
|
||||
// If no heap was returned, then nothing more can be evicted.
|
||||
if (heap == nullptr) {
|
||||
if (pageable == nullptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
sizeEvicted += heap->GetSize();
|
||||
resourcesToEvict.push_back(heap->GetD3D12Pageable());
|
||||
sizeEvicted += pageable->GetSize();
|
||||
resourcesToEvict.push_back(pageable->GetD3D12Pageable());
|
||||
}
|
||||
|
||||
if (resourcesToEvict.size() > 0) {
|
||||
|
@ -287,13 +287,13 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
// Inserts a heap at the bottom of the LRU. The passed heap must be resident or scheduled to
|
||||
// become resident within the current serial.
|
||||
void ResidencyManager::TrackResidentAllocation(Heap* heap) {
|
||||
void ResidencyManager::TrackResidentAllocation(Pageable* pageable) {
|
||||
if (!mResidencyManagementEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(heap->IsInList() == false);
|
||||
GetMemorySegmentInfo(heap->GetMemorySegment())->lruCache.Append(heap);
|
||||
ASSERT(pageable->IsInList() == false);
|
||||
GetMemorySegmentInfo(pageable->GetMemorySegment())->lruCache.Append(pageable);
|
||||
}
|
||||
|
||||
// Places an artifical cap on Dawn's budget so we can test in a predictable manner. If used,
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
class Device;
|
||||
class Heap;
|
||||
class Pageable;
|
||||
|
||||
class ResidencyManager {
|
||||
public:
|
||||
|
@ -41,14 +42,14 @@ namespace dawn_native { namespace d3d12 {
|
|||
uint64_t SetExternalMemoryReservation(MemorySegment segment,
|
||||
uint64_t requestedReservationSize);
|
||||
|
||||
void TrackResidentAllocation(Heap* heap);
|
||||
void TrackResidentAllocation(Pageable* pageable);
|
||||
|
||||
void RestrictBudgetForTesting(uint64_t artificialBudgetCap);
|
||||
|
||||
private:
|
||||
struct MemorySegmentInfo {
|
||||
const DXGI_MEMORY_SEGMENT_GROUP dxgiSegment;
|
||||
LinkedList<Heap> lruCache = {};
|
||||
LinkedList<Pageable> lruCache = {};
|
||||
uint64_t budget = 0;
|
||||
uint64_t usage = 0;
|
||||
uint64_t externalReservation = 0;
|
||||
|
@ -62,7 +63,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
MemorySegmentInfo* GetMemorySegmentInfo(MemorySegment memorySegment);
|
||||
MaybeError EnsureCanMakeResident(uint64_t allocationSize, MemorySegmentInfo* memorySegment);
|
||||
ResultOrError<Heap*> RemoveSingleEntryFromLRU(MemorySegmentInfo* memorySegment);
|
||||
ResultOrError<Pageable*> RemoveSingleEntryFromLRU(MemorySegmentInfo* memorySegment);
|
||||
void UpdateVideoMemoryInfo();
|
||||
void UpdateMemorySegmentInfo(MemorySegmentInfo* segmentInfo);
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
return false;
|
||||
}
|
||||
|
||||
ID3D12DescriptorHeap* descriptorHeap = mHeap.Get();
|
||||
ID3D12DescriptorHeap* descriptorHeap = mHeap->GetD3D12DescriptorHeap();
|
||||
|
||||
const uint64_t heapOffset = mSizeIncrement * startOffset;
|
||||
|
||||
|
@ -99,7 +99,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
}
|
||||
|
||||
ID3D12DescriptorHeap* ShaderVisibleDescriptorAllocator::GetShaderVisibleHeap() const {
|
||||
return mHeap.Get();
|
||||
return mHeap->GetD3D12DescriptorHeap();
|
||||
}
|
||||
|
||||
void ShaderVisibleDescriptorAllocator::Tick(uint64_t completedSerial) {
|
||||
|
@ -108,7 +108,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
// Creates a GPU descriptor heap that manages descriptors in a FIFO queue.
|
||||
MaybeError ShaderVisibleDescriptorAllocator::AllocateAndSwitchShaderVisibleHeap() {
|
||||
ComPtr<ID3D12DescriptorHeap> heap;
|
||||
std::unique_ptr<ShaderVisibleDescriptorHeap> descriptorHeap;
|
||||
// Return the switched out heap to the pool and retrieve the oldest heap that is no longer
|
||||
// used by GPU. This maintains a heap buffer to avoid frequently re-creating heaps for heavy
|
||||
// users.
|
||||
|
@ -119,7 +119,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
// Recycle existing heap if possible.
|
||||
if (!mPool.empty() && mPool.front().heapSerial <= mDevice->GetCompletedCommandSerial()) {
|
||||
heap = std::move(mPool.front().heap);
|
||||
descriptorHeap = std::move(mPool.front().heap);
|
||||
mPool.pop_front();
|
||||
}
|
||||
|
||||
|
@ -129,19 +129,23 @@ namespace dawn_native { namespace d3d12 {
|
|||
const uint32_t descriptorCount = GetD3D12ShaderVisibleHeapSize(
|
||||
mHeapType, mDevice->IsToggleEnabled(Toggle::UseD3D12SmallShaderVisibleHeapForTesting));
|
||||
|
||||
if (heap == nullptr) {
|
||||
if (descriptorHeap == nullptr) {
|
||||
ComPtr<ID3D12DescriptorHeap> d3d12DescriptorHeap;
|
||||
D3D12_DESCRIPTOR_HEAP_DESC heapDescriptor;
|
||||
heapDescriptor.Type = mHeapType;
|
||||
heapDescriptor.NumDescriptors = descriptorCount;
|
||||
heapDescriptor.Flags = GetD3D12HeapFlags(mHeapType);
|
||||
heapDescriptor.NodeMask = 0;
|
||||
DAWN_TRY(CheckOutOfMemoryHRESULT(mDevice->GetD3D12Device()->CreateDescriptorHeap(
|
||||
&heapDescriptor, IID_PPV_ARGS(&heap)),
|
||||
DAWN_TRY(
|
||||
CheckOutOfMemoryHRESULT(mDevice->GetD3D12Device()->CreateDescriptorHeap(
|
||||
&heapDescriptor, IID_PPV_ARGS(&d3d12DescriptorHeap)),
|
||||
"ID3D12Device::CreateDescriptorHeap"));
|
||||
descriptorHeap = std::make_unique<ShaderVisibleDescriptorHeap>(
|
||||
std::move(d3d12DescriptorHeap), mSizeIncrement * descriptorCount);
|
||||
}
|
||||
|
||||
// Create a FIFO buffer from the recently created heap.
|
||||
mHeap = std::move(heap);
|
||||
mHeap = std::move(descriptorHeap);
|
||||
mAllocator = RingBufferAllocator(descriptorCount);
|
||||
|
||||
// Invalidate all bindgroup allocations on previously bound heaps by incrementing the heap
|
||||
|
@ -171,4 +175,15 @@ namespace dawn_native { namespace d3d12 {
|
|||
return (allocation.GetLastUsageSerial() > mDevice->GetCompletedCommandSerial() &&
|
||||
allocation.GetHeapSerial() == mHeapSerial);
|
||||
}
|
||||
|
||||
ShaderVisibleDescriptorHeap::ShaderVisibleDescriptorHeap(
|
||||
ComPtr<ID3D12DescriptorHeap> d3d12DescriptorHeap,
|
||||
uint64_t size)
|
||||
: Pageable(d3d12DescriptorHeap, MemorySegment::Local, size),
|
||||
mD3d12DescriptorHeap(std::move(d3d12DescriptorHeap)) {
|
||||
}
|
||||
|
||||
ID3D12DescriptorHeap* ShaderVisibleDescriptorHeap::GetD3D12DescriptorHeap() const {
|
||||
return mD3d12DescriptorHeap.Get();
|
||||
}
|
||||
}} // namespace dawn_native::d3d12
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "dawn_native/Error.h"
|
||||
#include "dawn_native/RingBufferAllocator.h"
|
||||
#include "dawn_native/d3d12/PageableD3D12.h"
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
#include <list>
|
||||
|
@ -32,6 +33,16 @@ namespace dawn_native { namespace d3d12 {
|
|||
class Device;
|
||||
class GPUDescriptorHeapAllocation;
|
||||
|
||||
class ShaderVisibleDescriptorHeap : public Pageable {
|
||||
public:
|
||||
ShaderVisibleDescriptorHeap(ComPtr<ID3D12DescriptorHeap> d3d12DescriptorHeap,
|
||||
uint64_t size);
|
||||
ID3D12DescriptorHeap* GetD3D12DescriptorHeap() const;
|
||||
|
||||
private:
|
||||
ComPtr<ID3D12DescriptorHeap> mD3d12DescriptorHeap;
|
||||
};
|
||||
|
||||
class ShaderVisibleDescriptorAllocator {
|
||||
public:
|
||||
static ResultOrError<std::unique_ptr<ShaderVisibleDescriptorAllocator>> Create(
|
||||
|
@ -62,10 +73,10 @@ namespace dawn_native { namespace d3d12 {
|
|||
private:
|
||||
struct SerialDescriptorHeap {
|
||||
Serial heapSerial;
|
||||
ComPtr<ID3D12DescriptorHeap> heap;
|
||||
std::unique_ptr<ShaderVisibleDescriptorHeap> heap;
|
||||
};
|
||||
|
||||
ComPtr<ID3D12DescriptorHeap> mHeap;
|
||||
std::unique_ptr<ShaderVisibleDescriptorHeap> mHeap;
|
||||
RingBufferAllocator mAllocator;
|
||||
std::list<SerialDescriptorHeap> mPool;
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE mHeapType;
|
||||
|
|
Loading…
Reference in New Issue