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 static VkResult
panvk_per_arch(descriptor_set_create)46 panvk_per_arch(descriptor_set_create)(struct panvk_device *device,
47 struct panvk_descriptor_pool *pool,
48 const struct panvk_descriptor_set_layout *layout,
49 struct panvk_descriptor_set **out_set)
50 {
51 struct panvk_descriptor_set *set;
52
53 /* TODO: Allocate from the pool! */
54 set = vk_object_zalloc(&device->vk, NULL,
55 sizeof(struct panvk_descriptor_set),
56 VK_OBJECT_TYPE_DESCRIPTOR_SET);
57 if (!set)
58 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
59
60 set->layout = layout;
61 set->descs = vk_alloc(&device->vk.alloc,
62 sizeof(*set->descs) * layout->num_descs, 8,
63 VK_OBJECT_TYPE_DESCRIPTOR_SET);
64 if (!set->descs)
65 goto err_free_set;
66
67 if (layout->num_ubos) {
68 set->ubos = vk_zalloc(&device->vk.alloc,
69 pan_size(UNIFORM_BUFFER) * layout->num_ubos, 8,
70 VK_OBJECT_TYPE_DESCRIPTOR_SET);
71 if (!set->ubos)
72 goto err_free_set;
73 }
74
75 if (layout->num_dyn_ubos) {
76 set->dyn_ubos = vk_zalloc(&device->vk.alloc,
77 sizeof(*set->dyn_ubos) * layout->num_dyn_ubos, 8,
78 VK_OBJECT_TYPE_DESCRIPTOR_SET);
79 if (!set->dyn_ubos)
80 goto err_free_set;
81 }
82
83 if (layout->num_ssbos) {
84 set->ssbos = vk_zalloc(&device->vk.alloc,
85 sizeof(*set->ssbos) * layout->num_ssbos, 8,
86 VK_OBJECT_TYPE_DESCRIPTOR_SET);
87 if (!set->ssbos)
88 goto err_free_set;
89 }
90
91 if (layout->num_dyn_ssbos) {
92 set->dyn_ssbos = vk_zalloc(&device->vk.alloc,
93 sizeof(*set->dyn_ssbos) * layout->num_dyn_ssbos, 8,
94 VK_OBJECT_TYPE_DESCRIPTOR_SET);
95 if (!set->dyn_ssbos)
96 goto err_free_set;
97 }
98
99 if (layout->num_samplers) {
100 set->samplers = vk_zalloc(&device->vk.alloc,
101 pan_size(SAMPLER) * layout->num_samplers, 8,
102 VK_OBJECT_TYPE_DESCRIPTOR_SET);
103 if (!set->samplers)
104 goto err_free_set;
105 }
106
107 if (layout->num_textures) {
108 set->textures =
109 vk_zalloc(&device->vk.alloc,
110 (PAN_ARCH >= 6 ? pan_size(TEXTURE) : sizeof(mali_ptr)) *
111 layout->num_textures,
112 8, VK_OBJECT_TYPE_DESCRIPTOR_SET);
113 if (!set->textures)
114 goto err_free_set;
115 }
116
117 if (layout->num_imgs) {
118 set->img_fmts =
119 vk_zalloc(&device->vk.alloc,
120 sizeof(*set->img_fmts) * layout->num_imgs,
121 8, VK_OBJECT_TYPE_DESCRIPTOR_SET);
122 if (!set->img_fmts)
123 goto err_free_set;
124
125 set->img_attrib_bufs =
126 vk_zalloc(&device->vk.alloc,
127 pan_size(ATTRIBUTE_BUFFER) * 2 * layout->num_imgs,
128 8, VK_OBJECT_TYPE_DESCRIPTOR_SET);
129 if (!set->img_attrib_bufs)
130 goto err_free_set;
131 }
132
133 for (unsigned i = 0; i < layout->binding_count; i++) {
134 if (!layout->bindings[i].immutable_samplers)
135 continue;
136
137 for (unsigned j = 0; j < layout->bindings[i].array_size; j++) {
138 set->descs[layout->bindings[i].desc_idx].image.sampler =
139 layout->bindings[i].immutable_samplers[j];
140 }
141 }
142
143 *out_set = set;
144 return VK_SUCCESS;
145
146 err_free_set:
147 vk_free(&device->vk.alloc, set->textures);
148 vk_free(&device->vk.alloc, set->samplers);
149 vk_free(&device->vk.alloc, set->ssbos);
150 vk_free(&device->vk.alloc, set->dyn_ssbos);
151 vk_free(&device->vk.alloc, set->ubos);
152 vk_free(&device->vk.alloc, set->dyn_ubos);
153 vk_free(&device->vk.alloc, set->img_fmts);
154 vk_free(&device->vk.alloc, set->img_attrib_bufs);
155 vk_free(&device->vk.alloc, set->descs);
156 vk_object_free(&device->vk, NULL, set);
157 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
158 }
159
160 VkResult
panvk_per_arch(AllocateDescriptorSets)161 panvk_per_arch(AllocateDescriptorSets)(VkDevice _device,
162 const VkDescriptorSetAllocateInfo *pAllocateInfo,
163 VkDescriptorSet *pDescriptorSets)
164 {
165 VK_FROM_HANDLE(panvk_device, device, _device);
166 VK_FROM_HANDLE(panvk_descriptor_pool, pool, pAllocateInfo->descriptorPool);
167 VkResult result;
168 unsigned i;
169
170 for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
171 VK_FROM_HANDLE(panvk_descriptor_set_layout, layout,
172 pAllocateInfo->pSetLayouts[i]);
173 struct panvk_descriptor_set *set = NULL;
174
175 result = panvk_per_arch(descriptor_set_create)(device, pool, layout, &set);
176 if (result != VK_SUCCESS)
177 goto err_free_sets;
178
179 pDescriptorSets[i] = panvk_descriptor_set_to_handle(set);
180 }
181
182 return VK_SUCCESS;
183
184 err_free_sets:
185 panvk_FreeDescriptorSets(_device, pAllocateInfo->descriptorPool, i, pDescriptorSets);
186 for (i = 0; i < pAllocateInfo->descriptorSetCount; i++)
187 pDescriptorSets[i] = VK_NULL_HANDLE;
188
189 return result;
190 }
191
192 static void
panvk_set_buffer_desc(struct panvk_buffer_desc * bdesc,const VkDescriptorBufferInfo * pBufferInfo)193 panvk_set_buffer_desc(struct panvk_buffer_desc *bdesc,
194 const VkDescriptorBufferInfo *pBufferInfo)
195 {
196 VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer);
197
198 bdesc->buffer = buffer;
199 bdesc->offset = pBufferInfo->offset;
200 bdesc->size = pBufferInfo->range;
201 }
202
203 static void
panvk_per_arch(set_ubo_desc)204 panvk_per_arch(set_ubo_desc)(void *ubo,
205 const VkDescriptorBufferInfo *pBufferInfo)
206 {
207 VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer);
208 size_t size = pBufferInfo->range == VK_WHOLE_SIZE ?
209 (buffer->bo->size - pBufferInfo->offset) :
210 pBufferInfo->range;
211
212 panvk_per_arch(emit_ubo)(buffer->bo->ptr.gpu + pBufferInfo->offset, size, ubo);
213 }
214
215 static void
panvk_set_sampler_desc(void * desc,const VkDescriptorImageInfo * pImageInfo)216 panvk_set_sampler_desc(void *desc,
217 const VkDescriptorImageInfo *pImageInfo)
218 {
219 VK_FROM_HANDLE(panvk_sampler, sampler, pImageInfo->sampler);
220
221 memcpy(desc, &sampler->desc, sizeof(sampler->desc));
222 }
223
224 static void
panvk_per_arch(set_texture_desc)225 panvk_per_arch(set_texture_desc)(struct panvk_descriptor_set *set,
226 unsigned idx,
227 const VkDescriptorImageInfo *pImageInfo)
228 {
229 VK_FROM_HANDLE(panvk_image_view, view, pImageInfo->imageView);
230
231 #if PAN_ARCH >= 6
232 memcpy(&((struct mali_texture_packed *)set->textures)[idx],
233 view->descs.tex, pan_size(TEXTURE));
234 #else
235 ((mali_ptr *)set->textures)[idx] = view->bo->ptr.gpu;
236 #endif
237 }
238
239 static void
panvk_set_tex_buf_desc(struct panvk_device * dev,struct panvk_descriptor_set * set,unsigned idx,const VkBufferView bufferView)240 panvk_set_tex_buf_desc(struct panvk_device *dev,
241 struct panvk_descriptor_set *set,
242 unsigned idx,
243 const VkBufferView bufferView)
244 {
245 VK_FROM_HANDLE(panvk_buffer_view, view, bufferView);
246
247 #if PAN_ARCH >= 6
248 memcpy(&((struct mali_texture_packed *)set->textures)[idx],
249 view->descs.tex, pan_size(TEXTURE));
250 #else
251 ((mali_ptr *)set->textures)[idx] = view->bo->ptr.gpu;
252 #endif
253 }
254
255 static void
panvk_set_img_desc(struct panvk_device * dev,struct panvk_descriptor_set * set,unsigned idx,const VkDescriptorImageInfo * pImageInfo)256 panvk_set_img_desc(struct panvk_device *dev,
257 struct panvk_descriptor_set *set,
258 unsigned idx,
259 const VkDescriptorImageInfo *pImageInfo)
260 {
261 const struct panfrost_device *pdev = &dev->physical_device->pdev;
262 VK_FROM_HANDLE(panvk_image_view, view, pImageInfo->imageView);
263 void *attrib_buf = (uint8_t *)set->img_attrib_bufs + (pan_size(ATTRIBUTE_BUFFER) * 2 * idx);
264
265 set->img_fmts[idx] = pdev->formats[view->pview.format].hw;
266 memcpy(attrib_buf, view->descs.img_attrib_buf, pan_size(ATTRIBUTE_BUFFER) * 2);
267 }
268
269 static void
panvk_set_img_buf_desc(struct panvk_device * dev,struct panvk_descriptor_set * set,unsigned idx,const VkBufferView bufferView)270 panvk_set_img_buf_desc(struct panvk_device *dev,
271 struct panvk_descriptor_set *set,
272 unsigned idx,
273 const VkBufferView bufferView)
274 {
275 const struct panfrost_device *pdev = &dev->physical_device->pdev;
276 VK_FROM_HANDLE(panvk_buffer_view, view, bufferView);
277
278 void *attrib_buf = (uint8_t *)set->img_attrib_bufs + (pan_size(ATTRIBUTE_BUFFER) * 2 * idx);
279
280 set->img_fmts[idx] = pdev->formats[view->fmt].hw;
281 memcpy(attrib_buf, view->descs.img_attrib_buf, pan_size(ATTRIBUTE_BUFFER) * 2);
282 }
283
284 static void
panvk_per_arch(write_descriptor_set)285 panvk_per_arch(write_descriptor_set)(struct panvk_device *dev,
286 const VkWriteDescriptorSet *pDescriptorWrite)
287 {
288 VK_FROM_HANDLE(panvk_descriptor_set, set, pDescriptorWrite->dstSet);
289 const struct panvk_descriptor_set_layout *layout = set->layout;
290 unsigned dest_offset = pDescriptorWrite->dstArrayElement;
291 unsigned binding = pDescriptorWrite->dstBinding;
292 struct mali_uniform_buffer_packed *ubos = set->ubos;
293 struct mali_sampler_packed *samplers = set->samplers;
294 unsigned src_offset = 0;
295
296 while (src_offset < pDescriptorWrite->descriptorCount &&
297 binding < layout->binding_count) {
298 const struct panvk_descriptor_set_binding_layout *binding_layout =
299 &layout->bindings[binding];
300
301 if (!binding_layout->array_size) {
302 binding++;
303 dest_offset = 0;
304 continue;
305 }
306
307 assert(pDescriptorWrite->descriptorType == binding_layout->type);
308 unsigned ndescs = MIN2(pDescriptorWrite->descriptorCount - src_offset,
309 binding_layout->array_size - dest_offset);
310 assert(binding_layout->desc_idx + dest_offset + ndescs <= set->layout->num_descs);
311
312 switch (pDescriptorWrite->descriptorType) {
313 case VK_DESCRIPTOR_TYPE_SAMPLER:
314 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
315 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
316 for (unsigned i = 0; i < ndescs; i++) {
317 const VkDescriptorImageInfo *info = &pDescriptorWrite->pImageInfo[src_offset + i];
318
319 if ((pDescriptorWrite->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
320 pDescriptorWrite->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
321 !binding_layout->immutable_samplers) {
322 unsigned sampler = binding_layout->sampler_idx + dest_offset + i;
323
324 panvk_set_sampler_desc(&samplers[sampler], info);
325 }
326
327 if (pDescriptorWrite->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
328 pDescriptorWrite->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
329 unsigned tex = binding_layout->tex_idx + dest_offset + i;
330
331 panvk_per_arch(set_texture_desc)(set, tex, info);
332 }
333 }
334 break;
335
336 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
337 for (unsigned i = 0; i < ndescs; i++) {
338 unsigned tex = binding_layout->tex_idx + dest_offset + i;
339 panvk_set_tex_buf_desc(dev, set, tex,
340 pDescriptorWrite->pTexelBufferView[src_offset + i]);
341 }
342 break;
343
344 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
345 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
346 for (unsigned i = 0; i < ndescs; i++) {
347 const VkDescriptorImageInfo *info = &pDescriptorWrite->pImageInfo[src_offset + i];
348 unsigned img = binding_layout->img_idx + dest_offset + i;
349
350 panvk_set_img_desc(dev, set, img, info);
351 }
352 break;
353
354 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
355 for (unsigned i = 0; i < ndescs; i++) {
356 unsigned img = binding_layout->img_idx + dest_offset + i;
357 panvk_set_img_buf_desc(dev, set, img,
358 pDescriptorWrite->pTexelBufferView[src_offset + i]);
359 }
360 break;
361
362 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
363 for (unsigned i = 0; i < ndescs; i++) {
364 unsigned ubo = binding_layout->ubo_idx + dest_offset + i;
365 panvk_per_arch(set_ubo_desc)(&ubos[ubo],
366 &pDescriptorWrite->pBufferInfo[src_offset + i]);
367 }
368 break;
369 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
370 for (unsigned i = 0; i < ndescs; i++) {
371 unsigned ubo = binding_layout->dyn_ubo_idx + dest_offset + i;
372 panvk_set_buffer_desc(&set->dyn_ubos[ubo], &pDescriptorWrite->pBufferInfo[src_offset + i]);
373 }
374 break;
375 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
376 for (unsigned i = 0; i < ndescs; i++) {
377 unsigned ssbo = binding_layout->ssbo_idx + dest_offset + i;
378 panvk_set_buffer_desc(&set->ssbos[ssbo], &pDescriptorWrite->pBufferInfo[src_offset + i]);
379 }
380 break;
381 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
382 for (unsigned i = 0; i < ndescs; i++) {
383 unsigned ssbo = binding_layout->dyn_ssbo_idx + dest_offset + i;
384 panvk_set_buffer_desc(&set->dyn_ssbos[ssbo], &pDescriptorWrite->pBufferInfo[src_offset + i]);
385 }
386 break;
387 default:
388 unreachable("Invalid type");
389 }
390
391 src_offset += ndescs;
392 binding++;
393 dest_offset = 0;
394 }
395 }
396
397 static void
panvk_copy_descriptor_set(struct panvk_device * dev,const VkCopyDescriptorSet * pDescriptorCopy)398 panvk_copy_descriptor_set(struct panvk_device *dev,
399 const VkCopyDescriptorSet *pDescriptorCopy)
400 {
401 VK_FROM_HANDLE(panvk_descriptor_set, dest_set, pDescriptorCopy->dstSet);
402 VK_FROM_HANDLE(panvk_descriptor_set, src_set, pDescriptorCopy->srcSet);
403 const struct panvk_descriptor_set_layout *dest_layout = dest_set->layout;
404 const struct panvk_descriptor_set_layout *src_layout = dest_set->layout;
405 unsigned dest_offset = pDescriptorCopy->dstArrayElement;
406 unsigned src_offset = pDescriptorCopy->srcArrayElement;
407 unsigned dest_binding = pDescriptorCopy->dstBinding;
408 unsigned src_binding = pDescriptorCopy->srcBinding;
409 unsigned desc_count = pDescriptorCopy->descriptorCount;
410
411 while (desc_count && src_binding < src_layout->binding_count &&
412 dest_binding < dest_layout->binding_count) {
413 const struct panvk_descriptor_set_binding_layout *dest_binding_layout =
414 &src_layout->bindings[dest_binding];
415
416 if (!dest_binding_layout->array_size) {
417 dest_binding++;
418 dest_offset = 0;
419 continue;
420 }
421
422 const struct panvk_descriptor_set_binding_layout *src_binding_layout =
423 &src_layout->bindings[src_binding];
424
425 if (!src_binding_layout->array_size) {
426 src_binding++;
427 src_offset = 0;
428 continue;
429 }
430
431 assert(dest_binding_layout->type == src_binding_layout->type);
432
433 unsigned ndescs = MAX3(desc_count,
434 dest_binding_layout->array_size - dest_offset,
435 src_binding_layout->array_size - src_offset);
436
437 struct panvk_descriptor *dest_descs = dest_set->descs + dest_binding_layout->desc_idx + dest_offset;
438 struct panvk_descriptor *src_descs = src_set->descs + src_binding_layout->desc_idx + src_offset;
439 memcpy(dest_descs, src_descs, ndescs * sizeof(*dest_descs));
440 desc_count -= ndescs;
441 dest_offset += ndescs;
442 if (dest_offset == dest_binding_layout->array_size) {
443 dest_binding++;
444 dest_offset = 0;
445 continue;
446 }
447 src_offset += ndescs;
448 if (src_offset == src_binding_layout->array_size) {
449 src_binding++;
450 src_offset = 0;
451 continue;
452 }
453 }
454
455 assert(!desc_count);
456 }
457
458 void
panvk_per_arch(UpdateDescriptorSets)459 panvk_per_arch(UpdateDescriptorSets)(VkDevice _device,
460 uint32_t descriptorWriteCount,
461 const VkWriteDescriptorSet *pDescriptorWrites,
462 uint32_t descriptorCopyCount,
463 const VkCopyDescriptorSet *pDescriptorCopies)
464 {
465 VK_FROM_HANDLE(panvk_device, dev, _device);
466
467 for (unsigned i = 0; i < descriptorWriteCount; i++)
468 panvk_per_arch(write_descriptor_set)(dev, &pDescriptorWrites[i]);
469 for (unsigned i = 0; i < descriptorCopyCount; i++)
470 panvk_copy_descriptor_set(dev, &pDescriptorCopies[i]);
471 }
472