• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 (shader->info.stage == MESA_SHADER_TESS_CTRL) {
151             if (cross_invocation)
152                shader->info.tess.tcs_cross_invocation_inputs_read |= bitfield;
153             else
154                shader->info.tess.tcs_same_invocation_inputs_read |= bitfield;
155          }
156 
157          if (shader->info.stage == MESA_SHADER_FRAGMENT) {
158             shader->info.fs.uses_sample_qualifier |= var->data.sample;
159          }
160       } else {
161          assert(var->data.mode == nir_var_shader_out);
162          if (is_output_read) {
163             if (is_patch_generic) {
164                shader->info.patch_outputs_read |= bitfield;
165                if (indirect)
166                   shader->info.patch_outputs_accessed_indirectly |= bitfield;
167             } else {
168                shader->info.outputs_read |= bitfield;
169                if (indirect)
170                   shader->info.outputs_accessed_indirectly |= bitfield;
171             }
172 
173             if (cross_invocation && shader->info.stage == MESA_SHADER_TESS_CTRL)
174                shader->info.tess.tcs_cross_invocation_outputs_read |= bitfield;
175          } else {
176             if (is_patch_generic) {
177                shader->info.patch_outputs_written |= bitfield;
178                if (indirect)
179                   shader->info.patch_outputs_accessed_indirectly |= bitfield;
180             } else if (!var->data.read_only) {
181                shader->info.outputs_written |= bitfield;
182                if (indirect)
183                   shader->info.outputs_accessed_indirectly |= bitfield;
184             }
185          }
186 
187          if (cross_invocation && shader->info.stage == MESA_SHADER_MESH)
188             shader->info.mesh.ms_cross_invocation_output_access |= bitfield;
189 
190          if (var->data.fb_fetch_output) {
191             shader->info.outputs_read |= bitfield;
192             if (shader->info.stage == MESA_SHADER_FRAGMENT) {
193                shader->info.fs.uses_fbfetch_output = true;
194                shader->info.fs.fbfetch_coherent = var->data.access & ACCESS_COHERENT;
195             }
196          }
197 
198          if (shader->info.stage == MESA_SHADER_FRAGMENT &&
199              !is_output_read && var->data.index == 1)
200             shader->info.fs.color_is_dual_source = true;
201       }
202    }
203 }
204 
205 /**
206  * Mark an entire variable as used.  Caller must ensure that the variable
207  * represents a shader input or output.
208  */
209 static void
mark_whole_variable(nir_shader * shader,nir_variable * var,nir_deref_instr * deref,bool is_output_read)210 mark_whole_variable(nir_shader *shader, nir_variable *var,
211                     nir_deref_instr *deref, bool is_output_read)
212 {
213    const struct glsl_type *type = var->type;
214 
215    if (nir_is_arrayed_io(var, shader->info.stage) ||
216        /* For NV_mesh_shader. */
217        (shader->info.stage == MESA_SHADER_MESH &&
218         var->data.location == VARYING_SLOT_PRIMITIVE_INDICES &&
219         !var->data.per_primitive)) {
220       assert(glsl_type_is_array(type));
221       type = glsl_get_array_element(type);
222    }
223 
224    const unsigned slots = nir_variable_count_slots(var, type);
225    set_io_mask(shader, var, 0, slots, deref, is_output_read);
226 }
227 
228 static unsigned
get_io_offset(nir_deref_instr * deref,nir_variable * var,bool is_arrayed,bool skip_non_arrayed)229 get_io_offset(nir_deref_instr *deref, nir_variable *var, bool is_arrayed,
230               bool skip_non_arrayed)
231 {
232    if (var->data.compact) {
233       if (deref->deref_type == nir_deref_type_var) {
234          assert(glsl_type_is_array(var->type));
235          return 0;
236       }
237 
238       if (deref->deref_type == nir_deref_type_array_wildcard)
239          return -1;
240 
241       assert(deref->deref_type == nir_deref_type_array);
242       return nir_src_is_const(deref->arr.index) ? (nir_src_as_uint(deref->arr.index) + var->data.location_frac) / 4u : (unsigned)-1;
243    }
244 
245    unsigned offset = 0;
246 
247    for (nir_deref_instr *d = deref; d; d = nir_deref_instr_parent(d)) {
248       if (d->deref_type == nir_deref_type_array) {
249          if (is_arrayed && nir_deref_instr_parent(d)->deref_type == nir_deref_type_var)
250             break;
251 
252          if (!is_arrayed && skip_non_arrayed)
253             break;
254 
255          if (!nir_src_is_const(d->arr.index))
256             return -1;
257 
258          offset += glsl_count_attribute_slots(d->type, false) *
259                    nir_src_as_uint(d->arr.index);
260       } else if (d->deref_type == nir_deref_type_struct) {
261          const struct glsl_type *parent_type = nir_deref_instr_parent(d)->type;
262          for (unsigned i = 0; i < d->strct.index; i++) {
263             const struct glsl_type *field_type = glsl_get_struct_field(parent_type, i);
264             offset += glsl_count_attribute_slots(field_type, false);
265          }
266       }
267    }
268 
269    return offset;
270 }
271 
272 /**
273  * Try to mark a portion of the given varying as used.  Caller must ensure
274  * that the variable represents a shader input or output.
275  *
276  * If the index can't be interpreted as a constant, or some other problem
277  * occurs, then nothing will be marked and false will be returned.
278  */
279 static bool
try_mask_partial_io(nir_shader * shader,nir_variable * var,nir_deref_instr * deref,bool is_output_read)280 try_mask_partial_io(nir_shader *shader, nir_variable *var,
281                     nir_deref_instr *deref, bool is_output_read)
282 {
283    const struct glsl_type *type = var->type;
284    bool is_arrayed = nir_is_arrayed_io(var, shader->info.stage);
285    bool skip_non_arrayed = shader->info.stage == MESA_SHADER_MESH;
286 
287    if (is_arrayed) {
288       assert(glsl_type_is_array(type));
289       type = glsl_get_array_element(type);
290    }
291 
292    /* Per view variables will be considered as a whole. */
293    if (var->data.per_view)
294       return false;
295 
296    unsigned offset = get_io_offset(deref, var, is_arrayed, skip_non_arrayed);
297    if (offset == -1)
298       return false;
299 
300    const unsigned slots = nir_variable_count_slots(var, type);
301    if (offset >= slots) {
302       /* Constant index outside the bounds of the matrix/array.  This could
303        * arise as a result of constant folding of a legal GLSL program.
304        *
305        * Even though the spec says that indexing outside the bounds of a
306        * matrix/array results in undefined behaviour, we don't want to pass
307        * out-of-range values to set_io_mask() (since this could result in
308        * slots that don't exist being marked as used), so just let the caller
309        * mark the whole variable as used.
310        */
311       return false;
312    }
313 
314    unsigned len = nir_deref_count_slots(deref, var);
315    set_io_mask(shader, var, offset, len, deref, is_output_read);
316    return true;
317 }
318 
319 /** Returns true if the given intrinsic writes external memory
320  *
321  * Only returns true for writes to globally visible memory, not scratch and
322  * not shared.
323  */
324 bool
nir_intrinsic_writes_external_memory(const nir_intrinsic_instr * instr)325 nir_intrinsic_writes_external_memory(const nir_intrinsic_instr *instr)
326 {
327    switch (instr->intrinsic) {
328    case nir_intrinsic_atomic_counter_inc:
329    case nir_intrinsic_atomic_counter_inc_deref:
330    case nir_intrinsic_atomic_counter_add:
331    case nir_intrinsic_atomic_counter_add_deref:
332    case nir_intrinsic_atomic_counter_pre_dec:
333    case nir_intrinsic_atomic_counter_pre_dec_deref:
334    case nir_intrinsic_atomic_counter_post_dec:
335    case nir_intrinsic_atomic_counter_post_dec_deref:
336    case nir_intrinsic_atomic_counter_min:
337    case nir_intrinsic_atomic_counter_min_deref:
338    case nir_intrinsic_atomic_counter_max:
339    case nir_intrinsic_atomic_counter_max_deref:
340    case nir_intrinsic_atomic_counter_and:
341    case nir_intrinsic_atomic_counter_and_deref:
342    case nir_intrinsic_atomic_counter_or:
343    case nir_intrinsic_atomic_counter_or_deref:
344    case nir_intrinsic_atomic_counter_xor:
345    case nir_intrinsic_atomic_counter_xor_deref:
346    case nir_intrinsic_atomic_counter_exchange:
347    case nir_intrinsic_atomic_counter_exchange_deref:
348    case nir_intrinsic_atomic_counter_comp_swap:
349    case nir_intrinsic_atomic_counter_comp_swap_deref:
350    case nir_intrinsic_bindless_image_atomic:
351    case nir_intrinsic_bindless_image_atomic_swap:
352    case nir_intrinsic_bindless_image_store:
353    case nir_intrinsic_bindless_image_store_raw_intel:
354    case nir_intrinsic_global_atomic:
355    case nir_intrinsic_global_atomic_swap:
356    case nir_intrinsic_global_atomic_ir3:
357    case nir_intrinsic_global_atomic_swap_ir3:
358    case nir_intrinsic_image_atomic:
359    case nir_intrinsic_image_atomic_swap:
360    case nir_intrinsic_image_deref_atomic:
361    case nir_intrinsic_image_deref_atomic_swap:
362    case nir_intrinsic_image_deref_store:
363    case nir_intrinsic_image_deref_store_raw_intel:
364    case nir_intrinsic_image_store:
365    case nir_intrinsic_image_store_raw_intel:
366    case nir_intrinsic_ssbo_atomic:
367    case nir_intrinsic_ssbo_atomic_swap:
368    case nir_intrinsic_ssbo_atomic_ir3:
369    case nir_intrinsic_ssbo_atomic_swap_ir3:
370    case nir_intrinsic_store_global:
371    case nir_intrinsic_store_global_etna:
372    case nir_intrinsic_store_global_ir3:
373    case nir_intrinsic_store_global_amd:
374    case nir_intrinsic_store_ssbo:
375    case nir_intrinsic_store_ssbo_ir3:
376       return true;
377 
378    case nir_intrinsic_store_deref:
379    case nir_intrinsic_deref_atomic:
380    case nir_intrinsic_deref_atomic_swap:
381       return nir_deref_mode_may_be(nir_src_as_deref(instr->src[0]),
382                                    nir_var_mem_ssbo | nir_var_mem_global);
383 
384    default:
385       return false;
386    }
387 }
388 
389 static bool
intrinsic_is_bindless(nir_intrinsic_instr * instr)390 intrinsic_is_bindless(nir_intrinsic_instr *instr)
391 {
392    switch (instr->intrinsic) {
393    case nir_intrinsic_bindless_image_atomic:
394    case nir_intrinsic_bindless_image_atomic_swap:
395    case nir_intrinsic_bindless_image_descriptor_amd:
396    case nir_intrinsic_bindless_image_format:
397    case nir_intrinsic_bindless_image_load:
398    case nir_intrinsic_bindless_image_load_raw_intel:
399    case nir_intrinsic_bindless_image_order:
400    case nir_intrinsic_bindless_image_samples:
401    case nir_intrinsic_bindless_image_samples_identical:
402    case nir_intrinsic_bindless_image_size:
403    case nir_intrinsic_bindless_image_sparse_load:
404    case nir_intrinsic_bindless_image_store:
405    case nir_intrinsic_bindless_image_store_raw_intel:
406    case nir_intrinsic_bindless_resource_ir3:
407       return true;
408    default:
409       break;
410    }
411    return false;
412 }
413 
414 static void
gather_intrinsic_info(nir_intrinsic_instr * instr,nir_shader * shader,void * dead_ctx)415 gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader,
416                       void *dead_ctx)
417 {
418    uint64_t slot_mask = 0;
419    uint16_t slot_mask_16bit = 0;
420    bool is_patch_special = false;
421 
422    if (nir_intrinsic_infos[instr->intrinsic].index_map[NIR_INTRINSIC_IO_SEMANTICS] > 0) {
423       nir_io_semantics semantics = nir_intrinsic_io_semantics(instr);
424 
425       is_patch_special = semantics.location == VARYING_SLOT_TESS_LEVEL_INNER ||
426                          semantics.location == VARYING_SLOT_TESS_LEVEL_OUTER ||
427                          semantics.location == VARYING_SLOT_BOUNDING_BOX0 ||
428                          semantics.location == VARYING_SLOT_BOUNDING_BOX1;
429 
430       if (semantics.location >= VARYING_SLOT_PATCH0 &&
431           semantics.location <= VARYING_SLOT_PATCH31) {
432          /* Generic per-patch I/O. */
433          assert((shader->info.stage == MESA_SHADER_TESS_EVAL &&
434                  instr->intrinsic == nir_intrinsic_load_input) ||
435                 (shader->info.stage == MESA_SHADER_TESS_CTRL &&
436                  (instr->intrinsic == nir_intrinsic_load_output ||
437                   instr->intrinsic == nir_intrinsic_store_output)));
438 
439          semantics.location -= VARYING_SLOT_PATCH0;
440       }
441 
442       if (semantics.location >= VARYING_SLOT_VAR0_16BIT &&
443           semantics.location <= VARYING_SLOT_VAR15_16BIT) {
444          /* Convert num_slots from the units of half vectors to full vectors. */
445          unsigned num_slots = (semantics.num_slots + semantics.high_16bits + 1) / 2;
446          slot_mask_16bit =
447             BITFIELD_RANGE(semantics.location - VARYING_SLOT_VAR0_16BIT, num_slots);
448       } else {
449          unsigned num_slots = semantics.num_slots;
450          if (shader->options->compact_arrays &&
451              (instr->intrinsic != nir_intrinsic_load_input || shader->info.stage != MESA_SHADER_VERTEX)) {
452             /* clamp num_slots for compact arrays */
453             switch (semantics.location) {
454             case VARYING_SLOT_CLIP_DIST0:
455             case VARYING_SLOT_CLIP_DIST1:
456             case VARYING_SLOT_CULL_DIST0:
457             case VARYING_SLOT_CULL_DIST1:
458             case VARYING_SLOT_TESS_LEVEL_INNER:
459             case VARYING_SLOT_TESS_LEVEL_OUTER:
460                num_slots = DIV_ROUND_UP(num_slots, 4);
461                break;
462             default: break;
463             }
464          }
465          slot_mask = BITFIELD64_RANGE(semantics.location, num_slots);
466          assert(util_bitcount64(slot_mask) == num_slots);
467       }
468    }
469 
470    switch (instr->intrinsic) {
471    case nir_intrinsic_demote:
472    case nir_intrinsic_demote_if:
473    case nir_intrinsic_terminate:
474    case nir_intrinsic_terminate_if:
475       /* Freedreno uses discard_if() to end GS invocations that don't produce
476        * a vertex and RADV uses terminate() to end ray-tracing shaders,
477        * so only set uses_discard for fragment shaders.
478        */
479       if (shader->info.stage == MESA_SHADER_FRAGMENT)
480          shader->info.fs.uses_discard = true;
481       break;
482 
483    case nir_intrinsic_interp_deref_at_centroid:
484    case nir_intrinsic_interp_deref_at_sample:
485    case nir_intrinsic_interp_deref_at_offset:
486    case nir_intrinsic_interp_deref_at_vertex:
487    case nir_intrinsic_load_deref:
488    case nir_intrinsic_store_deref:
489    case nir_intrinsic_copy_deref: {
490       nir_deref_instr *deref = nir_src_as_deref(instr->src[0]);
491       if (nir_deref_mode_is_one_of(deref, nir_var_shader_in |
492                                              nir_var_shader_out)) {
493          nir_variable *var = nir_deref_instr_get_variable(deref);
494          bool is_output_read = false;
495          if (var->data.mode == nir_var_shader_out &&
496              instr->intrinsic == nir_intrinsic_load_deref)
497             is_output_read = true;
498 
499          if (!try_mask_partial_io(shader, var, deref, is_output_read))
500             mark_whole_variable(shader, var, deref, is_output_read);
501 
502          /* We need to track which input_reads bits correspond to a
503           * dvec3/dvec4 input attribute */
504          if (shader->info.stage == MESA_SHADER_VERTEX &&
505              var->data.mode == nir_var_shader_in &&
506              glsl_type_is_dual_slot(glsl_without_array(var->type))) {
507             for (unsigned i = 0; i < glsl_count_attribute_slots(var->type, false); i++) {
508                int idx = var->data.location + i;
509                shader->info.vs.double_inputs |= BITFIELD64_BIT(idx);
510             }
511          }
512       }
513       if (nir_intrinsic_writes_external_memory(instr))
514          shader->info.writes_memory = true;
515       break;
516    }
517    case nir_intrinsic_image_deref_load:
518    case nir_intrinsic_image_deref_sparse_load: {
519       nir_deref_instr *deref = nir_src_as_deref(instr->src[0]);
520       nir_variable *var = nir_deref_instr_get_variable(deref);
521       enum glsl_sampler_dim dim = glsl_get_sampler_dim(glsl_without_array(var->type));
522       if (dim != GLSL_SAMPLER_DIM_SUBPASS &&
523           dim != GLSL_SAMPLER_DIM_SUBPASS_MS)
524          break;
525 
526       var->data.fb_fetch_output = true;
527       shader->info.fs.uses_fbfetch_output = true;
528       break;
529    }
530 
531    case nir_intrinsic_bindless_image_load:
532    case nir_intrinsic_bindless_image_sparse_load: {
533       enum glsl_sampler_dim dim = nir_intrinsic_image_dim(instr);
534       if (dim != GLSL_SAMPLER_DIM_SUBPASS &&
535           dim != GLSL_SAMPLER_DIM_SUBPASS_MS)
536          break;
537       shader->info.fs.uses_fbfetch_output = true;
538       break;
539    }
540 
541    case nir_intrinsic_load_input:
542    case nir_intrinsic_load_per_vertex_input:
543    case nir_intrinsic_load_input_vertex:
544    case nir_intrinsic_load_interpolated_input:
545    case nir_intrinsic_load_per_primitive_input:
546    case nir_intrinsic_load_attribute_pan:
547       if (shader->info.stage == MESA_SHADER_TESS_EVAL &&
548           instr->intrinsic == nir_intrinsic_load_input &&
549           !is_patch_special) {
550          shader->info.patch_inputs_read |= slot_mask;
551          if (!nir_src_is_const(*nir_get_io_offset_src(instr)))
552             shader->info.patch_inputs_read_indirectly |= slot_mask;
553       } else {
554          shader->info.inputs_read |= slot_mask;
555          if (nir_intrinsic_io_semantics(instr).high_dvec2)
556             shader->info.dual_slot_inputs |= slot_mask;
557          if (instr->intrinsic == nir_intrinsic_load_per_primitive_input)
558             shader->info.per_primitive_inputs |= slot_mask;
559          shader->info.inputs_read_16bit |= slot_mask_16bit;
560          if (!nir_src_is_const(*nir_get_io_offset_src(instr))) {
561             shader->info.inputs_read_indirectly |= slot_mask;
562             shader->info.inputs_read_indirectly_16bit |= slot_mask_16bit;
563          }
564       }
565 
566       if (shader->info.stage == MESA_SHADER_TESS_CTRL &&
567           instr->intrinsic == nir_intrinsic_load_per_vertex_input) {
568          if (src_is_invocation_id(nir_get_io_arrayed_index_src(instr)))
569             shader->info.tess.tcs_same_invocation_inputs_read |= slot_mask;
570          else
571             shader->info.tess.tcs_cross_invocation_inputs_read |= slot_mask;
572       }
573       break;
574 
575    case nir_intrinsic_load_output:
576    case nir_intrinsic_load_per_vertex_output:
577    case nir_intrinsic_load_per_view_output:
578    case nir_intrinsic_load_per_primitive_output:
579       if (shader->info.stage == MESA_SHADER_TESS_CTRL &&
580           instr->intrinsic == nir_intrinsic_load_output &&
581           !is_patch_special) {
582          shader->info.patch_outputs_read |= slot_mask;
583          if (!nir_src_is_const(*nir_get_io_offset_src(instr)))
584             shader->info.patch_outputs_accessed_indirectly |= slot_mask;
585       } else {
586          shader->info.outputs_read |= slot_mask;
587          shader->info.outputs_read_16bit |= slot_mask_16bit;
588          if (!nir_src_is_const(*nir_get_io_offset_src(instr))) {
589             shader->info.outputs_accessed_indirectly |= slot_mask;
590             shader->info.outputs_accessed_indirectly_16bit |= slot_mask_16bit;
591          }
592       }
593 
594       if (shader->info.stage == MESA_SHADER_TESS_CTRL &&
595           instr->intrinsic == nir_intrinsic_load_per_vertex_output &&
596           !src_is_invocation_id(nir_get_io_arrayed_index_src(instr)))
597          shader->info.tess.tcs_cross_invocation_outputs_read |= slot_mask;
598 
599       /* NV_mesh_shader: mesh shaders can load their outputs. */
600       if (shader->info.stage == MESA_SHADER_MESH &&
601           (instr->intrinsic == nir_intrinsic_load_per_vertex_output ||
602            instr->intrinsic == nir_intrinsic_load_per_primitive_output) &&
603           !src_is_local_invocation_index(shader, nir_get_io_arrayed_index_src(instr)))
604          shader->info.mesh.ms_cross_invocation_output_access |= slot_mask;
605 
606       if (shader->info.stage == MESA_SHADER_FRAGMENT &&
607           nir_intrinsic_io_semantics(instr).fb_fetch_output)
608          shader->info.fs.uses_fbfetch_output = true;
609       break;
610 
611    case nir_intrinsic_store_output:
612    case nir_intrinsic_store_per_vertex_output:
613    case nir_intrinsic_store_per_view_output:
614    case nir_intrinsic_store_per_primitive_output:
615       if (shader->info.stage == MESA_SHADER_TESS_CTRL &&
616           instr->intrinsic == nir_intrinsic_store_output &&
617           !is_patch_special) {
618          shader->info.patch_outputs_written |= slot_mask;
619          if (!nir_src_is_const(*nir_get_io_offset_src(instr)))
620             shader->info.patch_outputs_accessed_indirectly |= slot_mask;
621       } else {
622          shader->info.outputs_written |= slot_mask;
623          shader->info.outputs_written_16bit |= slot_mask_16bit;
624          if (instr->intrinsic == nir_intrinsic_store_per_primitive_output)
625             shader->info.per_primitive_outputs |= slot_mask;
626          if (!nir_src_is_const(*nir_get_io_offset_src(instr))) {
627             shader->info.outputs_accessed_indirectly |= slot_mask;
628             shader->info.outputs_accessed_indirectly_16bit |= slot_mask_16bit;
629          }
630       }
631 
632       if (shader->info.stage == MESA_SHADER_MESH &&
633           (instr->intrinsic == nir_intrinsic_store_per_vertex_output ||
634            instr->intrinsic == nir_intrinsic_store_per_primitive_output) &&
635           !src_is_local_invocation_index(shader, nir_get_io_arrayed_index_src(instr)))
636          shader->info.mesh.ms_cross_invocation_output_access |= slot_mask;
637 
638       if (shader->info.stage == MESA_SHADER_FRAGMENT &&
639           nir_intrinsic_io_semantics(instr).dual_source_blend_index)
640          shader->info.fs.color_is_dual_source = true;
641       break;
642 
643    case nir_intrinsic_load_color0:
644    case nir_intrinsic_load_color1:
645       shader->info.inputs_read |=
646          BITFIELD64_BIT(VARYING_SLOT_COL0 << (instr->intrinsic == nir_intrinsic_load_color1));
647       FALLTHROUGH;
648    case nir_intrinsic_load_subgroup_size:
649    case nir_intrinsic_load_subgroup_invocation:
650    case nir_intrinsic_load_subgroup_eq_mask:
651    case nir_intrinsic_load_subgroup_ge_mask:
652    case nir_intrinsic_load_subgroup_gt_mask:
653    case nir_intrinsic_load_subgroup_le_mask:
654    case nir_intrinsic_load_subgroup_lt_mask:
655    case nir_intrinsic_load_num_subgroups:
656    case nir_intrinsic_load_subgroup_id:
657    case nir_intrinsic_load_vertex_id:
658    case nir_intrinsic_load_instance_id:
659    case nir_intrinsic_load_vertex_id_zero_base:
660    case nir_intrinsic_load_base_vertex:
661    case nir_intrinsic_load_first_vertex:
662    case nir_intrinsic_load_is_indexed_draw:
663    case nir_intrinsic_load_base_instance:
664    case nir_intrinsic_load_draw_id:
665    case nir_intrinsic_load_invocation_id:
666    case nir_intrinsic_load_frag_coord:
667    case nir_intrinsic_load_pixel_coord:
668    case nir_intrinsic_load_frag_shading_rate:
669    case nir_intrinsic_load_fully_covered:
670    case nir_intrinsic_load_point_coord:
671    case nir_intrinsic_load_line_coord:
672    case nir_intrinsic_load_front_face:
673    case nir_intrinsic_load_front_face_fsign:
674    case nir_intrinsic_load_sample_id:
675    case nir_intrinsic_load_sample_pos:
676    case nir_intrinsic_load_sample_pos_or_center:
677    case nir_intrinsic_load_sample_mask_in:
678    case nir_intrinsic_load_helper_invocation:
679    case nir_intrinsic_load_tess_coord:
680    case nir_intrinsic_load_tess_coord_xy:
681    case nir_intrinsic_load_patch_vertices_in:
682    case nir_intrinsic_load_primitive_id:
683    case nir_intrinsic_load_tess_level_outer:
684    case nir_intrinsic_load_tess_level_inner:
685    case nir_intrinsic_load_tess_level_outer_default:
686    case nir_intrinsic_load_tess_level_inner_default:
687    case nir_intrinsic_load_local_invocation_id:
688    case nir_intrinsic_load_local_invocation_index:
689    case nir_intrinsic_load_global_invocation_id:
690    case nir_intrinsic_load_base_global_invocation_id:
691    case nir_intrinsic_load_global_invocation_index:
692    case nir_intrinsic_load_global_size:
693    case nir_intrinsic_load_workgroup_id:
694    case nir_intrinsic_load_base_workgroup_id:
695    case nir_intrinsic_load_workgroup_index:
696    case nir_intrinsic_load_num_workgroups:
697    case nir_intrinsic_load_workgroup_size:
698    case nir_intrinsic_load_work_dim:
699    case nir_intrinsic_load_user_data_amd:
700    case nir_intrinsic_load_view_index:
701    case nir_intrinsic_load_barycentric_model:
702    case nir_intrinsic_load_ray_launch_id:
703    case nir_intrinsic_load_ray_launch_size:
704    case nir_intrinsic_load_ray_world_origin:
705    case nir_intrinsic_load_ray_world_direction:
706    case nir_intrinsic_load_ray_object_origin:
707    case nir_intrinsic_load_ray_object_direction:
708    case nir_intrinsic_load_ray_t_min:
709    case nir_intrinsic_load_ray_t_max:
710    case nir_intrinsic_load_ray_object_to_world:
711    case nir_intrinsic_load_ray_world_to_object:
712    case nir_intrinsic_load_ray_hit_kind:
713    case nir_intrinsic_load_ray_flags:
714    case nir_intrinsic_load_ray_geometry_index:
715    case nir_intrinsic_load_ray_instance_custom_index:
716    case nir_intrinsic_load_mesh_view_count:
717    case nir_intrinsic_load_gs_header_ir3:
718    case nir_intrinsic_load_tcs_header_ir3:
719    case nir_intrinsic_load_ray_triangle_vertex_positions:
720    case nir_intrinsic_load_layer_id:
721       BITSET_SET(shader->info.system_values_read,
722                  nir_system_value_from_intrinsic(instr->intrinsic));
723       break;
724 
725    case nir_intrinsic_load_barycentric_pixel:
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_PIXEL);
730       } else if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_NOPERSPECTIVE) {
731          BITSET_SET(shader->info.system_values_read,
732                     SYSTEM_VALUE_BARYCENTRIC_LINEAR_PIXEL);
733       }
734       break;
735 
736    case nir_intrinsic_load_barycentric_centroid:
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_CENTROID);
741       } else if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_NOPERSPECTIVE) {
742          BITSET_SET(shader->info.system_values_read,
743                     SYSTEM_VALUE_BARYCENTRIC_LINEAR_CENTROID);
744       }
745       break;
746 
747    case nir_intrinsic_load_barycentric_sample:
748       if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_SMOOTH ||
749           nir_intrinsic_interp_mode(instr) == INTERP_MODE_NONE) {
750          BITSET_SET(shader->info.system_values_read,
751                     SYSTEM_VALUE_BARYCENTRIC_PERSP_SAMPLE);
752       } else if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_NOPERSPECTIVE) {
753          BITSET_SET(shader->info.system_values_read,
754                     SYSTEM_VALUE_BARYCENTRIC_LINEAR_SAMPLE);
755       }
756       if (shader->info.stage == MESA_SHADER_FRAGMENT)
757          shader->info.fs.uses_sample_qualifier = true;
758       break;
759 
760    case nir_intrinsic_load_barycentric_coord_pixel:
761    case nir_intrinsic_load_barycentric_coord_centroid:
762    case nir_intrinsic_load_barycentric_coord_sample:
763    case nir_intrinsic_load_barycentric_coord_at_offset:
764    case nir_intrinsic_load_barycentric_coord_at_sample:
765       if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_SMOOTH ||
766           nir_intrinsic_interp_mode(instr) == INTERP_MODE_NONE) {
767          BITSET_SET(shader->info.system_values_read, SYSTEM_VALUE_BARYCENTRIC_PERSP_COORD);
768       } else if (nir_intrinsic_interp_mode(instr) == INTERP_MODE_NOPERSPECTIVE) {
769          BITSET_SET(shader->info.system_values_read, SYSTEM_VALUE_BARYCENTRIC_LINEAR_COORD);
770       }
771       break;
772 
773    case nir_intrinsic_ddx:
774    case nir_intrinsic_ddx_fine:
775    case nir_intrinsic_ddx_coarse:
776    case nir_intrinsic_ddy:
777    case nir_intrinsic_ddy_fine:
778    case nir_intrinsic_ddy_coarse:
779       if (shader->info.stage == MESA_SHADER_FRAGMENT)
780          shader->info.fs.needs_quad_helper_invocations = true;
781       break;
782 
783    case nir_intrinsic_quad_vote_any:
784    case nir_intrinsic_quad_vote_all:
785    case nir_intrinsic_quad_broadcast:
786    case nir_intrinsic_quad_swap_horizontal:
787    case nir_intrinsic_quad_swap_vertical:
788    case nir_intrinsic_quad_swap_diagonal:
789    case nir_intrinsic_quad_swizzle_amd:
790       if (shader->info.stage == MESA_SHADER_FRAGMENT)
791          shader->info.fs.needs_quad_helper_invocations = true;
792       break;
793 
794    case nir_intrinsic_vote_any:
795    case nir_intrinsic_vote_all:
796    case nir_intrinsic_vote_feq:
797    case nir_intrinsic_vote_ieq:
798    case nir_intrinsic_ballot:
799    case nir_intrinsic_first_invocation:
800    case nir_intrinsic_last_invocation:
801    case nir_intrinsic_read_invocation:
802    case nir_intrinsic_read_first_invocation:
803    case nir_intrinsic_elect:
804    case nir_intrinsic_reduce:
805    case nir_intrinsic_inclusive_scan:
806    case nir_intrinsic_exclusive_scan:
807    case nir_intrinsic_shuffle:
808    case nir_intrinsic_shuffle_xor:
809    case nir_intrinsic_shuffle_up:
810    case nir_intrinsic_shuffle_down:
811    case nir_intrinsic_rotate:
812    case nir_intrinsic_masked_swizzle_amd:
813       shader->info.uses_wide_subgroup_intrinsics = true;
814 
815       if (shader->info.stage == MESA_SHADER_FRAGMENT &&
816           shader->info.fs.require_full_quads)
817          shader->info.fs.needs_quad_helper_invocations = true;
818       break;
819 
820    case nir_intrinsic_end_primitive:
821    case nir_intrinsic_end_primitive_with_counter:
822    case nir_intrinsic_end_primitive_nv:
823       assert(shader->info.stage == MESA_SHADER_GEOMETRY);
824       shader->info.gs.uses_end_primitive = 1;
825       FALLTHROUGH;
826 
827    case nir_intrinsic_emit_vertex:
828    case nir_intrinsic_emit_vertex_with_counter:
829    case nir_intrinsic_emit_vertex_nv:
830       shader->info.gs.active_stream_mask |= 1 << nir_intrinsic_stream_id(instr);
831 
832       break;
833 
834    case nir_intrinsic_barrier:
835       shader->info.uses_control_barrier |=
836          nir_intrinsic_execution_scope(instr) != SCOPE_NONE;
837 
838       shader->info.uses_memory_barrier |=
839          nir_intrinsic_memory_scope(instr) != SCOPE_NONE;
840       break;
841 
842    case nir_intrinsic_store_zs_agx:
843       shader->info.outputs_written |= BITFIELD64_BIT(FRAG_RESULT_DEPTH) |
844                                       BITFIELD64_BIT(FRAG_RESULT_STENCIL);
845       break;
846 
847    case nir_intrinsic_sample_mask_agx:
848       shader->info.outputs_written |= BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK);
849       break;
850 
851    case nir_intrinsic_discard_agx:
852       shader->info.fs.uses_discard = true;
853       break;
854 
855    case nir_intrinsic_launch_mesh_workgroups:
856    case nir_intrinsic_launch_mesh_workgroups_with_payload_deref: {
857       for (unsigned i = 0; i < 3; ++i) {
858          nir_scalar dim = nir_scalar_resolved(instr->src[0].ssa, i);
859          if (nir_scalar_is_const(dim))
860             shader->info.mesh.ts_mesh_dispatch_dimensions[i] =
861                nir_scalar_as_uint(dim);
862       }
863       break;
864    }
865 
866    default:
867       shader->info.uses_bindless |= intrinsic_is_bindless(instr);
868       if (nir_intrinsic_writes_external_memory(instr))
869          shader->info.writes_memory = true;
870 
871       if (instr->intrinsic == nir_intrinsic_image_levels ||
872           instr->intrinsic == nir_intrinsic_image_size ||
873           instr->intrinsic == nir_intrinsic_image_samples ||
874           instr->intrinsic == nir_intrinsic_image_deref_levels ||
875           instr->intrinsic == nir_intrinsic_image_deref_size ||
876           instr->intrinsic == nir_intrinsic_image_deref_samples ||
877           instr->intrinsic == nir_intrinsic_bindless_image_levels ||
878           instr->intrinsic == nir_intrinsic_bindless_image_size ||
879           instr->intrinsic == nir_intrinsic_bindless_image_samples)
880          shader->info.uses_resource_info_query = true;
881       break;
882    }
883 }
884 
885 static void
gather_tex_info(nir_tex_instr * instr,nir_shader * shader)886 gather_tex_info(nir_tex_instr *instr, nir_shader *shader)
887 {
888    if (shader->info.stage == MESA_SHADER_FRAGMENT &&
889        nir_tex_instr_has_implicit_derivative(instr))
890       shader->info.fs.needs_quad_helper_invocations = true;
891 
892    if (nir_tex_instr_src_index(instr, nir_tex_src_texture_handle) != -1 ||
893        nir_tex_instr_src_index(instr, nir_tex_src_sampler_handle) != -1)
894       shader->info.uses_bindless = true;
895 
896    if (!nir_tex_instr_is_query(instr) &&
897        (instr->sampler_dim == GLSL_SAMPLER_DIM_SUBPASS ||
898         instr->sampler_dim == GLSL_SAMPLER_DIM_SUBPASS_MS))
899       shader->info.fs.uses_fbfetch_output = true;
900 
901    switch (instr->op) {
902    case nir_texop_tg4:
903       shader->info.uses_texture_gather = true;
904       break;
905    case nir_texop_txs:
906    case nir_texop_query_levels:
907    case nir_texop_texture_samples:
908       shader->info.uses_resource_info_query = true;
909       break;
910    default:
911       break;
912    }
913 }
914 
915 static void
gather_alu_info(nir_alu_instr * instr,nir_shader * shader)916 gather_alu_info(nir_alu_instr *instr, nir_shader *shader)
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_same_invocation_inputs_read = 0;
1033       shader->info.tess.tcs_cross_invocation_inputs_read = 0;
1034       shader->info.tess.tcs_cross_invocation_outputs_read = 0;
1035    }
1036    if (shader->info.stage == MESA_SHADER_MESH) {
1037       shader->info.mesh.ms_cross_invocation_output_access = 0;
1038    }
1039    if (shader->info.stage == MESA_SHADER_TASK) {
1040       shader->info.mesh.ts_mesh_dispatch_dimensions[0] = 0;
1041       shader->info.mesh.ts_mesh_dispatch_dimensions[1] = 0;
1042       shader->info.mesh.ts_mesh_dispatch_dimensions[2] = 0;
1043    }
1044 
1045    if (shader->info.stage != MESA_SHADER_FRAGMENT)
1046       shader->info.writes_memory = shader->info.has_transform_feedback_varyings;
1047 
1048    void *dead_ctx = ralloc_context(NULL);
1049    struct set *visited_funcs = _mesa_pointer_set_create(dead_ctx);
1050    gather_func_info(entrypoint, shader, visited_funcs, dead_ctx);
1051    ralloc_free(dead_ctx);
1052 
1053    shader->info.per_view_outputs = 0;
1054    nir_foreach_shader_out_variable(var, shader) {
1055       if (var->data.per_primitive) {
1056          assert(shader->info.stage == MESA_SHADER_MESH);
1057          assert(nir_is_arrayed_io(var, shader->info.stage));
1058          const unsigned slots =
1059             glsl_count_attribute_slots(glsl_get_array_element(var->type), false);
1060          shader->info.per_primitive_outputs |= BITFIELD64_RANGE(var->data.location, slots);
1061       }
1062       if (var->data.per_view) {
1063          const unsigned slots =
1064             glsl_count_attribute_slots(glsl_get_array_element(var->type), false);
1065          shader->info.per_view_outputs |= BITFIELD64_RANGE(var->data.location, slots);
1066       }
1067    }
1068 
1069    if (shader->info.stage == MESA_SHADER_FRAGMENT) {
1070       nir_foreach_shader_in_variable(var, shader) {
1071          if (var->data.per_primitive) {
1072             const unsigned slots =
1073                glsl_count_attribute_slots(var->type, false);
1074             shader->info.per_primitive_inputs |= BITFIELD64_RANGE(var->data.location, slots);
1075          }
1076       }
1077    }
1078 
1079    shader->info.ray_queries = 0;
1080    nir_foreach_variable_in_shader(var, shader) {
1081       if (!var->data.ray_query)
1082          continue;
1083 
1084       shader->info.ray_queries += MAX2(glsl_get_aoa_size(var->type), 1);
1085    }
1086    nir_foreach_function_impl(impl, shader) {
1087       nir_foreach_function_temp_variable(var, impl) {
1088          if (!var->data.ray_query)
1089             continue;
1090 
1091          shader->info.ray_queries += MAX2(glsl_get_aoa_size(var->type), 1);
1092       }
1093    }
1094 }
1095