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