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
28 #include "genxml/gen_macros.h"
29
30 #include "panvk_private.h"
31
32 #include <assert.h>
33 #include <fcntl.h>
34 #include <stdbool.h>
35 #include <string.h>
36 #include <unistd.h>
37
38 #include "util/mesa-sha1.h"
39 #include "vk_descriptors.h"
40 #include "vk_util.h"
41
42 #include "pan_bo.h"
43 #include "panvk_cs.h"
44
45 #define PANVK_DESCRIPTOR_ALIGN 8
46
47 struct panvk_bview_desc {
48 uint32_t elems;
49 };
50
51 static void
panvk_fill_bview_desc(struct panvk_bview_desc * desc,struct panvk_buffer_view * view)52 panvk_fill_bview_desc(struct panvk_bview_desc *desc,
53 struct panvk_buffer_view *view)
54 {
55 desc->elems = view->elems;
56 }
57
58 struct panvk_image_desc {
59 uint16_t width;
60 uint16_t height;
61 uint16_t depth;
62 uint8_t levels;
63 uint8_t samples;
64 };
65
66 static void
panvk_fill_image_desc(struct panvk_image_desc * desc,struct panvk_image_view * view)67 panvk_fill_image_desc(struct panvk_image_desc *desc,
68 struct panvk_image_view *view)
69 {
70 desc->width = view->vk.extent.width - 1;
71 desc->height = view->vk.extent.height - 1;
72 desc->depth = view->vk.extent.depth - 1;
73 desc->levels = view->vk.level_count;
74 desc->samples = view->vk.image->samples;
75
76 /* Stick array layer count after the last valid size component */
77 if (view->vk.image->image_type == VK_IMAGE_TYPE_1D)
78 desc->height = view->vk.layer_count - 1;
79 else if (view->vk.image->image_type == VK_IMAGE_TYPE_2D)
80 desc->depth = view->vk.layer_count - 1;
81 }
82
83 VkResult
panvk_per_arch(CreateDescriptorSetLayout)84 panvk_per_arch(CreateDescriptorSetLayout)(VkDevice _device,
85 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
86 const VkAllocationCallbacks *pAllocator,
87 VkDescriptorSetLayout *pSetLayout)
88 {
89 VK_FROM_HANDLE(panvk_device, device, _device);
90 struct panvk_descriptor_set_layout *set_layout;
91 VkDescriptorSetLayoutBinding *bindings = NULL;
92 unsigned num_bindings = 0;
93 VkResult result;
94
95 if (pCreateInfo->bindingCount) {
96 result =
97 vk_create_sorted_bindings(pCreateInfo->pBindings,
98 pCreateInfo->bindingCount,
99 &bindings);
100 if (result != VK_SUCCESS)
101 return vk_error(device, result);
102
103 num_bindings = bindings[pCreateInfo->bindingCount - 1].binding + 1;
104 }
105
106 unsigned num_immutable_samplers = 0;
107 for (unsigned i = 0; i < pCreateInfo->bindingCount; i++) {
108 if (bindings[i].pImmutableSamplers)
109 num_immutable_samplers += bindings[i].descriptorCount;
110 }
111
112 size_t size = sizeof(*set_layout) +
113 (sizeof(struct panvk_descriptor_set_binding_layout) *
114 num_bindings) +
115 (sizeof(struct panvk_sampler *) * num_immutable_samplers);
116 set_layout = vk_descriptor_set_layout_zalloc(&device->vk, size);
117 if (!set_layout) {
118 result = VK_ERROR_OUT_OF_HOST_MEMORY;
119 goto err_free_bindings;
120 }
121
122 struct panvk_sampler **immutable_samplers =
123 (struct panvk_sampler **)((uint8_t *)set_layout + sizeof(*set_layout) +
124 (sizeof(struct panvk_descriptor_set_binding_layout) *
125 num_bindings));
126
127 set_layout->binding_count = num_bindings;
128
129 unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0;
130 unsigned dyn_ubo_idx = 0, dyn_ssbo_idx = 0, img_idx = 0;
131 uint32_t desc_ubo_size = 0;
132
133 for (unsigned i = 0; i < pCreateInfo->bindingCount; i++) {
134 const VkDescriptorSetLayoutBinding *binding = &bindings[i];
135 struct panvk_descriptor_set_binding_layout *binding_layout =
136 &set_layout->bindings[binding->binding];
137
138 binding_layout->type = binding->descriptorType;
139 binding_layout->array_size = binding->descriptorCount;
140 binding_layout->shader_stages = binding->stageFlags;
141 binding_layout->desc_ubo_stride = 0;
142 if (binding->pImmutableSamplers) {
143 binding_layout->immutable_samplers = immutable_samplers;
144 immutable_samplers += binding_layout->array_size;
145 for (unsigned j = 0; j < binding_layout->array_size; j++) {
146 VK_FROM_HANDLE(panvk_sampler, sampler, binding->pImmutableSamplers[j]);
147 binding_layout->immutable_samplers[j] = sampler;
148 }
149 }
150
151 switch (binding_layout->type) {
152 case VK_DESCRIPTOR_TYPE_SAMPLER:
153 binding_layout->sampler_idx = sampler_idx;
154 sampler_idx += binding_layout->array_size;
155 break;
156 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
157 binding_layout->sampler_idx = sampler_idx;
158 binding_layout->tex_idx = tex_idx;
159 sampler_idx += binding_layout->array_size;
160 tex_idx += binding_layout->array_size;
161 binding_layout->desc_ubo_stride = sizeof(struct panvk_image_desc);
162 break;
163 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
164 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
165 binding_layout->tex_idx = tex_idx;
166 tex_idx += binding_layout->array_size;
167 binding_layout->desc_ubo_stride = sizeof(struct panvk_image_desc);
168 break;
169 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
170 binding_layout->tex_idx = tex_idx;
171 tex_idx += binding_layout->array_size;
172 binding_layout->desc_ubo_stride = sizeof(struct panvk_bview_desc);
173 break;
174 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
175 binding_layout->dyn_ubo_idx = dyn_ubo_idx;
176 dyn_ubo_idx += binding_layout->array_size;
177 break;
178 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
179 binding_layout->ubo_idx = ubo_idx;
180 ubo_idx += binding_layout->array_size;
181 break;
182 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
183 binding_layout->dyn_ssbo_idx = dyn_ssbo_idx;
184 dyn_ssbo_idx += binding_layout->array_size;
185 break;
186 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
187 binding_layout->desc_ubo_stride = sizeof(struct panvk_ssbo_addr);
188 break;
189 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
190 binding_layout->img_idx = img_idx;
191 img_idx += binding_layout->array_size;
192 binding_layout->desc_ubo_stride = sizeof(struct panvk_image_desc);
193 break;
194 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
195 binding_layout->img_idx = img_idx;
196 img_idx += binding_layout->array_size;
197 binding_layout->desc_ubo_stride = sizeof(struct panvk_bview_desc);
198 break;
199 default:
200 unreachable("Invalid descriptor type");
201 }
202
203 desc_ubo_size = ALIGN_POT(desc_ubo_size, PANVK_DESCRIPTOR_ALIGN);
204 binding_layout->desc_ubo_offset = desc_ubo_size;
205 desc_ubo_size += binding_layout->desc_ubo_stride *
206 binding_layout->array_size;
207 }
208
209 set_layout->desc_ubo_size = desc_ubo_size;
210 if (desc_ubo_size > 0)
211 set_layout->desc_ubo_index = ubo_idx++;
212
213 set_layout->num_samplers = sampler_idx;
214 set_layout->num_textures = tex_idx;
215 set_layout->num_ubos = ubo_idx;
216 set_layout->num_dyn_ubos = dyn_ubo_idx;
217 set_layout->num_dyn_ssbos = dyn_ssbo_idx;
218 set_layout->num_imgs = img_idx;
219
220 free(bindings);
221 *pSetLayout = panvk_descriptor_set_layout_to_handle(set_layout);
222 return VK_SUCCESS;
223
224 err_free_bindings:
225 free(bindings);
226 return vk_error(device, result);
227 }
228
229 static void
230 panvk_write_sampler_desc_raw(struct panvk_descriptor_set *set,
231 uint32_t binding, uint32_t elem,
232 struct panvk_sampler *sampler);
233
234 static VkResult
panvk_per_arch(descriptor_set_create)235 panvk_per_arch(descriptor_set_create)(struct panvk_device *device,
236 struct panvk_descriptor_pool *pool,
237 const struct panvk_descriptor_set_layout *layout,
238 struct panvk_descriptor_set **out_set)
239 {
240 struct panvk_descriptor_set *set;
241
242 /* TODO: Allocate from the pool! */
243 set = vk_object_zalloc(&device->vk, NULL,
244 sizeof(struct panvk_descriptor_set),
245 VK_OBJECT_TYPE_DESCRIPTOR_SET);
246 if (!set)
247 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
248
249 set->layout = layout;
250
251 if (layout->num_ubos) {
252 set->ubos = vk_zalloc(&device->vk.alloc,
253 pan_size(UNIFORM_BUFFER) * layout->num_ubos, 8,
254 VK_OBJECT_TYPE_DESCRIPTOR_SET);
255 if (!set->ubos)
256 goto err_free_set;
257 }
258
259 if (layout->num_dyn_ubos) {
260 set->dyn_ubos = vk_zalloc(&device->vk.alloc,
261 sizeof(*set->dyn_ubos) * layout->num_dyn_ubos, 8,
262 VK_OBJECT_TYPE_DESCRIPTOR_SET);
263 if (!set->dyn_ubos)
264 goto err_free_set;
265 }
266
267 if (layout->num_dyn_ssbos) {
268 set->dyn_ssbos = vk_zalloc(&device->vk.alloc,
269 sizeof(*set->dyn_ssbos) * layout->num_dyn_ssbos, 8,
270 VK_OBJECT_TYPE_DESCRIPTOR_SET);
271 if (!set->dyn_ssbos)
272 goto err_free_set;
273 }
274
275 if (layout->num_samplers) {
276 set->samplers = vk_zalloc(&device->vk.alloc,
277 pan_size(SAMPLER) * layout->num_samplers, 8,
278 VK_OBJECT_TYPE_DESCRIPTOR_SET);
279 if (!set->samplers)
280 goto err_free_set;
281 }
282
283 if (layout->num_textures) {
284 set->textures =
285 vk_zalloc(&device->vk.alloc, pan_size(TEXTURE) * layout->num_textures,
286 8, VK_OBJECT_TYPE_DESCRIPTOR_SET);
287 if (!set->textures)
288 goto err_free_set;
289 }
290
291 if (layout->num_imgs) {
292 set->img_fmts =
293 vk_zalloc(&device->vk.alloc,
294 sizeof(*set->img_fmts) * layout->num_imgs,
295 8, VK_OBJECT_TYPE_DESCRIPTOR_SET);
296 if (!set->img_fmts)
297 goto err_free_set;
298
299 set->img_attrib_bufs =
300 vk_zalloc(&device->vk.alloc,
301 pan_size(ATTRIBUTE_BUFFER) * 2 * layout->num_imgs,
302 8, VK_OBJECT_TYPE_DESCRIPTOR_SET);
303 if (!set->img_attrib_bufs)
304 goto err_free_set;
305 }
306
307 if (layout->desc_ubo_size) {
308 set->desc_bo = panfrost_bo_create(&device->physical_device->pdev,
309 layout->desc_ubo_size,
310 0, "Descriptor set");
311 if (!set->desc_bo)
312 goto err_free_set;
313
314 struct mali_uniform_buffer_packed *ubos = set->ubos;
315
316 panvk_per_arch(emit_ubo)(set->desc_bo->ptr.gpu,
317 layout->desc_ubo_size,
318 &ubos[layout->desc_ubo_index]);
319 }
320
321 for (unsigned i = 0; i < layout->binding_count; i++) {
322 if (!layout->bindings[i].immutable_samplers)
323 continue;
324
325 for (unsigned j = 0; j < layout->bindings[i].array_size; j++) {
326 struct panvk_sampler *sampler =
327 layout->bindings[i].immutable_samplers[j];
328 panvk_write_sampler_desc_raw(set, i, j, sampler);
329 }
330 }
331
332 *out_set = set;
333 return VK_SUCCESS;
334
335 err_free_set:
336 vk_free(&device->vk.alloc, set->textures);
337 vk_free(&device->vk.alloc, set->samplers);
338 vk_free(&device->vk.alloc, set->ubos);
339 vk_free(&device->vk.alloc, set->dyn_ubos);
340 vk_free(&device->vk.alloc, set->dyn_ssbos);
341 vk_free(&device->vk.alloc, set->img_fmts);
342 vk_free(&device->vk.alloc, set->img_attrib_bufs);
343 if (set->desc_bo)
344 panfrost_bo_unreference(set->desc_bo);
345 vk_object_free(&device->vk, NULL, set);
346 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
347 }
348
349 VkResult
panvk_per_arch(AllocateDescriptorSets)350 panvk_per_arch(AllocateDescriptorSets)(VkDevice _device,
351 const VkDescriptorSetAllocateInfo *pAllocateInfo,
352 VkDescriptorSet *pDescriptorSets)
353 {
354 VK_FROM_HANDLE(panvk_device, device, _device);
355 VK_FROM_HANDLE(panvk_descriptor_pool, pool, pAllocateInfo->descriptorPool);
356 VkResult result;
357 unsigned i;
358
359 for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
360 VK_FROM_HANDLE(panvk_descriptor_set_layout, layout,
361 pAllocateInfo->pSetLayouts[i]);
362 struct panvk_descriptor_set *set = NULL;
363
364 result = panvk_per_arch(descriptor_set_create)(device, pool, layout, &set);
365 if (result != VK_SUCCESS)
366 goto err_free_sets;
367
368 pDescriptorSets[i] = panvk_descriptor_set_to_handle(set);
369 }
370
371 return VK_SUCCESS;
372
373 err_free_sets:
374 panvk_FreeDescriptorSets(_device, pAllocateInfo->descriptorPool, i, pDescriptorSets);
375 for (i = 0; i < pAllocateInfo->descriptorSetCount; i++)
376 pDescriptorSets[i] = VK_NULL_HANDLE;
377
378 return result;
379 }
380
381 static void *
panvk_desc_ubo_data(struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem)382 panvk_desc_ubo_data(struct panvk_descriptor_set *set,
383 uint32_t binding, uint32_t elem)
384 {
385 const struct panvk_descriptor_set_binding_layout *binding_layout =
386 &set->layout->bindings[binding];
387
388 return (char *)set->desc_bo->ptr.cpu +
389 binding_layout->desc_ubo_offset +
390 elem * binding_layout->desc_ubo_stride;
391 }
392
393 static struct mali_sampler_packed *
panvk_sampler_desc(struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem)394 panvk_sampler_desc(struct panvk_descriptor_set *set,
395 uint32_t binding, uint32_t elem)
396 {
397 const struct panvk_descriptor_set_binding_layout *binding_layout =
398 &set->layout->bindings[binding];
399
400 uint32_t sampler_idx = binding_layout->sampler_idx + elem;
401
402 return &((struct mali_sampler_packed *)set->samplers)[sampler_idx];
403 }
404
405 static void
panvk_write_sampler_desc_raw(struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem,struct panvk_sampler * sampler)406 panvk_write_sampler_desc_raw(struct panvk_descriptor_set *set,
407 uint32_t binding, uint32_t elem,
408 struct panvk_sampler *sampler)
409 {
410 memcpy(panvk_sampler_desc(set, binding, elem),
411 &sampler->desc, sizeof(sampler->desc));
412 }
413
414 static void
panvk_write_sampler_desc(UNUSED struct panvk_device * dev,struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem,const VkDescriptorImageInfo * const pImageInfo)415 panvk_write_sampler_desc(UNUSED struct panvk_device *dev,
416 struct panvk_descriptor_set *set,
417 uint32_t binding, uint32_t elem,
418 const VkDescriptorImageInfo * const pImageInfo)
419 {
420 const struct panvk_descriptor_set_binding_layout *binding_layout =
421 &set->layout->bindings[binding];
422
423 if (binding_layout->immutable_samplers)
424 return;
425
426 VK_FROM_HANDLE(panvk_sampler, sampler, pImageInfo->sampler);
427 panvk_write_sampler_desc_raw(set, binding, elem, sampler);
428 }
429
430 static void
panvk_copy_sampler_desc(struct panvk_descriptor_set * dst_set,uint32_t dst_binding,uint32_t dst_elem,struct panvk_descriptor_set * src_set,uint32_t src_binding,uint32_t src_elem)431 panvk_copy_sampler_desc(struct panvk_descriptor_set *dst_set,
432 uint32_t dst_binding, uint32_t dst_elem,
433 struct panvk_descriptor_set *src_set,
434 uint32_t src_binding, uint32_t src_elem)
435 {
436 const struct panvk_descriptor_set_binding_layout *dst_binding_layout =
437 &dst_set->layout->bindings[dst_binding];
438
439 if (dst_binding_layout->immutable_samplers)
440 return;
441
442 memcpy(panvk_sampler_desc(dst_set, dst_binding, dst_elem),
443 panvk_sampler_desc(src_set, src_binding, src_elem),
444 sizeof(struct mali_sampler_packed));
445 }
446
447 static struct mali_texture_packed *
panvk_tex_desc(struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem)448 panvk_tex_desc(struct panvk_descriptor_set *set,
449 uint32_t binding, uint32_t elem)
450 {
451 const struct panvk_descriptor_set_binding_layout *binding_layout =
452 &set->layout->bindings[binding];
453
454 unsigned tex_idx = binding_layout->tex_idx + elem;
455
456 return &((struct mali_texture_packed *)set->textures)[tex_idx];
457 }
458
459 static void
panvk_write_tex_desc(UNUSED struct panvk_device * dev,struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem,const VkDescriptorImageInfo * const pImageInfo)460 panvk_write_tex_desc(UNUSED struct panvk_device *dev,
461 struct panvk_descriptor_set *set,
462 uint32_t binding, uint32_t elem,
463 const VkDescriptorImageInfo * const pImageInfo)
464 {
465 VK_FROM_HANDLE(panvk_image_view, view, pImageInfo->imageView);
466
467 memcpy(panvk_tex_desc(set, binding, elem),
468 view->descs.tex, pan_size(TEXTURE));
469
470 panvk_fill_image_desc(panvk_desc_ubo_data(set, binding, elem), view);
471 }
472
473 static void
panvk_copy_tex_desc(struct panvk_descriptor_set * dst_set,uint32_t dst_binding,uint32_t dst_elem,struct panvk_descriptor_set * src_set,uint32_t src_binding,uint32_t src_elem)474 panvk_copy_tex_desc(struct panvk_descriptor_set *dst_set,
475 uint32_t dst_binding, uint32_t dst_elem,
476 struct panvk_descriptor_set *src_set,
477 uint32_t src_binding, uint32_t src_elem)
478 {
479 *panvk_tex_desc(dst_set, dst_binding, dst_elem) =
480 *panvk_tex_desc(src_set, src_binding, src_elem);
481
482 /* Descriptor UBO data gets copied automatically */
483 }
484
485 static void
panvk_write_tex_buf_desc(UNUSED struct panvk_device * dev,struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem,const VkBufferView bufferView)486 panvk_write_tex_buf_desc(UNUSED struct panvk_device *dev,
487 struct panvk_descriptor_set *set,
488 uint32_t binding, uint32_t elem,
489 const VkBufferView bufferView)
490 {
491 VK_FROM_HANDLE(panvk_buffer_view, view, bufferView);
492
493 memcpy(panvk_tex_desc(set, binding, elem),
494 view->descs.tex, pan_size(TEXTURE));
495
496 panvk_fill_bview_desc(panvk_desc_ubo_data(set, binding, elem), view);
497 }
498
499 static uint32_t
panvk_img_idx(struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem)500 panvk_img_idx(struct panvk_descriptor_set *set,
501 uint32_t binding, uint32_t elem)
502 {
503 const struct panvk_descriptor_set_binding_layout *binding_layout =
504 &set->layout->bindings[binding];
505
506 return binding_layout->img_idx + elem;
507 }
508
509 static void
panvk_write_img_desc(struct panvk_device * dev,struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem,const VkDescriptorImageInfo * pImageInfo)510 panvk_write_img_desc(struct panvk_device *dev,
511 struct panvk_descriptor_set *set,
512 uint32_t binding, uint32_t elem,
513 const VkDescriptorImageInfo *pImageInfo)
514 {
515 const struct panfrost_device *pdev = &dev->physical_device->pdev;
516 VK_FROM_HANDLE(panvk_image_view, view, pImageInfo->imageView);
517
518 unsigned img_idx = panvk_img_idx(set, binding, elem);
519 void *attrib_buf = (uint8_t *)set->img_attrib_bufs +
520 (pan_size(ATTRIBUTE_BUFFER) * 2 * img_idx);
521
522 set->img_fmts[img_idx] = pdev->formats[view->pview.format].hw;
523 memcpy(attrib_buf, view->descs.img_attrib_buf, pan_size(ATTRIBUTE_BUFFER) * 2);
524
525 panvk_fill_image_desc(panvk_desc_ubo_data(set, binding, elem), view);
526 }
527
528 static void
panvk_copy_img_desc(struct panvk_descriptor_set * dst_set,uint32_t dst_binding,uint32_t dst_elem,struct panvk_descriptor_set * src_set,uint32_t src_binding,uint32_t src_elem)529 panvk_copy_img_desc(struct panvk_descriptor_set *dst_set,
530 uint32_t dst_binding, uint32_t dst_elem,
531 struct panvk_descriptor_set *src_set,
532 uint32_t src_binding, uint32_t src_elem)
533 {
534 unsigned dst_img_idx = panvk_img_idx(dst_set, dst_binding, dst_elem);
535 unsigned src_img_idx = panvk_img_idx(src_set, src_binding, src_elem);
536
537 void *dst_attrib_buf = (uint8_t *)dst_set->img_attrib_bufs +
538 (pan_size(ATTRIBUTE_BUFFER) * 2 * dst_img_idx);
539 void *src_attrib_buf = (uint8_t *)src_set->img_attrib_bufs +
540 (pan_size(ATTRIBUTE_BUFFER) * 2 * src_img_idx);
541
542 dst_set->img_fmts[dst_img_idx] = src_set->img_fmts[src_img_idx];
543 memcpy(dst_attrib_buf, src_attrib_buf, pan_size(ATTRIBUTE_BUFFER) * 2);
544
545 /* Descriptor UBO data gets copied automatically */
546 }
547
548 static void
panvk_write_img_buf_desc(struct panvk_device * dev,struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem,const VkBufferView bufferView)549 panvk_write_img_buf_desc(struct panvk_device *dev,
550 struct panvk_descriptor_set *set,
551 uint32_t binding, uint32_t elem,
552 const VkBufferView bufferView)
553 {
554 const struct panfrost_device *pdev = &dev->physical_device->pdev;
555 VK_FROM_HANDLE(panvk_buffer_view, view, bufferView);
556
557 unsigned img_idx = panvk_img_idx(set, binding, elem);
558 void *attrib_buf = (uint8_t *)set->img_attrib_bufs +
559 (pan_size(ATTRIBUTE_BUFFER) * 2 * img_idx);
560
561 set->img_fmts[img_idx] = pdev->formats[view->fmt].hw;
562 memcpy(attrib_buf, view->descs.img_attrib_buf, pan_size(ATTRIBUTE_BUFFER) * 2);
563
564 panvk_fill_bview_desc(panvk_desc_ubo_data(set, binding, elem), view);
565 }
566
567 static struct mali_uniform_buffer_packed *
panvk_ubo_desc(struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem)568 panvk_ubo_desc(struct panvk_descriptor_set *set,
569 uint32_t binding, uint32_t elem)
570 {
571 const struct panvk_descriptor_set_binding_layout *binding_layout =
572 &set->layout->bindings[binding];
573
574 unsigned ubo_idx = binding_layout->ubo_idx + elem;
575
576 return &((struct mali_uniform_buffer_packed *)set->ubos)[ubo_idx];
577 }
578
579 static void
panvk_write_ubo_desc(UNUSED struct panvk_device * dev,struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem,const VkDescriptorBufferInfo * pBufferInfo)580 panvk_write_ubo_desc(UNUSED struct panvk_device *dev,
581 struct panvk_descriptor_set *set,
582 uint32_t binding, uint32_t elem,
583 const VkDescriptorBufferInfo *pBufferInfo)
584 {
585 VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer);
586
587 mali_ptr ptr = panvk_buffer_gpu_ptr(buffer, pBufferInfo->offset);
588 size_t size = panvk_buffer_range(buffer, pBufferInfo->offset,
589 pBufferInfo->range);
590
591 panvk_per_arch(emit_ubo)(ptr, size, panvk_ubo_desc(set, binding, elem));
592 }
593
594 static void
panvk_copy_ubo_desc(struct panvk_descriptor_set * dst_set,uint32_t dst_binding,uint32_t dst_elem,struct panvk_descriptor_set * src_set,uint32_t src_binding,uint32_t src_elem)595 panvk_copy_ubo_desc(struct panvk_descriptor_set *dst_set,
596 uint32_t dst_binding, uint32_t dst_elem,
597 struct panvk_descriptor_set *src_set,
598 uint32_t src_binding, uint32_t src_elem)
599 {
600 *panvk_ubo_desc(dst_set, dst_binding, dst_elem) =
601 *panvk_ubo_desc(src_set, src_binding, src_elem);
602 }
603
604 static struct panvk_buffer_desc *
panvk_dyn_ubo_desc(struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem)605 panvk_dyn_ubo_desc(struct panvk_descriptor_set *set,
606 uint32_t binding, uint32_t elem)
607 {
608 const struct panvk_descriptor_set_binding_layout *binding_layout =
609 &set->layout->bindings[binding];
610
611 return &set->dyn_ubos[binding_layout->dyn_ubo_idx + elem];
612 }
613
614 static void
panvk_write_dyn_ubo_desc(UNUSED struct panvk_device * dev,struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem,const VkDescriptorBufferInfo * pBufferInfo)615 panvk_write_dyn_ubo_desc(UNUSED struct panvk_device *dev,
616 struct panvk_descriptor_set *set,
617 uint32_t binding, uint32_t elem,
618 const VkDescriptorBufferInfo *pBufferInfo)
619 {
620 VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer);
621
622 *panvk_dyn_ubo_desc(set, binding, elem) = (struct panvk_buffer_desc) {
623 .buffer = buffer,
624 .offset = pBufferInfo->offset,
625 .size = pBufferInfo->range,
626 };
627 }
628
629 static void
panvk_copy_dyn_ubo_desc(struct panvk_descriptor_set * dst_set,uint32_t dst_binding,uint32_t dst_elem,struct panvk_descriptor_set * src_set,uint32_t src_binding,uint32_t src_elem)630 panvk_copy_dyn_ubo_desc(struct panvk_descriptor_set *dst_set,
631 uint32_t dst_binding, uint32_t dst_elem,
632 struct panvk_descriptor_set *src_set,
633 uint32_t src_binding, uint32_t src_elem)
634 {
635 *panvk_dyn_ubo_desc(dst_set, dst_binding, dst_elem) =
636 *panvk_dyn_ubo_desc(src_set, src_binding, src_elem);
637 }
638
639 static void
panvk_write_ssbo_desc(UNUSED struct panvk_device * dev,struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem,const VkDescriptorBufferInfo * pBufferInfo)640 panvk_write_ssbo_desc(UNUSED struct panvk_device *dev,
641 struct panvk_descriptor_set *set,
642 uint32_t binding, uint32_t elem,
643 const VkDescriptorBufferInfo *pBufferInfo)
644 {
645 VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer);
646
647 struct panvk_ssbo_addr *desc = panvk_desc_ubo_data(set, binding, elem);
648 *desc = (struct panvk_ssbo_addr) {
649 .base_addr = panvk_buffer_gpu_ptr(buffer, pBufferInfo->offset),
650 .size = panvk_buffer_range(buffer, pBufferInfo->offset,
651 pBufferInfo->range),
652 };
653 }
654
655 static void
panvk_copy_ssbo_desc(struct panvk_descriptor_set * dst_set,uint32_t dst_binding,uint32_t dst_elem,struct panvk_descriptor_set * src_set,uint32_t src_binding,uint32_t src_elem)656 panvk_copy_ssbo_desc(struct panvk_descriptor_set *dst_set,
657 uint32_t dst_binding, uint32_t dst_elem,
658 struct panvk_descriptor_set *src_set,
659 uint32_t src_binding, uint32_t src_elem)
660 {
661 /* Descriptor UBO data gets copied automatically */
662 }
663
664 static struct panvk_buffer_desc *
panvk_dyn_ssbo_desc(struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem)665 panvk_dyn_ssbo_desc(struct panvk_descriptor_set *set,
666 uint32_t binding, uint32_t elem)
667 {
668 const struct panvk_descriptor_set_binding_layout *binding_layout =
669 &set->layout->bindings[binding];
670
671 return &set->dyn_ssbos[binding_layout->dyn_ssbo_idx + elem];
672 }
673
674 static void
panvk_write_dyn_ssbo_desc(UNUSED struct panvk_device * dev,struct panvk_descriptor_set * set,uint32_t binding,uint32_t elem,const VkDescriptorBufferInfo * pBufferInfo)675 panvk_write_dyn_ssbo_desc(UNUSED struct panvk_device *dev,
676 struct panvk_descriptor_set *set,
677 uint32_t binding, uint32_t elem,
678 const VkDescriptorBufferInfo *pBufferInfo)
679 {
680 VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer);
681
682 *panvk_dyn_ssbo_desc(set, binding, elem) = (struct panvk_buffer_desc) {
683 .buffer = buffer,
684 .offset = pBufferInfo->offset,
685 .size = pBufferInfo->range,
686 };
687 }
688
689 static void
panvk_copy_dyn_ssbo_desc(struct panvk_descriptor_set * dst_set,uint32_t dst_binding,uint32_t dst_elem,struct panvk_descriptor_set * src_set,uint32_t src_binding,uint32_t src_elem)690 panvk_copy_dyn_ssbo_desc(struct panvk_descriptor_set *dst_set,
691 uint32_t dst_binding, uint32_t dst_elem,
692 struct panvk_descriptor_set *src_set,
693 uint32_t src_binding, uint32_t src_elem)
694 {
695 *panvk_dyn_ssbo_desc(dst_set, dst_binding, dst_elem) =
696 *panvk_dyn_ssbo_desc(src_set, src_binding, src_elem);
697 }
698
699 void
panvk_per_arch(UpdateDescriptorSets)700 panvk_per_arch(UpdateDescriptorSets)(VkDevice _device,
701 uint32_t descriptorWriteCount,
702 const VkWriteDescriptorSet *pDescriptorWrites,
703 uint32_t descriptorCopyCount,
704 const VkCopyDescriptorSet *pDescriptorCopies)
705 {
706 VK_FROM_HANDLE(panvk_device, dev, _device);
707
708 for (unsigned i = 0; i < descriptorWriteCount; i++) {
709 const VkWriteDescriptorSet *write = &pDescriptorWrites[i];
710 VK_FROM_HANDLE(panvk_descriptor_set, set, write->dstSet);
711
712 switch (write->descriptorType) {
713 case VK_DESCRIPTOR_TYPE_SAMPLER:
714 for (uint32_t j = 0; j < write->descriptorCount; j++) {
715 panvk_write_sampler_desc(dev, set,
716 write->dstBinding,
717 write->dstArrayElement + j,
718 &write->pImageInfo[j]);
719 }
720 break;
721
722 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
723 for (uint32_t j = 0; j < write->descriptorCount; j++) {
724 panvk_write_sampler_desc(dev, set,
725 write->dstBinding,
726 write->dstArrayElement + j,
727 &write->pImageInfo[j]);
728 panvk_write_tex_desc(dev, set,
729 write->dstBinding,
730 write->dstArrayElement + j,
731 &write->pImageInfo[j]);
732 }
733 break;
734
735 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
736 for (uint32_t j = 0; j < write->descriptorCount; j++) {
737 panvk_write_tex_desc(dev, set,
738 write->dstBinding,
739 write->dstArrayElement + j,
740 &write->pImageInfo[j]);
741 }
742 break;
743
744 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
745 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
746 for (uint32_t j = 0; j < write->descriptorCount; j++) {
747 panvk_write_img_desc(dev, set,
748 write->dstBinding,
749 write->dstArrayElement + j,
750 &write->pImageInfo[j]);
751 }
752 break;
753
754 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
755 for (uint32_t j = 0; j < write->descriptorCount; j++) {
756 panvk_write_tex_buf_desc(dev, set,
757 write->dstBinding,
758 write->dstArrayElement + j,
759 write->pTexelBufferView[j]);
760 }
761 break;
762
763 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
764 for (uint32_t j = 0; j < write->descriptorCount; j++) {
765 panvk_write_img_buf_desc(dev, set,
766 write->dstBinding,
767 write->dstArrayElement + j,
768 write->pTexelBufferView[j]);
769 }
770 break;
771
772 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
773 for (uint32_t j = 0; j < write->descriptorCount; j++) {
774 panvk_write_ubo_desc(dev, set,
775 write->dstBinding,
776 write->dstArrayElement + j,
777 &write->pBufferInfo[j]);
778 }
779 break;
780
781 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
782 for (uint32_t j = 0; j < write->descriptorCount; j++) {
783 panvk_write_dyn_ubo_desc(dev, set,
784 write->dstBinding,
785 write->dstArrayElement + j,
786 &write->pBufferInfo[j]);
787 }
788 break;
789
790 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
791 for (uint32_t j = 0; j < write->descriptorCount; j++) {
792 panvk_write_ssbo_desc(dev, set,
793 write->dstBinding,
794 write->dstArrayElement + j,
795 &write->pBufferInfo[j]);
796 }
797 break;
798
799 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
800 for (uint32_t j = 0; j < write->descriptorCount; j++) {
801 panvk_write_dyn_ssbo_desc(dev, set,
802 write->dstBinding,
803 write->dstArrayElement + j,
804 &write->pBufferInfo[j]);
805 }
806 break;
807
808 default:
809 unreachable("Unsupported descriptor type");
810 }
811 }
812
813 for (unsigned i = 0; i < descriptorCopyCount; i++) {
814 const VkCopyDescriptorSet *copy = &pDescriptorCopies[i];
815 VK_FROM_HANDLE(panvk_descriptor_set, src_set, copy->srcSet);
816 VK_FROM_HANDLE(panvk_descriptor_set, dst_set, copy->dstSet);
817
818 const struct panvk_descriptor_set_binding_layout *dst_binding_layout =
819 &dst_set->layout->bindings[copy->dstBinding];
820 const struct panvk_descriptor_set_binding_layout *src_binding_layout =
821 &src_set->layout->bindings[copy->srcBinding];
822
823 assert(dst_binding_layout->type == src_binding_layout->type);
824
825 if (dst_binding_layout->desc_ubo_stride > 0 &&
826 src_binding_layout->desc_ubo_stride > 0) {
827 for (uint32_t j = 0; j < copy->descriptorCount; j++) {
828 memcpy(panvk_desc_ubo_data(dst_set, copy->dstBinding,
829 copy->dstArrayElement + j),
830 panvk_desc_ubo_data(src_set, copy->srcBinding,
831 copy->srcArrayElement + j),
832 MIN2(dst_binding_layout->desc_ubo_stride,
833 src_binding_layout->desc_ubo_stride));
834 }
835 }
836
837 switch (src_binding_layout->type) {
838 case VK_DESCRIPTOR_TYPE_SAMPLER:
839 for (uint32_t j = 0; j < copy->descriptorCount; j++) {
840 panvk_copy_sampler_desc(dst_set, copy->dstBinding,
841 copy->dstArrayElement + j,
842 src_set, copy->srcBinding,
843 copy->srcArrayElement + j);
844 }
845 break;
846
847 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
848 for (uint32_t j = 0; j < copy->descriptorCount; j++) {
849 panvk_copy_sampler_desc(dst_set, copy->dstBinding,
850 copy->dstArrayElement + j,
851 src_set, copy->srcBinding,
852 copy->srcArrayElement + j);
853 panvk_copy_tex_desc(dst_set, copy->dstBinding,
854 copy->dstArrayElement + j,
855 src_set, copy->srcBinding,
856 copy->srcArrayElement + j);
857 }
858 break;
859
860 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
861 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
862 for (uint32_t j = 0; j < copy->descriptorCount; j++) {
863 panvk_copy_tex_desc(dst_set, copy->dstBinding,
864 copy->dstArrayElement + j,
865 src_set, copy->srcBinding,
866 copy->srcArrayElement + j);
867 }
868 break;
869
870 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
871 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
872 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
873 for (uint32_t j = 0; j < copy->descriptorCount; j++) {
874 panvk_copy_img_desc(dst_set, copy->dstBinding,
875 copy->dstArrayElement + j,
876 src_set, copy->srcBinding,
877 copy->srcArrayElement + j);
878 }
879 break;
880
881 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
882 for (uint32_t j = 0; j < copy->descriptorCount; j++) {
883 panvk_copy_ubo_desc(dst_set, copy->dstBinding,
884 copy->dstArrayElement + j,
885 src_set, copy->srcBinding,
886 copy->srcArrayElement + j);
887 }
888 break;
889
890 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
891 for (uint32_t j = 0; j < copy->descriptorCount; j++) {
892 panvk_copy_dyn_ubo_desc(dst_set, copy->dstBinding,
893 copy->dstArrayElement + j,
894 src_set, copy->srcBinding,
895 copy->srcArrayElement + j);
896 }
897 break;
898
899 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
900 for (uint32_t j = 0; j < copy->descriptorCount; j++) {
901 panvk_copy_ssbo_desc(dst_set, copy->dstBinding,
902 copy->dstArrayElement + j,
903 src_set, copy->srcBinding,
904 copy->srcArrayElement + j);
905 }
906 break;
907
908 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
909 for (uint32_t j = 0; j < copy->descriptorCount; j++) {
910 panvk_copy_dyn_ssbo_desc(dst_set, copy->dstBinding,
911 copy->dstArrayElement + j,
912 src_set, copy->srcBinding,
913 copy->srcArrayElement + j);
914 }
915 break;
916
917 default:
918 unreachable("Unsupported descriptor type");
919 }
920 }
921 }
922