mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-08-09 13:39:20 +00:00
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/HeapD3D12.h",
|
||||||
"d3d12/NativeSwapChainImplD3D12.cpp",
|
"d3d12/NativeSwapChainImplD3D12.cpp",
|
||||||
"d3d12/NativeSwapChainImplD3D12.h",
|
"d3d12/NativeSwapChainImplD3D12.h",
|
||||||
|
"d3d12/PageableD3D12.cpp",
|
||||||
|
"d3d12/PageableD3D12.h",
|
||||||
"d3d12/PipelineLayoutD3D12.cpp",
|
"d3d12/PipelineLayoutD3D12.cpp",
|
||||||
"d3d12/PipelineLayoutD3D12.h",
|
"d3d12/PipelineLayoutD3D12.h",
|
||||||
"d3d12/PlatformFunctions.cpp",
|
"d3d12/PlatformFunctions.cpp",
|
||||||
|
@ -193,6 +193,8 @@ if (DAWN_ENABLE_D3D12)
|
|||||||
"d3d12/HeapD3D12.h"
|
"d3d12/HeapD3D12.h"
|
||||||
"d3d12/NativeSwapChainImplD3D12.cpp"
|
"d3d12/NativeSwapChainImplD3D12.cpp"
|
||||||
"d3d12/NativeSwapChainImplD3D12.h"
|
"d3d12/NativeSwapChainImplD3D12.h"
|
||||||
|
"d3d12/PageableD3D12.cpp"
|
||||||
|
"d3d12/PageableD3D12.h"
|
||||||
"d3d12/PipelineLayoutD3D12.cpp"
|
"d3d12/PipelineLayoutD3D12.cpp"
|
||||||
"d3d12/PipelineLayoutD3D12.h"
|
"d3d12/PipelineLayoutD3D12.h"
|
||||||
"d3d12/PlatformFunctions.cpp"
|
"d3d12/PlatformFunctions.cpp"
|
||||||
|
@ -16,16 +16,8 @@
|
|||||||
|
|
||||||
namespace dawn_native { namespace d3d12 {
|
namespace dawn_native { namespace d3d12 {
|
||||||
Heap::Heap(ComPtr<ID3D12Pageable> d3d12Pageable, MemorySegment memorySegment, uint64_t size)
|
Heap::Heap(ComPtr<ID3D12Pageable> d3d12Pageable, MemorySegment memorySegment, uint64_t size)
|
||||||
: mD3d12Pageable(std::move(d3d12Pageable)), mMemorySegment(memorySegment), mSize(size) {
|
: Pageable(std::move(d3d12Pageable), memorySegment, size) {
|
||||||
}
|
mD3d12Pageable.As(&mD3d12Heap);
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function should only be used when mD3D12Pageable was initialized from a
|
// 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
|
// ID3D12Pageable was initially created as an ID3D12Resource (i.e. DirectAllocation), then
|
||||||
// use GetD3D12Pageable().
|
// use GetD3D12Pageable().
|
||||||
ID3D12Heap* Heap::GetD3D12Heap() const {
|
ID3D12Heap* Heap::GetD3D12Heap() const {
|
||||||
ComPtr<ID3D12Heap> heap;
|
return mD3d12Heap.Get();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}} // namespace dawn_native::d3d12
|
}} // namespace dawn_native::d3d12
|
@ -15,67 +15,25 @@
|
|||||||
#ifndef DAWNNATIVE_D3D12_HEAPD3D12_H_
|
#ifndef DAWNNATIVE_D3D12_HEAPD3D12_H_
|
||||||
#define 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/ResourceHeap.h"
|
||||||
|
#include "dawn_native/d3d12/PageableD3D12.h"
|
||||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||||
|
|
||||||
namespace dawn_native { namespace d3d12 {
|
namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
class Device;
|
class Device;
|
||||||
|
|
||||||
// This class is used to represent heap allocations, but also serves as a node within the
|
// This class is used to represent ID3D12Heap allocations, as well as an implicit heap
|
||||||
// ResidencyManager's LRU cache. This node is inserted into the LRU-cache when it is first
|
// representing a directly allocated resource. It inherits from Pageable because each Heap must
|
||||||
// allocated, and any time it is scheduled to be used by the GPU. This node is removed from the
|
// be represented in the ResidencyManager.
|
||||||
// LRU cache when it is evicted from resident memory due to budget constraints, or when the heap
|
class Heap : public ResourceHeapBase, public Pageable {
|
||||||
// is destroyed.
|
|
||||||
class Heap : public ResourceHeapBase, public LinkNode<Heap> {
|
|
||||||
public:
|
public:
|
||||||
Heap(ComPtr<ID3D12Pageable> d3d12Pageable, MemorySegment memorySegment, uint64_t size);
|
Heap(ComPtr<ID3D12Pageable> d3d12Pageable, MemorySegment memorySegment, uint64_t size);
|
||||||
~Heap();
|
|
||||||
|
|
||||||
ID3D12Heap* GetD3D12Heap() const;
|
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:
|
private:
|
||||||
ComPtr<ID3D12Pageable> mD3d12Pageable;
|
ComPtr<ID3D12Heap> mD3d12Heap;
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
}} // namespace dawn_native::d3d12
|
}} // namespace dawn_native::d3d12
|
||||||
|
|
||||||
|
76
src/dawn_native/d3d12/PageableD3D12.cpp
Normal file
76
src/dawn_native/d3d12/PageableD3D12.cpp
Normal file
@ -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
|
80
src/dawn_native/d3d12/PageableD3D12.h
Normal file
80
src/dawn_native/d3d12/PageableD3D12.h
Normal file
@ -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
|
// Removes a heap from the LRU and returns the least recently used heap when possible. Returns
|
||||||
// nullptr when nothing further can be evicted.
|
// nullptr when nothing further can be evicted.
|
||||||
ResultOrError<Heap*> ResidencyManager::RemoveSingleEntryFromLRU(
|
ResultOrError<Pageable*> ResidencyManager::RemoveSingleEntryFromLRU(
|
||||||
MemorySegmentInfo* memorySegment) {
|
MemorySegmentInfo* memorySegment) {
|
||||||
ASSERT(!memorySegment->lruCache.empty());
|
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,
|
// 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.
|
// 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));
|
DAWN_TRY(mDevice->WaitForSerial(lastSubmissionSerial));
|
||||||
}
|
}
|
||||||
|
|
||||||
heap->RemoveFromList();
|
pageable->RemoveFromList();
|
||||||
return heap;
|
return pageable;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError ResidencyManager::EnsureCanAllocate(uint64_t allocationSize,
|
MaybeError ResidencyManager::EnsureCanAllocate(uint64_t allocationSize,
|
||||||
@ -197,16 +197,16 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
uint64_t sizeNeededToBeUnderBudget = memoryUsageAfterMakeResident - memorySegment->budget;
|
uint64_t sizeNeededToBeUnderBudget = memoryUsageAfterMakeResident - memorySegment->budget;
|
||||||
uint64_t sizeEvicted = 0;
|
uint64_t sizeEvicted = 0;
|
||||||
while (sizeEvicted < sizeNeededToBeUnderBudget) {
|
while (sizeEvicted < sizeNeededToBeUnderBudget) {
|
||||||
Heap* heap;
|
Pageable* pageable;
|
||||||
DAWN_TRY_ASSIGN(heap, RemoveSingleEntryFromLRU(memorySegment));
|
DAWN_TRY_ASSIGN(pageable, RemoveSingleEntryFromLRU(memorySegment));
|
||||||
|
|
||||||
// If no heap was returned, then nothing more can be evicted.
|
// If no heap was returned, then nothing more can be evicted.
|
||||||
if (heap == nullptr) {
|
if (pageable == nullptr) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sizeEvicted += heap->GetSize();
|
sizeEvicted += pageable->GetSize();
|
||||||
resourcesToEvict.push_back(heap->GetD3D12Pageable());
|
resourcesToEvict.push_back(pageable->GetD3D12Pageable());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resourcesToEvict.size() > 0) {
|
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
|
// Inserts a heap at the bottom of the LRU. The passed heap must be resident or scheduled to
|
||||||
// become resident within the current serial.
|
// become resident within the current serial.
|
||||||
void ResidencyManager::TrackResidentAllocation(Heap* heap) {
|
void ResidencyManager::TrackResidentAllocation(Pageable* pageable) {
|
||||||
if (!mResidencyManagementEnabled) {
|
if (!mResidencyManagementEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(heap->IsInList() == false);
|
ASSERT(pageable->IsInList() == false);
|
||||||
GetMemorySegmentInfo(heap->GetMemorySegment())->lruCache.Append(heap);
|
GetMemorySegmentInfo(pageable->GetMemorySegment())->lruCache.Append(pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Places an artifical cap on Dawn's budget so we can test in a predictable manner. If used,
|
// 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 Device;
|
||||||
class Heap;
|
class Heap;
|
||||||
|
class Pageable;
|
||||||
|
|
||||||
class ResidencyManager {
|
class ResidencyManager {
|
||||||
public:
|
public:
|
||||||
@ -41,14 +42,14 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
uint64_t SetExternalMemoryReservation(MemorySegment segment,
|
uint64_t SetExternalMemoryReservation(MemorySegment segment,
|
||||||
uint64_t requestedReservationSize);
|
uint64_t requestedReservationSize);
|
||||||
|
|
||||||
void TrackResidentAllocation(Heap* heap);
|
void TrackResidentAllocation(Pageable* pageable);
|
||||||
|
|
||||||
void RestrictBudgetForTesting(uint64_t artificialBudgetCap);
|
void RestrictBudgetForTesting(uint64_t artificialBudgetCap);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct MemorySegmentInfo {
|
struct MemorySegmentInfo {
|
||||||
const DXGI_MEMORY_SEGMENT_GROUP dxgiSegment;
|
const DXGI_MEMORY_SEGMENT_GROUP dxgiSegment;
|
||||||
LinkedList<Heap> lruCache = {};
|
LinkedList<Pageable> lruCache = {};
|
||||||
uint64_t budget = 0;
|
uint64_t budget = 0;
|
||||||
uint64_t usage = 0;
|
uint64_t usage = 0;
|
||||||
uint64_t externalReservation = 0;
|
uint64_t externalReservation = 0;
|
||||||
@ -62,7 +63,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
|
|
||||||
MemorySegmentInfo* GetMemorySegmentInfo(MemorySegment memorySegment);
|
MemorySegmentInfo* GetMemorySegmentInfo(MemorySegment memorySegment);
|
||||||
MaybeError EnsureCanMakeResident(uint64_t allocationSize, MemorySegmentInfo* memorySegment);
|
MaybeError EnsureCanMakeResident(uint64_t allocationSize, MemorySegmentInfo* memorySegment);
|
||||||
ResultOrError<Heap*> RemoveSingleEntryFromLRU(MemorySegmentInfo* memorySegment);
|
ResultOrError<Pageable*> RemoveSingleEntryFromLRU(MemorySegmentInfo* memorySegment);
|
||||||
void UpdateVideoMemoryInfo();
|
void UpdateVideoMemoryInfo();
|
||||||
void UpdateMemorySegmentInfo(MemorySegmentInfo* segmentInfo);
|
void UpdateMemorySegmentInfo(MemorySegmentInfo* segmentInfo);
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D12DescriptorHeap* descriptorHeap = mHeap.Get();
|
ID3D12DescriptorHeap* descriptorHeap = mHeap->GetD3D12DescriptorHeap();
|
||||||
|
|
||||||
const uint64_t heapOffset = mSizeIncrement * startOffset;
|
const uint64_t heapOffset = mSizeIncrement * startOffset;
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ID3D12DescriptorHeap* ShaderVisibleDescriptorAllocator::GetShaderVisibleHeap() const {
|
ID3D12DescriptorHeap* ShaderVisibleDescriptorAllocator::GetShaderVisibleHeap() const {
|
||||||
return mHeap.Get();
|
return mHeap->GetD3D12DescriptorHeap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderVisibleDescriptorAllocator::Tick(uint64_t completedSerial) {
|
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.
|
// Creates a GPU descriptor heap that manages descriptors in a FIFO queue.
|
||||||
MaybeError ShaderVisibleDescriptorAllocator::AllocateAndSwitchShaderVisibleHeap() {
|
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
|
// 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
|
// used by GPU. This maintains a heap buffer to avoid frequently re-creating heaps for heavy
|
||||||
// users.
|
// users.
|
||||||
@ -119,7 +119,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
|
|
||||||
// Recycle existing heap if possible.
|
// Recycle existing heap if possible.
|
||||||
if (!mPool.empty() && mPool.front().heapSerial <= mDevice->GetCompletedCommandSerial()) {
|
if (!mPool.empty() && mPool.front().heapSerial <= mDevice->GetCompletedCommandSerial()) {
|
||||||
heap = std::move(mPool.front().heap);
|
descriptorHeap = std::move(mPool.front().heap);
|
||||||
mPool.pop_front();
|
mPool.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,19 +129,23 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
const uint32_t descriptorCount = GetD3D12ShaderVisibleHeapSize(
|
const uint32_t descriptorCount = GetD3D12ShaderVisibleHeapSize(
|
||||||
mHeapType, mDevice->IsToggleEnabled(Toggle::UseD3D12SmallShaderVisibleHeapForTesting));
|
mHeapType, mDevice->IsToggleEnabled(Toggle::UseD3D12SmallShaderVisibleHeapForTesting));
|
||||||
|
|
||||||
if (heap == nullptr) {
|
if (descriptorHeap == nullptr) {
|
||||||
|
ComPtr<ID3D12DescriptorHeap> d3d12DescriptorHeap;
|
||||||
D3D12_DESCRIPTOR_HEAP_DESC heapDescriptor;
|
D3D12_DESCRIPTOR_HEAP_DESC heapDescriptor;
|
||||||
heapDescriptor.Type = mHeapType;
|
heapDescriptor.Type = mHeapType;
|
||||||
heapDescriptor.NumDescriptors = descriptorCount;
|
heapDescriptor.NumDescriptors = descriptorCount;
|
||||||
heapDescriptor.Flags = GetD3D12HeapFlags(mHeapType);
|
heapDescriptor.Flags = GetD3D12HeapFlags(mHeapType);
|
||||||
heapDescriptor.NodeMask = 0;
|
heapDescriptor.NodeMask = 0;
|
||||||
DAWN_TRY(CheckOutOfMemoryHRESULT(mDevice->GetD3D12Device()->CreateDescriptorHeap(
|
DAWN_TRY(
|
||||||
&heapDescriptor, IID_PPV_ARGS(&heap)),
|
CheckOutOfMemoryHRESULT(mDevice->GetD3D12Device()->CreateDescriptorHeap(
|
||||||
"ID3D12Device::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.
|
// Create a FIFO buffer from the recently created heap.
|
||||||
mHeap = std::move(heap);
|
mHeap = std::move(descriptorHeap);
|
||||||
mAllocator = RingBufferAllocator(descriptorCount);
|
mAllocator = RingBufferAllocator(descriptorCount);
|
||||||
|
|
||||||
// Invalidate all bindgroup allocations on previously bound heaps by incrementing the heap
|
// 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() &&
|
return (allocation.GetLastUsageSerial() > mDevice->GetCompletedCommandSerial() &&
|
||||||
allocation.GetHeapSerial() == mHeapSerial);
|
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
|
}} // namespace dawn_native::d3d12
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "dawn_native/Error.h"
|
#include "dawn_native/Error.h"
|
||||||
#include "dawn_native/RingBufferAllocator.h"
|
#include "dawn_native/RingBufferAllocator.h"
|
||||||
|
#include "dawn_native/d3d12/PageableD3D12.h"
|
||||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -32,6 +33,16 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
class Device;
|
class Device;
|
||||||
class GPUDescriptorHeapAllocation;
|
class GPUDescriptorHeapAllocation;
|
||||||
|
|
||||||
|
class ShaderVisibleDescriptorHeap : public Pageable {
|
||||||
|
public:
|
||||||
|
ShaderVisibleDescriptorHeap(ComPtr<ID3D12DescriptorHeap> d3d12DescriptorHeap,
|
||||||
|
uint64_t size);
|
||||||
|
ID3D12DescriptorHeap* GetD3D12DescriptorHeap() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ComPtr<ID3D12DescriptorHeap> mD3d12DescriptorHeap;
|
||||||
|
};
|
||||||
|
|
||||||
class ShaderVisibleDescriptorAllocator {
|
class ShaderVisibleDescriptorAllocator {
|
||||||
public:
|
public:
|
||||||
static ResultOrError<std::unique_ptr<ShaderVisibleDescriptorAllocator>> Create(
|
static ResultOrError<std::unique_ptr<ShaderVisibleDescriptorAllocator>> Create(
|
||||||
@ -62,10 +73,10 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
private:
|
private:
|
||||||
struct SerialDescriptorHeap {
|
struct SerialDescriptorHeap {
|
||||||
Serial heapSerial;
|
Serial heapSerial;
|
||||||
ComPtr<ID3D12DescriptorHeap> heap;
|
std::unique_ptr<ShaderVisibleDescriptorHeap> heap;
|
||||||
};
|
};
|
||||||
|
|
||||||
ComPtr<ID3D12DescriptorHeap> mHeap;
|
std::unique_ptr<ShaderVisibleDescriptorHeap> mHeap;
|
||||||
RingBufferAllocator mAllocator;
|
RingBufferAllocator mAllocator;
|
||||||
std::list<SerialDescriptorHeap> mPool;
|
std::list<SerialDescriptorHeap> mPool;
|
||||||
D3D12_DESCRIPTOR_HEAP_TYPE mHeapType;
|
D3D12_DESCRIPTOR_HEAP_TYPE mHeapType;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user