Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 7359165

Browse files
jvanverthSkia Commit-Bot
authored andcommitted
Automatically grow D3DRenderTargetView heap as needed.
Change-Id: I55cf2daa48ec694fc9e1939e270f55dd7a3162a7 Bug: skia:9935 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/287619 Reviewed-by: Greg Daniel <[email protected]> Commit-Queue: Jim Van Verth <[email protected]>
1 parent c683912 commit 7359165

File tree

7 files changed

+254
-91
lines changed

7 files changed

+254
-91
lines changed

gn/gpu.gni

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,8 @@ skia_direct3d_sources = [
737737
"$_include/gpu/d3d/GrD3DTypes.h",
738738
"$_include/gpu/d3d/GrD3DTypesMinimal.h",
739739
"$_include/private/GrD3DTypesPriv.h",
740+
"$_src/gpu/d3d/GrD3DAttachmentViewManager.cpp",
741+
"$_src/gpu/d3d/GrD3DAttachmentViewManager.h",
740742
"$_src/gpu/d3d/GrD3DBuffer.cpp",
741743
"$_src/gpu/d3d/GrD3DBuffer.h",
742744
"$_src/gpu/d3d/GrD3DCaps.cpp",
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright 2020 Google LLC
3+
*
4+
* Use of this source code is governed by a BSD-style license that can be
5+
* found in the LICENSE file.
6+
*/
7+
8+
#include "src/gpu/d3d/GrD3DAttachmentViewManager.h"
9+
10+
#include "src/gpu/d3d/GrD3DGpu.h"
11+
12+
GrD3DAttachmentViewManager::GrD3DAttachmentViewManager(GrD3DGpu* gpu)
13+
: fRTVDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_RTV)
14+
, fDSVDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_DSV) {}
15+
16+
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DAttachmentViewManager::createRenderTargetView(
17+
GrD3DGpu* gpu, ID3D12Resource* textureResource) {
18+
D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fRTVDescriptorPool.allocateHandle(gpu);
19+
gpu->device()->CreateRenderTargetView(textureResource, nullptr, descriptor);
20+
return descriptor;
21+
}
22+
23+
void GrD3DAttachmentViewManager::recycleRenderTargetView(
24+
D3D12_CPU_DESCRIPTOR_HANDLE* rtvDescriptor) {
25+
fRTVDescriptorPool.releaseHandle(rtvDescriptor);
26+
}
27+
28+
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DAttachmentViewManager::createDepthStencilView(
29+
GrD3DGpu* gpu, ID3D12Resource* textureResource) {
30+
D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fDSVDescriptorPool.allocateHandle(gpu);
31+
gpu->device()->CreateDepthStencilView(textureResource, nullptr, descriptor);
32+
return descriptor;
33+
}
34+
35+
void GrD3DAttachmentViewManager::recycleDepthStencilView(
36+
D3D12_CPU_DESCRIPTOR_HANDLE* dsvDescriptor) {
37+
fDSVDescriptorPool.releaseHandle(dsvDescriptor);
38+
}
39+
40+
////////////////////////////////////////////////////////////////////////////////////////////////
41+
42+
std::unique_ptr<GrD3DAttachmentViewManager::Heap> GrD3DAttachmentViewManager::Heap::Make(
43+
GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE type, unsigned int numDescriptors) {
44+
std::unique_ptr<GrD3DDescriptorHeap> heap =
45+
GrD3DDescriptorHeap::Make(gpu, type, numDescriptors, D3D12_DESCRIPTOR_HEAP_FLAG_NONE);
46+
if (!heap) {
47+
return nullptr;
48+
}
49+
50+
return std::unique_ptr<Heap>(new Heap(heap, numDescriptors));
51+
52+
}
53+
54+
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DAttachmentViewManager::Heap::allocateCPUHandle() {
55+
SkBitSet::OptionalIndex freeBlock = fFreeBlocks.findFirst();
56+
SkASSERT(freeBlock);
57+
fFreeBlocks.reset(*freeBlock);
58+
--fFreeCount;
59+
return fHeap->getCPUHandle(*freeBlock);
60+
}
61+
62+
bool GrD3DAttachmentViewManager::Heap::freeCPUHandle(D3D12_CPU_DESCRIPTOR_HANDLE* handle) {
63+
size_t index;
64+
if (!fHeap->getIndex(*handle, &index)) {
65+
return false;
66+
}
67+
fFreeBlocks.set(index);
68+
++fFreeCount;
69+
handle->ptr = 0;
70+
return true;
71+
}
72+
73+
////////////////////////////////////////////////////////////////////////////////////////////////
74+
75+
GrD3DAttachmentViewManager::HeapPool::HeapPool(GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE heapType)
76+
: fMaxAvailableDescriptors(32)
77+
, fHeapType(heapType) {
78+
std::unique_ptr<GrD3DAttachmentViewManager::Heap> heap =
79+
GrD3DAttachmentViewManager::Heap::Make(gpu, fHeapType, fMaxAvailableDescriptors);
80+
fDescriptorHeaps.push_back(std::move(heap));
81+
}
82+
83+
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DAttachmentViewManager::HeapPool::allocateHandle(GrD3DGpu* gpu) {
84+
for (unsigned int i = 0; i < fDescriptorHeaps.size(); ++i) {
85+
if (fDescriptorHeaps[i]->canAllocate()) {
86+
D3D12_CPU_DESCRIPTOR_HANDLE handle = fDescriptorHeaps[i]->allocateCPUHandle();
87+
return handle;
88+
}
89+
}
90+
91+
// need to allocate more space
92+
std::unique_ptr<GrD3DAttachmentViewManager::Heap> heap =
93+
GrD3DAttachmentViewManager::Heap::Make(gpu, fHeapType, fMaxAvailableDescriptors);
94+
95+
fDescriptorHeaps.push_back(std::move(heap));
96+
fMaxAvailableDescriptors *= 2;
97+
D3D12_CPU_DESCRIPTOR_HANDLE handle =
98+
fDescriptorHeaps[fDescriptorHeaps.size() - 1]->allocateCPUHandle();
99+
return handle;
100+
}
101+
102+
void GrD3DAttachmentViewManager::HeapPool::releaseHandle(
103+
D3D12_CPU_DESCRIPTOR_HANDLE* dsvDescriptor) {
104+
for (unsigned int i = 0; i < fDescriptorHeaps.size(); ++i) {
105+
if (fDescriptorHeaps[i]->freeCPUHandle(dsvDescriptor)) {
106+
return;
107+
}
108+
}
109+
SkASSERT(false);
110+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright 2020 Google LLC
3+
*
4+
* Use of this source code is governed by a BSD-style license that can be
5+
* found in the LICENSE file.
6+
*/
7+
8+
#ifndef GrD3DAttachmentViewManager_DEFINED
9+
#define GrD3DAttachmentViewManager_DEFINED
10+
11+
#include "src/gpu/d3d/GrD3DDescriptorHeap.h"
12+
13+
class GrD3DGpu;
14+
15+
class GrD3DAttachmentViewManager {
16+
public:
17+
GrD3DAttachmentViewManager(GrD3DGpu*);
18+
19+
D3D12_CPU_DESCRIPTOR_HANDLE createRenderTargetView(GrD3DGpu*, ID3D12Resource* textureResource);
20+
void recycleRenderTargetView(D3D12_CPU_DESCRIPTOR_HANDLE*);
21+
22+
D3D12_CPU_DESCRIPTOR_HANDLE createDepthStencilView(GrD3DGpu*, ID3D12Resource* textureResource);
23+
void recycleDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE*);
24+
25+
private:
26+
class Heap {
27+
public:
28+
static std::unique_ptr<Heap> Make(GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE type,
29+
unsigned int numDescriptors);
30+
31+
D3D12_CPU_DESCRIPTOR_HANDLE allocateCPUHandle();
32+
bool freeCPUHandle(D3D12_CPU_DESCRIPTOR_HANDLE*);
33+
34+
bool canAllocate() { return fFreeCount > 0; }
35+
36+
private:
37+
Heap(std::unique_ptr<GrD3DDescriptorHeap>& heap, unsigned int numDescriptors)
38+
: fHeap(std::move(heap))
39+
, fFreeBlocks(numDescriptors)
40+
, fFreeCount(numDescriptors) {
41+
for (unsigned int i = 0; i < numDescriptors; ++i) {
42+
fFreeBlocks.set(i);
43+
}
44+
}
45+
46+
std::unique_ptr<GrD3DDescriptorHeap> fHeap;
47+
SkBitSet fFreeBlocks;
48+
unsigned int fFreeCount;
49+
};
50+
51+
class HeapPool {
52+
public:
53+
HeapPool(GrD3DGpu*, D3D12_DESCRIPTOR_HEAP_TYPE);
54+
55+
D3D12_CPU_DESCRIPTOR_HANDLE allocateHandle(GrD3DGpu*);
56+
void releaseHandle(D3D12_CPU_DESCRIPTOR_HANDLE*);
57+
58+
private:
59+
std::vector<std::unique_ptr<Heap>> fDescriptorHeaps;
60+
int fMaxAvailableDescriptors;
61+
D3D12_DESCRIPTOR_HEAP_TYPE fHeapType;
62+
};
63+
64+
HeapPool fRTVDescriptorPool;
65+
HeapPool fDSVDescriptorPool;
66+
};
67+
68+
#endif

