Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/d3d12/d3d12_descriptor_pool.cpp
4570 views
1
/*
2
* Copyright © Microsoft Corporation
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
#include "d3d12_context.h"
25
#include "d3d12_descriptor_pool.h"
26
#include "d3d12_screen.h"
27
28
#include "pipe/p_context.h"
29
#include "pipe/p_state.h"
30
31
#include "util/list.h"
32
#include "util/u_dynarray.h"
33
#include "util/u_memory.h"
34
35
#include <directx/d3d12.h>
36
#include <dxguids/dxguids.h>
37
38
struct d3d12_descriptor_pool {
39
ID3D12Device *dev;
40
D3D12_DESCRIPTOR_HEAP_TYPE type;
41
uint32_t num_descriptors;
42
list_head heaps;
43
};
44
45
struct d3d12_descriptor_heap {
46
struct d3d12_descriptor_pool *pool;
47
48
D3D12_DESCRIPTOR_HEAP_DESC desc;
49
ID3D12Device *dev;
50
ID3D12DescriptorHeap *heap;
51
uint32_t desc_size;
52
uint64_t cpu_base;
53
uint64_t gpu_base;
54
uint32_t size;
55
uint32_t next;
56
util_dynarray free_list;
57
list_head link;
58
};
59
60
struct d3d12_descriptor_heap*
61
d3d12_descriptor_heap_new(ID3D12Device *dev,
62
D3D12_DESCRIPTOR_HEAP_TYPE type,
63
D3D12_DESCRIPTOR_HEAP_FLAGS flags,
64
uint32_t num_descriptors)
65
{
66
struct d3d12_descriptor_heap *heap = CALLOC_STRUCT(d3d12_descriptor_heap);
67
68
heap->desc.NumDescriptors = num_descriptors;
69
heap->desc.Type = type;
70
heap->desc.Flags = flags;
71
if (FAILED(dev->CreateDescriptorHeap(&heap->desc,
72
IID_PPV_ARGS(&heap->heap)))) {
73
FREE(heap);
74
return NULL;
75
}
76
77
heap->dev = dev;
78
heap->desc_size = dev->GetDescriptorHandleIncrementSize(type);
79
heap->size = num_descriptors * heap->desc_size;
80
heap->cpu_base = heap->heap->GetCPUDescriptorHandleForHeapStart().ptr;
81
if (flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE)
82
heap->gpu_base = heap->heap->GetGPUDescriptorHandleForHeapStart().ptr;
83
util_dynarray_init(&heap->free_list, NULL);
84
85
return heap;
86
}
87
88
void
89
d3d12_descriptor_heap_free(struct d3d12_descriptor_heap *heap)
90
{
91
heap->heap->Release();
92
util_dynarray_fini(&heap->free_list);
93
FREE(heap);
94
}
95
96
ID3D12DescriptorHeap*
97
d3d12_descriptor_heap_get(struct d3d12_descriptor_heap *heap)
98
{
99
return heap->heap;
100
}
101
102
static uint32_t
103
d3d12_descriptor_heap_is_online(struct d3d12_descriptor_heap *heap)
104
{
105
return (heap->desc.Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE) ? 1 : 0;
106
}
107
108
static uint32_t
109
d3d12_descriptor_heap_can_allocate(struct d3d12_descriptor_heap *heap)
110
{
111
return (heap->free_list.size > 0 ||
112
heap->size >= heap->next + heap->desc_size);
113
}
114
115
uint32_t
116
d3d12_descriptor_heap_get_remaining_handles(struct d3d12_descriptor_heap *heap)
117
{
118
return (heap->size - heap->next) / heap->desc_size;
119
}
120
121
void
122
d2d12_descriptor_heap_get_next_handle(struct d3d12_descriptor_heap *heap,
123
struct d3d12_descriptor_handle *handle)
124
{
125
handle->heap = heap;
126
handle->cpu_handle.ptr = heap->cpu_base + heap->next;
127
handle->gpu_handle.ptr = d3d12_descriptor_heap_is_online(heap) ?
128
heap->gpu_base + heap->next : 0;
129
}
130
131
uint32_t
132
d3d12_descriptor_heap_alloc_handle(struct d3d12_descriptor_heap *heap,
133
struct d3d12_descriptor_handle *handle)
134
{
135
uint32_t offset = 0;
136
137
assert(handle != NULL);
138
139
if (heap->free_list.size > 0) {
140
offset = util_dynarray_pop(&heap->free_list, uint32_t);
141
} else if (heap->size >= heap->next + heap->desc_size) {
142
offset = heap->next;
143
heap->next += heap->desc_size;
144
} else {
145
/* Todo: we should add a new descriptor heap to get more handles */
146
assert(0 && "No handles available in descriptor heap");
147
return 0;
148
}
149
150
handle->heap = heap;
151
handle->cpu_handle.ptr = heap->cpu_base + offset;
152
handle->gpu_handle.ptr = d3d12_descriptor_heap_is_online(heap) ?
153
heap->gpu_base + offset : 0;
154
155
return 1;
156
}
157
158
void
159
d3d12_descriptor_handle_free(struct d3d12_descriptor_handle *handle)
160
{
161
const uint32_t index = handle->cpu_handle.ptr - handle->heap->cpu_base;
162
if (index + handle->heap->desc_size == handle->heap->next) {
163
handle->heap->next = index;
164
} else {
165
util_dynarray_append(&handle->heap->free_list, uint32_t, index);
166
}
167
168
handle->heap = NULL;
169
handle->cpu_handle.ptr = 0;
170
handle->gpu_handle.ptr = 0;
171
}
172
173
void
174
d3d12_descriptor_heap_append_handles(struct d3d12_descriptor_heap *heap,
175
D3D12_CPU_DESCRIPTOR_HANDLE *handles,
176
unsigned num_handles)
177
{
178
D3D12_CPU_DESCRIPTOR_HANDLE dst;
179
180
assert(heap->next + (num_handles * heap->desc_size) <= heap->size);
181
dst.ptr = heap->cpu_base + heap->next;
182
heap->dev->CopyDescriptors(1, &dst, &num_handles,
183
num_handles, handles, NULL,
184
heap->desc.Type);
185
heap->next += num_handles * heap->desc_size;
186
}
187
188
void
189
d3d12_descriptor_heap_clear(struct d3d12_descriptor_heap *heap)
190
{
191
heap->next = 0;
192
util_dynarray_clear(&heap->free_list);
193
}
194
195
struct d3d12_descriptor_pool*
196
d3d12_descriptor_pool_new(struct d3d12_screen *screen,
197
D3D12_DESCRIPTOR_HEAP_TYPE type,
198
uint32_t num_descriptors)
199
{
200
struct d3d12_descriptor_pool *pool = CALLOC_STRUCT(d3d12_descriptor_pool);
201
if (!pool)
202
return NULL;
203
204
pool->dev = screen->dev;
205
pool->type = type;
206
pool->num_descriptors = num_descriptors;
207
list_inithead(&pool->heaps);
208
209
return pool;
210
}
211
212
void
213
d3d12_descriptor_pool_free(struct d3d12_descriptor_pool *pool)
214
{
215
list_for_each_entry_safe(struct d3d12_descriptor_heap, heap, &pool->heaps, link) {
216
list_del(&heap->link);
217
d3d12_descriptor_heap_free(heap);
218
}
219
FREE(pool);
220
}
221
222
uint32_t
223
d3d12_descriptor_pool_alloc_handle(struct d3d12_descriptor_pool *pool,
224
struct d3d12_descriptor_handle *handle)
225
{
226
struct d3d12_descriptor_heap *valid_heap = NULL;
227
228
list_for_each_entry(struct d3d12_descriptor_heap, heap, &pool->heaps, link) {
229
if (d3d12_descriptor_heap_can_allocate(heap)) {
230
valid_heap = heap;
231
break;
232
}
233
}
234
235
if (!valid_heap) {
236
valid_heap = d3d12_descriptor_heap_new(pool->dev,
237
pool->type,
238
D3D12_DESCRIPTOR_HEAP_FLAG_NONE,
239
pool->num_descriptors);
240
list_addtail(&valid_heap->link, &pool->heaps);
241
}
242
243
return d3d12_descriptor_heap_alloc_handle(valid_heap, handle);
244
}
245
246