Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/panfrost/vulkan/panvk_descriptor_set.c
4560 views
1
/*
2
* Copyright © 2021 Collabora Ltd.
3
*
4
* Derived from:
5
* Copyright © 2016 Red Hat.
6
* Copyright © 2016 Bas Nieuwenhuizen
7
*
8
* Permission is hereby granted, free of charge, to any person obtaining a
9
* copy of this software and associated documentation files (the "Software"),
10
* to deal in the Software without restriction, including without limitation
11
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
* and/or sell copies of the Software, and to permit persons to whom the
13
* Software is furnished to do so, subject to the following conditions:
14
*
15
* The above copyright notice and this permission notice (including the next
16
* paragraph) shall be included in all copies or substantial portions of the
17
* Software.
18
*
19
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
* DEALINGS IN THE SOFTWARE.
26
*/
27
#include "panvk_private.h"
28
29
#include <assert.h>
30
#include <fcntl.h>
31
#include <stdbool.h>
32
#include <string.h>
33
#include <unistd.h>
34
35
#include "util/mesa-sha1.h"
36
#include "vk_descriptors.h"
37
#include "vk_util.h"
38
39
#include "pan_bo.h"
40
#include "midgard_pack.h"
41
42
VkResult
43
panvk_CreateDescriptorSetLayout(VkDevice _device,
44
const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
45
const VkAllocationCallbacks *pAllocator,
46
VkDescriptorSetLayout *pSetLayout)
47
{
48
VK_FROM_HANDLE(panvk_device, device, _device);
49
struct panvk_descriptor_set_layout *set_layout;
50
VkDescriptorSetLayoutBinding *bindings = NULL;
51
unsigned num_bindings = 0;
52
VkResult result;
53
54
if (pCreateInfo->bindingCount) {
55
result =
56
vk_create_sorted_bindings(pCreateInfo->pBindings,
57
pCreateInfo->bindingCount,
58
&bindings);
59
if (result != VK_SUCCESS)
60
return vk_error(device->instance, result);
61
62
num_bindings = bindings[pCreateInfo->bindingCount - 1].binding + 1;
63
}
64
65
unsigned num_immutable_samplers = 0;
66
for (unsigned i = 0; i < pCreateInfo->bindingCount; i++) {
67
if (bindings[i].pImmutableSamplers)
68
num_immutable_samplers += bindings[i].descriptorCount;
69
}
70
71
size_t size = sizeof(*set_layout) +
72
(sizeof(struct panvk_descriptor_set_binding_layout) *
73
num_bindings) +
74
(sizeof(struct panvk_sampler *) * num_immutable_samplers);
75
set_layout = vk_object_zalloc(&device->vk, pAllocator, size,
76
VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT);
77
if (!set_layout) {
78
result = VK_ERROR_OUT_OF_HOST_MEMORY;
79
goto err_free_bindings;
80
}
81
82
struct panvk_sampler **immutable_samplers =
83
(struct panvk_sampler **)((uint8_t *)set_layout + sizeof(*set_layout) +
84
(sizeof(struct panvk_descriptor_set_binding_layout) *
85
num_bindings));
86
87
set_layout->flags = pCreateInfo->flags;
88
set_layout->binding_count = num_bindings;
89
90
unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0, ssbo_idx = 0;
91
unsigned dynoffset_idx = 0, desc_idx = 0;
92
93
for (unsigned i = 0; i < pCreateInfo->bindingCount; i++) {
94
const VkDescriptorSetLayoutBinding *binding = &bindings[i];
95
struct panvk_descriptor_set_binding_layout *binding_layout =
96
&set_layout->bindings[binding->binding];
97
98
binding_layout->type = binding->descriptorType;
99
binding_layout->array_size = binding->descriptorCount;
100
binding_layout->shader_stages = binding->stageFlags;
101
if (binding->pImmutableSamplers) {
102
binding_layout->immutable_samplers = immutable_samplers;
103
immutable_samplers += binding_layout->array_size;
104
for (unsigned j = 0; j < binding_layout->array_size; j++) {
105
VK_FROM_HANDLE(panvk_sampler, sampler, binding->pImmutableSamplers[j]);
106
binding_layout->immutable_samplers[j] = sampler;
107
}
108
}
109
110
binding_layout->desc_idx = desc_idx;
111
desc_idx += binding->descriptorCount;
112
switch (binding_layout->type) {
113
case VK_DESCRIPTOR_TYPE_SAMPLER:
114
binding_layout->sampler_idx = sampler_idx;
115
sampler_idx += binding_layout->array_size;
116
break;
117
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
118
binding_layout->sampler_idx = sampler_idx;
119
binding_layout->tex_idx = tex_idx;
120
sampler_idx += binding_layout->array_size;
121
tex_idx += binding_layout->array_size;
122
break;
123
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
124
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
125
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
126
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
127
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
128
binding_layout->tex_idx = tex_idx;
129
tex_idx += binding_layout->array_size;
130
break;
131
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
132
binding_layout->dynoffset_idx = dynoffset_idx;
133
dynoffset_idx += binding_layout->array_size;
134
FALLTHROUGH;
135
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
136
binding_layout->ubo_idx = ubo_idx;
137
ubo_idx += binding_layout->array_size;
138
break;
139
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
140
binding_layout->dynoffset_idx = dynoffset_idx;
141
dynoffset_idx += binding_layout->array_size;
142
FALLTHROUGH;
143
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
144
binding_layout->ssbo_idx = ssbo_idx;
145
ssbo_idx += binding_layout->array_size;
146
break;
147
default:
148
unreachable("Invalid descriptor type");
149
}
150
}
151
152
set_layout->num_descs = desc_idx;
153
set_layout->num_samplers = sampler_idx;
154
set_layout->num_textures = tex_idx;
155
set_layout->num_ubos = ubo_idx;
156
set_layout->num_ssbos = ssbo_idx;
157
set_layout->num_dynoffsets = dynoffset_idx;
158
159
free(bindings);
160
*pSetLayout = panvk_descriptor_set_layout_to_handle(set_layout);
161
return VK_SUCCESS;
162
163
err_free_bindings:
164
free(bindings);
165
return vk_error(device->instance, result);
166
}
167
168
void
169
panvk_DestroyDescriptorSetLayout(VkDevice _device,
170
VkDescriptorSetLayout _set_layout,
171
const VkAllocationCallbacks *pAllocator)
172
{
173
VK_FROM_HANDLE(panvk_device, device, _device);
174
VK_FROM_HANDLE(panvk_descriptor_set_layout, set_layout, _set_layout);
175
176
if (!set_layout)
177
return;
178
179
vk_object_free(&device->vk, pAllocator, set_layout);
180
}
181
182
/* FIXME: make sure those values are correct */
183
#define PANVK_MAX_TEXTURES (1 << 16)
184
#define PANVK_MAX_SAMPLERS (1 << 16)
185
#define PANVK_MAX_UBOS 255
186
187
void
188
panvk_GetDescriptorSetLayoutSupport(VkDevice _device,
189
const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
190
VkDescriptorSetLayoutSupport *pSupport)
191
{
192
VK_FROM_HANDLE(panvk_device, device, _device);
193
194
pSupport->supported = false;
195
196
VkDescriptorSetLayoutBinding *bindings;
197
VkResult result =
198
vk_create_sorted_bindings(pCreateInfo->pBindings,
199
pCreateInfo->bindingCount,
200
&bindings);
201
if (result != VK_SUCCESS) {
202
vk_error(device->instance, result);
203
return;
204
}
205
206
unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0, ssbo_idx = 0, dynoffset_idx = 0;
207
for (unsigned i = 0; i < pCreateInfo->bindingCount; i++) {
208
const VkDescriptorSetLayoutBinding *binding = &bindings[i];
209
210
switch (binding->descriptorType) {
211
case VK_DESCRIPTOR_TYPE_SAMPLER:
212
sampler_idx += binding->descriptorCount;
213
break;
214
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
215
sampler_idx += binding->descriptorCount;
216
tex_idx += binding->descriptorCount;
217
break;
218
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
219
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
220
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
221
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
222
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
223
tex_idx += binding->descriptorCount;
224
break;
225
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
226
dynoffset_idx += binding->descriptorCount;
227
FALLTHROUGH;
228
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
229
ubo_idx += binding->descriptorCount;
230
break;
231
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
232
dynoffset_idx += binding->descriptorCount;
233
FALLTHROUGH;
234
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
235
ssbo_idx += binding->descriptorCount;
236
break;
237
default:
238
unreachable("Invalid descriptor type");
239
}
240
}
241
242
/* The maximum values apply to all sets attached to a pipeline since all
243
* sets descriptors have to be merged in a single array.
244
*/
245
if (tex_idx > PANVK_MAX_TEXTURES / MAX_SETS ||
246
sampler_idx > PANVK_MAX_SAMPLERS / MAX_SETS ||
247
ubo_idx > PANVK_MAX_UBOS / MAX_SETS)
248
return;
249
250
pSupport->supported = true;
251
}
252
253
/*
254
* Pipeline layouts. These have nothing to do with the pipeline. They are
255
* just multiple descriptor set layouts pasted together.
256
*/
257
258
VkResult
259
panvk_CreatePipelineLayout(VkDevice _device,
260
const VkPipelineLayoutCreateInfo *pCreateInfo,
261
const VkAllocationCallbacks *pAllocator,
262
VkPipelineLayout *pPipelineLayout)
263
{
264
VK_FROM_HANDLE(panvk_device, device, _device);
265
struct panvk_pipeline_layout *layout;
266
struct mesa_sha1 ctx;
267
268
layout = vk_object_zalloc(&device->vk, pAllocator, sizeof(*layout),
269
VK_OBJECT_TYPE_PIPELINE_LAYOUT);
270
if (layout == NULL)
271
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
272
273
layout->num_sets = pCreateInfo->setLayoutCount;
274
_mesa_sha1_init(&ctx);
275
276
unsigned sampler_idx = 0, tex_idx = 0, ssbo_idx = 0, ubo_idx = 0, dynoffset_idx = 0;
277
for (unsigned set = 0; set < pCreateInfo->setLayoutCount; set++) {
278
VK_FROM_HANDLE(panvk_descriptor_set_layout, set_layout,
279
pCreateInfo->pSetLayouts[set]);
280
layout->sets[set].layout = set_layout;
281
layout->sets[set].sampler_offset = sampler_idx;
282
layout->sets[set].tex_offset = tex_idx;
283
layout->sets[set].ubo_offset = ubo_idx;
284
layout->sets[set].ssbo_offset = ssbo_idx;
285
layout->sets[set].dynoffset_offset = dynoffset_idx;
286
sampler_idx += set_layout->num_samplers;
287
tex_idx += set_layout->num_textures;
288
ubo_idx += set_layout->num_ubos + (set_layout->num_dynoffsets != 0);
289
ssbo_idx += set_layout->num_ssbos;
290
dynoffset_idx += set_layout->num_dynoffsets;
291
292
for (unsigned b = 0; b < set_layout->binding_count; b++) {
293
struct panvk_descriptor_set_binding_layout *binding_layout =
294
&set_layout->bindings[b];
295
296
if (binding_layout->immutable_samplers) {
297
for (unsigned s = 0; s < binding_layout->array_size; s++) {
298
struct panvk_sampler *sampler = binding_layout->immutable_samplers[s];
299
300
_mesa_sha1_update(&ctx, &sampler->desc, sizeof(sampler->desc));
301
}
302
}
303
_mesa_sha1_update(&ctx, &binding_layout->type, sizeof(binding_layout->type));
304
_mesa_sha1_update(&ctx, &binding_layout->array_size, sizeof(binding_layout->array_size));
305
_mesa_sha1_update(&ctx, &binding_layout->desc_idx, sizeof(binding_layout->sampler_idx));
306
_mesa_sha1_update(&ctx, &binding_layout->shader_stages, sizeof(binding_layout->shader_stages));
307
}
308
}
309
310
layout->num_samplers = sampler_idx;
311
layout->num_textures = tex_idx;
312
layout->num_ubos = ubo_idx;
313
layout->num_ssbos = ssbo_idx;
314
layout->num_dynoffsets = dynoffset_idx;
315
316
_mesa_sha1_final(&ctx, layout->sha1);
317
318
*pPipelineLayout = panvk_pipeline_layout_to_handle(layout);
319
return VK_SUCCESS;
320
}
321
322
void
323
panvk_DestroyPipelineLayout(VkDevice _device,
324
VkPipelineLayout _pipelineLayout,
325
const VkAllocationCallbacks *pAllocator)
326
{
327
VK_FROM_HANDLE(panvk_device, device, _device);
328
VK_FROM_HANDLE(panvk_pipeline_layout, pipeline_layout, _pipelineLayout);
329
330
if (!pipeline_layout)
331
return;
332
333
vk_object_free(&device->vk, pAllocator, pipeline_layout);
334
}
335
336
VkResult
337
panvk_CreateDescriptorPool(VkDevice _device,
338
const VkDescriptorPoolCreateInfo *pCreateInfo,
339
const VkAllocationCallbacks *pAllocator,
340
VkDescriptorPool *pDescriptorPool)
341
{
342
VK_FROM_HANDLE(panvk_device, device, _device);
343
struct panvk_descriptor_pool *pool;
344
345
pool = vk_object_zalloc(&device->vk, pAllocator,
346
sizeof(struct panvk_descriptor_pool),
347
VK_OBJECT_TYPE_DESCRIPTOR_POOL);
348
if (!pool)
349
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
350
351
pool->max.sets = pCreateInfo->maxSets;
352
353
for (unsigned i = 0; i < pCreateInfo->poolSizeCount; ++i) {
354
unsigned desc_count = pCreateInfo->pPoolSizes[i].descriptorCount;
355
356
switch(pCreateInfo->pPoolSizes[i].type) {
357
case VK_DESCRIPTOR_TYPE_SAMPLER:
358
pool->max.samplers += desc_count;
359
break;
360
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
361
pool->max.combined_image_samplers += desc_count;
362
break;
363
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
364
pool->max.sampled_images += desc_count;
365
break;
366
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
367
pool->max.storage_images += desc_count;
368
break;
369
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
370
pool->max.uniform_texel_bufs += desc_count;
371
break;
372
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
373
pool->max.storage_texel_bufs += desc_count;
374
break;
375
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
376
pool->max.input_attachments += desc_count;
377
break;
378
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
379
pool->max.uniform_bufs += desc_count;
380
break;
381
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
382
pool->max.storage_bufs += desc_count;
383
break;
384
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
385
pool->max.uniform_dyn_bufs += desc_count;
386
break;
387
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
388
pool->max.storage_dyn_bufs += desc_count;
389
break;
390
default:
391
unreachable("Invalid descriptor type");
392
}
393
}
394
395
*pDescriptorPool = panvk_descriptor_pool_to_handle(pool);
396
return VK_SUCCESS;
397
}
398
399
void
400
panvk_DestroyDescriptorPool(VkDevice _device,
401
VkDescriptorPool _pool,
402
const VkAllocationCallbacks *pAllocator)
403
{
404
VK_FROM_HANDLE(panvk_device, device, _device);
405
VK_FROM_HANDLE(panvk_descriptor_pool, pool, _pool);
406
407
if (pool)
408
vk_object_free(&device->vk, pAllocator, pool);
409
}
410
411
VkResult
412
panvk_ResetDescriptorPool(VkDevice _device,
413
VkDescriptorPool _pool,
414
VkDescriptorPoolResetFlags flags)
415
{
416
VK_FROM_HANDLE(panvk_descriptor_pool, pool, _pool);
417
memset(&pool->cur, 0, sizeof(pool->cur));
418
return VK_SUCCESS;
419
}
420
421
static VkResult
422
panvk_descriptor_set_create(struct panvk_device *device,
423
struct panvk_descriptor_pool *pool,
424
const struct panvk_descriptor_set_layout *layout,
425
struct panvk_descriptor_set **out_set)
426
{
427
const struct panfrost_device *pdev = &device->physical_device->pdev;
428
struct panvk_descriptor_set *set;
429
430
/* TODO: Allocate from the pool! */
431
set = vk_object_zalloc(&device->vk, NULL,
432
sizeof(struct panvk_descriptor_set),
433
VK_OBJECT_TYPE_DESCRIPTOR_SET);
434
if (!set)
435
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
436
437
set->layout = layout;
438
set->descs = vk_alloc(&device->vk.alloc,
439
sizeof(*set->descs) * layout->num_descs, 8,
440
VK_OBJECT_TYPE_DESCRIPTOR_SET);
441
if (!set->descs)
442
goto err_free_set;
443
444
if (layout->num_ubos) {
445
set->ubos = vk_zalloc(&device->vk.alloc,
446
sizeof(*set->ubos) * layout->num_ubos, 8,
447
VK_OBJECT_TYPE_DESCRIPTOR_SET);
448
if (!set->ubos)
449
goto err_free_set;
450
}
451
452
if (layout->num_samplers) {
453
set->samplers = vk_zalloc(&device->vk.alloc,
454
sizeof(*set->samplers) * layout->num_samplers, 8,
455
VK_OBJECT_TYPE_DESCRIPTOR_SET);
456
if (!set->samplers)
457
goto err_free_set;
458
}
459
460
if (layout->num_textures) {
461
if (pan_is_bifrost(pdev)) {
462
set->textures.bifrost = vk_zalloc(&device->vk.alloc,
463
sizeof(*set->textures.bifrost) *
464
layout->num_textures,
465
8, VK_OBJECT_TYPE_DESCRIPTOR_SET);
466
} else {
467
set->textures.midgard = vk_zalloc(&device->vk.alloc,
468
sizeof(*set->textures.midgard) *
469
layout->num_textures,
470
8, VK_OBJECT_TYPE_DESCRIPTOR_SET);
471
}
472
473
if (!set->textures.midgard)
474
goto err_free_set;
475
}
476
477
for (unsigned i = 0; i < layout->binding_count; i++) {
478
if (!layout->bindings[i].immutable_samplers)
479
continue;
480
481
for (unsigned j = 0; j < layout->bindings[i].array_size; j++) {
482
set->descs[layout->bindings[i].desc_idx].image.sampler =
483
layout->bindings[i].immutable_samplers[j];
484
}
485
}
486
487
*out_set = set;
488
return VK_SUCCESS;
489
490
err_free_set:
491
vk_free(&device->vk.alloc, set->textures.midgard);
492
vk_free(&device->vk.alloc, set->samplers);
493
vk_free(&device->vk.alloc, set->ubos);
494
vk_free(&device->vk.alloc, set->descs);
495
vk_object_free(&device->vk, NULL, set);
496
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
497
}
498
499
static void
500
panvk_descriptor_set_destroy(struct panvk_device *device,
501
struct panvk_descriptor_pool *pool,
502
struct panvk_descriptor_set *set)
503
{
504
vk_free(&device->vk.alloc, set->textures.midgard);
505
vk_free(&device->vk.alloc, set->samplers);
506
vk_free(&device->vk.alloc, set->ubos);
507
vk_free(&device->vk.alloc, set->descs);
508
vk_object_free(&device->vk, NULL, set);
509
}
510
511
VkResult
512
panvk_AllocateDescriptorSets(VkDevice _device,
513
const VkDescriptorSetAllocateInfo *pAllocateInfo,
514
VkDescriptorSet *pDescriptorSets)
515
{
516
VK_FROM_HANDLE(panvk_device, device, _device);
517
VK_FROM_HANDLE(panvk_descriptor_pool, pool, pAllocateInfo->descriptorPool);
518
VkResult result;
519
unsigned i;
520
521
for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
522
VK_FROM_HANDLE(panvk_descriptor_set_layout, layout,
523
pAllocateInfo->pSetLayouts[i]);
524
struct panvk_descriptor_set *set = NULL;
525
526
result = panvk_descriptor_set_create(device, pool, layout, &set);
527
if (result != VK_SUCCESS)
528
goto err_free_sets;
529
530
pDescriptorSets[i] = panvk_descriptor_set_to_handle(set);
531
}
532
533
return VK_SUCCESS;
534
535
err_free_sets:
536
panvk_FreeDescriptorSets(_device, pAllocateInfo->descriptorPool, i, pDescriptorSets);
537
for (i = 0; i < pAllocateInfo->descriptorSetCount; i++)
538
pDescriptorSets[i] = VK_NULL_HANDLE;
539
540
return result;
541
}
542
543
VkResult
544
panvk_FreeDescriptorSets(VkDevice _device,
545
VkDescriptorPool descriptorPool,
546
uint32_t count,
547
const VkDescriptorSet *pDescriptorSets)
548
{
549
VK_FROM_HANDLE(panvk_device, device, _device);
550
VK_FROM_HANDLE(panvk_descriptor_pool, pool, descriptorPool);
551
552
for (unsigned i = 0; i < count; i++) {
553
VK_FROM_HANDLE(panvk_descriptor_set, set, pDescriptorSets[i]);
554
555
if (set)
556
panvk_descriptor_set_destroy(device, pool, set);
557
}
558
return VK_SUCCESS;
559
}
560
561
static void
562
panvk_set_image_desc(struct panvk_descriptor *desc,
563
const VkDescriptorImageInfo *pImageInfo)
564
{
565
VK_FROM_HANDLE(panvk_sampler, sampler, pImageInfo->sampler);
566
VK_FROM_HANDLE(panvk_image_view, image_view, pImageInfo->imageView);
567
desc->image.sampler = sampler;
568
desc->image.view = image_view;
569
desc->image.layout = pImageInfo->imageLayout;
570
}
571
572
static void
573
panvk_set_texel_buffer_view_desc(struct panvk_descriptor *desc,
574
const VkBufferView *pTexelBufferView)
575
{
576
VK_FROM_HANDLE(panvk_buffer_view, buffer_view, *pTexelBufferView);
577
desc->buffer_view = buffer_view;
578
}
579
580
static void
581
panvk_set_buffer_info_desc(struct panvk_descriptor *desc,
582
const VkDescriptorBufferInfo *pBufferInfo)
583
{
584
VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer);
585
desc->buffer_info.buffer = buffer;
586
desc->buffer_info.offset = pBufferInfo->offset;
587
desc->buffer_info.range = pBufferInfo->range;
588
}
589
590
static void
591
panvk_set_ubo_desc(void *ubo,
592
const VkDescriptorBufferInfo *pBufferInfo)
593
{
594
VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer);
595
size_t size = pBufferInfo->range == VK_WHOLE_SIZE ?
596
(buffer->bo->size - pBufferInfo->offset) :
597
pBufferInfo->range;
598
599
pan_pack(ubo, UNIFORM_BUFFER, cfg) {
600
cfg.pointer = buffer->bo->ptr.gpu + pBufferInfo->offset;
601
cfg.entries = DIV_ROUND_UP(size, 16);
602
}
603
}
604
605
static void
606
panvk_set_sampler_desc(void *desc,
607
const VkDescriptorImageInfo *pImageInfo)
608
{
609
VK_FROM_HANDLE(panvk_sampler, sampler, pImageInfo->sampler);
610
611
memcpy(desc, &sampler->desc, sizeof(sampler->desc));
612
}
613
614
static void
615
panvk_set_bifrost_texture_desc(struct mali_bifrost_texture_packed *desc,
616
const VkDescriptorImageInfo *pImageInfo)
617
{
618
VK_FROM_HANDLE(panvk_image_view, view, pImageInfo->imageView);
619
620
*desc = view->bifrost.tex_desc;
621
}
622
623
static void
624
panvk_set_midgard_texture_desc(mali_ptr *desc,
625
const VkDescriptorImageInfo *pImageInfo)
626
{
627
VK_FROM_HANDLE(panvk_image_view, view, pImageInfo->imageView);
628
629
*desc = view->bo->ptr.gpu;
630
}
631
632
static void
633
panvk_write_descriptor_set(struct panvk_device *dev,
634
const VkWriteDescriptorSet *pDescriptorWrite)
635
{
636
const struct panfrost_device *pdev = &dev->physical_device->pdev;
637
VK_FROM_HANDLE(panvk_descriptor_set, set, pDescriptorWrite->dstSet);
638
const struct panvk_descriptor_set_layout *layout = set->layout;
639
unsigned dest_offset = pDescriptorWrite->dstArrayElement;
640
unsigned binding = pDescriptorWrite->dstBinding;
641
unsigned src_offset = 0;
642
643
while (src_offset < pDescriptorWrite->descriptorCount &&
644
binding < layout->binding_count) {
645
const struct panvk_descriptor_set_binding_layout *binding_layout =
646
&layout->bindings[binding];
647
648
if (!binding_layout->array_size) {
649
binding++;
650
dest_offset = 0;
651
continue;
652
}
653
654
assert(pDescriptorWrite->descriptorType == binding_layout->type);
655
unsigned ndescs = MIN2(pDescriptorWrite->descriptorCount - src_offset,
656
binding_layout->array_size - dest_offset);
657
struct panvk_descriptor *descs = &set->descs[binding_layout->desc_idx + dest_offset];
658
assert(binding_layout->desc_idx + dest_offset + ndescs <= set->layout->num_descs);
659
660
switch (pDescriptorWrite->descriptorType) {
661
case VK_DESCRIPTOR_TYPE_SAMPLER:
662
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
663
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
664
for (unsigned i = 0; i < ndescs; i++) {
665
const VkDescriptorImageInfo *info = &pDescriptorWrite->pImageInfo[src_offset + i];
666
667
if (pDescriptorWrite->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
668
pDescriptorWrite->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
669
unsigned sampler = binding_layout->sampler_idx + dest_offset + i;
670
671
panvk_set_sampler_desc(&set->samplers[sampler], info);
672
}
673
674
if (pDescriptorWrite->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
675
pDescriptorWrite->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
676
unsigned tex = binding_layout->tex_idx + dest_offset + i;
677
678
if (pan_is_bifrost(pdev))
679
panvk_set_bifrost_texture_desc(&set->textures.bifrost[tex], info);
680
else
681
panvk_set_midgard_texture_desc(&set->textures.midgard[tex], info);
682
}
683
}
684
break;
685
686
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
687
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
688
for (unsigned i = 0; i < ndescs; i++)
689
panvk_set_image_desc(&descs[i], &pDescriptorWrite->pImageInfo[src_offset + i]);
690
break;
691
692
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
693
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
694
for (unsigned i = 0; i < ndescs; i++)
695
panvk_set_texel_buffer_view_desc(&descs[i], &pDescriptorWrite->pTexelBufferView[src_offset + i]);
696
break;
697
698
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
699
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
700
for (unsigned i = 0; i < ndescs; i++) {
701
unsigned ubo = binding_layout->ubo_idx + dest_offset + i;
702
panvk_set_ubo_desc(&set->ubos[ubo],
703
&pDescriptorWrite->pBufferInfo[src_offset + i]);
704
}
705
break;
706
707
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
708
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
709
for (unsigned i = 0; i < ndescs; i++)
710
panvk_set_buffer_info_desc(&descs[i], &pDescriptorWrite->pBufferInfo[src_offset + i]);
711
break;
712
default:
713
unreachable("Invalid type");
714
}
715
716
src_offset += ndescs;
717
binding++;
718
dest_offset = 0;
719
}
720
}
721
722
static void
723
panvk_copy_descriptor_set(struct panvk_device *dev,
724
const VkCopyDescriptorSet *pDescriptorCopy)
725
{
726
VK_FROM_HANDLE(panvk_descriptor_set, dest_set, pDescriptorCopy->dstSet);
727
VK_FROM_HANDLE(panvk_descriptor_set, src_set, pDescriptorCopy->srcSet);
728
const struct panvk_descriptor_set_layout *dest_layout = dest_set->layout;
729
const struct panvk_descriptor_set_layout *src_layout = dest_set->layout;
730
unsigned dest_offset = pDescriptorCopy->dstArrayElement;
731
unsigned src_offset = pDescriptorCopy->srcArrayElement;
732
unsigned dest_binding = pDescriptorCopy->dstBinding;
733
unsigned src_binding = pDescriptorCopy->srcBinding;
734
unsigned desc_count = pDescriptorCopy->descriptorCount;
735
736
while (desc_count && src_binding < src_layout->binding_count &&
737
dest_binding < dest_layout->binding_count) {
738
const struct panvk_descriptor_set_binding_layout *dest_binding_layout =
739
&src_layout->bindings[dest_binding];
740
741
if (!dest_binding_layout->array_size) {
742
dest_binding++;
743
dest_offset = 0;
744
continue;
745
}
746
747
const struct panvk_descriptor_set_binding_layout *src_binding_layout =
748
&src_layout->bindings[src_binding];
749
750
if (!src_binding_layout->array_size) {
751
src_binding++;
752
src_offset = 0;
753
continue;
754
}
755
756
assert(dest_binding_layout->type == src_binding_layout->type);
757
758
unsigned ndescs = MAX3(desc_count,
759
dest_binding_layout->array_size - dest_offset,
760
src_binding_layout->array_size - src_offset);
761
762
struct panvk_descriptor *dest_descs = dest_set->descs + dest_binding_layout->desc_idx + dest_offset;
763
struct panvk_descriptor *src_descs = src_set->descs + src_binding_layout->desc_idx + src_offset;
764
memcpy(dest_descs, src_descs, ndescs * sizeof(*dest_descs));
765
desc_count -= ndescs;
766
dest_offset += ndescs;
767
if (dest_offset == dest_binding_layout->array_size) {
768
dest_binding++;
769
dest_offset = 0;
770
continue;
771
}
772
src_offset += ndescs;
773
if (src_offset == src_binding_layout->array_size) {
774
src_binding++;
775
src_offset = 0;
776
continue;
777
}
778
}
779
780
assert(!desc_count);
781
}
782
783
void
784
panvk_UpdateDescriptorSets(VkDevice _device,
785
uint32_t descriptorWriteCount,
786
const VkWriteDescriptorSet *pDescriptorWrites,
787
uint32_t descriptorCopyCount,
788
const VkCopyDescriptorSet *pDescriptorCopies)
789
{
790
VK_FROM_HANDLE(panvk_device, dev, _device);
791
792
for (unsigned i = 0; i < descriptorWriteCount; i++)
793
panvk_write_descriptor_set(dev, &pDescriptorWrites[i]);
794
for (unsigned i = 0; i < descriptorCopyCount; i++)
795
panvk_copy_descriptor_set(dev, &pDescriptorCopies[i]);
796
}
797
798
VkResult
799
panvk_CreateDescriptorUpdateTemplate(VkDevice _device,
800
const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
801
const VkAllocationCallbacks *pAllocator,
802
VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate)
803
{
804
panvk_stub();
805
return VK_SUCCESS;
806
}
807
808
void
809
panvk_DestroyDescriptorUpdateTemplate(VkDevice _device,
810
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
811
const VkAllocationCallbacks *pAllocator)
812
{
813
panvk_stub();
814
}
815
816
void
817
panvk_UpdateDescriptorSetWithTemplate(VkDevice _device,
818
VkDescriptorSet descriptorSet,
819
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
820
const void *pData)
821
{
822
panvk_stub();
823
}
824
825
VkResult
826
panvk_CreateSamplerYcbcrConversion(VkDevice device,
827
const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
828
const VkAllocationCallbacks *pAllocator,
829
VkSamplerYcbcrConversion *pYcbcrConversion)
830
{
831
panvk_stub();
832
return VK_SUCCESS;
833
}
834
835
void
836
panvk_DestroySamplerYcbcrConversion(VkDevice device,
837
VkSamplerYcbcrConversion ycbcrConversion,
838
const VkAllocationCallbacks *pAllocator)
839
{
840
panvk_stub();
841
}
842
843