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