• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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