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