src/gpu/d3d/GrD3DDescriptorHeap.cpp

Lines changed: 17 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
#include "src/gpu/d3d/GrD3DDescriptorHeap.h"
99
#include "src/gpu/d3d/GrD3DGpu.h"
1010

11-
sk_sp<GrD3DDescriptorHeap> GrD3DDescriptorHeap::Make(GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE type,
12-
unsigned int numDescriptors,
13-
D3D12_DESCRIPTOR_HEAP_FLAGS flags) {
11+
std::unique_ptr<GrD3DDescriptorHeap> GrD3DDescriptorHeap::Make(GrD3DGpu* gpu,
12+
D3D12_DESCRIPTOR_HEAP_TYPE type,
13+
unsigned int numDescriptors,
14+
D3D12_DESCRIPTOR_HEAP_FLAGS flags) {
1415
D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
1516
heapDesc.Type = type;
1617
heapDesc.NumDescriptors = numDescriptors;
@@ -19,73 +20,34 @@ sk_sp<GrD3DDescriptorHeap> GrD3DDescriptorHeap::Make(GrD3DGpu* gpu, D3D12_DESCRI
1920
ID3D12DescriptorHeap* heap;
2021
gpu->device()->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&heap));
2122

22-
return sk_sp<GrD3DDescriptorHeap>(
23-
new GrD3DDescriptorHeap(std::move(gr_cp<ID3D12DescriptorHeap>(heap)), heapDesc,
23+
return std::unique_ptr<GrD3DDescriptorHeap>(
24+
new GrD3DDescriptorHeap(std::move(gr_cp<ID3D12DescriptorHeap>(heap)),
2425
gpu->device()->GetDescriptorHandleIncrementSize(type)));
2526
}
2627

2728
GrD3DDescriptorHeap::GrD3DDescriptorHeap(const gr_cp<ID3D12DescriptorHeap>& heap,
28-
const D3D12_DESCRIPTOR_HEAP_DESC& descriptor,
2929
unsigned int handleIncrementSize)
3030
: fHeap(heap)
31-
, fHandleIncrementSize(handleIncrementSize)
32-
, fFreeBlocks(descriptor.NumDescriptors) {
33-
// set all the bits in freeBlocks
34-
for (UINT i = 0; i < descriptor.NumDescriptors; ++i) {
35-
fFreeBlocks.set(i);
36-
}
31+
, fHandleIncrementSize(handleIncrementSize) {
32+
fCPUHeapStart = fHeap->GetCPUDescriptorHandleForHeapStart();
33+
fGPUHeapStart = fHeap->GetGPUDescriptorHandleForHeapStart();
3734
}
3835

39-
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DDescriptorHeap::allocateCPUHandle() {
36+
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DDescriptorHeap::getCPUHandle(unsigned int index) {
4037
// valid only for non-shader-visible heaps
4138
SkASSERT(!SkToBool(fHeap->GetDesc().Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE));
42-
D3D12_CPU_DESCRIPTOR_HANDLE handle = fHeap->GetCPUDescriptorHandleForHeapStart();
43-
SkBitSet::OptionalIndex freeBlock = fFreeBlocks.findFirst();
44-
SkASSERT(freeBlock);
45-
handle.ptr += *freeBlock * fHandleIncrementSize;
46-
fFreeBlocks.reset(*freeBlock);
47-
48-
return handle;
49-
}
50-
51-
D3D12_GPU_DESCRIPTOR_HANDLE GrD3DDescriptorHeap::allocateGPUHandle() {
52-
D3D12_GPU_DESCRIPTOR_HANDLE handle = fHeap->GetGPUDescriptorHandleForHeapStart();
53-
SkBitSet::OptionalIndex freeBlock = fFreeBlocks.findFirst();
54-
SkASSERT(freeBlock);
55-
handle.ptr += *freeBlock * fHandleIncrementSize;
56-
fFreeBlocks.reset(*freeBlock);
57-
58-
return handle;
59-
}
60-
61-
void GrD3DDescriptorHeap::freeCPUHandle(D3D12_CPU_DESCRIPTOR_HANDLE* handle) {
62-
// valid only for non-shader-visible heaps
63-
SkASSERT(!SkToBool(fHeap->GetDesc().Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE));
64-
D3D12_CPU_DESCRIPTOR_HANDLE heapStart = fHeap->GetCPUDescriptorHandleForHeapStart();
65-
// Make sure this handle belongs to this heap
66-
SkASSERT(handle->ptr >= heapStart.ptr);
67-
SIZE_T index = (handle->ptr - heapStart.ptr) / fHandleIncrementSize;
6839
SkASSERT(index < fHeap->GetDesc().NumDescriptors);
69-
fFreeBlocks.set(index);
70-
handle->ptr = 0;
40+
D3D12_CPU_DESCRIPTOR_HANDLE handle = fCPUHeapStart;
41+
handle.ptr += index * fHandleIncrementSize;
42+
return handle;
7143
}
7244

73-
void GrD3DDescriptorHeap::freeGPUHandle(D3D12_GPU_DESCRIPTOR_HANDLE* handle) {
74-
D3D12_GPU_DESCRIPTOR_HANDLE heapStart = fHeap->GetGPUDescriptorHandleForHeapStart();
75-
// Make sure this handle belongs to this heap
76-
SkASSERT(handle->ptr >= heapStart.ptr);
77-
SIZE_T index = (handle->ptr - heapStart.ptr) / fHandleIncrementSize;
45+
D3D12_GPU_DESCRIPTOR_HANDLE GrD3DDescriptorHeap::getGPUHandle(unsigned int index) {
7846
SkASSERT(index < fHeap->GetDesc().NumDescriptors);
79-
fFreeBlocks.set(index);
80-
handle->ptr = 0;
47+
D3D12_GPU_DESCRIPTOR_HANDLE handle = fGPUHeapStart;
48+
handle.ptr += index * fHandleIncrementSize;
49+
return handle;
8150
}
8251

83-
#ifdef SK_TRACE_MANAGED_RESOURCES
84-
/** Output a human-readable dump of this resource's information
85-
*/
86-
void GrD3DDescriptorHeap::dumpInfo() const {
87-
SkDebugf("GrD3DDescriptorHeap: %d (%d refs)\n", fHeap.get(), this->getRefCnt());
88-
}
89-
#endif
9052

9153

src/gpu/d3d/GrD3DDescriptorHeap.h

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,50 @@
1414

1515
class GrD3DGpu;
1616

17-
class GrD3DDescriptorHeap : public GrManagedResource {
17+
class GrD3DDescriptorHeap {
1818
public:
19-
static sk_sp<GrD3DDescriptorHeap> Make(GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE,
20-
unsigned int numDescriptors,
21-
D3D12_DESCRIPTOR_HEAP_FLAGS);
22-
23-
~GrD3DDescriptorHeap() override = default;
24-
25-
D3D12_CPU_DESCRIPTOR_HANDLE allocateCPUHandle(); // valid only for non-shader-visible heaps
26-
D3D12_GPU_DESCRIPTOR_HANDLE allocateGPUHandle();
27-
void freeCPUHandle(D3D12_CPU_DESCRIPTOR_HANDLE*);
28-
void freeGPUHandle(D3D12_GPU_DESCRIPTOR_HANDLE*);
29-
30-
#ifdef SK_TRACE_MANAGED_RESOURCES
31-
/** Output a human-readable dump of this resource's information
32-
*/
33-
void dumpInfo() const override;
34-
#endif
35-
36-
void freeGPUData() const override {}
37-
38-
private:
39-
GrD3DDescriptorHeap(const gr_cp<ID3D12DescriptorHeap>&, const D3D12_DESCRIPTOR_HEAP_DESC&,
40-
unsigned int handleIncrementSize);
19+
static std::unique_ptr<GrD3DDescriptorHeap> Make(GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE,
20+
unsigned int numDescriptors,
21+
D3D12_DESCRIPTOR_HEAP_FLAGS);
22+
23+
~GrD3DDescriptorHeap() = default;
24+
25+
D3D12_CPU_DESCRIPTOR_HANDLE getCPUHandle(unsigned int index); // only if non-shader-visible
26+
D3D12_GPU_DESCRIPTOR_HANDLE getGPUHandle(unsigned int index);
27+
28+
bool getIndex(D3D12_CPU_DESCRIPTOR_HANDLE handle, size_t* indexPtr) {
29+
if (handle.ptr < fCPUHeapStart.ptr) {
30+
return false;
31+
}
32+
size_t index = (handle.ptr - fCPUHeapStart.ptr) / fHandleIncrementSize;
33+
if (index >= fHeap->GetDesc().NumDescriptors) {
34+
return false;
35+
}
36+
SkASSERT(handle.ptr == fCPUHeapStart.ptr + index * fHandleIncrementSize);
37+
*indexPtr = index;
38+
return true;
39+
}
40+
41+
bool getIndex(D3D12_GPU_DESCRIPTOR_HANDLE handle, size_t* indexPtr) {
42+
if (handle.ptr < fGPUHeapStart.ptr) {
43+
return false;
44+
}
45+
size_t index = (handle.ptr - fGPUHeapStart.ptr) / fHandleIncrementSize;
46+
if (index >= fHeap->GetDesc().NumDescriptors) {
47+
return false;
48+
}
49+
SkASSERT(handle.ptr == fGPUHeapStart.ptr + index * fHandleIncrementSize);
50+
*indexPtr = index;
51+
return true;
52+
}
53+
54+
protected:
55+
GrD3DDescriptorHeap(const gr_cp<ID3D12DescriptorHeap>&, unsigned int handleIncrementSize);
4156

4257
gr_cp<ID3D12DescriptorHeap> fHeap;
4358
size_t fHandleIncrementSize;
44-
SkBitSet fFreeBlocks;
59+
D3D12_CPU_DESCRIPTOR_HANDLE fCPUHeapStart;
60+
D3D12_GPU_DESCRIPTOR_HANDLE fGPUHeapStart;
4561
};
4662

4763
#endif

0 commit comments

Comments
 (0)