• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2021 Collabora Ltd.
3  *
4  * Derived from tu_shader.c which is:
5  * Copyright © 2019 Google LLC
6  *
7  * Also derived from anv_pipeline.c which is
8  * Copyright © 2015 Intel Corporation
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the "Software"),
12  * to deal in the Software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  * and/or sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice (including the next
18  * paragraph) shall be included in all copies or substantial portions of the
19  * Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  */
29 
30 #include "panvk_device.h"
31 #include "panvk_shader.h"
32 
33 #include "vk_pipeline.h"
34 #include "vk_pipeline_layout.h"
35 
36 #include "util/bitset.h"
37 #include "nir.h"
38 #include "nir_builder.h"
39 
40 #if PAN_ARCH >= 9
41 #define VALHALL_RESOURCE_TABLE_IDX 62
42 #endif
43 
44 struct panvk_shader_desc_map {
45    /* The index of the map serves as the table offset, the value of the
46     * entry is a COPY_DESC_HANDLE() encoding the source set, and the
47     * index of the descriptor in the set. */
48    uint32_t *map;
49 
50    /* Number of entries in the map array. */
51    uint32_t count;
52 };
53 
54 struct panvk_shader_desc_info {
55    uint32_t used_set_mask;
56 #if PAN_ARCH <= 7
57    struct panvk_shader_desc_map dyn_ubos;
58    struct panvk_shader_desc_map dyn_ssbos;
59    struct panvk_shader_desc_map others[PANVK_BIFROST_DESC_TABLE_COUNT];
60 #else
61    uint32_t dummy_sampler_handle;
62    uint32_t dyn_bufs_start;
63    struct panvk_shader_desc_map dyn_bufs;
64    uint32_t num_varying_attr_descs;
65 #endif
66 };
67 
68 struct lower_desc_ctx {
69    const struct panvk_descriptor_set_layout *set_layouts[MAX_SETS];
70    struct panvk_shader_desc_info desc_info;
71    struct hash_table_u64 *ht;
72    bool add_bounds_checks;
73    nir_address_format ubo_addr_format;
74    nir_address_format ssbo_addr_format;
75 };
76 
77 static nir_address_format
addr_format_for_desc_type(VkDescriptorType desc_type,const struct lower_desc_ctx * ctx)78 addr_format_for_desc_type(VkDescriptorType desc_type,
79                           const struct lower_desc_ctx *ctx)
80 {
81    switch (desc_type) {
82    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
83    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
84       return ctx->ubo_addr_format;
85 
86    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
87    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
88       return ctx->ssbo_addr_format;
89 
90    default:
91       unreachable("Unsupported descriptor type");
92    }
93 }
94 
95 static const struct panvk_descriptor_set_layout *
get_set_layout(uint32_t set,const struct lower_desc_ctx * ctx)96 get_set_layout(uint32_t set, const struct lower_desc_ctx *ctx)
97 {
98    return ctx->set_layouts[set];
99 }
100 
101 static const struct panvk_descriptor_set_binding_layout *
get_binding_layout(uint32_t set,uint32_t binding,const struct lower_desc_ctx * ctx)102 get_binding_layout(uint32_t set, uint32_t binding,
103                    const struct lower_desc_ctx *ctx)
104 {
105    return &get_set_layout(set, ctx)->bindings[binding];
106 }
107 
108 struct desc_id {
109    union {
110       struct {
111          uint32_t binding;
112          uint32_t set : 4;
113          uint32_t subdesc : 1;
114          uint32_t pad : 27;
115       };
116       uint64_t ht_key;
117    };
118 };
119 
120 #if PAN_ARCH <= 7
121 static enum panvk_bifrost_desc_table_type
desc_type_to_table_type(VkDescriptorType type,unsigned subdesc_idx)122 desc_type_to_table_type(VkDescriptorType type, unsigned subdesc_idx)
123 {
124    switch (type) {
125    case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
126       return subdesc_idx == 1 ? PANVK_BIFROST_DESC_TABLE_SAMPLER
127                               : PANVK_BIFROST_DESC_TABLE_TEXTURE;
128    case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
129    case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
130    case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
131       return PANVK_BIFROST_DESC_TABLE_TEXTURE;
132    case VK_DESCRIPTOR_TYPE_SAMPLER:
133       return PANVK_BIFROST_DESC_TABLE_SAMPLER;
134    case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
135    case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
136       return PANVK_BIFROST_DESC_TABLE_IMG;
137    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
138       return PANVK_BIFROST_DESC_TABLE_UBO;
139    default:
140       return PANVK_BIFROST_DESC_TABLE_INVALID;
141    }
142 }
143 #endif
144 
145 static uint32_t
get_subdesc_idx(const struct panvk_descriptor_set_binding_layout * bind_layout,VkDescriptorType subdesc_type)146 get_subdesc_idx(const struct panvk_descriptor_set_binding_layout *bind_layout,
147                 VkDescriptorType subdesc_type)
148 {
149    if (bind_layout->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
150       assert(subdesc_type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
151              subdesc_type == VK_DESCRIPTOR_TYPE_SAMPLER);
152       return subdesc_type == VK_DESCRIPTOR_TYPE_SAMPLER ? 1 : 0;
153    }
154 
155    return 0;
156 }
157 
158 static uint32_t
shader_desc_idx(uint32_t set,uint32_t binding,VkDescriptorType subdesc_type,const struct lower_desc_ctx * ctx)159 shader_desc_idx(uint32_t set, uint32_t binding, VkDescriptorType subdesc_type,
160                 const struct lower_desc_ctx *ctx)
161 {
162    const struct panvk_descriptor_set_layout *set_layout =
163       get_set_layout(set, ctx);
164    const struct panvk_descriptor_set_binding_layout *bind_layout =
165       &set_layout->bindings[binding];
166    uint32_t subdesc_idx = get_subdesc_idx(bind_layout, subdesc_type);
167 
168    /* On Valhall, all non-dynamic descriptors are accessed directly through
169     * their set. The vertex attribute table always comes first, so we always
170     * offset user sets by one if we're dealing with a vertex shader. */
171    if (PAN_ARCH >= 9 && !vk_descriptor_type_is_dynamic(bind_layout->type))
172       return pan_res_handle(set + 1, bind_layout->desc_idx + subdesc_idx);
173 
174    /* On Bifrost, the SSBO descriptors are read directly from the set. */
175    if (PAN_ARCH <= 7 && bind_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
176       return bind_layout->desc_idx;
177 
178    struct desc_id src = {
179       .set = set,
180       .subdesc = subdesc_idx,
181       .binding = binding,
182    };
183    uint32_t *entry =
184       _mesa_hash_table_u64_search(ctx->ht, src.ht_key);
185 
186    assert(entry);
187 
188    const struct panvk_shader_desc_map *map;
189 
190 #if PAN_ARCH <= 7
191    if (bind_layout->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
192       map = &ctx->desc_info.dyn_ubos;
193    } else if (bind_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
194       map = &ctx->desc_info.dyn_ssbos;
195    } else {
196       uint32_t table = desc_type_to_table_type(bind_layout->type, src.subdesc);
197 
198       assert(table < PANVK_BIFROST_DESC_TABLE_COUNT);
199       map = &ctx->desc_info.others[table];
200    }
201 #else
202    map = &ctx->desc_info.dyn_bufs;
203 #endif
204 
205    assert(entry >= map->map && entry < map->map + map->count);
206 
207    uint32_t idx = entry - map->map;
208 
209 #if PAN_ARCH <= 7
210    /* Adjust the destination index for all dynamic UBOs, which are laid out
211     * just after the regular UBOs in the UBO table. */
212    if (bind_layout->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
213       idx += ctx->desc_info.others[PANVK_BIFROST_DESC_TABLE_UBO].count;
214 #else
215    /* Dynamic buffers are pushed directly in the resource tables, after all
216     * sets. */
217    idx = pan_res_handle(0, ctx->desc_info.dyn_bufs_start + idx);
218 #endif
219 
220    return idx;
221 }
222 
223 static nir_address_format
addr_format_for_type(VkDescriptorType type,const struct lower_desc_ctx * ctx)224 addr_format_for_type(VkDescriptorType type, const struct lower_desc_ctx *ctx)
225 {
226    switch (type) {
227    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
228    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
229       return ctx->ubo_addr_format;
230 
231    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
232    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
233       return ctx->ssbo_addr_format;
234 
235    default:
236       unreachable("Unsupported descriptor type");
237       return ~0;
238    }
239 }
240 
241 #if PAN_ARCH <= 7
242 static uint32_t
shader_ssbo_table(nir_builder * b,unsigned set,unsigned binding,const struct lower_desc_ctx * ctx)243 shader_ssbo_table(nir_builder *b, unsigned set, unsigned binding,
244                   const struct lower_desc_ctx *ctx)
245 {
246    const struct panvk_descriptor_set_layout *set_layout =
247       get_set_layout(set, ctx);
248    const struct panvk_descriptor_set_binding_layout *bind_layout =
249       &set_layout->bindings[binding];
250 
251    assert(bind_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
252           bind_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
253    bool is_dyn = bind_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
254 
255    if (!is_dyn)
256       return PANVK_DESC_TABLE_USER + set;
257 
258    switch (b->shader->info.stage) {
259    case MESA_SHADER_COMPUTE:
260       return PANVK_DESC_TABLE_CS_DYN_SSBOS;
261    case MESA_SHADER_VERTEX:
262       return PANVK_DESC_TABLE_VS_DYN_SSBOS;
263    case MESA_SHADER_FRAGMENT:
264       return PANVK_DESC_TABLE_FS_DYN_SSBOS;
265    default:
266       assert(!"Invalid stage");
267       return ~0;
268    }
269 }
270 #endif
271 
272 /** Build a Vulkan resource index
273  *
274  * A "resource index" is the term used by our SPIR-V parser and the relevant
275  * NIR intrinsics for a reference into a descriptor set.  It acts much like a
276  * deref in NIR except that it accesses opaque descriptors instead of memory.
277  *
278  * Coming out of SPIR-V, both the resource indices (in the form of
279  * vulkan_resource_[re]index intrinsics) and the memory derefs (in the form
280  * of nir_deref_instr) use the same vector component/bit size.  The meaning
281  * of those values for memory derefs (nir_deref_instr) is given by the
282  * nir_address_format associated with the descriptor type.  For resource
283  * indices, it's an entirely internal to panvk encoding which describes, in
284  * some sense, the address of the descriptor.  Thanks to the NIR/SPIR-V rules,
285  * it must be packed into the same size SSA values as a memory address.  For
286  * this reason, the actual encoding may depend both on the address format for
287  * memory derefs and the descriptor address format.
288  *
289  * The load_vulkan_descriptor intrinsic exists to provide a transition point
290  * between these two forms of derefs: descriptor and memory.
291  */
292 static nir_def *
build_res_index(nir_builder * b,uint32_t set,uint32_t binding,nir_def * array_index,nir_address_format addr_format,const struct lower_desc_ctx * ctx)293 build_res_index(nir_builder *b, uint32_t set, uint32_t binding,
294                 nir_def *array_index, nir_address_format addr_format,
295                 const struct lower_desc_ctx *ctx)
296 {
297    const struct panvk_descriptor_set_layout *set_layout =
298       get_set_layout(set, ctx);
299    const struct panvk_descriptor_set_binding_layout *bind_layout =
300       &set_layout->bindings[binding];
301    uint32_t array_size = bind_layout->desc_count;
302    nir_address_format addr_fmt = addr_format_for_type(bind_layout->type, ctx);
303    uint32_t desc_idx = shader_desc_idx(set, binding, bind_layout->type, ctx);
304 
305    switch (addr_fmt) {
306 #if PAN_ARCH <= 7
307    case nir_address_format_32bit_index_offset: {
308       const uint32_t packed_desc_idx_array_size =
309          (array_size - 1) << 16 | desc_idx;
310 
311       return nir_vec2(b, nir_imm_int(b, packed_desc_idx_array_size),
312                       array_index);
313    }
314 
315    case nir_address_format_64bit_bounded_global:
316    case nir_address_format_64bit_global_32bit_offset: {
317       unsigned desc_table = shader_ssbo_table(b, set, binding, ctx);
318 
319       return nir_vec4(b, nir_imm_int(b, desc_table),
320                       nir_imm_int(b, desc_idx), array_index,
321                       nir_imm_int(b, array_size - 1));
322    }
323 #else
324    case nir_address_format_vec2_index_32bit_offset:
325       return nir_vec3(b, nir_imm_int(b, desc_idx), array_index,
326                       nir_imm_int(b, array_size - 1));
327 #endif
328 
329    default:
330       unreachable("Unsupported descriptor type");
331    }
332 }
333 
334 /** Adjust a Vulkan resource index
335  *
336  * This is the equivalent of nir_deref_type_ptr_as_array for resource indices.
337  * For array descriptors, it allows us to adjust the array index.  Thanks to
338  * variable pointers, we cannot always fold this re-index operation into the
339  * vulkan_resource_index intrinsic and we have to do it based on nothing but
340  * the address format.
341  */
342 static nir_def *
build_res_reindex(nir_builder * b,nir_def * orig,nir_def * delta,nir_address_format addr_format)343 build_res_reindex(nir_builder *b, nir_def *orig, nir_def *delta,
344                   nir_address_format addr_format)
345 {
346    switch (addr_format) {
347 #if PAN_ARCH <= 7
348    case nir_address_format_32bit_index_offset:
349       return nir_vec2(b, nir_channel(b, orig, 0),
350                       nir_iadd(b, nir_channel(b, orig, 1), delta));
351 
352    case nir_address_format_64bit_bounded_global:
353    case nir_address_format_64bit_global_32bit_offset:
354       return nir_vec4(b, nir_channel(b, orig, 0), nir_channel(b, orig, 1),
355                       nir_iadd(b, nir_channel(b, orig, 2), delta),
356                       nir_imm_int(b, 3));
357 #else
358    case nir_address_format_vec2_index_32bit_offset:
359       return nir_vec3(b, nir_channel(b, orig, 0),
360                       nir_iadd(b, nir_channel(b, orig, 1), delta),
361                       nir_channel(b, orig, 2));
362 #endif
363 
364    default:
365       unreachable("Unhandled address format");
366    }
367 }
368 
369 /** Convert a Vulkan resource index into a buffer address
370  *
371  * In some cases, this does a  memory load from the descriptor set and, in
372  * others, it simply converts from one form to another.
373  *
374  * See build_res_index for details about each resource index format.
375  */
376 static nir_def *
build_buffer_addr_for_res_index(nir_builder * b,nir_def * res_index,nir_address_format addr_format,const struct lower_desc_ctx * ctx)377 build_buffer_addr_for_res_index(nir_builder *b, nir_def *res_index,
378                                 nir_address_format addr_format,
379                                 const struct lower_desc_ctx *ctx)
380 {
381    switch (addr_format) {
382 #if PAN_ARCH <= 7
383    case nir_address_format_32bit_index_offset: {
384       nir_def *packed = nir_channel(b, res_index, 0);
385       nir_def *array_index = nir_channel(b, res_index, 1);
386       nir_def *first_desc_index = nir_extract_u16(b, packed, nir_imm_int(b, 0));
387       nir_def *array_max = nir_extract_u16(b, packed, nir_imm_int(b, 1));
388 
389       if (ctx->add_bounds_checks)
390          array_index = nir_umin(b, array_index, array_max);
391 
392       return nir_vec2(b, nir_iadd(b, first_desc_index, array_index),
393                       nir_imm_int(b, 0));
394    }
395 
396    case nir_address_format_64bit_bounded_global:
397    case nir_address_format_64bit_global_32bit_offset: {
398       nir_def *desc_table_index = nir_channel(b, res_index, 0);
399       nir_def *first_desc_index = nir_channel(b, res_index, 1);
400       nir_def *array_index = nir_channel(b, res_index, 2);
401       nir_def *array_max = nir_channel(b, res_index, 3);
402 
403       if (ctx->add_bounds_checks)
404          array_index = nir_umin(b, array_index, array_max);
405 
406       nir_def *desc_offset = nir_imul_imm(
407          b, nir_iadd(b, array_index, first_desc_index), PANVK_DESCRIPTOR_SIZE);
408 
409       nir_def *base_addr =
410          b->shader->info.stage == MESA_SHADER_COMPUTE
411             ? load_sysval_entry(b, compute, 64, desc.sets, desc_table_index)
412             : load_sysval_entry(b, graphics, 64, desc.sets, desc_table_index);
413 
414       nir_def *desc_addr = nir_iadd(b, base_addr, nir_u2u64(b, desc_offset));
415       nir_def *desc =
416          nir_load_global(b, desc_addr, PANVK_DESCRIPTOR_SIZE, 4, 32);
417 
418       /* The offset in the descriptor is guaranteed to be zero when it's
419        * written into the descriptor set.  This lets us avoid some unnecessary
420        * adds.
421        */
422       return nir_vec4(b, nir_channel(b, desc, 0), nir_channel(b, desc, 1),
423                       nir_channel(b, desc, 2), nir_imm_int(b, 0));
424    }
425 #else
426    case nir_address_format_vec2_index_32bit_offset: {
427       nir_def *first_desc_index = nir_channel(b, res_index, 0);
428       nir_def *array_index = nir_channel(b, res_index, 1);
429       nir_def *array_max = nir_channel(b, res_index, 2);
430 
431       if (ctx->add_bounds_checks)
432          array_index = nir_umin(b, array_index, array_max);
433 
434       return nir_vec3(b, first_desc_index, array_index, nir_imm_int(b, 0));
435    }
436 #endif
437 
438    default:
439       unreachable("Unhandled address format");
440    }
441 }
442 
443 static bool
lower_res_intrinsic(nir_builder * b,nir_intrinsic_instr * intrin,const struct lower_desc_ctx * ctx)444 lower_res_intrinsic(nir_builder *b, nir_intrinsic_instr *intrin,
445                     const struct lower_desc_ctx *ctx)
446 {
447    b->cursor = nir_before_instr(&intrin->instr);
448 
449    const VkDescriptorType desc_type = nir_intrinsic_desc_type(intrin);
450    nir_address_format addr_format = addr_format_for_desc_type(desc_type, ctx);
451 
452    nir_def *res;
453    switch (intrin->intrinsic) {
454    case nir_intrinsic_vulkan_resource_index:
455       res = build_res_index(b, nir_intrinsic_desc_set(intrin),
456                             nir_intrinsic_binding(intrin), intrin->src[0].ssa,
457                             addr_format, ctx);
458       break;
459 
460    case nir_intrinsic_vulkan_resource_reindex:
461       res = build_res_reindex(b, intrin->src[0].ssa, intrin->src[1].ssa,
462                               addr_format);
463       break;
464 
465    case nir_intrinsic_load_vulkan_descriptor:
466       res = build_buffer_addr_for_res_index(b, intrin->src[0].ssa, addr_format,
467                                             ctx);
468       break;
469 
470    default:
471       unreachable("Unhandled resource intrinsic");
472    }
473 
474    assert(intrin->def.bit_size == res->bit_size);
475    assert(intrin->def.num_components == res->num_components);
476    nir_def_replace(&intrin->def, res);
477 
478    return true;
479 }
480 
481 static void
get_resource_deref_binding(nir_deref_instr * deref,uint32_t * set,uint32_t * binding,uint32_t * index_imm,nir_def ** index_ssa,uint32_t * max_idx)482 get_resource_deref_binding(nir_deref_instr *deref, uint32_t *set,
483                            uint32_t *binding, uint32_t *index_imm,
484                            nir_def **index_ssa, uint32_t *max_idx)
485 {
486    *index_imm = 0;
487    *max_idx = 0;
488    *index_ssa = NULL;
489 
490    if (deref->deref_type == nir_deref_type_array) {
491       if (nir_src_is_const(deref->arr.index)) {
492          *index_imm = nir_src_as_uint(deref->arr.index);
493          *max_idx = *index_imm;
494       } else {
495          *index_ssa = deref->arr.index.ssa;
496 
497          /* Zero means variable array. The minus one should give us UINT32_MAX,
498           * which matches what we want. */
499          *max_idx = ((uint32_t)glsl_array_size(nir_deref_instr_parent(deref)->type)) - 1;
500       }
501 
502       deref = nir_deref_instr_parent(deref);
503    }
504 
505    assert(deref->deref_type == nir_deref_type_var);
506    nir_variable *var = deref->var;
507 
508    *set = var->data.descriptor_set;
509    *binding = var->data.binding;
510 }
511 
512 static nir_def *
load_resource_deref_desc(nir_builder * b,nir_deref_instr * deref,VkDescriptorType subdesc_type,unsigned desc_offset,unsigned num_components,unsigned bit_size,const struct lower_desc_ctx * ctx)513 load_resource_deref_desc(nir_builder *b, nir_deref_instr *deref,
514                          VkDescriptorType subdesc_type, unsigned desc_offset,
515                          unsigned num_components, unsigned bit_size,
516                          const struct lower_desc_ctx *ctx)
517 {
518    uint32_t set, binding, index_imm, max_idx;
519    nir_def *index_ssa;
520    get_resource_deref_binding(deref, &set, &binding, &index_imm, &index_ssa,
521                               &max_idx);
522 
523    const struct panvk_descriptor_set_layout *set_layout =
524       get_set_layout(set, ctx);
525    const struct panvk_descriptor_set_binding_layout *bind_layout =
526       &set_layout->bindings[binding];
527    unsigned subdesc_idx = get_subdesc_idx(bind_layout, subdesc_type);
528 
529    assert(index_ssa == NULL || index_imm == 0);
530    if (index_ssa == NULL)
531       index_ssa = nir_imm_int(b, index_imm);
532 
533    unsigned desc_stride = panvk_get_desc_stride(bind_layout->type);
534    nir_def *set_offset =
535       nir_imul_imm(b,
536                    nir_iadd_imm(b, nir_imul_imm(b, index_ssa, desc_stride),
537                                 bind_layout->desc_idx + subdesc_idx),
538                    PANVK_DESCRIPTOR_SIZE);
539 
540    set_offset = nir_iadd_imm(b, set_offset, desc_offset);
541 
542 #if PAN_ARCH <= 7
543    nir_def *set_base_addr =
544       b->shader->info.stage == MESA_SHADER_COMPUTE
545          ? load_sysval_entry(b, compute, 64, desc.sets, nir_imm_int(b, set))
546          : load_sysval_entry(b, graphics, 64, desc.sets, nir_imm_int(b, set));
547 
548    unsigned desc_align = 1 << (ffs(PANVK_DESCRIPTOR_SIZE + desc_offset) - 1);
549 
550    return nir_load_global(b,
551                           nir_iadd(b, set_base_addr, nir_u2u64(b, set_offset)),
552                           desc_align, num_components, bit_size);
553 #else
554    /* note that user sets start from index 1 */
555    return nir_load_ubo(
556       b, num_components, bit_size,
557       nir_imm_int(b, pan_res_handle(VALHALL_RESOURCE_TABLE_IDX, set + 1)),
558       set_offset, .range = ~0u, .align_mul = PANVK_DESCRIPTOR_SIZE,
559       .align_offset = desc_offset);
560 #endif
561 }
562 
563 static nir_def *
load_tex_size(nir_builder * b,nir_deref_instr * deref,enum glsl_sampler_dim dim,bool is_array,const struct lower_desc_ctx * ctx)564 load_tex_size(nir_builder *b, nir_deref_instr *deref, enum glsl_sampler_dim dim,
565               bool is_array, const struct lower_desc_ctx *ctx)
566 {
567    if (dim == GLSL_SAMPLER_DIM_BUF) {
568       nir_def *tex_w = load_resource_deref_desc(
569          b, deref, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 4, 1, 16, ctx);
570 
571       /* S dimension is 16 bits wide. We don't support combining S,T dimensions
572        * to allow large buffers yet. */
573       return nir_iadd_imm(b, nir_u2u32(b, tex_w), 1);
574    } else {
575       nir_def *tex_w_h = load_resource_deref_desc(
576          b, deref, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 4, 2, 16, ctx);
577       nir_def *tex_depth_or_layer_count = load_resource_deref_desc(
578          b, deref, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
579          dim == GLSL_SAMPLER_DIM_3D ? 28 : 24, 1, 16, ctx);
580 
581       nir_def *tex_sz =
582          is_array && dim == GLSL_SAMPLER_DIM_1D
583             ? nir_vec2(b, nir_channel(b, tex_w_h, 0), tex_depth_or_layer_count)
584             : nir_vec3(b, nir_channel(b, tex_w_h, 0),
585                        nir_channel(b, tex_w_h, 1), tex_depth_or_layer_count);
586 
587       tex_sz = nir_pad_vector_imm_int(b, tex_sz, 0, 4);
588 
589       /* The sizes are provided as 16-bit values with 1 subtracted so
590        * convert to 32-bit and add 1.
591        */
592       return nir_iadd_imm(b, nir_u2u32(b, tex_sz), 1);
593    }
594 }
595 
596 static nir_def *
load_img_size(nir_builder * b,nir_deref_instr * deref,enum glsl_sampler_dim dim,bool is_array,const struct lower_desc_ctx * ctx)597 load_img_size(nir_builder *b, nir_deref_instr *deref, enum glsl_sampler_dim dim,
598               bool is_array, const struct lower_desc_ctx *ctx)
599 {
600    if (PAN_ARCH >= 9)
601       return load_tex_size(b, deref, dim, is_array, ctx);
602 
603    if (dim == GLSL_SAMPLER_DIM_BUF) {
604       nir_def *tex_w = load_resource_deref_desc(
605          b, deref, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 18, 1, 16, ctx);
606 
607       /* S dimension is 16 bits wide. We don't support combining S,T dimensions
608        * to allow large buffers yet. */
609       return nir_iadd_imm(b, nir_u2u32(b, tex_w), 1);
610    } else {
611       nir_def *tex_sz = load_resource_deref_desc(
612          b, deref, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 18, 3, 16, ctx);
613 
614 #if PAN_ARCH <= 7
615       if (is_array && dim == GLSL_SAMPLER_DIM_CUBE)
616          tex_sz =
617             nir_vector_insert_imm(b, tex_sz,
618                                      nir_udiv_imm(b, nir_channel(b, tex_sz, 2),
619                                                      6),
620                                      2);
621 #endif
622 
623       if (is_array && dim == GLSL_SAMPLER_DIM_1D)
624          tex_sz =
625             nir_vec2(b, nir_channel(b, tex_sz, 0), nir_channel(b, tex_sz, 2));
626 
627       tex_sz = nir_pad_vector_imm_int(b, tex_sz, 0, 4);
628 
629       /* The sizes are provided as 16-bit values with 1 subtracted so
630        * convert to 32-bit and add 1.
631        */
632       return nir_iadd_imm(b, nir_u2u32(b, tex_sz), 1);
633    }
634 }
635 
636 static nir_def *
load_tex_levels(nir_builder * b,nir_deref_instr * deref,enum glsl_sampler_dim dim,const struct lower_desc_ctx * ctx)637 load_tex_levels(nir_builder *b, nir_deref_instr *deref,
638                 enum glsl_sampler_dim dim, const struct lower_desc_ctx *ctx)
639 {
640    assert(dim != GLSL_SAMPLER_DIM_BUF);
641 
642    /* LOD count is stored in word2[16:21] and has a minus(1) modifier. */
643    nir_def *tex_word2 = load_resource_deref_desc(
644       b, deref, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 8, 1, 32, ctx);
645    nir_def *lod_count = nir_iand_imm(b, nir_ushr_imm(b, tex_word2, 16), 0x1f);
646    return nir_iadd_imm(b, lod_count, 1);
647 }
648 
649 static nir_def *
load_tex_samples(nir_builder * b,nir_deref_instr * deref,enum glsl_sampler_dim dim,const struct lower_desc_ctx * ctx)650 load_tex_samples(nir_builder *b, nir_deref_instr *deref,
651                  enum glsl_sampler_dim dim, const struct lower_desc_ctx *ctx)
652 {
653    assert(dim != GLSL_SAMPLER_DIM_BUF);
654 
655    /* Sample count is stored in word3[13:25], and has a log2 modifier. */
656    nir_def *tex_word3 = load_resource_deref_desc(
657       b, deref, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 12, 1, 32, ctx);
658    nir_def *sample_count = nir_iand_imm(b, nir_ushr_imm(b, tex_word3, 13), 0x7);
659    return nir_ishl(b, nir_imm_int(b, 1), sample_count);
660 }
661 
662 static nir_def *
load_img_samples(nir_builder * b,nir_deref_instr * deref,enum glsl_sampler_dim dim,const struct lower_desc_ctx * ctx)663 load_img_samples(nir_builder *b, nir_deref_instr *deref,
664                  enum glsl_sampler_dim dim, const struct lower_desc_ctx *ctx)
665 {
666    if (PAN_ARCH >= 9)
667       return load_tex_samples(b, deref, dim, ctx);
668 
669    assert(dim != GLSL_SAMPLER_DIM_BUF);
670 
671    /* Sample count is stored in the image depth field.
672     * FIXME: This won't work for 2DMSArray images, but those are already
673     * broken. */
674    nir_def *sample_count = load_resource_deref_desc(
675       b, deref, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 22, 1, 16, ctx);
676    return nir_iadd_imm(b, nir_u2u32(b, sample_count), 1);
677 }
678 
679 static uint32_t
get_desc_array_stride(const struct panvk_descriptor_set_binding_layout * layout)680 get_desc_array_stride(const struct panvk_descriptor_set_binding_layout *layout)
681 {
682    /* On Bifrost, descriptors are copied from the sets to the final
683     * descriptor tables which are per-type, making the stride one in
684     * this context. */
685    return PAN_ARCH >= 9 ? panvk_get_desc_stride(layout->type) : 1;
686 }
687 
688 static bool
lower_tex(nir_builder * b,nir_tex_instr * tex,const struct lower_desc_ctx * ctx)689 lower_tex(nir_builder *b, nir_tex_instr *tex, const struct lower_desc_ctx *ctx)
690 {
691    bool progress = false;
692 
693    b->cursor = nir_before_instr(&tex->instr);
694 
695    if (tex->op == nir_texop_txs || tex->op == nir_texop_query_levels ||
696        tex->op == nir_texop_texture_samples) {
697       int tex_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_texture_deref);
698       assert(tex_src_idx >= 0);
699       nir_deref_instr *deref = nir_src_as_deref(tex->src[tex_src_idx].src);
700 
701       const enum glsl_sampler_dim dim = tex->sampler_dim;
702 
703       nir_def *res;
704       switch (tex->op) {
705       case nir_texop_txs:
706          res = nir_channels(b, load_tex_size(b, deref, dim, tex->is_array, ctx),
707                             nir_component_mask(tex->def.num_components));
708          break;
709       case nir_texop_query_levels:
710          assert(tex->def.num_components == 1);
711          res = load_tex_levels(b, deref, dim, ctx);
712          break;
713       case nir_texop_texture_samples:
714          assert(tex->def.num_components == 1);
715          res = load_tex_samples(b, deref, dim, ctx);
716          break;
717       default:
718          unreachable("Unsupported texture query op");
719       }
720 
721       nir_def_replace(&tex->def, res);
722       return true;
723    }
724 
725    int sampler_src_idx =
726       nir_tex_instr_src_index(tex, nir_tex_src_sampler_deref);
727    if (sampler_src_idx >= 0) {
728       nir_deref_instr *deref = nir_src_as_deref(tex->src[sampler_src_idx].src);
729       nir_tex_instr_remove_src(tex, sampler_src_idx);
730 
731       uint32_t set, binding, index_imm, max_idx;
732       nir_def *index_ssa;
733       get_resource_deref_binding(deref, &set, &binding, &index_imm, &index_ssa, &max_idx);
734 
735       const struct panvk_descriptor_set_layout *set_layout =
736          get_set_layout(set, ctx);
737       const struct panvk_descriptor_set_binding_layout *bind_layout =
738          &set_layout->bindings[binding];
739       uint32_t desc_stride = get_desc_array_stride(bind_layout);
740 
741       tex->sampler_index =
742          shader_desc_idx(set, binding, VK_DESCRIPTOR_TYPE_SAMPLER, ctx) +
743          index_imm * desc_stride;
744 
745       if (index_ssa != NULL) {
746          nir_def *offset = nir_imul_imm(b, index_ssa, desc_stride);
747          nir_tex_instr_add_src(tex, nir_tex_src_sampler_offset, offset);
748       }
749       progress = true;
750    } else {
751 #if PAN_ARCH >= 9
752       tex->sampler_index = ctx->desc_info.dummy_sampler_handle;
753 #endif
754    }
755 
756    int tex_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_texture_deref);
757    if (tex_src_idx >= 0) {
758       nir_deref_instr *deref = nir_src_as_deref(tex->src[tex_src_idx].src);
759       nir_tex_instr_remove_src(tex, tex_src_idx);
760 
761       uint32_t set, binding, index_imm, max_idx;
762       nir_def *index_ssa;
763       get_resource_deref_binding(deref, &set, &binding, &index_imm, &index_ssa,
764                                  &max_idx);
765 
766       const struct panvk_descriptor_set_layout *set_layout =
767          get_set_layout(set, ctx);
768       const struct panvk_descriptor_set_binding_layout *bind_layout =
769          &set_layout->bindings[binding];
770       uint32_t desc_stride = get_desc_array_stride(bind_layout);
771 
772       tex->texture_index =
773          shader_desc_idx(set, binding, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, ctx) +
774          index_imm * desc_stride;
775 
776       if (index_ssa != NULL) {
777          nir_def *offset = nir_imul_imm(b, index_ssa, desc_stride);
778          nir_tex_instr_add_src(tex, nir_tex_src_texture_offset, offset);
779       }
780       progress = true;
781    }
782 
783    return progress;
784 }
785 
786 static nir_def *
get_img_index(nir_builder * b,nir_deref_instr * deref,const struct lower_desc_ctx * ctx)787 get_img_index(nir_builder *b, nir_deref_instr *deref,
788               const struct lower_desc_ctx *ctx)
789 {
790    uint32_t set, binding, index_imm, max_idx;
791    nir_def *index_ssa;
792    get_resource_deref_binding(deref, &set, &binding, &index_imm, &index_ssa,
793                               &max_idx);
794 
795    const struct panvk_descriptor_set_binding_layout *bind_layout =
796       get_binding_layout(set, binding, ctx);
797    assert(bind_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
798           bind_layout->type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
799           bind_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
800 
801    unsigned img_offset = shader_desc_idx(set, binding, bind_layout->type, ctx);
802 
803    if (index_ssa == NULL) {
804       return nir_imm_int(b, img_offset + index_imm);
805    } else {
806       assert(index_imm == 0);
807       return nir_iadd_imm(b, index_ssa, img_offset);
808    }
809 }
810 
811 static bool
lower_img_intrinsic(nir_builder * b,nir_intrinsic_instr * intr,struct lower_desc_ctx * ctx)812 lower_img_intrinsic(nir_builder *b, nir_intrinsic_instr *intr,
813                     struct lower_desc_ctx *ctx)
814 {
815    b->cursor = nir_before_instr(&intr->instr);
816    nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
817 
818    if (intr->intrinsic == nir_intrinsic_image_deref_size ||
819        intr->intrinsic == nir_intrinsic_image_deref_samples) {
820       const enum glsl_sampler_dim dim = nir_intrinsic_image_dim(intr);
821       bool is_array = nir_intrinsic_image_array(intr);
822 
823       nir_def *res;
824       switch (intr->intrinsic) {
825       case nir_intrinsic_image_deref_size:
826          res = nir_channels(b, load_img_size(b, deref, dim, is_array, ctx),
827                             nir_component_mask(intr->def.num_components));
828          break;
829       case nir_intrinsic_image_deref_samples:
830          res = load_img_samples(b, deref, dim, ctx);
831          break;
832       default:
833          unreachable("Unsupported image query op");
834       }
835 
836       nir_def_replace(&intr->def, res);
837    } else {
838       nir_rewrite_image_intrinsic(intr, get_img_index(b, deref, ctx), false);
839    }
840 
841    return true;
842 }
843 
844 static bool
lower_intrinsic(nir_builder * b,nir_intrinsic_instr * intr,struct lower_desc_ctx * ctx)845 lower_intrinsic(nir_builder *b, nir_intrinsic_instr *intr,
846                 struct lower_desc_ctx *ctx)
847 {
848    switch (intr->intrinsic) {
849    case nir_intrinsic_vulkan_resource_index:
850    case nir_intrinsic_vulkan_resource_reindex:
851    case nir_intrinsic_load_vulkan_descriptor:
852       return lower_res_intrinsic(b, intr, ctx);
853    case nir_intrinsic_image_deref_store:
854    case nir_intrinsic_image_deref_load:
855    case nir_intrinsic_image_deref_atomic:
856    case nir_intrinsic_image_deref_atomic_swap:
857    case nir_intrinsic_image_deref_size:
858    case nir_intrinsic_image_deref_samples:
859       return lower_img_intrinsic(b, intr, ctx);
860    default:
861       return false;
862    }
863 }
864 
865 static bool
lower_descriptors_instr(nir_builder * b,nir_instr * instr,void * data)866 lower_descriptors_instr(nir_builder *b, nir_instr *instr, void *data)
867 {
868    struct lower_desc_ctx *ctx = data;
869 
870    switch (instr->type) {
871    case nir_instr_type_tex:
872       return lower_tex(b, nir_instr_as_tex(instr), ctx);
873    case nir_instr_type_intrinsic:
874       return lower_intrinsic(b, nir_instr_as_intrinsic(instr), ctx);
875    default:
876       return false;
877    }
878 }
879 
880 static void
record_binding(struct lower_desc_ctx * ctx,unsigned set,unsigned binding,VkDescriptorType subdesc_type,uint32_t max_idx)881 record_binding(struct lower_desc_ctx *ctx, unsigned set, unsigned binding,
882                VkDescriptorType subdesc_type, uint32_t max_idx)
883 {
884    const struct panvk_descriptor_set_layout *set_layout = ctx->set_layouts[set];
885    const struct panvk_descriptor_set_binding_layout *binding_layout =
886       &set_layout->bindings[binding];
887    uint32_t subdesc_idx = get_subdesc_idx(binding_layout, subdesc_type);
888    uint32_t desc_stride = panvk_get_desc_stride(binding_layout->type);
889 
890    assert(desc_stride == 1 || desc_stride == 2);
891    ctx->desc_info.used_set_mask |= BITFIELD_BIT(set);
892 
893    /* On valhall, we only record dynamic bindings, others are accessed directly
894     * from the set. */
895    if (PAN_ARCH >= 9 && !vk_descriptor_type_is_dynamic(binding_layout->type))
896       return;
897 
898    /* SSBOs are accessed directly from the sets, no need to record accesses
899     * to such resources. */
900    if (PAN_ARCH <= 7 &&
901        binding_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
902       return;
903 
904    assert(subdesc_idx < desc_stride);
905 
906    struct desc_id src = {
907       .set = set,
908       .subdesc = subdesc_idx,
909       .binding = binding,
910    };
911    uint32_t *entry = _mesa_hash_table_u64_search(ctx->ht, src.ht_key);
912    uint32_t old_desc_count = (uintptr_t)entry;
913    uint32_t new_desc_count =
914       max_idx == UINT32_MAX ? binding_layout->desc_count : max_idx + 1;
915 
916    assert(new_desc_count <= binding_layout->desc_count);
917 
918    if (old_desc_count >= new_desc_count)
919       return;
920 
921    _mesa_hash_table_u64_insert(ctx->ht, src.ht_key,
922                                (void *)(uintptr_t)new_desc_count);
923 
924    uint32_t desc_count_diff = new_desc_count - old_desc_count;
925 
926 #if PAN_ARCH <= 7
927    if (binding_layout->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
928       ctx->desc_info.dyn_ubos.count += desc_count_diff;
929    } else if (binding_layout->type ==
930               VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
931       ctx->desc_info.dyn_ssbos.count += desc_count_diff;
932    } else {
933       uint32_t table =
934          desc_type_to_table_type(binding_layout->type, subdesc_idx);
935 
936       assert(table < PANVK_BIFROST_DESC_TABLE_COUNT);
937       ctx->desc_info.others[table].count += desc_count_diff;
938    }
939 #else
940    ctx->desc_info.dyn_bufs.count += desc_count_diff;
941 #endif
942 }
943 
944 static uint32_t *
fill_copy_descs_for_binding(struct lower_desc_ctx * ctx,unsigned set,unsigned binding,uint32_t subdesc_idx,uint32_t desc_count)945 fill_copy_descs_for_binding(struct lower_desc_ctx *ctx, unsigned set,
946                             unsigned binding, uint32_t subdesc_idx,
947                             uint32_t desc_count)
948 {
949    assert(desc_count);
950 
951    const struct panvk_descriptor_set_layout *set_layout = ctx->set_layouts[set];
952    const struct panvk_descriptor_set_binding_layout *binding_layout =
953       &set_layout->bindings[binding];
954    uint32_t desc_stride = panvk_get_desc_stride(binding_layout->type);
955    uint32_t *first_entry = NULL;
956 
957    assert(desc_count <= binding_layout->desc_count);
958 
959    for (uint32_t i = 0; i < desc_count; i++) {
960       uint32_t src_idx =
961          binding_layout->desc_idx + (i * desc_stride) + subdesc_idx;
962       struct panvk_shader_desc_map *map;
963 
964 #if PAN_ARCH <= 7
965       if (binding_layout->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
966          map = &ctx->desc_info.dyn_ubos;
967       } else if (binding_layout->type ==
968                  VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
969          map = &ctx->desc_info.dyn_ssbos;
970       } else {
971          uint32_t dst_table =
972             desc_type_to_table_type(binding_layout->type, subdesc_idx);
973 
974          assert(dst_table < PANVK_BIFROST_DESC_TABLE_COUNT);
975          map = &ctx->desc_info.others[dst_table];
976       }
977 #else
978       map = &ctx->desc_info.dyn_bufs;
979 #endif
980 
981       if (!first_entry)
982          first_entry = &map->map[map->count];
983 
984       map->map[map->count++] = COPY_DESC_HANDLE(set, src_idx);
985    }
986 
987    return first_entry;
988 }
989 
990 static void
create_copy_table(nir_shader * nir,struct lower_desc_ctx * ctx)991 create_copy_table(nir_shader *nir, struct lower_desc_ctx *ctx)
992 {
993    struct panvk_shader_desc_info *desc_info = &ctx->desc_info;
994    uint32_t copy_count;
995 
996 #if PAN_ARCH <= 7
997    copy_count = desc_info->dyn_ubos.count + desc_info->dyn_ssbos.count;
998    for (uint32_t i = 0; i < PANVK_BIFROST_DESC_TABLE_COUNT; i++)
999       copy_count += desc_info->others[i].count;
1000 #else
1001    uint32_t dummy_sampler_idx;
1002    switch (nir->info.stage) {
1003    case MESA_SHADER_VERTEX:
1004       /* Dummy sampler comes after the vertex attributes. */
1005       dummy_sampler_idx = 16;
1006       break;
1007    case MESA_SHADER_FRAGMENT:
1008       /* Dummy sampler comes after the varyings. */
1009       dummy_sampler_idx = desc_info->num_varying_attr_descs;
1010       break;
1011    case MESA_SHADER_COMPUTE:
1012       dummy_sampler_idx = 0;
1013       break;
1014    default:
1015       unreachable("unexpected stage");
1016    }
1017    desc_info->dummy_sampler_handle = pan_res_handle(0, dummy_sampler_idx);
1018 
1019    copy_count = desc_info->dyn_bufs.count + desc_info->dyn_bufs.count;
1020 #endif
1021 
1022    if (copy_count == 0)
1023       return;
1024 
1025 #if PAN_ARCH <= 7
1026    uint32_t *copy_table = rzalloc_array(ctx->ht, uint32_t, copy_count);
1027 
1028    assert(copy_table);
1029    desc_info->dyn_ubos.map = copy_table;
1030    copy_table += desc_info->dyn_ubos.count;
1031    desc_info->dyn_ubos.count = 0;
1032    desc_info->dyn_ssbos.map = copy_table;
1033    copy_table += desc_info->dyn_ssbos.count;
1034    desc_info->dyn_ssbos.count = 0;
1035 
1036    for (uint32_t i = 0; i < PANVK_BIFROST_DESC_TABLE_COUNT; i++) {
1037       desc_info->others[i].map = copy_table;
1038       copy_table += desc_info->others[i].count;
1039       desc_info->others[i].count = 0;
1040    }
1041 #else
1042    /* Dynamic buffers come after the dummy sampler. */
1043    desc_info->dyn_bufs_start = dummy_sampler_idx + 1;
1044 
1045    desc_info->dyn_bufs.map = rzalloc_array(ctx->ht, uint32_t, copy_count);
1046    assert(desc_info->dyn_bufs.map);
1047 #endif
1048 
1049    hash_table_u64_foreach(ctx->ht, he) {
1050       /* We use the upper binding bit to encode the subdesc index. */
1051       uint32_t desc_count = (uintptr_t)he.data;
1052       struct desc_id src = {
1053          .ht_key = he.key,
1054       };
1055 
1056       /* Until now, we were just using the hash table to track descriptors
1057        * count, but after that point, it's a <set,binding> -> <table_index>
1058        * map. */
1059       void *new_data = fill_copy_descs_for_binding(ctx, src.set, src.binding,
1060                                                    src.subdesc, desc_count);
1061       _mesa_hash_table_u64_replace(ctx->ht, &he, new_data);
1062    }
1063 }
1064 
1065 /* TODO: Texture instructions support bindless through DTSEL_IMM(63),
1066  * which would save us copies of the texture/sampler descriptors. */
1067 static bool
collect_tex_desc_access(nir_builder * b,nir_tex_instr * tex,struct lower_desc_ctx * ctx)1068 collect_tex_desc_access(nir_builder *b, nir_tex_instr *tex,
1069                         struct lower_desc_ctx *ctx)
1070 {
1071    bool recorded = false;
1072    int sampler_src_idx =
1073       nir_tex_instr_src_index(tex, nir_tex_src_sampler_deref);
1074    if (sampler_src_idx >= 0) {
1075       nir_deref_instr *deref = nir_src_as_deref(tex->src[sampler_src_idx].src);
1076 
1077       uint32_t set, binding, index_imm, max_idx;
1078       nir_def *index_ssa;
1079       get_resource_deref_binding(deref, &set, &binding, &index_imm, &index_ssa,
1080                                  &max_idx);
1081 
1082       record_binding(ctx, set, binding, VK_DESCRIPTOR_TYPE_SAMPLER, max_idx);
1083       recorded = true;
1084    }
1085 
1086    int tex_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_texture_deref);
1087    if (tex_src_idx >= 0) {
1088       nir_deref_instr *deref = nir_src_as_deref(tex->src[tex_src_idx].src);
1089 
1090       uint32_t set, binding, index_imm, max_idx;
1091       nir_def *index_ssa;
1092       get_resource_deref_binding(deref, &set, &binding, &index_imm, &index_ssa,
1093                                  &max_idx);
1094 
1095       record_binding(ctx, set, binding, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
1096                      max_idx);
1097       recorded = true;
1098    }
1099 
1100    return recorded;
1101 }
1102 
1103 static bool
collect_intr_desc_access(nir_builder * b,nir_intrinsic_instr * intrin,struct lower_desc_ctx * ctx)1104 collect_intr_desc_access(nir_builder *b, nir_intrinsic_instr *intrin,
1105                          struct lower_desc_ctx *ctx)
1106 {
1107    switch (intrin->intrinsic) {
1108    case nir_intrinsic_vulkan_resource_index: {
1109       unsigned set, binding;
1110 
1111       set = nir_intrinsic_desc_set(intrin);
1112       binding = nir_intrinsic_binding(intrin);
1113 
1114       /* TODO: walk the reindex chain from load_vulkan_descriptor() to try and
1115        * guess the max index. */
1116       record_binding(ctx, set, binding, ~0, UINT32_MAX);
1117       return true;
1118    }
1119 
1120    case nir_intrinsic_image_deref_store:
1121    case nir_intrinsic_image_deref_load:
1122    case nir_intrinsic_image_deref_atomic:
1123    case nir_intrinsic_image_deref_atomic_swap:
1124    case nir_intrinsic_image_deref_size:
1125    case nir_intrinsic_image_deref_samples: {
1126       nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
1127       unsigned set, binding, index_imm, max_idx;
1128       nir_def *index_ssa;
1129 
1130       get_resource_deref_binding(deref, &set, &binding, &index_imm, &index_ssa,
1131                                  &max_idx);
1132       record_binding(ctx, set, binding, ~0, max_idx);
1133       return true;
1134    }
1135    default:
1136       return false;
1137    }
1138 }
1139 
1140 static bool
collect_instr_desc_access(nir_builder * b,nir_instr * instr,void * data)1141 collect_instr_desc_access(nir_builder *b, nir_instr *instr, void *data)
1142 {
1143    struct lower_desc_ctx *ctx = data;
1144 
1145    switch (instr->type) {
1146    case nir_instr_type_tex:
1147       return collect_tex_desc_access(b, nir_instr_as_tex(instr), ctx);
1148    case nir_instr_type_intrinsic:
1149       return collect_intr_desc_access(b, nir_instr_as_intrinsic(instr), ctx);
1150    default:
1151       return false;
1152    }
1153 }
1154 
1155 static void
upload_shader_desc_info(struct panvk_device * dev,struct panvk_shader * shader,const struct panvk_shader_desc_info * desc_info)1156 upload_shader_desc_info(struct panvk_device *dev, struct panvk_shader *shader,
1157                         const struct panvk_shader_desc_info *desc_info)
1158 {
1159 #if PAN_ARCH <= 7
1160    unsigned copy_count = 0;
1161    for (unsigned i = 0; i < ARRAY_SIZE(shader->desc_info.others.count); i++) {
1162       shader->desc_info.others.count[i] = desc_info->others[i].count;
1163       copy_count += desc_info->others[i].count;
1164    }
1165 
1166    if (copy_count > 0) {
1167       shader->desc_info.others.map = panvk_pool_upload_aligned(
1168          &dev->mempools.rw, desc_info->others[0].map,
1169          copy_count * sizeof(uint32_t), sizeof(uint32_t));
1170    }
1171 
1172    assert(desc_info->dyn_ubos.count <=
1173           ARRAY_SIZE(shader->desc_info.dyn_ubos.map));
1174    shader->desc_info.dyn_ubos.count = desc_info->dyn_ubos.count;
1175    memcpy(shader->desc_info.dyn_ubos.map, desc_info->dyn_ubos.map,
1176           desc_info->dyn_ubos.count * sizeof(*shader->desc_info.dyn_ubos.map));
1177    assert(desc_info->dyn_ssbos.count <=
1178           ARRAY_SIZE(shader->desc_info.dyn_ssbos.map));
1179    shader->desc_info.dyn_ssbos.count = desc_info->dyn_ssbos.count;
1180    memcpy(
1181       shader->desc_info.dyn_ssbos.map, desc_info->dyn_ssbos.map,
1182       desc_info->dyn_ssbos.count * sizeof(*shader->desc_info.dyn_ssbos.map));
1183 #else
1184    assert(desc_info->dyn_bufs.count <=
1185           ARRAY_SIZE(shader->desc_info.dyn_bufs.map));
1186    shader->desc_info.dyn_bufs.count = desc_info->dyn_bufs.count;
1187    memcpy(shader->desc_info.dyn_bufs.map, desc_info->dyn_bufs.map,
1188           desc_info->dyn_bufs.count * sizeof(*shader->desc_info.dyn_bufs.map));
1189 #endif
1190 
1191    shader->desc_info.used_set_mask = desc_info->used_set_mask;
1192 }
1193 
1194 void
panvk_per_arch(nir_lower_descriptors)1195 panvk_per_arch(nir_lower_descriptors)(
1196    nir_shader *nir, struct panvk_device *dev,
1197    const struct vk_pipeline_robustness_state *rs, uint32_t set_layout_count,
1198    struct vk_descriptor_set_layout *const *set_layouts,
1199    struct panvk_shader *shader)
1200 {
1201    struct lower_desc_ctx ctx = {
1202       .add_bounds_checks =
1203          rs->storage_buffers !=
1204             VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT ||
1205          rs->uniform_buffers !=
1206             VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT ||
1207          rs->images != VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED_EXT,
1208    };
1209    bool progress = false;
1210 
1211 #if PAN_ARCH <= 7
1212    ctx.ubo_addr_format = nir_address_format_32bit_index_offset;
1213    ctx.ssbo_addr_format =
1214       rs->storage_buffers != VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT
1215          ? nir_address_format_64bit_bounded_global
1216          : nir_address_format_64bit_global_32bit_offset;
1217 #else
1218    ctx.ubo_addr_format = nir_address_format_vec2_index_32bit_offset;
1219    ctx.ssbo_addr_format = nir_address_format_vec2_index_32bit_offset;
1220 #endif
1221 
1222    ctx.ht = _mesa_hash_table_u64_create(NULL);
1223    assert(ctx.ht);
1224 
1225    for (uint32_t i = 0; i < set_layout_count; i++)
1226       ctx.set_layouts[i] = to_panvk_descriptor_set_layout(set_layouts[i]);
1227 
1228    NIR_PASS(progress, nir, nir_shader_instructions_pass,
1229             collect_instr_desc_access, nir_metadata_all, &ctx);
1230    if (!progress)
1231       goto out;
1232 
1233 #if PAN_ARCH >= 9
1234    ctx.desc_info.num_varying_attr_descs = 0;
1235    /* We require Attribute Descriptors if we cannot use LD_VAR_BUF[_IMM] for
1236     * varyings. */
1237    if (shader->info.stage == MESA_SHADER_FRAGMENT &&
1238        !panvk_use_ld_var_buf(shader))
1239       ctx.desc_info.num_varying_attr_descs =
1240          shader->desc_info.max_varying_loads;
1241 #endif
1242    create_copy_table(nir, &ctx);
1243    upload_shader_desc_info(dev, shader, &ctx.desc_info);
1244 
1245    NIR_PASS(progress, nir, nir_shader_instructions_pass,
1246             lower_descriptors_instr, nir_metadata_control_flow, &ctx);
1247 
1248 out:
1249    _mesa_hash_table_u64_destroy(ctx.ht);
1250 }
1251