1 /*
2 * Copyright © 2022 Imagination Technologies Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24 #include <assert.h>
25 #include <limits.h>
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <vulkan/vulkan.h>
30
31 #include "hwdef/rogue_hw_utils.h"
32 #include "pvr_bo.h"
33 #include "pvr_private.h"
34 #include "pvr_types.h"
35 #include "util/compiler.h"
36 #include "util/list.h"
37 #include "util/log.h"
38 #include "util/macros.h"
39 #include "vk_alloc.h"
40 #include "vk_format.h"
41 #include "vk_log.h"
42 #include "vk_object.h"
43 #include "vk_util.h"
44
45 #if defined(DEBUG)
46 static const struct {
47 const char *raw;
48 const char *primary;
49 const char *secondary;
50 const char *primary_dynamic;
51 const char *secondary_dynamic;
52 } stage_names[] = {
53 { "Vertex",
54 "Vertex Primary",
55 "Vertex Secondary",
56 "Vertex Dynamic Primary",
57 "Vertex Dynamic Secondary" },
58 { "Fragment",
59 "Fragment Primary",
60 "Fragment Secondary",
61 "Fragment Dynamic Primary",
62 "Fragment Dynamic Secondary" },
63 { "Compute",
64 "Compute Primary",
65 "Compute Secondary",
66 "Compute Dynamic Primary",
67 "Compute Dynamic Secondary" },
68 };
69
70 static const char *descriptor_names[] = { "VK SAMPLER",
71 "VK COMBINED_IMAGE_SAMPLER",
72 "VK SAMPLED_IMAGE",
73 "VK STORAGE_IMAGE",
74 "VK UNIFORM_TEXEL_BUFFER",
75 "VK STORAGE_TEXEL_BUFFER",
76 "VK UNIFORM_BUFFER",
77 "VK STORAGE_BUFFER",
78 "VK UNIFORM_BUFFER_DYNAMIC",
79 "VK STORAGE_BUFFER_DYNAMIC",
80 "VK INPUT_ATTACHMENT" };
81 #endif
82
83 #define PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYBASE 0U
84 #define PVR_DESC_IMAGE_SECONDARY_SIZE_ARRAYBASE 2U
85 #define PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYSTRIDE \
86 (PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYBASE + \
87 PVR_DESC_IMAGE_SECONDARY_SIZE_ARRAYBASE)
88 #define PVR_DESC_IMAGE_SECONDARY_SIZE_ARRAYSTRIDE 1U
89
90 #define PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYMAXINDEX(dev_info) \
91 (PVR_HAS_FEATURE(dev_info, tpu_array_textures) \
92 ? (0) \
93 : PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYSTRIDE + \
94 PVR_DESC_IMAGE_SECONDARY_SIZE_ARRAYSTRIDE)
95
96 #define PVR_DESC_IMAGE_SECONDARY_SIZE_ARRAYMAXINDEX 1U
97 #define PVR_DESC_IMAGE_SECONDARY_OFFSET_WIDTH(dev_info) \
98 (PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYMAXINDEX(dev_info) + \
99 PVR_DESC_IMAGE_SECONDARY_SIZE_ARRAYMAXINDEX)
100 #define PVR_DESC_IMAGE_SECONDARY_SIZE_WIDTH 1U
101 #define PVR_DESC_IMAGE_SECONDARY_OFFSET_HEIGHT(dev_info) \
102 (PVR_DESC_IMAGE_SECONDARY_OFFSET_WIDTH(dev_info) + \
103 PVR_DESC_IMAGE_SECONDARY_SIZE_WIDTH)
104 #define PVR_DESC_IMAGE_SECONDARY_SIZE_HEIGHT 1U
105 #define PVR_DESC_IMAGE_SECONDARY_OFFSET_DEPTH(dev_info) \
106 (PVR_DESC_IMAGE_SECONDARY_OFFSET_HEIGHT(dev_info) + \
107 PVR_DESC_IMAGE_SECONDARY_SIZE_HEIGHT)
108 #define PVR_DESC_IMAGE_SECONDARY_SIZE_DEPTH 1U
109 #define PVR_DESC_IMAGE_SECONDARY_TOTAL_SIZE(dev_info) \
110 (PVR_DESC_IMAGE_SECONDARY_OFFSET_DEPTH(dev_info) + \
111 PVR_DESC_IMAGE_SECONDARY_SIZE_DEPTH)
112
pvr_descriptor_size_info_init(const struct pvr_device * device,VkDescriptorType type,struct pvr_descriptor_size_info * const size_info_out)113 static void pvr_descriptor_size_info_init(
114 const struct pvr_device *device,
115 VkDescriptorType type,
116 struct pvr_descriptor_size_info *const size_info_out)
117 {
118 /* UINT_MAX is a place holder. These values will be filled by calling the
119 * init function, and set appropriately based on device features.
120 */
121 static const struct pvr_descriptor_size_info template_size_infos[] = {
122 /* VK_DESCRIPTOR_TYPE_SAMPLER */
123 { PVR_SAMPLER_DESCRIPTOR_SIZE, 0, 4 },
124 /* VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER */
125 { PVR_IMAGE_DESCRIPTOR_SIZE + PVR_SAMPLER_DESCRIPTOR_SIZE, UINT_MAX, 4 },
126 /* VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE */
127 { 4, UINT_MAX, 4 },
128 /* VK_DESCRIPTOR_TYPE_STORAGE_IMAGE */
129 { 4, UINT_MAX, 4 },
130 /* VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER */
131 { 4, UINT_MAX, 4 },
132 /* VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER */
133 { 4, UINT_MAX, 4 },
134 /* VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER */
135 { 2, UINT_MAX, 2 },
136 /* VK_DESCRIPTOR_TYPE_STORAGE_BUFFER */
137 { 2, 1, 2 },
138 /* VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC */
139 { 2, UINT_MAX, 2 },
140 /* VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC */
141 { 2, 1, 2 },
142 /* VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT */
143 { 8, UINT_MAX, 4 }
144 };
145
146 *size_info_out = template_size_infos[type];
147
148 switch (type) {
149 case VK_DESCRIPTOR_TYPE_SAMPLER:
150 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
151 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
152 break;
153
154 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
155 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
156 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
157 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
158 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
159 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
160 size_info_out->secondary =
161 PVR_DESC_IMAGE_SECONDARY_TOTAL_SIZE(&device->pdevice->dev_info);
162 break;
163
164 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
165 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
166 size_info_out->secondary = (uint32_t)device->features.robustBufferAccess;
167 break;
168
169 default:
170 unreachable("Unknown descriptor type");
171 }
172 }
173
pvr_stage_matches_vk_flags(enum pvr_stage_allocation pvr_stage,VkShaderStageFlags flags)174 static bool pvr_stage_matches_vk_flags(enum pvr_stage_allocation pvr_stage,
175 VkShaderStageFlags flags)
176 {
177 VkShaderStageFlags flags_per_stage;
178
179 switch (pvr_stage) {
180 case PVR_STAGE_ALLOCATION_VERTEX_GEOMETRY:
181 flags_per_stage = VK_SHADER_STAGE_VERTEX_BIT |
182 VK_SHADER_STAGE_GEOMETRY_BIT;
183 break;
184 case PVR_STAGE_ALLOCATION_FRAGMENT:
185 flags_per_stage = VK_SHADER_STAGE_FRAGMENT_BIT;
186 break;
187 case PVR_STAGE_ALLOCATION_COMPUTE:
188 flags_per_stage = VK_SHADER_STAGE_COMPUTE_BIT;
189 break;
190 default:
191 unreachable("Unrecognized allocation stage.");
192 }
193
194 return !!(flags_per_stage & flags);
195 }
196
197 /* If allocator == NULL, the internal one will be used. */
198 static struct pvr_descriptor_set_layout *
pvr_descriptor_set_layout_allocate(struct pvr_device * device,const VkAllocationCallbacks * allocator,uint32_t binding_count,uint32_t immutable_sampler_count,uint32_t supported_descriptors_count)199 pvr_descriptor_set_layout_allocate(struct pvr_device *device,
200 const VkAllocationCallbacks *allocator,
201 uint32_t binding_count,
202 uint32_t immutable_sampler_count,
203 uint32_t supported_descriptors_count)
204 {
205 struct pvr_descriptor_set_layout_binding *bindings;
206 struct pvr_descriptor_set_layout *layout;
207 __typeof__(layout->per_stage_descriptor_count) counts;
208 const struct pvr_sampler **immutable_samplers;
209
210 VK_MULTIALLOC(ma);
211 vk_multialloc_add(&ma, &layout, __typeof__(*layout), 1);
212 vk_multialloc_add(&ma, &bindings, __typeof__(*bindings), binding_count);
213 vk_multialloc_add(&ma,
214 &immutable_samplers,
215 __typeof__(*immutable_samplers),
216 immutable_sampler_count);
217
218 for (uint32_t stage = 0; stage < ARRAY_SIZE(counts); stage++) {
219 vk_multialloc_add(&ma,
220 &counts[stage],
221 __typeof__(*counts[0]),
222 supported_descriptors_count);
223 }
224
225 /* pvr_CreateDescriptorSetLayout() relies on this being zero allocated. */
226 if (!vk_multialloc_zalloc2(&ma,
227 &device->vk.alloc,
228 allocator,
229 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)) {
230 return NULL;
231 }
232
233 layout->bindings = bindings;
234 layout->immutable_samplers = immutable_samplers;
235
236 memcpy(&layout->per_stage_descriptor_count, &counts, sizeof(counts));
237
238 vk_object_base_init(&device->vk,
239 &layout->base,
240 VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT);
241
242 return layout;
243 }
244
245 /* If allocator == NULL, the internal one will be used. */
246 static void
pvr_descriptor_set_layout_free(struct pvr_device * device,const VkAllocationCallbacks * allocator,struct pvr_descriptor_set_layout * layout)247 pvr_descriptor_set_layout_free(struct pvr_device *device,
248 const VkAllocationCallbacks *allocator,
249 struct pvr_descriptor_set_layout *layout)
250 {
251 vk_object_base_finish(&layout->base);
252 vk_free2(&device->vk.alloc, allocator, layout);
253 }
254
pvr_binding_compare(const void * a,const void * b)255 static int pvr_binding_compare(const void *a, const void *b)
256 {
257 uint32_t binding_a = ((VkDescriptorSetLayoutBinding *)a)->binding;
258 uint32_t binding_b = ((VkDescriptorSetLayoutBinding *)b)->binding;
259
260 if (binding_a < binding_b)
261 return -1;
262
263 if (binding_a > binding_b)
264 return 1;
265
266 return 0;
267 }
268
269 /* If allocator == NULL, the internal one will be used. */
270 static VkDescriptorSetLayoutBinding *
pvr_create_sorted_bindings(struct pvr_device * device,const VkAllocationCallbacks * allocator,const VkDescriptorSetLayoutBinding * bindings,uint32_t binding_count)271 pvr_create_sorted_bindings(struct pvr_device *device,
272 const VkAllocationCallbacks *allocator,
273 const VkDescriptorSetLayoutBinding *bindings,
274 uint32_t binding_count)
275 {
276 VkDescriptorSetLayoutBinding *sorted_bindings =
277 vk_alloc2(&device->vk.alloc,
278 allocator,
279 binding_count * sizeof(*sorted_bindings),
280 8,
281 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
282 if (!sorted_bindings)
283 return NULL;
284
285 memcpy(sorted_bindings, bindings, binding_count * sizeof(*sorted_bindings));
286
287 qsort(sorted_bindings,
288 binding_count,
289 sizeof(*sorted_bindings),
290 pvr_binding_compare);
291
292 return sorted_bindings;
293 }
294
295 struct pvr_register_usage {
296 uint32_t primary;
297 uint32_t primary_dynamic;
298 uint32_t secondary;
299 uint32_t secondary_dynamic;
300 };
301
pvr_setup_in_memory_layout_sizes(struct pvr_descriptor_set_layout * layout,const struct pvr_register_usage reg_usage[PVR_STAGE_ALLOCATION_COUNT])302 static void pvr_setup_in_memory_layout_sizes(
303 struct pvr_descriptor_set_layout *layout,
304 const struct pvr_register_usage reg_usage[PVR_STAGE_ALLOCATION_COUNT])
305 {
306 for (uint32_t stage = 0;
307 stage < ARRAY_SIZE(layout->memory_layout_in_dwords_per_stage);
308 stage++) {
309 layout->total_size_in_dwords = ALIGN_POT(layout->total_size_in_dwords, 4);
310
311 layout->memory_layout_in_dwords_per_stage[stage].primary_offset =
312 layout->total_size_in_dwords;
313 layout->memory_layout_in_dwords_per_stage[stage].primary_size =
314 reg_usage[stage].primary;
315
316 layout->total_size_in_dwords += reg_usage[stage].primary;
317 layout->total_size_in_dwords = ALIGN_POT(layout->total_size_in_dwords, 4);
318
319 layout->memory_layout_in_dwords_per_stage[stage].secondary_offset =
320 layout->total_size_in_dwords;
321 layout->memory_layout_in_dwords_per_stage[stage].secondary_size =
322 reg_usage[stage].secondary;
323
324 layout->total_size_in_dwords += reg_usage[stage].secondary;
325
326 layout->memory_layout_in_dwords_per_stage[stage].primary_dynamic_size =
327 reg_usage[stage].primary_dynamic;
328 layout->memory_layout_in_dwords_per_stage[stage].secondary_dynamic_size =
329 reg_usage[stage].secondary_dynamic;
330 }
331 }
332
333 #if defined(DEBUG)
334 static void
pvr_dump_in_memory_layout_sizes(const struct pvr_descriptor_set_layout * layout)335 pvr_dump_in_memory_layout_sizes(const struct pvr_descriptor_set_layout *layout)
336 {
337 mesa_logd("=== SET LAYOUT ===");
338 mesa_logd("----------------------------------------------");
339 mesa_logd(" in memory:");
340 mesa_logd("----------------------------------------------");
341
342 for (uint32_t stage = 0;
343 stage < ARRAY_SIZE(layout->memory_layout_in_dwords_per_stage);
344 stage++) {
345 mesa_logd(
346 "| %-18s @ %04u |",
347 stage_names[stage].primary,
348 layout->memory_layout_in_dwords_per_stage[stage].primary_offset);
349 mesa_logd("----------------------------------------------");
350
351 /* Print primaries. */
352 for (uint32_t i = 0; i < layout->binding_count; i++) {
353 const struct pvr_descriptor_set_layout_binding *const binding =
354 &layout->bindings[i];
355
356 if (binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
357 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
358 continue;
359
360 mesa_logd("| %s %04u | %-26s[%3u] |",
361 (binding->shader_stage_mask & (1U << stage)) ? " " : "X",
362 binding->per_stage_offset_in_dwords[stage].primary,
363 descriptor_names[binding->type],
364 binding->descriptor_count);
365 }
366
367 /* Print dynamic primaries. */
368 for (uint32_t i = 0; i < layout->binding_count; i++) {
369 const struct pvr_descriptor_set_layout_binding *const binding =
370 &layout->bindings[i];
371
372 if (binding->type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC &&
373 binding->type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
374 continue;
375
376 mesa_logd("| * %s %04u | %-26s[%3u] |",
377 (binding->shader_stage_mask & (1U << stage)) ? " " : "X",
378 binding->per_stage_offset_in_dwords[stage].primary,
379 descriptor_names[binding->type],
380 binding->descriptor_count);
381 }
382
383 mesa_logd("----------------------------------------------");
384 mesa_logd(
385 "| %-18s @ %04u |",
386 stage_names[stage].secondary,
387 layout->memory_layout_in_dwords_per_stage[stage].secondary_offset);
388 mesa_logd("----------------------------------------------");
389
390 /* Print secondaries. */
391 for (uint32_t i = 0; i < layout->binding_count; i++) {
392 const struct pvr_descriptor_set_layout_binding *const binding =
393 &layout->bindings[i];
394
395 if (binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
396 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
397 continue;
398
399 mesa_logd("| %s %04u | %-26s[%3u] |",
400 (binding->shader_stage_mask & (1U << stage)) ? " " : "X",
401 binding->per_stage_offset_in_dwords[stage].secondary,
402 descriptor_names[binding->type],
403 binding->descriptor_count);
404 }
405
406 /* Print dynamic secondaries. */
407 for (uint32_t i = 0; i < layout->binding_count; i++) {
408 const struct pvr_descriptor_set_layout_binding *const binding =
409 &layout->bindings[i];
410
411 if (binding->type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC &&
412 binding->type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
413 continue;
414
415 mesa_logd("| * %s %04u | %-26s[%3u] |",
416 (binding->shader_stage_mask & (1U << stage)) ? " " : "X",
417 binding->per_stage_offset_in_dwords[stage].secondary,
418 descriptor_names[binding->type],
419 binding->descriptor_count);
420 }
421
422 mesa_logd("==============================================");
423 }
424 }
425 #endif
426
pvr_CreateDescriptorSetLayout(VkDevice _device,const VkDescriptorSetLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorSetLayout * pSetLayout)427 VkResult pvr_CreateDescriptorSetLayout(
428 VkDevice _device,
429 const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
430 const VkAllocationCallbacks *pAllocator,
431 VkDescriptorSetLayout *pSetLayout)
432 {
433 /* Used to accumulate sizes and set each descriptor's offsets per stage. */
434 struct pvr_register_usage reg_usage[PVR_STAGE_ALLOCATION_COUNT] = { 0 };
435 PVR_FROM_HANDLE(pvr_device, device, _device);
436 struct pvr_descriptor_set_layout *layout;
437 VkDescriptorSetLayoutBinding *bindings;
438 uint32_t immutable_sampler_count;
439
440 assert(pCreateInfo->sType ==
441 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
442
443 vk_foreach_struct_const (ext, pCreateInfo->pNext) {
444 pvr_debug_ignored_stype(ext->sType);
445 }
446
447 /* TODO: Add support for push descriptors. */
448
449 if (pCreateInfo->bindingCount == 0) {
450 layout = pvr_descriptor_set_layout_allocate(device, pAllocator, 0, 0, 0);
451 if (!layout)
452 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
453
454 *pSetLayout = pvr_descriptor_set_layout_to_handle(layout);
455 return VK_SUCCESS;
456 }
457
458 /* TODO: Instead of sorting, maybe do what anvil does? */
459 bindings = pvr_create_sorted_bindings(device,
460 pAllocator,
461 pCreateInfo->pBindings,
462 pCreateInfo->bindingCount);
463 if (!bindings)
464 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
465
466 immutable_sampler_count = 0;
467 for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
468 /* From the Vulkan 1.1.97 spec for VkDescriptorSetLayoutBinding:
469 *
470 * "If descriptorType specifies a VK_DESCRIPTOR_TYPE_SAMPLER or
471 * VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER type descriptor, then
472 * pImmutableSamplers can be used to initialize a set of immutable
473 * samplers. [...] If descriptorType is not one of these descriptor
474 * types, then pImmutableSamplers is ignored.
475 *
476 * We need to be careful here and only parse pImmutableSamplers if we
477 * have one of the right descriptor types.
478 */
479 const VkDescriptorType descriptor_type = bindings[i].descriptorType;
480 if ((descriptor_type == VK_DESCRIPTOR_TYPE_SAMPLER ||
481 descriptor_type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
482 bindings[i].pImmutableSamplers)
483 immutable_sampler_count += bindings[i].descriptorCount;
484 }
485
486 /* From the Vulkan 1.2.190 spec for VkDescriptorSetLayoutCreateInfo:
487 *
488 * "The VkDescriptorSetLayoutBinding::binding members of the elements
489 * of the pBindings array must each have different values."
490 *
491 * So we don't worry about duplicates and just allocate for bindingCount
492 * amount of bindings.
493 */
494 layout = pvr_descriptor_set_layout_allocate(
495 device,
496 pAllocator,
497 pCreateInfo->bindingCount,
498 immutable_sampler_count,
499 PVR_PIPELINE_LAYOUT_SUPPORTED_DESCRIPTOR_TYPE_COUNT);
500 if (!layout) {
501 vk_free2(&device->vk.alloc, pAllocator, bindings);
502 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
503 }
504
505 layout->binding_count = pCreateInfo->bindingCount;
506
507 for (uint32_t bind_num = 0; bind_num < layout->binding_count; bind_num++) {
508 const VkDescriptorSetLayoutBinding *const binding = &bindings[bind_num];
509 struct pvr_descriptor_set_layout_binding *const internal_binding =
510 &layout->bindings[bind_num];
511 VkShaderStageFlags shader_stages = 0;
512
513 internal_binding->type = binding->descriptorType;
514 /* The binding_numbers can be non-contiguous so we ignore the user
515 * specified binding numbers and make them contiguous ourselves.
516 */
517 internal_binding->binding_number = bind_num;
518
519 /* From Vulkan spec 1.2.189:
520 *
521 * "If descriptorCount is zero this binding entry is reserved and the
522 * resource must not be accessed from any stage via this binding"
523 *
524 * So do not use bindings->stageFlags, use shader_stages instead.
525 */
526 if (binding->descriptorCount) {
527 shader_stages = binding->stageFlags;
528
529 internal_binding->descriptor_count = binding->descriptorCount;
530 internal_binding->descriptor_index = layout->descriptor_count;
531 layout->descriptor_count += binding->descriptorCount;
532 }
533
534 switch (binding->descriptorType) {
535 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
536 case VK_DESCRIPTOR_TYPE_SAMPLER:
537 if (binding->pImmutableSamplers && binding->descriptorCount > 0) {
538 internal_binding->has_immutable_samplers = true;
539 internal_binding->immutable_samplers_index =
540 layout->immutable_sampler_count;
541
542 for (uint32_t j = 0; j < binding->descriptorCount; j++) {
543 PVR_FROM_HANDLE(pvr_sampler,
544 sampler,
545 bindings->pImmutableSamplers[j]);
546 const uint32_t next = j + layout->immutable_sampler_count;
547
548 layout->immutable_samplers[next] = sampler;
549 }
550
551 layout->immutable_sampler_count += binding->descriptorCount;
552 }
553 break;
554
555 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
556 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
557 layout->dynamic_buffer_count += binding->descriptorCount;
558 break;
559
560 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
561 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
562 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
563 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
564 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
565 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
566 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
567 break;
568
569 default:
570 unreachable("Unknown descriptor type");
571 break;
572 }
573
574 if (!shader_stages)
575 continue;
576
577 internal_binding->shader_stages = shader_stages;
578 layout->shader_stages |= shader_stages;
579
580 for (uint32_t stage = 0;
581 stage < ARRAY_SIZE(layout->bindings[0].per_stage_offset_in_dwords);
582 stage++) {
583 const VkDescriptorType descriptor_type = binding->descriptorType;
584
585 if (!pvr_stage_matches_vk_flags(stage, shader_stages))
586 continue;
587
588 internal_binding->shader_stage_mask |= (1U << stage);
589
590 /* TODO: Do we have to allocate them at the end? We could speed it
591 * by allocating them here if not. */
592 /* We allocate dynamics primary and secondaries at the end. */
593 if (descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC &&
594 descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
595 struct pvr_descriptor_size_info size_info;
596
597 pvr_descriptor_size_info_init(device, descriptor_type, &size_info);
598
599 STATIC_ASSERT(
600 ARRAY_SIZE(reg_usage) ==
601 ARRAY_SIZE(layout->bindings[0].per_stage_offset_in_dwords));
602
603 reg_usage[stage].primary =
604 ALIGN_POT(reg_usage[stage].primary, size_info.alignment);
605
606 internal_binding->per_stage_offset_in_dwords[stage].primary =
607 reg_usage[stage].primary;
608 reg_usage[stage].primary +=
609 size_info.primary * internal_binding->descriptor_count;
610
611 internal_binding->per_stage_offset_in_dwords[stage].secondary =
612 reg_usage[stage].secondary;
613 reg_usage[stage].secondary +=
614 size_info.secondary * internal_binding->descriptor_count;
615 }
616
617 STATIC_ASSERT(
618 ARRAY_SIZE(layout->per_stage_descriptor_count) ==
619 ARRAY_SIZE(layout->bindings[0].per_stage_offset_in_dwords));
620
621 layout->per_stage_descriptor_count[stage][descriptor_type] +=
622 internal_binding->descriptor_count;
623 }
624 }
625
626 for (uint32_t bind_num = 0; bind_num < layout->binding_count; bind_num++) {
627 struct pvr_descriptor_set_layout_binding *const internal_binding =
628 &layout->bindings[bind_num];
629 const VkDescriptorType descriptor_type = internal_binding->type;
630
631 if (descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC &&
632 descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
633 continue;
634
635 for (uint32_t stage = 0;
636 stage < ARRAY_SIZE(layout->bindings[0].per_stage_offset_in_dwords);
637 stage++) {
638 struct pvr_descriptor_size_info size_info;
639 const VkShaderStageFlags shader_stages =
640 internal_binding->shader_stages;
641
642 if (!pvr_stage_matches_vk_flags(stage, shader_stages))
643 continue;
644
645 pvr_descriptor_size_info_init(device, descriptor_type, &size_info);
646
647 /* TODO: align primary like we did with other descriptors? */
648 internal_binding->per_stage_offset_in_dwords[stage].primary =
649 reg_usage[stage].primary_dynamic;
650 reg_usage[stage].primary_dynamic +=
651 size_info.primary * internal_binding->descriptor_count;
652
653 internal_binding->per_stage_offset_in_dwords[stage].secondary =
654 reg_usage[stage].secondary_dynamic;
655 reg_usage[stage].secondary_dynamic +=
656 size_info.secondary * internal_binding->descriptor_count;
657 }
658 }
659
660 pvr_setup_in_memory_layout_sizes(layout, reg_usage);
661
662 #if defined(DEBUG)
663 pvr_dump_in_memory_layout_sizes(layout);
664 #endif
665
666 vk_free2(&device->vk.alloc, pAllocator, bindings);
667
668 *pSetLayout = pvr_descriptor_set_layout_to_handle(layout);
669
670 return VK_SUCCESS;
671 }
672
pvr_DestroyDescriptorSetLayout(VkDevice _device,VkDescriptorSetLayout _set_layout,const VkAllocationCallbacks * pAllocator)673 void pvr_DestroyDescriptorSetLayout(VkDevice _device,
674 VkDescriptorSetLayout _set_layout,
675 const VkAllocationCallbacks *pAllocator)
676 {
677 PVR_FROM_HANDLE(pvr_descriptor_set_layout, layout, _set_layout);
678 PVR_FROM_HANDLE(pvr_device, device, _device);
679
680 pvr_descriptor_set_layout_free(device, pAllocator, layout);
681 }
682
683 #if defined(DEBUG)
684 static void
pvr_dump_in_register_layout_sizes(const struct pvr_device * device,const struct pvr_pipeline_layout * layout)685 pvr_dump_in_register_layout_sizes(const struct pvr_device *device,
686 const struct pvr_pipeline_layout *layout)
687 {
688 mesa_logd("=== SET LAYOUT ===");
689 mesa_logd("----------------------------------------------------");
690 mesa_logd(" in registers:");
691 mesa_logd("----------------------------------------------------");
692
693 for (uint32_t stage = 0;
694 stage < ARRAY_SIZE(layout->register_layout_in_dwords_per_stage);
695 stage++) {
696 uint32_t dynamic_offset = 0;
697
698 mesa_logd("| %-48s |", stage_names[stage].primary_dynamic);
699 mesa_logd("----------------------------------------------------");
700
701 /* Print dynamic primaries. */
702 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) {
703 const struct pvr_descriptor_set_layout *const set_layout =
704 layout->set_layout[set_num];
705
706 for (uint32_t i = 0; i < set_layout->binding_count; i++) {
707 const struct pvr_descriptor_set_layout_binding *const binding =
708 &set_layout->bindings[i];
709 bool valid = !!(binding->shader_stage_mask & (1U << stage));
710
711 if (binding->type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC &&
712 binding->type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
713 continue;
714
715 mesa_logd("| %s %04u | %u:%03u | %-26s[%3u] |",
716 (valid) ? " " : "X",
717 dynamic_offset,
718 set_num,
719 i,
720 descriptor_names[binding->type],
721 binding->descriptor_count);
722
723 if (valid) {
724 struct pvr_descriptor_size_info size_info;
725
726 pvr_descriptor_size_info_init(device, binding->type, &size_info);
727
728 dynamic_offset += size_info.primary;
729 }
730 }
731 }
732
733 mesa_logd("----------------------------------------------------");
734 mesa_logd("| %-48s |", stage_names[stage].secondary_dynamic);
735 mesa_logd("----------------------------------------------------");
736
737 /* Print dynamic secondaries. */
738 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) {
739 const struct pvr_descriptor_set_layout *const set_layout =
740 layout->set_layout[set_num];
741
742 for (uint32_t i = 0; i < set_layout->binding_count; i++) {
743 const struct pvr_descriptor_set_layout_binding *const binding =
744 &set_layout->bindings[i];
745 bool valid = !!(binding->shader_stage_mask & (1U << stage));
746
747 if (binding->type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC &&
748 binding->type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
749 continue;
750
751 mesa_logd("| %s %04u | %u:%03u | %-26s[%3u] |",
752 (valid) ? " " : "X",
753 dynamic_offset,
754 set_num,
755 i,
756 descriptor_names[binding->type],
757 binding->descriptor_count);
758
759 if (valid) {
760 struct pvr_descriptor_size_info size_info;
761
762 pvr_descriptor_size_info_init(device, binding->type, &size_info);
763
764 dynamic_offset += size_info.secondary;
765 }
766 }
767 }
768
769 mesa_logd("----------------------------------------------------");
770 mesa_logd("| %-48s |", stage_names[stage].primary);
771 mesa_logd("----------------------------------------------------");
772
773 /* Print primaries. */
774 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) {
775 const struct pvr_descriptor_set_layout *const set_layout =
776 layout->set_layout[set_num];
777 const uint32_t base =
778 layout->register_layout_in_dwords_per_stage[stage][set_num]
779 .primary_offset;
780
781 for (uint32_t i = 0; i < set_layout->binding_count; i++) {
782 const struct pvr_descriptor_set_layout_binding *const binding =
783 &set_layout->bindings[i];
784
785 if (binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
786 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
787 continue;
788
789 mesa_logd("| %s %04u | %u:%03u | %-26s[%3u] |",
790 (binding->shader_stage_mask & (1U << stage)) ? " " : "X",
791 base + binding->per_stage_offset_in_dwords[stage].primary,
792 set_num,
793 i,
794 descriptor_names[binding->type],
795 binding->descriptor_count);
796 }
797 }
798
799 mesa_logd("----------------------------------------------------");
800 mesa_logd("| %-48s |", stage_names[stage].secondary);
801 mesa_logd("----------------------------------------------------");
802
803 /* Print secondaries. */
804 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) {
805 const struct pvr_descriptor_set_layout *const set_layout =
806 layout->set_layout[set_num];
807 const uint32_t base =
808 layout->register_layout_in_dwords_per_stage[stage][set_num]
809 .secondary_offset;
810
811 for (uint32_t i = 0; i < set_layout->binding_count; i++) {
812 const struct pvr_descriptor_set_layout_binding *const binding =
813 &set_layout->bindings[i];
814
815 if (binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
816 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
817 continue;
818
819 mesa_logd("| %s %04u | %u:%03u | %-26s[%3u] |",
820 (binding->shader_stage_mask & (1U << stage)) ? " " : "X",
821 base +
822 binding->per_stage_offset_in_dwords[stage].secondary,
823 set_num,
824 i,
825 descriptor_names[binding->type],
826 binding->descriptor_count);
827 }
828 }
829
830 mesa_logd("====================================================");
831 }
832 }
833 #endif
834
835 /* Pipeline layouts. These have nothing to do with the pipeline. They are
836 * just multiple descriptor set layouts pasted together.
837 */
pvr_CreatePipelineLayout(VkDevice _device,const VkPipelineLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipelineLayout * pPipelineLayout)838 VkResult pvr_CreatePipelineLayout(VkDevice _device,
839 const VkPipelineLayoutCreateInfo *pCreateInfo,
840 const VkAllocationCallbacks *pAllocator,
841 VkPipelineLayout *pPipelineLayout)
842 {
843 uint32_t next_free_reg[PVR_STAGE_ALLOCATION_COUNT];
844 PVR_FROM_HANDLE(pvr_device, device, _device);
845 struct pvr_pipeline_layout *layout;
846
847 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
848 assert(pCreateInfo->setLayoutCount <= PVR_MAX_DESCRIPTOR_SETS);
849
850 layout = vk_object_alloc(&device->vk,
851 pAllocator,
852 sizeof(*layout),
853 VK_OBJECT_TYPE_PIPELINE_LAYOUT);
854 if (!layout)
855 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
856
857 layout->set_count = pCreateInfo->setLayoutCount;
858 layout->shader_stages = 0;
859 for (uint32_t stage = 0; stage < PVR_STAGE_ALLOCATION_COUNT; stage++) {
860 uint32_t descriptor_counts
861 [PVR_PIPELINE_LAYOUT_SUPPORTED_DESCRIPTOR_TYPE_COUNT] = { 0 };
862 struct pvr_pipeline_layout_reg_info *const reg_info =
863 &layout->per_stage_reg_info[stage];
864
865 *reg_info = (struct pvr_pipeline_layout_reg_info){ 0 };
866
867 layout->per_stage_descriptor_masks[stage] = 0;
868
869 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) {
870 /* So we don't write these again and again. Just do it once. */
871 if (stage == 0) {
872 PVR_FROM_HANDLE(pvr_descriptor_set_layout,
873 set_layout,
874 pCreateInfo->pSetLayouts[set_num]);
875
876 layout->set_layout[set_num] = set_layout;
877 layout->shader_stages |= set_layout->shader_stages;
878 }
879
880 const struct pvr_descriptor_set_layout_mem_layout *const mem_layout =
881 &layout->set_layout[set_num]
882 ->memory_layout_in_dwords_per_stage[stage];
883
884 /* Allocate registers counts for dynamic descriptors. */
885 reg_info->primary_dynamic_size_in_dwords +=
886 mem_layout->primary_dynamic_size;
887 reg_info->secondary_dynamic_size_in_dwords +=
888 mem_layout->secondary_dynamic_size;
889
890 for (VkDescriptorType type = 0;
891 type < PVR_PIPELINE_LAYOUT_SUPPORTED_DESCRIPTOR_TYPE_COUNT;
892 type++) {
893 uint32_t descriptor_count;
894
895 layout->descriptor_offsets[set_num][stage][type] =
896 descriptor_counts[type];
897
898 descriptor_count = layout->set_layout[set_num]
899 ->per_stage_descriptor_count[stage][type];
900
901 if (!descriptor_count)
902 continue;
903
904 switch (type) {
905 case VK_DESCRIPTOR_TYPE_SAMPLER:
906 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
907 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
908 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
909 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
910 layout->per_stage_descriptor_masks[stage] |= 1U << set_num;
911 descriptor_counts[type] += descriptor_count;
912 break;
913
914 /* We don't need to keep track of the counts or masks for other
915 * descriptor types so there is no assert() here since other
916 * types are not invalid or unsupported.
917 */
918 /* TODO: Improve the comment above to specify why, when we find
919 * out.
920 */
921 default:
922 break;
923 }
924 }
925 }
926
927 next_free_reg[stage] = reg_info->primary_dynamic_size_in_dwords +
928 reg_info->secondary_dynamic_size_in_dwords;
929 }
930
931 /* Allocate registers counts for primary and secondary descriptors. */
932 for (uint32_t stage = 0; stage < PVR_STAGE_ALLOCATION_COUNT; stage++) {
933 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) {
934 const struct pvr_descriptor_set_layout_mem_layout *const mem_layout =
935 &layout->set_layout[set_num]
936 ->memory_layout_in_dwords_per_stage[stage];
937 struct pvr_descriptor_set_layout_mem_layout *const reg_layout =
938 &layout->register_layout_in_dwords_per_stage[stage][set_num];
939
940 next_free_reg[stage] = ALIGN_POT(next_free_reg[stage], 4);
941
942 reg_layout->primary_offset = next_free_reg[stage];
943 reg_layout->primary_size = mem_layout->primary_size;
944
945 next_free_reg[stage] += reg_layout->primary_size;
946 }
947
948 /* To optimize the total shared layout allocation used by the shader,
949 * secondary descriptors come last since they're less likely to be used.
950 */
951 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) {
952 const struct pvr_descriptor_set_layout_mem_layout *const mem_layout =
953 &layout->set_layout[set_num]
954 ->memory_layout_in_dwords_per_stage[stage];
955 struct pvr_descriptor_set_layout_mem_layout *const reg_layout =
956 &layout->register_layout_in_dwords_per_stage[stage][set_num];
957
958 /* Should we be aligning next_free_reg like it's done with the
959 * primary descriptors?
960 */
961
962 reg_layout->secondary_offset = next_free_reg[stage];
963 reg_layout->secondary_size = mem_layout->secondary_size;
964
965 next_free_reg[stage] += reg_layout->secondary_size;
966 }
967 }
968
969 layout->push_constants_shader_stages = 0;
970 for (uint32_t i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) {
971 const VkPushConstantRange *range = &pCreateInfo->pPushConstantRanges[i];
972
973 layout->push_constants_shader_stages |= range->stageFlags;
974 }
975
976 #if defined(DEBUG)
977 pvr_dump_in_register_layout_sizes(device, layout);
978 #endif
979
980 *pPipelineLayout = pvr_pipeline_layout_to_handle(layout);
981
982 return VK_SUCCESS;
983 }
984
pvr_DestroyPipelineLayout(VkDevice _device,VkPipelineLayout _pipelineLayout,const VkAllocationCallbacks * pAllocator)985 void pvr_DestroyPipelineLayout(VkDevice _device,
986 VkPipelineLayout _pipelineLayout,
987 const VkAllocationCallbacks *pAllocator)
988 {
989 PVR_FROM_HANDLE(pvr_device, device, _device);
990 PVR_FROM_HANDLE(pvr_pipeline_layout, layout, _pipelineLayout);
991
992 vk_object_free(&device->vk, pAllocator, layout);
993 }
994
pvr_CreateDescriptorPool(VkDevice _device,const VkDescriptorPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorPool * pDescriptorPool)995 VkResult pvr_CreateDescriptorPool(VkDevice _device,
996 const VkDescriptorPoolCreateInfo *pCreateInfo,
997 const VkAllocationCallbacks *pAllocator,
998 VkDescriptorPool *pDescriptorPool)
999 {
1000 PVR_FROM_HANDLE(pvr_device, device, _device);
1001 struct pvr_descriptor_pool *pool;
1002
1003 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO);
1004
1005 pool = vk_object_alloc(&device->vk,
1006 pAllocator,
1007 sizeof(*pool),
1008 VK_OBJECT_TYPE_DESCRIPTOR_POOL);
1009 if (!pool)
1010 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1011
1012 if (pAllocator)
1013 pool->alloc = *pAllocator;
1014 else
1015 pool->alloc = device->vk.alloc;
1016
1017 pool->max_sets = pCreateInfo->maxSets;
1018 list_inithead(&pool->descriptor_sets);
1019
1020 pool->total_size_in_dwords = 0;
1021 for (uint32_t i = 0; i < pCreateInfo->poolSizeCount; i++) {
1022 struct pvr_descriptor_size_info size_info;
1023 const uint32_t descriptor_count =
1024 pCreateInfo->pPoolSizes[i].descriptorCount;
1025
1026 pvr_descriptor_size_info_init(device,
1027 pCreateInfo->pPoolSizes[i].type,
1028 &size_info);
1029
1030 const uint32_t secondary = ALIGN_POT(size_info.secondary, 4);
1031 const uint32_t primary = ALIGN_POT(size_info.primary, 4);
1032
1033 pool->total_size_in_dwords += descriptor_count * (primary + secondary);
1034 }
1035 pool->total_size_in_dwords *= PVR_STAGE_ALLOCATION_COUNT;
1036 pool->current_size_in_dwords = 0;
1037
1038 pvr_finishme("Entry tracker for allocations?");
1039
1040 *pDescriptorPool = pvr_descriptor_pool_to_handle(pool);
1041
1042 return VK_SUCCESS;
1043 }
1044
pvr_free_descriptor_set(struct pvr_device * device,struct pvr_descriptor_pool * pool,struct pvr_descriptor_set * set)1045 static void pvr_free_descriptor_set(struct pvr_device *device,
1046 struct pvr_descriptor_pool *pool,
1047 struct pvr_descriptor_set *set)
1048 {
1049 list_del(&set->link);
1050 pvr_bo_free(device, set->pvr_bo);
1051 vk_object_free(&device->vk, &pool->alloc, set);
1052 }
1053
pvr_DestroyDescriptorPool(VkDevice _device,VkDescriptorPool _pool,const VkAllocationCallbacks * pAllocator)1054 void pvr_DestroyDescriptorPool(VkDevice _device,
1055 VkDescriptorPool _pool,
1056 const VkAllocationCallbacks *pAllocator)
1057 {
1058 PVR_FROM_HANDLE(pvr_device, device, _device);
1059 PVR_FROM_HANDLE(pvr_descriptor_pool, pool, _pool);
1060
1061 if (!pool)
1062 return;
1063
1064 list_for_each_entry_safe (struct pvr_descriptor_set,
1065 set,
1066 &pool->descriptor_sets,
1067 link) {
1068 pvr_free_descriptor_set(device, pool, set);
1069 }
1070
1071 vk_object_free(&device->vk, pAllocator, pool);
1072 }
1073
pvr_ResetDescriptorPool(VkDevice _device,VkDescriptorPool descriptorPool,VkDescriptorPoolResetFlags flags)1074 VkResult pvr_ResetDescriptorPool(VkDevice _device,
1075 VkDescriptorPool descriptorPool,
1076 VkDescriptorPoolResetFlags flags)
1077 {
1078 assert(!"Unimplemented");
1079 return VK_SUCCESS;
1080 }
1081
pvr_get_descriptor_primary_offset(const struct pvr_device * device,const struct pvr_descriptor_set_layout * layout,const struct pvr_descriptor_set_layout_binding * binding,const uint32_t stage,const uint32_t desc_idx)1082 static uint16_t pvr_get_descriptor_primary_offset(
1083 const struct pvr_device *device,
1084 const struct pvr_descriptor_set_layout *layout,
1085 const struct pvr_descriptor_set_layout_binding *binding,
1086 const uint32_t stage,
1087 const uint32_t desc_idx)
1088 {
1089 struct pvr_descriptor_size_info size_info;
1090 uint32_t offset;
1091
1092 assert(stage < ARRAY_SIZE(layout->memory_layout_in_dwords_per_stage));
1093 assert(desc_idx < binding->descriptor_count);
1094
1095 pvr_descriptor_size_info_init(device, binding->type, &size_info);
1096
1097 offset = layout->memory_layout_in_dwords_per_stage[stage].primary_offset;
1098 offset += binding->per_stage_offset_in_dwords[stage].primary;
1099 offset += (desc_idx * size_info.primary);
1100
1101 /* Offset must be less than 16bits. */
1102 assert(offset < UINT16_MAX);
1103
1104 return (uint16_t)offset;
1105 }
1106
pvr_get_descriptor_secondary_offset(const struct pvr_device * device,const struct pvr_descriptor_set_layout * layout,const struct pvr_descriptor_set_layout_binding * binding,const uint32_t stage,const uint32_t desc_idx)1107 static uint16_t pvr_get_descriptor_secondary_offset(
1108 const struct pvr_device *device,
1109 const struct pvr_descriptor_set_layout *layout,
1110 const struct pvr_descriptor_set_layout_binding *binding,
1111 const uint32_t stage,
1112 const uint32_t desc_idx)
1113 {
1114 struct pvr_descriptor_size_info size_info;
1115 uint32_t offset;
1116
1117 assert(stage < ARRAY_SIZE(layout->memory_layout_in_dwords_per_stage));
1118 assert(desc_idx < binding->descriptor_count);
1119
1120 pvr_descriptor_size_info_init(device, binding->type, &size_info);
1121
1122 offset = layout->memory_layout_in_dwords_per_stage[stage].secondary_offset;
1123 offset += binding->per_stage_offset_in_dwords[stage].secondary;
1124 offset += (desc_idx * size_info.secondary);
1125
1126 /* Offset must be less than 16bits. */
1127 assert(offset < UINT16_MAX);
1128
1129 return (uint16_t)offset;
1130 }
1131
1132 #define PVR_MAX_DESCRIPTOR_MEM_SIZE_IN_DWORDS (4 * 1024)
1133
1134 static VkResult
pvr_descriptor_set_create(struct pvr_device * device,struct pvr_descriptor_pool * pool,const struct pvr_descriptor_set_layout * layout,struct pvr_descriptor_set ** const descriptor_set_out)1135 pvr_descriptor_set_create(struct pvr_device *device,
1136 struct pvr_descriptor_pool *pool,
1137 const struct pvr_descriptor_set_layout *layout,
1138 struct pvr_descriptor_set **const descriptor_set_out)
1139 {
1140 struct pvr_descriptor_set *set;
1141 VkResult result;
1142 size_t size;
1143 void *map;
1144
1145 size = sizeof(*set) + sizeof(set->descriptors[0]) * layout->descriptor_count;
1146
1147 /* TODO: Add support to allocate descriptors from descriptor pool, also
1148 * check the required descriptors must not exceed max allowed descriptors.
1149 */
1150 set = vk_object_zalloc(&device->vk,
1151 &pool->alloc,
1152 size,
1153 VK_OBJECT_TYPE_DESCRIPTOR_SET);
1154 if (!set)
1155 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1156
1157 /* TODO: Add support to allocate device memory from a common pool. Look at
1158 * something like anv. Also we can allocate a whole chunk of device memory
1159 * for max descriptors supported by pool as done by v3dv. Also check the
1160 * possibility if this can be removed from here and done on need basis.
1161 */
1162
1163 if (layout->binding_count > 0) {
1164 const uint32_t cache_line_size =
1165 rogue_get_slc_cache_line_size(&device->pdevice->dev_info);
1166 uint64_t bo_size = MIN2(pool->total_size_in_dwords,
1167 PVR_MAX_DESCRIPTOR_MEM_SIZE_IN_DWORDS) *
1168 sizeof(uint32_t);
1169
1170 result = pvr_bo_alloc(device,
1171 device->heaps.general_heap,
1172 bo_size,
1173 cache_line_size,
1174 PVR_BO_ALLOC_FLAG_CPU_MAPPED,
1175 &set->pvr_bo);
1176 if (result != VK_SUCCESS)
1177 goto err_free_descriptor_set;
1178 }
1179
1180 set->layout = layout;
1181 set->pool = pool;
1182
1183 map = set->pvr_bo->bo->map;
1184 for (uint32_t i = 0; i < layout->binding_count; i++) {
1185 const struct pvr_descriptor_set_layout_binding *binding =
1186 &layout->bindings[i];
1187
1188 if (binding->descriptor_count == 0 || !binding->has_immutable_samplers)
1189 continue;
1190
1191 for (uint32_t stage = 0;
1192 stage < ARRAY_SIZE(binding->per_stage_offset_in_dwords);
1193 stage++) {
1194 if (!(binding->shader_stage_mask & (1U << stage)))
1195 continue;
1196
1197 for (uint32_t j = 0; j < binding->descriptor_count; j++) {
1198 uint32_t idx = binding->immutable_samplers_index + j;
1199 const struct pvr_sampler *sampler = layout->immutable_samplers[idx];
1200 unsigned int offset_in_dwords =
1201 pvr_get_descriptor_primary_offset(device,
1202 layout,
1203 binding,
1204 stage,
1205 j);
1206
1207 if (binding->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1208 offset_in_dwords += 4;
1209
1210 memcpy((uint8_t *)map + offset_in_dwords * sizeof(uint32_t),
1211 sampler->descriptor.words,
1212 sizeof(sampler->descriptor.words));
1213 }
1214 }
1215 }
1216
1217 list_addtail(&set->link, &pool->descriptor_sets);
1218
1219 *descriptor_set_out = set;
1220
1221 return VK_SUCCESS;
1222
1223 err_free_descriptor_set:
1224 vk_object_free(&device->vk, &pool->alloc, set);
1225
1226 return result;
1227 }
1228
1229 VkResult
pvr_AllocateDescriptorSets(VkDevice _device,const VkDescriptorSetAllocateInfo * pAllocateInfo,VkDescriptorSet * pDescriptorSets)1230 pvr_AllocateDescriptorSets(VkDevice _device,
1231 const VkDescriptorSetAllocateInfo *pAllocateInfo,
1232 VkDescriptorSet *pDescriptorSets)
1233 {
1234 PVR_FROM_HANDLE(pvr_descriptor_pool, pool, pAllocateInfo->descriptorPool);
1235 PVR_FROM_HANDLE(pvr_device, device, _device);
1236 VkResult result;
1237 uint32_t i;
1238
1239 vk_foreach_struct_const (ext, pAllocateInfo->pNext) {
1240 pvr_debug_ignored_stype(ext->sType);
1241 }
1242
1243 for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
1244 PVR_FROM_HANDLE(pvr_descriptor_set_layout,
1245 layout,
1246 pAllocateInfo->pSetLayouts[i]);
1247 struct pvr_descriptor_set *set = NULL;
1248
1249 result = pvr_descriptor_set_create(device, pool, layout, &set);
1250 if (result != VK_SUCCESS)
1251 goto err_free_descriptor_sets;
1252
1253 pDescriptorSets[i] = pvr_descriptor_set_to_handle(set);
1254 }
1255
1256 return VK_SUCCESS;
1257
1258 err_free_descriptor_sets:
1259 pvr_FreeDescriptorSets(_device,
1260 pAllocateInfo->descriptorPool,
1261 i,
1262 pDescriptorSets);
1263
1264 for (i = 0; i < pAllocateInfo->descriptorSetCount; i++)
1265 pDescriptorSets[i] = VK_NULL_HANDLE;
1266
1267 return result;
1268 }
1269
pvr_FreeDescriptorSets(VkDevice _device,VkDescriptorPool descriptorPool,uint32_t count,const VkDescriptorSet * pDescriptorSets)1270 VkResult pvr_FreeDescriptorSets(VkDevice _device,
1271 VkDescriptorPool descriptorPool,
1272 uint32_t count,
1273 const VkDescriptorSet *pDescriptorSets)
1274 {
1275 PVR_FROM_HANDLE(pvr_descriptor_pool, pool, descriptorPool);
1276 PVR_FROM_HANDLE(pvr_device, device, _device);
1277
1278 for (uint32_t i = 0; i < count; i++) {
1279 struct pvr_descriptor_set *set;
1280
1281 if (!pDescriptorSets[i])
1282 continue;
1283
1284 set = pvr_descriptor_set_from_handle(pDescriptorSets[i]);
1285 pvr_free_descriptor_set(device, pool, set);
1286 }
1287
1288 return VK_SUCCESS;
1289 }
1290
pvr_compare_layout_binding(const void * a,const void * b)1291 static int pvr_compare_layout_binding(const void *a, const void *b)
1292 {
1293 uint32_t binding_a;
1294 uint32_t binding_b;
1295
1296 binding_a = ((struct pvr_descriptor_set_layout_binding *)a)->binding_number;
1297 binding_b = ((struct pvr_descriptor_set_layout_binding *)b)->binding_number;
1298
1299 if (binding_a < binding_b)
1300 return -1;
1301
1302 if (binding_a > binding_b)
1303 return 1;
1304
1305 return 0;
1306 }
1307
1308 /* This function does not assume that the binding will always exist for a
1309 * particular binding_num. Caller should check before using the return pointer.
1310 */
1311 static struct pvr_descriptor_set_layout_binding *
pvr_get_descriptor_binding(const struct pvr_descriptor_set_layout * layout,const uint32_t binding_num)1312 pvr_get_descriptor_binding(const struct pvr_descriptor_set_layout *layout,
1313 const uint32_t binding_num)
1314 {
1315 struct pvr_descriptor_set_layout_binding binding;
1316 binding.binding_number = binding_num;
1317
1318 return bsearch(&binding,
1319 layout->bindings,
1320 layout->binding_count,
1321 sizeof(binding),
1322 pvr_compare_layout_binding);
1323 }
1324
pvr_descriptor_update_buffer_info(const struct pvr_device * device,const VkWriteDescriptorSet * write_set,struct pvr_descriptor_set * set,const struct pvr_descriptor_set_layout_binding * binding,uint32_t * mem_ptr,uint32_t start_stage,uint32_t end_stage)1325 static void pvr_descriptor_update_buffer_info(
1326 const struct pvr_device *device,
1327 const VkWriteDescriptorSet *write_set,
1328 struct pvr_descriptor_set *set,
1329 const struct pvr_descriptor_set_layout_binding *binding,
1330 uint32_t *mem_ptr,
1331 uint32_t start_stage,
1332 uint32_t end_stage)
1333 {
1334 struct pvr_descriptor_size_info size_info;
1335 bool is_dynamic;
1336
1337 is_dynamic = (binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
1338 (binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
1339
1340 pvr_descriptor_size_info_init(device, binding->type, &size_info);
1341
1342 for (uint32_t i = 0; i < write_set->descriptorCount; i++) {
1343 const VkDescriptorBufferInfo *buffer_info = &write_set->pBufferInfo[i];
1344 PVR_FROM_HANDLE(pvr_buffer, buffer, buffer_info->buffer);
1345 const uint32_t desc_idx =
1346 binding->descriptor_index + write_set->dstArrayElement + i;
1347 const pvr_dev_addr_t addr =
1348 PVR_DEV_ADDR_OFFSET(buffer->dev_addr, buffer_info->offset);
1349 uint32_t range = (buffer_info->range == VK_WHOLE_SIZE)
1350 ? (buffer->vk.size - buffer_info->offset)
1351 : (buffer_info->range);
1352
1353 set->descriptors[desc_idx].type = write_set->descriptorType;
1354 set->descriptors[desc_idx].buffer_dev_addr = addr;
1355 set->descriptors[desc_idx].buffer_create_info_size = buffer->vk.size;
1356 set->descriptors[desc_idx].buffer_desc_range = range;
1357
1358 if (is_dynamic)
1359 continue;
1360
1361 /* Update the entries in the descriptor memory for static buffer. */
1362 for (uint32_t j = start_stage; j < end_stage; j++) {
1363 uint32_t primary_offset;
1364 uint32_t secondary_offset;
1365
1366 if (!(binding->shader_stage_mask & BITFIELD_BIT(j)))
1367 continue;
1368
1369 /* Offset calculation functions expect descriptor_index to be
1370 * binding relative not layout relative, so we have used
1371 * write_set->dstArrayElement + i rather than desc_idx.
1372 */
1373 primary_offset =
1374 pvr_get_descriptor_primary_offset(device,
1375 set->layout,
1376 binding,
1377 j,
1378 write_set->dstArrayElement + i);
1379 secondary_offset =
1380 pvr_get_descriptor_secondary_offset(device,
1381 set->layout,
1382 binding,
1383 j,
1384 write_set->dstArrayElement + i);
1385
1386 memcpy(mem_ptr + primary_offset, &addr, size_info.primary << 2);
1387 memcpy(mem_ptr + secondary_offset, &range, size_info.secondary << 2);
1388 }
1389 }
1390 }
1391
pvr_descriptor_update_sampler(const struct pvr_device * device,const VkWriteDescriptorSet * write_set,struct pvr_descriptor_set * set,const struct pvr_descriptor_set_layout_binding * binding,uint32_t * mem_ptr,uint32_t start_stage,uint32_t end_stage)1392 static void pvr_descriptor_update_sampler(
1393 const struct pvr_device *device,
1394 const VkWriteDescriptorSet *write_set,
1395 struct pvr_descriptor_set *set,
1396 const struct pvr_descriptor_set_layout_binding *binding,
1397 uint32_t *mem_ptr,
1398 uint32_t start_stage,
1399 uint32_t end_stage)
1400 {
1401 struct pvr_descriptor_size_info size_info;
1402
1403 pvr_descriptor_size_info_init(device, binding->type, &size_info);
1404
1405 for (uint32_t i = 0; i < write_set->descriptorCount; i++) {
1406 PVR_FROM_HANDLE(pvr_sampler, sampler, write_set->pImageInfo[i].sampler);
1407 const uint32_t desc_idx =
1408 binding->descriptor_index + write_set->dstArrayElement + i;
1409
1410 set->descriptors[desc_idx].type = write_set->descriptorType;
1411 set->descriptors[desc_idx].sampler = sampler;
1412
1413 for (uint32_t j = start_stage; j < end_stage; j++) {
1414 uint32_t primary_offset;
1415
1416 if (!(binding->shader_stage_mask & BITFIELD_BIT(j)))
1417 continue;
1418
1419 /* Offset calculation functions expect descriptor_index to be binding
1420 * relative not layout relative, so we have used
1421 * write_set->dstArrayElement + i rather than desc_idx.
1422 */
1423 primary_offset =
1424 pvr_get_descriptor_primary_offset(device,
1425 set->layout,
1426 binding,
1427 j,
1428 write_set->dstArrayElement + i);
1429
1430 memcpy(mem_ptr + primary_offset,
1431 sampler->descriptor.words,
1432 sizeof(sampler->descriptor.words));
1433 }
1434 }
1435 }
1436
1437 static void
pvr_write_image_descriptor_primaries(const struct pvr_device_info * dev_info,const struct pvr_image_view * iview,VkDescriptorType descriptorType,uint32_t * primary)1438 pvr_write_image_descriptor_primaries(const struct pvr_device_info *dev_info,
1439 const struct pvr_image_view *iview,
1440 VkDescriptorType descriptorType,
1441 uint32_t *primary)
1442 {
1443 uint64_t *qword_ptr = (uint64_t *)primary;
1444
1445 if (descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE &&
1446 (iview->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE ||
1447 iview->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)) {
1448 qword_ptr[0] = iview->texture_state[PVR_TEXTURE_STATE_STORAGE][0];
1449 qword_ptr[1] = iview->texture_state[PVR_TEXTURE_STATE_STORAGE][1];
1450 } else if (descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) {
1451 qword_ptr[0] = iview->texture_state[PVR_TEXTURE_STATE_ATTACHMENT][0];
1452 qword_ptr[1] = iview->texture_state[PVR_TEXTURE_STATE_ATTACHMENT][1];
1453 } else {
1454 qword_ptr[0] = iview->texture_state[PVR_TEXTURE_STATE_SAMPLE][0];
1455 qword_ptr[1] = iview->texture_state[PVR_TEXTURE_STATE_SAMPLE][1];
1456 }
1457
1458 if (descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE &&
1459 !PVR_HAS_FEATURE(dev_info, tpu_extended_integer_lookup)) {
1460 uint64_t tmp;
1461
1462 pvr_csb_pack (&tmp, TEXSTATE_STRIDE_IMAGE_WORD1, word1) {
1463 word1.index_lookup = true;
1464 }
1465
1466 qword_ptr[1] |= tmp;
1467 }
1468 }
1469
1470 static void
pvr_write_image_descriptor_secondaries(const struct pvr_device_info * dev_info,const struct pvr_image_view * iview,VkDescriptorType descriptorType,uint32_t * secondary)1471 pvr_write_image_descriptor_secondaries(const struct pvr_device_info *dev_info,
1472 const struct pvr_image_view *iview,
1473 VkDescriptorType descriptorType,
1474 uint32_t *secondary)
1475 {
1476 const bool cube_array_adjust =
1477 descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE &&
1478 iview->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
1479
1480 if (!PVR_HAS_FEATURE(dev_info, tpu_array_textures)) {
1481 uint64_t addr = iview->image->dev_addr.addr +
1482 iview->vk.base_array_layer * iview->image->layer_size;
1483
1484 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYBASE] = (uint32_t)addr;
1485 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYBASE + 1U] =
1486 (uint32_t)(addr >> 32U);
1487
1488 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYSTRIDE] =
1489 cube_array_adjust ? iview->image->layer_size * 6
1490 : iview->image->layer_size;
1491 }
1492
1493 if (cube_array_adjust) {
1494 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYMAXINDEX(dev_info)] =
1495 iview->vk.layer_count / 6 - 1;
1496 } else {
1497 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYMAXINDEX(dev_info)] =
1498 iview->vk.layer_count - 1;
1499 }
1500
1501 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_WIDTH(dev_info)] =
1502 iview->vk.extent.width;
1503 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_HEIGHT(dev_info)] =
1504 iview->vk.extent.height;
1505 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_DEPTH(dev_info)] =
1506 iview->vk.extent.depth;
1507 }
1508
pvr_descriptor_update_sampler_texture(const struct pvr_device * device,const VkWriteDescriptorSet * write_set,struct pvr_descriptor_set * set,const struct pvr_descriptor_set_layout_binding * binding,uint32_t * mem_ptr,uint32_t start_stage,uint32_t end_stage)1509 static void pvr_descriptor_update_sampler_texture(
1510 const struct pvr_device *device,
1511 const VkWriteDescriptorSet *write_set,
1512 struct pvr_descriptor_set *set,
1513 const struct pvr_descriptor_set_layout_binding *binding,
1514 uint32_t *mem_ptr,
1515 uint32_t start_stage,
1516 uint32_t end_stage)
1517 {
1518 const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
1519
1520 for (uint32_t i = 0; i < write_set->descriptorCount; i++) {
1521 PVR_FROM_HANDLE(pvr_image_view,
1522 iview,
1523 write_set->pImageInfo[i].imageView);
1524 const uint32_t desc_idx =
1525 binding->descriptor_index + write_set->dstArrayElement + i;
1526
1527 set->descriptors[desc_idx].type = write_set->descriptorType;
1528 set->descriptors[desc_idx].iview = iview;
1529 set->descriptors[desc_idx].layout = write_set->pImageInfo[i].imageLayout;
1530
1531 for (uint32_t j = start_stage; j < end_stage; j++) {
1532 uint32_t secondary_offset;
1533 uint32_t primary_offset;
1534
1535 if (!(binding->shader_stage_mask & BITFIELD_BIT(j)))
1536 continue;
1537
1538 /* Offset calculation functions expect descriptor_index to be
1539 * binding relative not layout relative, so we have used
1540 * write_set->dstArrayElement + i rather than desc_idx.
1541 */
1542 primary_offset =
1543 pvr_get_descriptor_primary_offset(device,
1544 set->layout,
1545 binding,
1546 j,
1547 write_set->dstArrayElement + i);
1548 secondary_offset =
1549 pvr_get_descriptor_secondary_offset(device,
1550 set->layout,
1551 binding,
1552 j,
1553 write_set->dstArrayElement + i);
1554
1555 pvr_write_image_descriptor_primaries(dev_info,
1556 iview,
1557 write_set->descriptorType,
1558 mem_ptr + primary_offset);
1559
1560 /* We don't need to update the sampler words if they belong to an
1561 * immutable sampler.
1562 */
1563 if (!binding->has_immutable_samplers) {
1564 PVR_FROM_HANDLE(pvr_sampler,
1565 sampler,
1566 write_set->pImageInfo[i].sampler);
1567 set->descriptors[desc_idx].sampler = sampler;
1568
1569 /* Sampler words are located at the end of the primary image words.
1570 */
1571 memcpy(mem_ptr + primary_offset + PVR_IMAGE_DESCRIPTOR_SIZE,
1572 sampler->descriptor.words,
1573 sizeof(sampler->descriptor.words));
1574 }
1575
1576 pvr_write_image_descriptor_secondaries(dev_info,
1577 iview,
1578 write_set->descriptorType,
1579 mem_ptr + secondary_offset);
1580 }
1581 }
1582 }
1583
pvr_descriptor_update_texture(const struct pvr_device * device,const VkWriteDescriptorSet * write_set,struct pvr_descriptor_set * set,const struct pvr_descriptor_set_layout_binding * binding,uint32_t * mem_ptr,uint32_t start_stage,uint32_t end_stage)1584 static void pvr_descriptor_update_texture(
1585 const struct pvr_device *device,
1586 const VkWriteDescriptorSet *write_set,
1587 struct pvr_descriptor_set *set,
1588 const struct pvr_descriptor_set_layout_binding *binding,
1589 uint32_t *mem_ptr,
1590 uint32_t start_stage,
1591 uint32_t end_stage)
1592 {
1593 const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
1594
1595 for (uint32_t i = 0; i < write_set->descriptorCount; i++) {
1596 PVR_FROM_HANDLE(pvr_image_view,
1597 iview,
1598 write_set->pImageInfo[i].imageView);
1599 const uint32_t desc_idx =
1600 binding->descriptor_index + write_set->dstArrayElement + i;
1601
1602 set->descriptors[desc_idx].type = write_set->descriptorType;
1603 set->descriptors[desc_idx].iview = iview;
1604 set->descriptors[desc_idx].layout = write_set->pImageInfo[i].imageLayout;
1605
1606 for (uint32_t j = start_stage; j < end_stage; j++) {
1607 uint32_t secondary_offset;
1608 uint32_t primary_offset;
1609
1610 if (!(binding->shader_stage_mask & BITFIELD_BIT(j)))
1611 continue;
1612
1613 /* Offset calculation functions expect descriptor_index to be
1614 * binding relative not layout relative, so we have used
1615 * write_set->dstArrayElement + i rather than desc_idx.
1616 */
1617 primary_offset =
1618 pvr_get_descriptor_primary_offset(device,
1619 set->layout,
1620 binding,
1621 j,
1622 write_set->dstArrayElement + i);
1623 secondary_offset =
1624 pvr_get_descriptor_secondary_offset(device,
1625 set->layout,
1626 binding,
1627 j,
1628 write_set->dstArrayElement + i);
1629
1630 pvr_write_image_descriptor_primaries(dev_info,
1631 iview,
1632 write_set->descriptorType,
1633 mem_ptr + primary_offset);
1634
1635 pvr_write_image_descriptor_secondaries(dev_info,
1636 iview,
1637 write_set->descriptorType,
1638 mem_ptr + secondary_offset);
1639 }
1640 }
1641 }
1642
pvr_write_buffer_descriptor(const struct pvr_device_info * dev_info,const struct pvr_buffer_view * bview,VkDescriptorType descriptorType,uint32_t * primary,uint32_t * secondary)1643 static void pvr_write_buffer_descriptor(const struct pvr_device_info *dev_info,
1644 const struct pvr_buffer_view *bview,
1645 VkDescriptorType descriptorType,
1646 uint32_t *primary,
1647 uint32_t *secondary)
1648 {
1649 uint64_t *qword_ptr = (uint64_t *)primary;
1650
1651 qword_ptr[0] = bview->texture_state[0];
1652 qword_ptr[1] = bview->texture_state[1];
1653
1654 if (descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER &&
1655 !PVR_HAS_FEATURE(dev_info, tpu_extended_integer_lookup)) {
1656 uint64_t tmp;
1657
1658 pvr_csb_pack (&tmp, TEXSTATE_STRIDE_IMAGE_WORD1, word1) {
1659 word1.index_lookup = true;
1660 }
1661
1662 qword_ptr[1] |= tmp;
1663 }
1664
1665 if (secondary) {
1666 /* NOTE: Range check for texture buffer writes is not strictly required as
1667 * we have already validated that the index is in range. We'd need a
1668 * compiler change to allow us to skip the range check.
1669 */
1670 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_WIDTH(dev_info)] =
1671 (uint32_t)(bview->range / vk_format_get_blocksize(bview->format));
1672 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_HEIGHT(dev_info)] = 1;
1673 }
1674 }
1675
pvr_descriptor_update_buffer_view(const struct pvr_device * device,const VkWriteDescriptorSet * write_set,struct pvr_descriptor_set * set,const struct pvr_descriptor_set_layout_binding * binding,uint32_t * mem_ptr,uint32_t start_stage,uint32_t end_stage)1676 static void pvr_descriptor_update_buffer_view(
1677 const struct pvr_device *device,
1678 const VkWriteDescriptorSet *write_set,
1679 struct pvr_descriptor_set *set,
1680 const struct pvr_descriptor_set_layout_binding *binding,
1681 uint32_t *mem_ptr,
1682 uint32_t start_stage,
1683 uint32_t end_stage)
1684 {
1685 const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
1686 struct pvr_descriptor_size_info size_info;
1687
1688 pvr_descriptor_size_info_init(device, binding->type, &size_info);
1689
1690 for (uint32_t i = 0; i < write_set->descriptorCount; i++) {
1691 PVR_FROM_HANDLE(pvr_buffer_view, bview, write_set->pTexelBufferView[i]);
1692 const uint32_t desc_idx =
1693 binding->descriptor_index + write_set->dstArrayElement + i;
1694
1695 set->descriptors[desc_idx].type = write_set->descriptorType;
1696 set->descriptors[desc_idx].bview = bview;
1697
1698 for (uint32_t j = start_stage; j < end_stage; j++) {
1699 uint32_t secondary_offset;
1700 uint32_t primary_offset;
1701
1702 if (!(binding->shader_stage_mask & BITFIELD_BIT(j)))
1703 continue;
1704
1705 /* Offset calculation functions expect descriptor_index to be
1706 * binding relative not layout relative, so we have used
1707 * write_set->dstArrayElement + i rather than desc_idx.
1708 */
1709 primary_offset =
1710 pvr_get_descriptor_primary_offset(device,
1711 set->layout,
1712 binding,
1713 j,
1714 write_set->dstArrayElement + i);
1715 secondary_offset =
1716 pvr_get_descriptor_secondary_offset(device,
1717 set->layout,
1718 binding,
1719 j,
1720 write_set->dstArrayElement + i);
1721
1722 pvr_write_buffer_descriptor(
1723 dev_info,
1724 bview,
1725 write_set->descriptorType,
1726 mem_ptr + primary_offset,
1727 size_info.secondary ? mem_ptr + secondary_offset : NULL);
1728 }
1729 }
1730 }
1731
pvr_descriptor_update_input_attachment(const struct pvr_device * device,const VkWriteDescriptorSet * write_set,struct pvr_descriptor_set * set,const struct pvr_descriptor_set_layout_binding * binding,uint32_t * mem_ptr,uint32_t start_stage,uint32_t end_stage)1732 static void pvr_descriptor_update_input_attachment(
1733 const struct pvr_device *device,
1734 const VkWriteDescriptorSet *write_set,
1735 struct pvr_descriptor_set *set,
1736 const struct pvr_descriptor_set_layout_binding *binding,
1737 uint32_t *mem_ptr,
1738 uint32_t start_stage,
1739 uint32_t end_stage)
1740 {
1741 const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
1742 struct pvr_descriptor_size_info size_info;
1743
1744 pvr_descriptor_size_info_init(device, binding->type, &size_info);
1745
1746 for (uint32_t i = 0; i < write_set->descriptorCount; i++) {
1747 PVR_FROM_HANDLE(pvr_image_view,
1748 iview,
1749 write_set->pImageInfo[i].imageView);
1750 const uint32_t desc_idx =
1751 binding->descriptor_index + write_set->dstArrayElement + i;
1752
1753 set->descriptors[desc_idx].type = write_set->descriptorType;
1754 set->descriptors[desc_idx].iview = iview;
1755 set->descriptors[desc_idx].layout = write_set->pImageInfo[i].imageLayout;
1756
1757 for (uint32_t j = start_stage; j < end_stage; j++) {
1758 uint32_t primary_offset;
1759
1760 if (!(binding->shader_stage_mask & BITFIELD_BIT(j)))
1761 continue;
1762
1763 /* Offset calculation functions expect descriptor_index to be
1764 * binding relative not layout relative, so we have used
1765 * write_set->dstArrayElement + i rather than desc_idx.
1766 */
1767 primary_offset =
1768 pvr_get_descriptor_primary_offset(device,
1769 set->layout,
1770 binding,
1771 j,
1772 write_set->dstArrayElement + i);
1773
1774 pvr_write_image_descriptor_primaries(dev_info,
1775 iview,
1776 write_set->descriptorType,
1777 mem_ptr + primary_offset);
1778
1779 *(uint64_t *)(mem_ptr + primary_offset + PVR_IMAGE_DESCRIPTOR_SIZE) =
1780 device->input_attachment_sampler;
1781
1782 if (!PVR_HAS_FEATURE(dev_info, tpu_array_textures)) {
1783 const uint32_t secondary_offset =
1784 pvr_get_descriptor_secondary_offset(device,
1785 set->layout,
1786 binding,
1787 j,
1788 write_set->dstArrayElement +
1789 i);
1790
1791 pvr_write_image_descriptor_secondaries(dev_info,
1792 iview,
1793 write_set->descriptorType,
1794 mem_ptr + secondary_offset);
1795 }
1796 }
1797 }
1798 }
1799
pvr_UpdateDescriptorSets(VkDevice _device,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites,uint32_t descriptorCopyCount,const VkCopyDescriptorSet * pDescriptorCopies)1800 void pvr_UpdateDescriptorSets(VkDevice _device,
1801 uint32_t descriptorWriteCount,
1802 const VkWriteDescriptorSet *pDescriptorWrites,
1803 uint32_t descriptorCopyCount,
1804 const VkCopyDescriptorSet *pDescriptorCopies)
1805 {
1806 PVR_FROM_HANDLE(pvr_device, device, _device);
1807
1808 for (uint32_t i = 0; i < descriptorWriteCount; i++) {
1809 const VkWriteDescriptorSet *write_set = &pDescriptorWrites[i];
1810 PVR_FROM_HANDLE(pvr_descriptor_set, set, write_set->dstSet);
1811 uint32_t *map = set->pvr_bo->bo->map;
1812 const struct pvr_descriptor_set_layout_binding *binding =
1813 pvr_get_descriptor_binding(set->layout, write_set->dstBinding);
1814
1815 /* Binding should not be NULL. */
1816 assert(binding);
1817
1818 /* Only need to update the descriptor if it is actually being used. If it
1819 * was not used in any stage, then the shader_stage_mask would be 0 and we
1820 * can skip this update.
1821 */
1822 if (binding->shader_stage_mask == 0)
1823 continue;
1824
1825 vk_foreach_struct_const (ext, write_set->pNext) {
1826 pvr_debug_ignored_stype(ext->sType);
1827 }
1828
1829 switch (write_set->descriptorType) {
1830 case VK_DESCRIPTOR_TYPE_SAMPLER:
1831 pvr_descriptor_update_sampler(device,
1832 write_set,
1833 set,
1834 binding,
1835 map,
1836 0,
1837 PVR_STAGE_ALLOCATION_COUNT);
1838 break;
1839
1840 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1841 pvr_descriptor_update_sampler_texture(device,
1842 write_set,
1843 set,
1844 binding,
1845 map,
1846 0,
1847 PVR_STAGE_ALLOCATION_COUNT);
1848 break;
1849
1850 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1851 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1852 pvr_descriptor_update_texture(device,
1853 write_set,
1854 set,
1855 binding,
1856 map,
1857 0,
1858 PVR_STAGE_ALLOCATION_COUNT);
1859 break;
1860
1861 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1862 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1863 pvr_descriptor_update_buffer_view(device,
1864 write_set,
1865 set,
1866 binding,
1867 map,
1868 0,
1869 PVR_STAGE_ALLOCATION_COUNT);
1870 break;
1871
1872 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1873 pvr_descriptor_update_input_attachment(device,
1874 write_set,
1875 set,
1876 binding,
1877 map,
1878 0,
1879 PVR_STAGE_ALLOCATION_COUNT);
1880 break;
1881
1882 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1883 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1884 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1885 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1886 pvr_descriptor_update_buffer_info(device,
1887 write_set,
1888 set,
1889 binding,
1890 map,
1891 0,
1892 PVR_STAGE_ALLOCATION_COUNT);
1893 break;
1894
1895 default:
1896 unreachable("Unknown descriptor type");
1897 break;
1898 }
1899 }
1900
1901 if (descriptorCopyCount > 0)
1902 pvr_finishme("Descriptor copying support missing\n");
1903 }
1904