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