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