xref: /aosp_15_r20/external/mesa3d/src/compiler/nir/nir_gather_info.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2015 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "nir.h"
25 #include "nir_deref.h"
26 
27 #include "util/set.h"
28 
29 static bool
src_is_invocation_id(const nir_src * src)30 src_is_invocation_id(const nir_src *src)
31 {
32    nir_scalar s = nir_scalar_resolved(src->ssa, 0);
33    return nir_scalar_is_intrinsic(s) &&
34           nir_scalar_intrinsic_op(s) == nir_intrinsic_load_invocation_id;
35 }
36 
37 static bool
src_is_local_invocation_index(nir_shader * shader,const nir_src * src)38 src_is_local_invocation_index(nir_shader *shader, const nir_src *src)
39 {
40    assert(shader->info.stage == MESA_SHADER_MESH && !shader->info.workgroup_size_variable);
41 
42    nir_scalar s = nir_scalar_resolved(src->ssa, 0);
43    if (!nir_scalar_is_intrinsic(s))
44       return false;
45 
46    const nir_intrinsic_op op = nir_scalar_intrinsic_op(s);
47    if (op == nir_intrinsic_load_local_invocation_index)
48       return true;
49    if (op != nir_intrinsic_load_local_invocation_id)
50       return false;
51 
52    unsigned nz_ids = 0;
53    for (unsigned i = 0; i < 3; i++)
54       nz_ids |= (shader->info.workgroup_size[i] > 1) ? (1u << i) : 0;
55 
56    return nz_ids == 0 || (util_bitcount(nz_ids) == 1 && s.comp == ffs(nz_ids) - 1);
57 }
58 
59 static void
get_deref_info(nir_shader * shader,nir_variable * var,nir_deref_instr * deref,bool * cross_invocation,bool * indirect)60 get_deref_info(nir_shader *shader, nir_variable *var, nir_deref_instr *deref,
61                bool *cross_invocation, bool *indirect)
62 {
63    *cross_invocation = false;
64    *indirect = false;
65 
66    const bool is_arrayed = nir_is_arrayed_io(var, shader->info.stage);
67 
68    nir_deref_path path;
69    nir_deref_path_init(&path, deref, NULL);
70    assert(path.path[0]->deref_type == nir_deref_type_var);
71    nir_deref_instr **p = &path.path[1];
72 
73    /* Vertex index is the outermost array index. */
74    if (is_arrayed) {
75       assert((*p)->deref_type == nir_deref_type_array);
76       if (shader->info.stage == MESA_SHADER_TESS_CTRL)
77          *cross_invocation = !src_is_invocation_id(&(*p)->arr.index);
78       else if (shader->info.stage == MESA_SHADER_MESH)
79          *cross_invocation = !src_is_local_invocation_index(shader, &(*p)->arr.index);
80       p++;
81    }
82 
83    /* We always lower indirect dereferences for "compact" array vars. */
84    if (!path.path[0]->var->data.compact) {
85       /* Non-compact array vars: find out if they are indirect. */
86       for (; *p; p++) {
87          if ((*p)->deref_type == nir_deref_type_array) {
88             *indirect |= !nir_src_is_const((*p)->arr.index);
89          } else if ((*p)->deref_type == nir_deref_type_struct) {
90             /* Struct indices are always constant. */
91          }  else if ((*p)->deref_type == nir_deref_type_array_wildcard) {
92             /* Wilcards ref the whole array dimension and should get lowered
93              * to direct deref at a later point.
94              */
95          } else {
96             unreachable("Unsupported deref type");
97          }
98       }
99    }
100 
101    nir_deref_path_finish(&path);
102 }
103 
104 static void
set_io_mask(nir_shader * shader,nir_variable * var,int offset,int len,nir_deref_instr * deref,bool is_output_read)105 set_io_mask(nir_shader *shader, nir_variable *var, int offset, int len,
106             nir_deref_instr *deref, bool is_output_read)
107 {
108    for (int i = 0; i < len; i++) {
109       /* Varyings might not have been assigned values yet so abort. */
110       if (var->data.location == -1)
111          return;
112 
113       int idx = var->data.location + offset + i;
114       bool is_patch_generic = var->data.patch &&
115                               idx != VARYING_SLOT_TESS_LEVEL_INNER &&
116                               idx != VARYING_SLOT_TESS_LEVEL_OUTER &&
117                               idx != VARYING_SLOT_BOUNDING_BOX0 &&
118                               idx != VARYING_SLOT_BOUNDING_BOX1;
119       uint64_t bitfield;
120 
121       if (is_patch_generic) {
122          /* Varyings might still have temp locations so abort */
123          if (idx < VARYING_SLOT_PATCH0 || idx >= VARYING_SLOT_TESS_MAX)
124             return;
125 
126          bitfield = BITFIELD64_BIT(idx - VARYING_SLOT_PATCH0);
127       } else {
128          /* Varyings might still have temp locations so abort */
129          if (idx >= VARYING_SLOT_MAX)
130             return;
131 
132          bitfield = BITFIELD64_BIT(idx);
133       }
134 
135       bool cross_invocation;
136       bool indirect;
137       get_deref_info(shader, var, deref, &cross_invocation, &indirect);
138 
139       if (var->data.mode == nir_var_shader_in) {
140          if (is_patch_generic) {
141             shader->info.patch_inputs_read |= bitfield;
142             if (indirect)
143                shader->info.patch_inputs_read_indirectly |= bitfield;
144          } else {
145             shader->info.inputs_read |= bitfield;
146             if (indirect)
147                shader->info.inputs_read_indirectly |= bitfield;
148          }
149 
150          if (cross_invocation && shader->info.stage == MESA_SHADER_TESS_CTRL)
151             shader->info.tess.tcs_cross_invocation_inputs_read |= bitfield;
152 
153          if (shader->info.stage == MESA_SHADER_FRAGMENT) {
154             shader->info.fs.uses_sample_qualifier |= var->data.sample;
155          }
156       } else {
157          assert(var->data.mode == nir_var_shader_out);
158          if (is_output_read) {
159             if (is_patch_generic) {
160                shader->info.patch_outputs_read |= bitfield;
161                if (indirect)
162                   shader->info.patch_outputs_accessed_indirectly |= bitfield;
163             } else {
164                shader->info.outputs_read |= bitfield;
165                if (indirect)
166                   shader->info.outputs_accessed_indirectly |= bitfield;
167             }
168 
169             if (cross_invocation && shader->info.stage == MESA_SHADER_TESS_CTRL)
170                shader->info.tess.tcs_cross_invocation_outputs_read |= bitfield;
171          } else {
172             if (is_patch_generic) {
173                shader->info.patch_outputs_written |= bitfield;
174                if (indirect)
175                   shader->info.patch_outputs_accessed_indirectly |= bitfield;
176             } else if (!var->data.read_only) {
177                shader->info.outputs_written |= bitfield;
178                if (indirect)
179                   shader->info.outputs_accessed_indirectly |= bitfield;
180             }
181          }
182 
183          if (cross_invocation && shader->info.stage == MESA_SHADER_MESH)
184             shader->info.mesh.ms_cross_invocation_output_access |= bitfield;
185 
186          if (var->data.fb_fetch_output) {
187             shader->info.outputs_read |= bitfield;
188             if (shader->info.stage == MESA_SHADER_FRAGMENT) {
189                shader->info.fs.uses_fbfetch_output = true;
190                shader->info.fs.fbfetch_coherent = var->data.access & ACCESS_COHERENT;
191             }
192          }
193 
194          if (shader->info.stage == MESA_SHADER_FRAGMENT &&
195              !is_output_read && var->data.index == 1)
196             shader->info.fs.color_is_dual_source = true;
197       }
198    }
199 }
200 
201 /**
202  * Mark an entire variable as used.  Caller must ensure that the variable
203  * represents a shader input or output.
204  */
205 static void
mark_whole_variable(nir_shader * shader,nir_variable * var,nir_deref_instr * deref,bool is_output_read)206 mark_whole_variable(nir_shader *shader, nir_variable *var,
207                     nir_deref_instr *deref, bool is_output_read)
208 {
209    const struct glsl_type *type = var->type;
210 
211    if (nir_is_arrayed_io(var, shader->info.stage) ||
212        /* For NV_mesh_shader. */
213        (shader->info.stage == MESA_SHADER_MESH &&
214         var->data.location == VARYING_SLOT_PRIMITIVE_INDICES &&
215         !var->data.per_primitive)) {
216       assert(glsl_type_is_array(type));
217       type = glsl_get_array_element(type);
218    }
219 
220    if (var->data.per_view) {
221       assert(glsl_type_is_array(type));
222       type = glsl_get_array_element(type);
223    }
224 
225    const unsigned slots = nir_variable_count_slots(var, type);
226    set_io_mask(shader, var, 0, slots, deref, is_output_read);
227 }
228 
229 static unsigned
get_io_offset(nir_deref_instr * deref,nir_variable * var,bool is_arrayed,bool skip_non_arrayed)230 get_io_offset(nir_deref_instr *deref, nir_variable *var, bool is_arrayed,
231               bool skip_non_arrayed)
232 {
233    if (var->data.compact) {
234       if (deref->deref_type == nir_deref_type_var) {
235          assert(glsl_type_is_array(var->type));
236          return 0;
237       }
238       assert(deref->deref_type == nir_deref_type_array);
239       return nir_src_is_const(deref->arr.index) ? (nir_src_as_uint(deref->arr.index) + var->data.location_frac) / 4u : (unsigned)-1;
240    }
241 
242    unsigned offset = 0;
243 
244    for (nir_deref_instr *d = deref; d; d = nir_deref_instr_parent(d)) {
245       if (d->deref_type == nir_deref_type_array) {
246          if (is_arrayed && nir_deref_instr_parent(d)->deref_type == nir_deref_type_var)
247             break;
248 
249          if (!is_arrayed && skip_non_arrayed)
250             break;
251 
252          if (!nir_src_is_const(d->arr.index))
253             return -1;
254 
255          offset += glsl_count_attribute_slots(d->type, false) *
256                    nir_src_as_uint(d->arr.index);
257       } else if (d->deref_type == nir_deref_type_struct) {
258          const struct glsl_type *parent_type = nir_deref_instr_parent(d)->type;
259          for (unsigned i = 0; i < d->strct.index; i++) {
260             const struct glsl_type *field_type = glsl_get_struct_field(parent_type, i);
261             offset += glsl_count_attribute_slots(field_type, false);
262          }
263       }
264    }
265 
266    return offset;
267 }
268 
269 /**
270  * Try to mark a portion of the given varying as used.  Caller must ensure
271  * that the variable represents a shader input or output.
272  *
273  * If the index can't be interpreted as a constant, or some other problem
274  * occurs, then nothing will be marked and false will be returned.
275  */
276 static bool
try_mask_partial_io(nir_shader * shader,nir_variable * var,nir_deref_instr * deref,bool is_output_read)277 try_mask_partial_io(nir_shader *shader, nir_variable *var,
278                     nir_deref_instr *deref, bool is_output_read)
279 {
280    const struct glsl_type *type = var->type;
281    bool is_arrayed = nir_is_arrayed_io(var, shader->info.stage);
282    bool skip_non_arrayed = shader->info.stage == MESA_SHADER_MESH;
283 
284    if (is_arrayed) {
285       assert(glsl_type_is_array(type));
286       type = glsl_get_array_element(type);
287    }
288 
289    /* Per view variables will be considered as a whole. */
290    if (var->data.per_view)
291       return false;
292 
293    unsigned offset = get_io_offset(deref, var, is_arrayed, skip_non_arrayed);
294    if (offset == -1)
295       return false;
296 
297    const unsigned slots = nir_variable_count_slots(var, type);
298    if (offset >= slots) {
299       /* Constant index outside the bounds of the matrix/array.  This could
300        * arise as a result of constant folding of a legal GLSL program.
301        *
302        * Even though the spec says that indexing outside the bounds of a
303        * matrix/array results in undefined behaviour, we don't want to pass
304        * out-of-range values to set_io_mask() (since this could result in
305        * slots that don't exist being marked as used), so just let the caller
306        * mark the whole variable as used.
307        */
308       return false;
309    }
310 
311    unsigned len = nir_deref_count_slots(deref, var);
312    set_io_mask(shader, var, offset, len, deref, is_output_read);
313    return true;
314 }
315 
316 /** Returns true if the given intrinsic writes external memory
317  *
318  * Only returns true for writes to globally visible memory, not scratch and
319  * not shared.
320  */
321 bool
nir_intrinsic_writes_external_memory(const nir_intrinsic_instr * instr)322 nir_intrinsic_writes_external_memory(const nir_intrinsic_instr *instr)
323 {
324    switch (instr->intrinsic) {
325    case nir_intrinsic_atomic_counter_inc:
326    case nir_intrinsic_atomic_counter_inc_deref:
327    case nir_intrinsic_atomic_counter_add:
328    case nir_intrinsic_atomic_counter_add_deref:
329    case nir_intrinsic_atomic_counter_pre_dec:
330    case nir_intrinsic_atomic_counter_pre_dec_deref:
331    case nir_intrinsic_atomic_counter_post_dec:
332    case nir_intrinsic_atomic_counter_post_dec_deref:
333    case nir_intrinsic_atomic_counter_min:
334    case nir_intrinsic_atomic_counter_min_deref:
335    case nir_intrinsic_atomic_counter_max:
336    case nir_intrinsic_atomic_counter_max_deref:
337    case nir_intrinsic_atomic_counter_and:
338    case nir_intrinsic_atomic_counter_and_deref:
339    case nir_intrinsic_atomic_counter_or:
340    case nir_intrinsic_atomic_counter_or_deref:
341    case nir_intrinsic_atomic_counter_xor:
342    case nir_intrinsic_atomic_counter_xor_deref:
343    case nir_intrinsic_atomic_counter_exchange:
344    case nir_intrinsic_atomic_counter_exchange_deref:
345    case nir_intrinsic_atomic_counter_comp_swap:
346    case nir_intrinsic_atomic_counter_comp_swap_deref:
347    case nir_intrinsic_bindless_image_atomic:
348    case nir_intrinsic_bindless_image_atomic_swap:
349    case nir_intrinsic_bindless_image_store:
350    case nir_intrinsic_bindless_image_store_raw_intel:
351    case nir_intrinsic_global_atomic:
352    case nir_intrinsic_global_atomic_swap:
353    case nir_intrinsic_global_atomic_ir3:
354    case nir_intrinsic_global_atomic_swap_ir3:
355    case nir_intrinsic_image_atomic:
356    case nir_intrinsic_image_atomic_swap:
357    case nir_intrinsic_image_deref_atomic:
358    case nir_intrinsic_image_deref_atomic_swap:
359    case nir_intrinsic_image_deref_store:
360    case nir_intrinsic_image_deref_store_raw_intel:
361    case nir_intrinsic_image_store:
362    case nir_intrinsic_image_store_raw_intel:
363    case nir_intrinsic_ssbo_atomic:
364    case nir_intrinsic_ssbo_atomic_swap:
365    case nir_intrinsic_ssbo_atomic_ir3:
366    case nir_intrinsic_ssbo_atomic_swap_ir3:
367    case nir_intrinsic_store_global:
368    case nir_intrinsic_store_global_etna:
369    case nir_intrinsic_store_global_ir3:
370    case nir_intrinsic_store_global_amd:
371    case nir_intrinsic_store_ssbo:
372    case nir_intrinsic_store_ssbo_ir3:
373       return true;
374 
375    case nir_intrinsic_store_deref:
376    case nir_intrinsic_deref_atomic:
377    case nir_intrinsic_deref_atomic_swap:
378       return nir_deref_mode_may_be(nir_src_as_deref(instr->src[0]),
379                                    nir_var_mem_ssbo | nir_var_mem_global);
380 
381    default:
382       return false;
383    }
384 }
385 
386 static bool
intrinsic_is_bindless(nir_intrinsic_instr * instr)387 intrinsic_is_bindless(nir_intrinsic_instr *instr)
388 {
389    switch (instr->intrinsic) {
390    case nir_intrinsic_bindless_image_atomic:
391    case nir_intrinsic_bindless_image_atomic_swap:
392    case nir_intrinsic_bindless_image_descriptor_amd:
393    case nir_intrinsic_bindless_image_format:
394    case nir_intrinsic_bindless_image_load:
395    case nir_intrinsic_bindless_image_load_raw_intel:
396    case nir_intrinsic_bindless_image_order:
397    case nir_intrinsic_bindless_image_samples:
398    case nir_intrinsic_bindless_image_samples_identical:
399    case nir_intrinsic_bindless_image_size:
400    case nir_intrinsic_bindless_image_sparse_load:
401    case nir_intrinsic_bindless_image_store:
402    case nir_intrinsic_bindless_image_store_raw_intel:
403    case nir_intrinsic_bindless_resource_ir3:
404       return true;
405    default:
406       break;
407    }
408    return false;
409 }
410 
411 static void
gather_intrinsic_info(nir_intrinsic_instr * instr,nir_shader * shader,void * dead_ctx)412 gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader,
413                       void *dead_ctx)
414 {
415    uint64_t slot_mask = 0;
416    uint16_t slot_mask_16bit = 0;
417    bool is_patch_special = false;
418 
419    if (nir_intrinsic_infos[instr->intrinsic].index_map[NIR_INTRINSIC_IO_SEMANTICS] > 0) {
420       nir_io_semantics semantics = nir_intrinsic_io_semantics(instr);
421 
422       is_patch_special = semantics.location == VARYING_SLOT_TESS_LEVEL_INNER ||
423                          semantics.location == VARYING_SLOT_TESS_LEVEL_OUTER ||
424                          semantics.location == VARYING_SLOT_BOUNDING_BOX0 ||
425                          semantics.location == VARYING_SLOT_BOUNDING_BOX1;
426 
427       if (semantics.location >= VARYING_SLOT_PATCH0 &&
428           semantics.location <= VARYING_SLOT_PATCH31) {
429          /* Generic per-patch I/O. */
430          assert((shader->info.stage == MESA_SHADER_TESS_EVAL &&
431                  instr->intrinsic == nir_intrinsic_load_input) ||
432                 (shader->info.stage == MESA_SHADER_TESS_CTRL &&
433                  (instr->intrinsic == nir_intrinsic_load_output ||
434                   instr->intrinsic == nir_intrinsic_store_output)));
435 
436          semantics.location -= VARYING_SLOT_PATCH0;
437       }
438 
439       if (semantics.location >= VARYING_SLOT_VAR0_16BIT &&
440           semantics.location <= VARYING_SLOT_VAR15_16BIT) {
441          /* Convert num_slots from the units of half vectors to full vectors. */
442          unsigned num_slots = (semantics.num_slots + semantics.high_16bits + 1) / 2;
443          slot_mask_16bit =
444             BITFIELD_RANGE(semantics.location - VARYING_SLOT_VAR0_16BIT, num_slots);
445       } else {
446          unsigned num_slots = semantics.num_slots;
447          if (shader->options->compact_arrays &&
448              (instr->intrinsic != nir_intrinsic_load_input || shader->info.stage != MESA_SHADER_VERTEX)) {
449             /* clamp num_slots for compact arrays */
450             switch (semantics.location) {
451             case VARYING_SLOT_CLIP_DIST0:
452             case VARYING_SLOT_CLIP_DIST1:
453             case VARYING_SLOT_CULL_DIST0:
454             case VARYING_SLOT_CULL_DIST1:
455             case VARYING_SLOT_TESS_LEVEL_INNER:
456             case VARYING_SLOT_TESS_LEVEL_OUTER:
457                num_slots = DIV_ROUND_UP(num_slots, 4);
458                break;
459             default: break;
460             }
461          }
462          slot_mask = BITFIELD64_RANGE(semantics.location, num_slots);
463          assert(util_bitcount64(slot_mask) == num_slots);
464       }
465    }
466 
467    switch (instr->intrinsic) {
468    case nir_intrinsic_demote:
469    case nir_intrinsic_demote_if:
470    case nir_intrinsic_terminate:
471    case nir_intrinsic_terminate_if:
472       /* Freedreno uses discard_if() to end GS invocations that don't produce
473        * a vertex and RADV uses terminate() to end ray-tracing shaders,
474        * so only set uses_discard for fragment shaders.
475        */
476       if (shader->info.stage == MESA_SHADER_FRAGMENT)
477          shader->info.fs.uses_discard = true;
478       break;
479 
480    case nir_intrinsic_interp_deref_at_centroid:
481    case nir_intrinsic_interp_deref_at_sample:
482    case nir_intrinsic_interp_deref_at_offset:
483    case nir_intrinsic_interp_deref_at_vertex:
484    case nir_intrinsic_load_deref:
485    case nir_intrinsic_store_deref:
486    case nir_intrinsic_copy_deref: {
487       nir_deref_instr *deref = nir_src_as_deref(instr->src[0]);
488       if (nir_deref_mode_is_one_of(deref, nir_var_shader_in |
489                                              nir_var_shader_out)) {
490          nir_variable *var = nir_deref_instr_get_variable(deref);
491          bool is_output_read = false;
492          if (var->data.mode == nir_var_shader_out &&
493              instr->intrinsic == nir_intrinsic_load_deref)
494             is_output_read = true;
495 
496          if (!try_mask_partial_io(shader, var, deref, is_output_read))
497             mark_whole_variable(shader, var, deref, is_output_read);
498 
499          /* We need to track which input_reads bits correspond to a
500           * dvec3/dvec4 input attribute */
501          if (shader->info.stage == MESA_SHADER_VERTEX &&
502              var->data.mode == nir_var_shader_in &&
503              glsl_type_is_dual_slot(glsl_without_array(var->type))) {
504             for (unsigned i = 0; i < glsl_count_attribute_slots(var->type, false); i++) {
505                int idx = var->data.location + i;
506                shader->info.vs.double_inputs |= BITFIELD64_BIT(idx);
507             }
508          }
509       }
510       if (nir_intrinsic_writes_external_memory(instr))
511          shader->info.writes_memory = true;
512       break;
513    }
514    case nir_intrinsic_image_deref_load:
515    case nir_intrinsic_image_deref_sparse_load: {
516       nir_deref_instr *deref = nir_src_as_deref(instr->src[0]);
517       nir_variable *var = nir_deref_instr_get_variable(deref);
518       enum glsl_sampler_dim dim = glsl_get_sampler_dim(glsl_without_array(var->type));
519       if (dim != GLSL_SAMPLER_DIM_SUBPASS &&
520           dim != GLSL_SAMPLER_DIM_SUBPASS_MS)
521          break;
522 
523       var->data.fb_fetch_output = true;
524       shader->info.fs.uses_fbfetch_output = true;
525       break;
526    }
527 
528    case nir_intrinsic_bindless_image_load:
529    case nir_intrinsic_bindless_image_sparse_load: {
530       enum glsl_sampler_dim dim = nir_intrinsic_image_dim(instr);
531       if (dim != GLSL_SAMPLER_DIM_SUBPASS &&
532           dim != GLSL_SAMPLER_DIM_SUBPASS_MS)
533          break;
534       shader->info.fs.uses_fbfetch_output = true;
535       break;
536    }
537 
538    case nir_intrinsic_load_input:
539    case nir_intrinsic_load_per_vertex_input:
540    case nir_intrinsic_load_input_vertex:
541    case nir_intrinsic_load_interpolated_input:
542    case nir_intrinsic_load_per_primitive_input:
543       if (shader->info.stage == MESA_SHADER_TESS_EVAL &&
544           instr->intrinsic == nir_intrinsic_load_input &&
545           !is_patch_special) {
546          shader->info.patch_inputs_read |= slot_mask;
547          if (!nir_src_is_const(*nir_get_io_offset_src(instr)))
548             shader->info.patch_inputs_read_indirectly |= slot_mask;
549       } else {
550          shader->info.inputs_read |= slot_mask;
551          if (nir_intrinsic_io_semantics(instr).high_dvec2)
552             shader->info.dual_slot_inputs |= slot_mask;
553          if (instr->intrinsic == nir_intrinsic_load_per_primitive_input)
554             shader->info.per_primitive_inputs |= slot_mask;
555          shader->info.inputs_read_16bit |= slot_mask_16bit;
556          if (!nir_src_is_const(*nir_get_io_offset_src(instr))) {
557             shader->info.inputs_read_indirectly |= slot_mask;
558             shader->info.inputs_read_indirectly_16bit |= slot_mask_16bit;
559          }
560       }
561 
562       if (shader->info.stage == MESA_SHADER_TESS_CTRL &&
563           instr->intrinsic == nir_intrinsic_load_per_vertex_input &&
564           !src_is_invocation_id(nir_get_io_arrayed_index_src(instr)))
565          shader->info.tess.tcs_cross_invocation_inputs_read |= slot_mask;
566       break;
567 
568    case nir_intrinsic_load_output:
569    case nir_intrinsic_load_per_vertex_output:
570    case nir_intrinsic_load_per_primitive_output:
571       if (shader->info.stage == MESA_SHADER_TESS_CTRL &&
572           instr->intrinsic == nir_intrinsic_load_output &&
573           !is_patch_special) {
574          shader->info.patch_outputs_read |= slot_mask;
575          if (!nir_src_is_const(*nir_get_io_offset_src(instr)))
576             shader->info.patch_outputs_accessed_indirectly |= slot_mask;
577       } else {
578          shader->info.outputs_read |= slot_mask;
579          shader->info.outputs_read_16bit |= slot_mask_16bit;
580          if (!nir_src_is_const(*nir_get_io_offset_src(instr))) {
581             shader->info.outputs_accessed_indirectly |= slot_mask;
582             shader->info.outputs_accessed_indirectly_16bit |= slot_mask_16bit;
583          }
584       }
585 
586       if (shader->info.stage == MESA_SHADER_TESS_CTRL &&
587           instr->intrinsic == nir_intrinsic_load_per_vertex_output &&
588           !src_is_invocation_id(nir_get_io_arrayed_index_src(instr)))
589          shader->info.tess.tcs_cross_invocation_outputs_read |= slot_mask;
590 
591       /* NV_mesh_shader: mesh shaders can load their outputs. */
592       if (shader->info.stage == MESA_SHADER_MESH &&
593           (instr->intrinsic == nir_intrinsic_load_per_vertex_output ||
594            instr->intrinsic == nir_intrinsic_load_per_primitive_output) &&
595           !src_is_local_invocation_index(shader, nir_get_io_arrayed_index_src(instr)))
596          shader->info.mesh.ms_cross_invocation_output_access |= slot_mask;
597 
598       if (shader->info.stage == MESA_SHADER_FRAGMENT &&
599           nir_intrinsic_io_semantics(instr).fb_fetch_output)
600          shader->info.fs.uses_fbfetch_output = true;
601       break;
602 
603    case nir_intrinsic_store_output:
604    case nir_intrinsic_store_per_vertex_output:
605    case nir_intrinsic_store_per_primitive_output:
606       if (shader->info.stage == MESA_SHADER_TESS_CTRL &&
607           instr->intrinsic == nir_intrinsic_store_output &&
608           !is_patch_special) {
609          shader->info.patch_outputs_written |= slot_mask;
610          if (!nir_src_is_const(*nir_get_io_offset_src(instr)))
611             shader->info.patch_outputs_accessed_indirectly |= slot_mask;
612       } else {
613          shader->info.outputs_written |= slot_mask;
614          shader->info.outputs_written_16bit |= slot_mask_16bit;
615          if (instr->intrinsic == nir_intrinsic_store_per_primitive_output)
616             shader->info.per_primitive_outputs |= slot_mask;
617          if (!nir_src_is_const(*nir_get_io_offset_src(instr))) {
618             shader->info.outputs_accessed_indirectly |= slot_mask;
619             shader->info.outputs_accessed_indirectly_16bit |= slot_mask_16bit;
620          }
621       }
622 
623       if (shader->info.stage == MESA_SHADER_MESH &&
624           (instr->intrinsic == nir_intrinsic_store_per_vertex_output ||
625            instr->intrinsic == nir_intrinsic_store_per_primitive_output) &&
626           !src_is_local_invocation_index(shader, nir_get_io_arrayed_index_src(instr)))
627          shader->info.mesh.ms_cross_invocation_output_access |= slot_mask;
628 
629       if (shader->info.stage == MESA_SHADER_FRAGMENT &&
630           nir_intrinsic_io_semantics(instr).dual_source_blend_index)
631          shader->info.fs.color_is_dual_source = true;
632       break;
633 
634    case nir_intrinsic_load_color0:
635    case nir_intrinsic_load_color1:
636       shader->info.inputs_read |=
637          BITFIELD64_BIT(VARYING_SLOT_COL0 << (instr->intrinsic == nir_intrinsic_load_color1));
638       FALLTHROUGH;
639    case nir_intrinsic_load_subgroup_size:
640    case nir_intrinsic_load_subgroup_invocation:
641    case nir_intrinsic_load_subgroup_eq_mask:
642    case nir_intrinsic_load_subgroup_ge_mask:
643    case nir_intrinsic_load_subgroup_gt_mask:
644    case nir_intrinsic_load_subgroup_le_mask:
645    case nir_intrinsic_load_subgroup_lt_mask:
646    case nir_intrinsic_load_num_subgroups:
647    case nir_intrinsic_load_subgroup_id:
648    case nir_intrinsic_load_vertex_id:
649    case nir_intrinsic_load_instance_id:
650    case nir_intrinsic_load_vertex_id_zero_base:
651    case nir_intrinsic_load_base_vertex:
652    case nir_intrinsic_load_first_vertex:
653    case nir_intrinsic_load_is_indexed_draw:
654    case nir_intrinsic_load_base_instance:
655    case nir_intrinsic_load_draw_id:
656    case nir_intrinsic_load_invocation_id:
657    case nir_intrinsic_load_frag_coord:
658    case nir_intrinsic_load_frag_shading_rate:
659    case nir_intrinsic_load_fully_covered:
660    case nir_intrinsic_load_point_coord:
661    case nir_intrinsic_load_line_coord:
662    case nir_intrinsic_load_front_face:
663    case nir_intrinsic_load_sample_id:
664    case nir_intrinsic_load_sample_pos:
665    case nir_intrinsic_load_sample_pos_or_center:
666    case nir_intrinsic_load_sample_mask_in:
667    case nir_intrinsic_load_helper_invocation:
668    case nir_intrinsic_load_tess_coord:
669    case nir_intrinsic_load_tess_coord_xy:
670    case nir_intrinsic_load_patch_vertices_in:
671    case nir_intrinsic_load_primitive_id:
672    case nir_intrinsic_load_tess_level_outer:
673    case nir_intrinsic_load_tess_level_inner:
674    case nir_intrinsic_load_tess_level_outer_default:
675    case nir_intrinsic_load_tess_level_inner_default:
676    case nir_intrinsic_load_local_invocation_id:
677    case nir_intrinsic_load_local_invocation_index:
678    case nir_intrinsic_load_global_invocation_id:
679    case nir_intrinsic_load_base_global_invocation_id:
680    case nir_intrinsic_load_global_invocation_index:
681    case nir_intrinsic_load_global_size:
682    case nir_intrinsic_load_workgroup_id:
683    case nir_intrinsic_load_base_workgroup_id:
684    case nir_intrinsic_load_workgroup_index:
685    case nir_intrinsic_load_num_workgroups:
686    case nir_intrinsic_load_workgroup_size:
687    case nir_intrinsic_load_work_dim:
688    case nir_intrinsic_load_user_data_amd:
689    case nir_intrinsic_load_view_index:
690    case nir_intrinsic_load_barycentric_model:
691    case nir_intrinsic_load_ray_launch_id:
692    case nir_intrinsic_load_ray_launch_size:
693    case nir_intrinsic_load_ray_world_origin:
694    case nir_intrinsic_load_ray_world_direction:
695    case nir_intrinsic_load_ray_object_origin:
696    case nir_intrinsic_load_ray_object_direction:
697    case nir_intrinsic_load_ray_t_min:
698    case nir_intrinsic_load_ray_t_max:
699    case nir_intrinsic_load_ray_object_to_world:
700    case nir_intrinsic_load_ray_world_to_object:
701    case nir_intrinsic_load_ray_hit_kind:
702    case nir_intrinsic_load_ray_flags:
703    case nir_intrinsic_load_ray_geometry_index:
704    case nir_intrinsic_load_ray_instance_custom_index:
705    case nir_intrinsic_load_mesh_view_count:
706    case nir_intrinsic_load_gs_header_ir3:
707    case nir_intrinsic_load_tcs_header_ir3:
708    case nir_intrinsic_load_ray_triangle_vertex_positions:
709    case nir_intrinsic_load_layer_id:
710       BITSET_SET(shader->info.system_values_read,
711                  nir_system_value_from_intrinsic(instr->intrinsic));
712       break;
713 
714    case nir_intrinsic_load_barycentric_pixel:
715       if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_SMOOTH ||
716           nir_intrinsic_interp_mode(instr) == INTERP_MODE_NONE) {
717          BITSET_SET(shader->info.system_values_read,
718                     SYSTEM_VALUE_BARYCENTRIC_PERSP_PIXEL);
719       } else if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_NOPERSPECTIVE) {
720          BITSET_SET(shader->info.system_values_read,
721                     SYSTEM_VALUE_BARYCENTRIC_LINEAR_PIXEL);
722       }
723       break;
724 
725    case nir_intrinsic_load_barycentric_centroid:
726       if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_SMOOTH ||
727           nir_intrinsic_interp_mode(instr) == INTERP_MODE_NONE) {
728          BITSET_SET(shader->info.system_values_read,
729                     SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID);
730       } else if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_NOPERSPECTIVE) {
731          BITSET_SET(shader->info.system_values_read,
732                     SYSTEM_VALUE_BARYCENTRIC_LINEAR_CENTROID);
733       }
734       break;
735 
736    case nir_intrinsic_load_barycentric_sample:
737       if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_SMOOTH ||
738           nir_intrinsic_interp_mode(instr) == INTERP_MODE_NONE) {
739          BITSET_SET(shader->info.system_values_read,
740                     SYSTEM_VALUE_BARYCENTRIC_PERSP_SAMPLE);
741       } else if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_NOPERSPECTIVE) {
742          BITSET_SET(shader->info.system_values_read,
743                     SYSTEM_VALUE_BARYCENTRIC_LINEAR_SAMPLE);
744       }
745       if (shader->info.stage == MESA_SHADER_FRAGMENT)
746          shader->info.fs.uses_sample_qualifier = true;
747       break;
748 
749    case nir_intrinsic_load_barycentric_coord_pixel:
750    case nir_intrinsic_load_barycentric_coord_centroid:
751    case nir_intrinsic_load_barycentric_coord_sample:
752    case nir_intrinsic_load_barycentric_coord_at_offset:
753    case nir_intrinsic_load_barycentric_coord_at_sample:
754       if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_SMOOTH ||
755           nir_intrinsic_interp_mode(instr) == INTERP_MODE_NONE) {
756          BITSET_SET(shader->info.system_values_read, SYSTEM_VALUE_BARYCENTRIC_PERSP_COORD);
757       } else if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_NOPERSPECTIVE) {
758          BITSET_SET(shader->info.system_values_read, SYSTEM_VALUE_BARYCENTRIC_LINEAR_COORD);
759       }
760       break;
761 
762    case nir_intrinsic_ddx:
763    case nir_intrinsic_ddx_fine:
764    case nir_intrinsic_ddx_coarse:
765    case nir_intrinsic_ddy:
766    case nir_intrinsic_ddy_fine:
767    case nir_intrinsic_ddy_coarse:
768       shader->info.uses_fddx_fddy = true;
769 
770       if (shader->info.stage == MESA_SHADER_FRAGMENT)
771          shader->info.fs.needs_quad_helper_invocations = true;
772       break;
773 
774    case nir_intrinsic_quad_vote_any:
775    case nir_intrinsic_quad_vote_all:
776    case nir_intrinsic_quad_broadcast:
777    case nir_intrinsic_quad_swap_horizontal:
778    case nir_intrinsic_quad_swap_vertical:
779    case nir_intrinsic_quad_swap_diagonal:
780    case nir_intrinsic_quad_swizzle_amd:
781       if (shader->info.stage == MESA_SHADER_FRAGMENT)
782          shader->info.fs.needs_quad_helper_invocations = true;
783       break;
784 
785    case nir_intrinsic_vote_any:
786    case nir_intrinsic_vote_all:
787    case nir_intrinsic_vote_feq:
788    case nir_intrinsic_vote_ieq:
789    case nir_intrinsic_ballot:
790    case nir_intrinsic_first_invocation:
791    case nir_intrinsic_last_invocation:
792    case nir_intrinsic_read_invocation:
793    case nir_intrinsic_read_first_invocation:
794    case nir_intrinsic_elect:
795    case nir_intrinsic_reduce:
796    case nir_intrinsic_inclusive_scan:
797    case nir_intrinsic_exclusive_scan:
798    case nir_intrinsic_shuffle:
799    case nir_intrinsic_shuffle_xor:
800    case nir_intrinsic_shuffle_up:
801    case nir_intrinsic_shuffle_down:
802    case nir_intrinsic_rotate:
803    case nir_intrinsic_masked_swizzle_amd:
804       shader->info.uses_wide_subgroup_intrinsics = true;
805 
806       if (shader->info.stage == MESA_SHADER_FRAGMENT &&
807           shader->info.fs.require_full_quads)
808          shader->info.fs.needs_quad_helper_invocations = true;
809       break;
810 
811    case nir_intrinsic_end_primitive:
812    case nir_intrinsic_end_primitive_with_counter:
813    case nir_intrinsic_end_primitive_nv:
814       assert(shader->info.stage == MESA_SHADER_GEOMETRY);
815       shader->info.gs.uses_end_primitive = 1;
816       FALLTHROUGH;
817 
818    case nir_intrinsic_emit_vertex:
819    case nir_intrinsic_emit_vertex_with_counter:
820    case nir_intrinsic_emit_vertex_nv:
821       shader->info.gs.active_stream_mask |= 1 << nir_intrinsic_stream_id(instr);
822 
823       break;
824 
825    case nir_intrinsic_barrier:
826       shader->info.uses_control_barrier |=
827          nir_intrinsic_execution_scope(instr) != SCOPE_NONE;
828 
829       shader->info.uses_memory_barrier |=
830          nir_intrinsic_memory_scope(instr) != SCOPE_NONE;
831       break;
832 
833    case nir_intrinsic_store_zs_agx:
834       shader->info.outputs_written |= BITFIELD64_BIT(FRAG_RESULT_DEPTH) |
835                                       BITFIELD64_BIT(FRAG_RESULT_STENCIL);
836       break;
837 
838    case nir_intrinsic_sample_mask_agx:
839       shader->info.outputs_written |= BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK);
840       break;
841 
842    case nir_intrinsic_discard_agx:
843       shader->info.fs.uses_discard = true;
844       break;
845 
846    case nir_intrinsic_launch_mesh_workgroups:
847    case nir_intrinsic_launch_mesh_workgroups_with_payload_deref: {
848       for (unsigned i = 0; i < 3; ++i) {
849          nir_scalar dim = nir_scalar_resolved(instr->src[0].ssa, i);
850          if (nir_scalar_is_const(dim))
851             shader->info.mesh.ts_mesh_dispatch_dimensions[i] =
852                nir_scalar_as_uint(dim);
853       }
854       break;
855    }
856 
857    default:
858       shader->info.uses_bindless |= intrinsic_is_bindless(instr);
859       if (nir_intrinsic_writes_external_memory(instr))
860          shader->info.writes_memory = true;
861 
862       if (instr->intrinsic == nir_intrinsic_image_levels ||
863           instr->intrinsic == nir_intrinsic_image_size ||
864           instr->intrinsic == nir_intrinsic_image_samples ||
865           instr->intrinsic == nir_intrinsic_image_deref_levels ||
866           instr->intrinsic == nir_intrinsic_image_deref_size ||
867           instr->intrinsic == nir_intrinsic_image_deref_samples ||
868           instr->intrinsic == nir_intrinsic_bindless_image_levels ||
869           instr->intrinsic == nir_intrinsic_bindless_image_size ||
870           instr->intrinsic == nir_intrinsic_bindless_image_samples)
871          shader->info.uses_resource_info_query = true;
872       break;
873    }
874 }
875 
876 static void
gather_tex_info(nir_tex_instr * instr,nir_shader * shader)877 gather_tex_info(nir_tex_instr *instr, nir_shader *shader)
878 {
879    if (shader->info.stage == MESA_SHADER_FRAGMENT &&
880        nir_tex_instr_has_implicit_derivative(instr))
881       shader->info.fs.needs_quad_helper_invocations = true;
882 
883    if (nir_tex_instr_src_index(instr, nir_tex_src_texture_handle) != -1 ||
884        nir_tex_instr_src_index(instr, nir_tex_src_sampler_handle) != -1)
885       shader->info.uses_bindless = true;
886 
887    if (!nir_tex_instr_is_query(instr) &&
888        (instr->sampler_dim == GLSL_SAMPLER_DIM_SUBPASS ||
889         instr->sampler_dim == GLSL_SAMPLER_DIM_SUBPASS_MS))
890       shader->info.fs.uses_fbfetch_output = true;
891 
892    switch (instr->op) {
893    case nir_texop_tg4:
894       shader->info.uses_texture_gather = true;
895       break;
896    case nir_texop_txs:
897    case nir_texop_query_levels:
898    case nir_texop_texture_samples:
899       shader->info.uses_resource_info_query = true;
900       break;
901    default:
902       break;
903    }
904 }
905 
906 static void
gather_alu_info(nir_alu_instr * instr,nir_shader * shader)907 gather_alu_info(nir_alu_instr *instr, nir_shader *shader)
908 {
909    if (nir_op_is_derivative(instr->op) &&
910        shader->info.stage == MESA_SHADER_FRAGMENT) {
911 
912       shader->info.fs.needs_quad_helper_invocations = true;
913    }
914 
915    if (instr->op == nir_op_fddx || instr->op == nir_op_fddy)
916       shader->info.uses_fddx_fddy = true;
917 
918    const nir_op_info *info = &nir_op_infos[instr->op];
919 
920    for (unsigned i = 0; i < info->num_inputs; i++) {
921       if (nir_alu_type_get_base_type(info->input_types[i]) == nir_type_float)
922          shader->info.bit_sizes_float |= nir_src_bit_size(instr->src[i].src);
923       else
924          shader->info.bit_sizes_int |= nir_src_bit_size(instr->src[i].src);
925    }
926    if (nir_alu_type_get_base_type(info->output_type) == nir_type_float)
927       shader->info.bit_sizes_float |= instr->def.bit_size;
928    else
929       shader->info.bit_sizes_int |= instr->def.bit_size;
930 }
931 
932 static void
gather_func_info(nir_function_impl * func,nir_shader * shader,struct set * visited_funcs,void * dead_ctx)933 gather_func_info(nir_function_impl *func, nir_shader *shader,
934                  struct set *visited_funcs, void *dead_ctx)
935 {
936    if (_mesa_set_search(visited_funcs, func))
937       return;
938 
939    _mesa_set_add(visited_funcs, func);
940 
941    nir_foreach_block(block, func) {
942       nir_foreach_instr(instr, block) {
943          switch (instr->type) {
944          case nir_instr_type_alu:
945             gather_alu_info(nir_instr_as_alu(instr), shader);
946             break;
947          case nir_instr_type_intrinsic:
948             gather_intrinsic_info(nir_instr_as_intrinsic(instr), shader, dead_ctx);
949             break;
950          case nir_instr_type_tex:
951             gather_tex_info(nir_instr_as_tex(instr), shader);
952             break;
953          case nir_instr_type_call: {
954             nir_call_instr *call = nir_instr_as_call(instr);
955             nir_function_impl *impl = call->callee->impl;
956 
957             assert(impl || !"nir_shader_gather_info only works with linked shaders");
958             gather_func_info(impl, shader, visited_funcs, dead_ctx);
959             break;
960          }
961          default:
962             break;
963          }
964       }
965    }
966 }
967 
968 void
nir_shader_gather_info(nir_shader * shader,nir_function_impl * entrypoint)969 nir_shader_gather_info(nir_shader *shader, nir_function_impl *entrypoint)
970 {
971    shader->info.num_textures = 0;
972    shader->info.num_images = 0;
973    shader->info.bit_sizes_float = 0;
974    shader->info.bit_sizes_int = 0;
975    shader->info.uses_bindless = false;
976 
977    nir_foreach_variable_with_modes(var, shader, nir_var_image | nir_var_uniform) {
978       if (var->data.bindless)
979          shader->info.uses_bindless = true;
980       /* Bindless textures and images don't use non-bindless slots.
981        * Interface blocks imply inputs, outputs, UBO, or SSBO, which can only
982        * mean bindless.
983        */
984       if (var->data.bindless || var->interface_type)
985          continue;
986 
987       shader->info.num_textures += glsl_type_get_sampler_count(var->type) +
988                                    glsl_type_get_texture_count(var->type);
989       shader->info.num_images += glsl_type_get_image_count(var->type);
990    }
991 
992    /* these types may not initially be marked bindless */
993    nir_foreach_variable_with_modes(var, shader, nir_var_shader_in | nir_var_shader_out) {
994       const struct glsl_type *type = glsl_without_array(var->type);
995       if (glsl_type_is_sampler(type) || glsl_type_is_image(type))
996          shader->info.uses_bindless = true;
997    }
998 
999    shader->info.inputs_read = 0;
1000    shader->info.dual_slot_inputs = 0;
1001    shader->info.outputs_written = 0;
1002    shader->info.outputs_read = 0;
1003    shader->info.inputs_read_16bit = 0;
1004    shader->info.outputs_written_16bit = 0;
1005    shader->info.outputs_read_16bit = 0;
1006    shader->info.inputs_read_indirectly_16bit = 0;
1007    shader->info.outputs_accessed_indirectly_16bit = 0;
1008    shader->info.patch_outputs_read = 0;
1009    shader->info.patch_inputs_read = 0;
1010    shader->info.patch_outputs_written = 0;
1011    BITSET_ZERO(shader->info.system_values_read);
1012    shader->info.inputs_read_indirectly = 0;
1013    shader->info.outputs_accessed_indirectly = 0;
1014    shader->info.patch_inputs_read_indirectly = 0;
1015    shader->info.patch_outputs_accessed_indirectly = 0;
1016    shader->info.per_primitive_inputs = 0;
1017    shader->info.per_primitive_outputs = 0;
1018 
1019    shader->info.uses_resource_info_query = false;
1020 
1021    if (shader->info.stage == MESA_SHADER_VERTEX) {
1022       shader->info.vs.double_inputs = 0;
1023    }
1024    if (shader->info.stage == MESA_SHADER_FRAGMENT) {
1025       shader->info.fs.uses_sample_qualifier = false;
1026       shader->info.fs.uses_discard = false;
1027       shader->info.fs.color_is_dual_source = false;
1028       shader->info.fs.uses_fbfetch_output = false;
1029       shader->info.fs.needs_quad_helper_invocations = false;
1030    }
1031    if (shader->info.stage == MESA_SHADER_TESS_CTRL) {
1032       shader->info.tess.tcs_cross_invocation_inputs_read = 0;
1033       shader->info.tess.tcs_cross_invocation_outputs_read = 0;
1034    }
1035    if (shader->info.stage == MESA_SHADER_MESH) {
1036       shader->info.mesh.ms_cross_invocation_output_access = 0;
1037    }
1038    if (shader->info.stage == MESA_SHADER_TASK) {
1039       shader->info.mesh.ts_mesh_dispatch_dimensions[0] = 0;
1040       shader->info.mesh.ts_mesh_dispatch_dimensions[1] = 0;
1041       shader->info.mesh.ts_mesh_dispatch_dimensions[2] = 0;
1042    }
1043 
1044    if (shader->info.stage != MESA_SHADER_FRAGMENT)
1045       shader->info.writes_memory = shader->info.has_transform_feedback_varyings;
1046 
1047    void *dead_ctx = ralloc_context(NULL);
1048    struct set *visited_funcs = _mesa_pointer_set_create(dead_ctx);
1049    gather_func_info(entrypoint, shader, visited_funcs, dead_ctx);
1050    ralloc_free(dead_ctx);
1051 
1052    shader->info.per_view_outputs = 0;
1053    nir_foreach_shader_out_variable(var, shader) {
1054       if (var->data.per_primitive) {
1055          assert(shader->info.stage == MESA_SHADER_MESH);
1056          assert(nir_is_arrayed_io(var, shader->info.stage));
1057          const unsigned slots =
1058             glsl_count_attribute_slots(glsl_get_array_element(var->type), false);
1059          shader->info.per_primitive_outputs |= BITFIELD64_RANGE(var->data.location, slots);
1060       }
1061       if (var->data.per_view) {
1062          const unsigned slots =
1063             glsl_count_attribute_slots(glsl_get_array_element(var->type), false);
1064          shader->info.per_view_outputs |= BITFIELD64_RANGE(var->data.location, slots);
1065       }
1066    }
1067 
1068    if (shader->info.stage == MESA_SHADER_FRAGMENT) {
1069       nir_foreach_shader_in_variable(var, shader) {
1070          if (var->data.per_primitive) {
1071             const unsigned slots =
1072                glsl_count_attribute_slots(var->type, false);
1073             shader->info.per_primitive_inputs |= BITFIELD64_RANGE(var->data.location, slots);
1074          }
1075       }
1076    }
1077 
1078    shader->info.ray_queries = 0;
1079    nir_foreach_variable_in_shader(var, shader) {
1080       if (!var->data.ray_query)
1081          continue;
1082 
1083       shader->info.ray_queries += MAX2(glsl_get_aoa_size(var->type), 1);
1084    }
1085    nir_foreach_function_impl(impl, shader) {
1086       nir_foreach_function_temp_variable(var, impl) {
1087          if (!var->data.ray_query)
1088             continue;
1089 
1090          shader->info.ray_queries += MAX2(glsl_get_aoa_size(var->type), 1);
1091       }
1092    }
1093 }
1094