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