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