blob: 202d432343c2d0c20ad5ee618cf248c4893104da [file] [log] [blame]
Jim Van Verthafd41132020-05-28 06:44:55 -04001/*
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/GrD3DCpuDescriptorManager.h"
9
10#include "src/gpu/d3d/GrD3DGpu.h"
11
12GrD3DCpuDescriptorManager::GrD3DCpuDescriptorManager(GrD3DGpu* gpu)
13 : fRTVDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_RTV)
14 , fDSVDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_DSV)
15 , fCBVSRVDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
16 , fSamplerDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) {}
17
18D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::createRenderTargetView(
19 GrD3DGpu* gpu, ID3D12Resource* textureResource) {
20 D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fRTVDescriptorPool.allocateHandle(gpu);
21 gpu->device()->CreateRenderTargetView(textureResource, nullptr, descriptor);
22 return descriptor;
23}
24
25void GrD3DCpuDescriptorManager::recycleRenderTargetView(
26 D3D12_CPU_DESCRIPTOR_HANDLE* rtvDescriptor) {
27 fRTVDescriptorPool.releaseHandle(rtvDescriptor);
28}
29
30D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::createDepthStencilView(
31 GrD3DGpu* gpu, ID3D12Resource* textureResource) {
32 D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fDSVDescriptorPool.allocateHandle(gpu);
33 gpu->device()->CreateDepthStencilView(textureResource, nullptr, descriptor);
34 return descriptor;
35}
36
37void GrD3DCpuDescriptorManager::recycleDepthStencilView(
38 D3D12_CPU_DESCRIPTOR_HANDLE* dsvDescriptor) {
39 fDSVDescriptorPool.releaseHandle(dsvDescriptor);
40}
41
42D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::createConstantBufferView(
43 GrD3DGpu* gpu, ID3D12Resource* bufferResource, size_t offset, size_t size) {
44 D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fCBVSRVDescriptorPool.allocateHandle(gpu);
45 D3D12_CONSTANT_BUFFER_VIEW_DESC desc = {};
46 desc.BufferLocation = bufferResource->GetGPUVirtualAddress() + offset;
47 desc.SizeInBytes = size;
48 gpu->device()->CreateConstantBufferView(&desc, descriptor);
49 return descriptor;
50}
51
52D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::createShaderResourceView(
53 GrD3DGpu* gpu, ID3D12Resource* resource) {
54 D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fCBVSRVDescriptorPool.allocateHandle(gpu);
55 // TODO: for 4:2:0 YUV formats we'll need to map two different views, one for Y and one for UV.
56 // For now map the entire resource.
57 gpu->device()->CreateShaderResourceView(resource, nullptr, descriptor);
58 return descriptor;
59}
60
61void GrD3DCpuDescriptorManager::recycleConstantOrShaderView(D3D12_CPU_DESCRIPTOR_HANDLE* view) {
62 fCBVSRVDescriptorPool.releaseHandle(view);
63}
64
65D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::createSampler(
66 GrD3DGpu* gpu, D3D12_FILTER filter, D3D12_TEXTURE_ADDRESS_MODE addressModeU,
67 D3D12_TEXTURE_ADDRESS_MODE addressModeV) {
68 D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fSamplerDescriptorPool.allocateHandle(gpu);
69 D3D12_SAMPLER_DESC desc = {};
70 desc.Filter = filter;
71 desc.AddressU = addressModeU;
72 desc.AddressV = addressModeV;
73 desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
74 desc.MipLODBias = 0;
75 desc.MaxAnisotropy = 1;
76 desc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
77 // desc.BorderColor initialized to { 0, 0, 0, 0 } by default initializer, above.
78 desc.MinLOD = 0;
79 desc.MaxLOD = SK_ScalarMax;
80
81 gpu->device()->CreateSampler(&desc, descriptor);
82 return descriptor;
83}
84
85void GrD3DCpuDescriptorManager::recycleSampler(D3D12_CPU_DESCRIPTOR_HANDLE* samplerDescriptor) {
86 fSamplerDescriptorPool.releaseHandle(samplerDescriptor);
87}
88
89////////////////////////////////////////////////////////////////////////////////////////////////
90
91std::unique_ptr<GrD3DCpuDescriptorManager::Heap> GrD3DCpuDescriptorManager::Heap::Make(
92 GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE type, unsigned int numDescriptors) {
93 std::unique_ptr<GrD3DDescriptorHeap> heap =
94 GrD3DDescriptorHeap::Make(gpu, type, numDescriptors, D3D12_DESCRIPTOR_HEAP_FLAG_NONE);
95 if (!heap) {
96 return nullptr;
97 }
98
99 return std::unique_ptr<Heap>(new Heap(heap, numDescriptors));
100}
101
102D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::Heap::allocateCPUHandle() {
103 SkBitSet::OptionalIndex freeBlock = fFreeBlocks.findFirst();
104 SkASSERT(freeBlock);
105 fFreeBlocks.reset(*freeBlock);
106 --fFreeCount;
107 return fHeap->getCPUHandle(*freeBlock);
108}
109
110bool GrD3DCpuDescriptorManager::Heap::freeCPUHandle(D3D12_CPU_DESCRIPTOR_HANDLE* handle) {
111 size_t index;
112 if (!fHeap->getIndex(*handle, &index)) {
113 return false;
114 }
115 fFreeBlocks.set(index);
116 ++fFreeCount;
117 handle->ptr = 0;
118 return true;
119}
120
121////////////////////////////////////////////////////////////////////////////////////////////////
122
123GrD3DCpuDescriptorManager::HeapPool::HeapPool(GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE heapType)
124 : fMaxAvailableDescriptors(32)
125 , fHeapType(heapType) {
126 std::unique_ptr<GrD3DCpuDescriptorManager::Heap> heap =
127 GrD3DCpuDescriptorManager::Heap::Make(gpu, fHeapType, fMaxAvailableDescriptors);
128 fDescriptorHeaps.push_back(std::move(heap));
129}
130
131D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::HeapPool::allocateHandle(GrD3DGpu* gpu) {
132 for (unsigned int i = 0; i < fDescriptorHeaps.size(); ++i) {
133 if (fDescriptorHeaps[i]->canAllocate()) {
134 D3D12_CPU_DESCRIPTOR_HANDLE handle = fDescriptorHeaps[i]->allocateCPUHandle();
135 return handle;
136 }
137 }
138
139 // need to allocate more space
140 std::unique_ptr<GrD3DCpuDescriptorManager::Heap> heap =
141 GrD3DCpuDescriptorManager::Heap::Make(gpu, fHeapType, fMaxAvailableDescriptors);
142
143 fDescriptorHeaps.push_back(std::move(heap));
144 fMaxAvailableDescriptors *= 2;
145 D3D12_CPU_DESCRIPTOR_HANDLE handle =
146 fDescriptorHeaps[fDescriptorHeaps.size() - 1]->allocateCPUHandle();
147 return handle;
148}
149
150void GrD3DCpuDescriptorManager::HeapPool::releaseHandle(
151 D3D12_CPU_DESCRIPTOR_HANDLE* dsvDescriptor) {
152 for (unsigned int i = 0; i < fDescriptorHeaps.size(); ++i) {
153 if (fDescriptorHeaps[i]->freeCPUHandle(dsvDescriptor)) {
154 return;
155 }
156 }
157 SkASSERT(false);
158}