1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2014 Intel Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker *
23*61046927SAndroid Build Coastguard Worker * Authors:
24*61046927SAndroid Build Coastguard Worker * Connor Abbott ([email protected])
25*61046927SAndroid Build Coastguard Worker *
26*61046927SAndroid Build Coastguard Worker */
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Worker #include "nir.h"
29*61046927SAndroid Build Coastguard Worker #include <assert.h>
30*61046927SAndroid Build Coastguard Worker #include <limits.h>
31*61046927SAndroid Build Coastguard Worker #include <math.h>
32*61046927SAndroid Build Coastguard Worker #include "util/half_float.h"
33*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
34*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
35*61046927SAndroid Build Coastguard Worker #include "util/u_qsort.h"
36*61046927SAndroid Build Coastguard Worker #include "nir_builder.h"
37*61046927SAndroid Build Coastguard Worker #include "nir_control_flow_private.h"
38*61046927SAndroid Build Coastguard Worker #include "nir_worklist.h"
39*61046927SAndroid Build Coastguard Worker
40*61046927SAndroid Build Coastguard Worker #ifndef NDEBUG
41*61046927SAndroid Build Coastguard Worker uint32_t nir_debug = 0;
42*61046927SAndroid Build Coastguard Worker bool nir_debug_print_shader[MESA_SHADER_KERNEL + 1] = { 0 };
43*61046927SAndroid Build Coastguard Worker
44*61046927SAndroid Build Coastguard Worker static const struct debug_named_value nir_debug_control[] = {
45*61046927SAndroid Build Coastguard Worker { "clone", NIR_DEBUG_CLONE,
46*61046927SAndroid Build Coastguard Worker "Test cloning a shader at each successful lowering/optimization call" },
47*61046927SAndroid Build Coastguard Worker { "serialize", NIR_DEBUG_SERIALIZE,
48*61046927SAndroid Build Coastguard Worker "Test serialize and deserialize shader at each successful lowering/optimization call" },
49*61046927SAndroid Build Coastguard Worker { "novalidate", NIR_DEBUG_NOVALIDATE,
50*61046927SAndroid Build Coastguard Worker "Disable shader validation at each successful lowering/optimization call" },
51*61046927SAndroid Build Coastguard Worker { "validate_ssa_dominance", NIR_DEBUG_VALIDATE_SSA_DOMINANCE,
52*61046927SAndroid Build Coastguard Worker "Validate SSA dominance in shader at each successful lowering/optimization call" },
53*61046927SAndroid Build Coastguard Worker { "tgsi", NIR_DEBUG_TGSI,
54*61046927SAndroid Build Coastguard Worker "Dump NIR/TGSI shaders when doing a NIR<->TGSI translation" },
55*61046927SAndroid Build Coastguard Worker { "print", NIR_DEBUG_PRINT,
56*61046927SAndroid Build Coastguard Worker "Dump resulting shader after each successful lowering/optimization call" },
57*61046927SAndroid Build Coastguard Worker { "print_vs", NIR_DEBUG_PRINT_VS,
58*61046927SAndroid Build Coastguard Worker "Dump resulting vertex shader after each successful lowering/optimization call" },
59*61046927SAndroid Build Coastguard Worker { "print_tcs", NIR_DEBUG_PRINT_TCS,
60*61046927SAndroid Build Coastguard Worker "Dump resulting tessellation control shader after each successful lowering/optimization call" },
61*61046927SAndroid Build Coastguard Worker { "print_tes", NIR_DEBUG_PRINT_TES,
62*61046927SAndroid Build Coastguard Worker "Dump resulting tessellation evaluation shader after each successful lowering/optimization call" },
63*61046927SAndroid Build Coastguard Worker { "print_gs", NIR_DEBUG_PRINT_GS,
64*61046927SAndroid Build Coastguard Worker "Dump resulting geometry shader after each successful lowering/optimization call" },
65*61046927SAndroid Build Coastguard Worker { "print_fs", NIR_DEBUG_PRINT_FS,
66*61046927SAndroid Build Coastguard Worker "Dump resulting fragment shader after each successful lowering/optimization call" },
67*61046927SAndroid Build Coastguard Worker { "print_cs", NIR_DEBUG_PRINT_CS,
68*61046927SAndroid Build Coastguard Worker "Dump resulting compute shader after each successful lowering/optimization call" },
69*61046927SAndroid Build Coastguard Worker { "print_ts", NIR_DEBUG_PRINT_TS,
70*61046927SAndroid Build Coastguard Worker "Dump resulting task shader after each successful lowering/optimization call" },
71*61046927SAndroid Build Coastguard Worker { "print_ms", NIR_DEBUG_PRINT_MS,
72*61046927SAndroid Build Coastguard Worker "Dump resulting mesh shader after each successful lowering/optimization call" },
73*61046927SAndroid Build Coastguard Worker { "print_rgs", NIR_DEBUG_PRINT_RGS,
74*61046927SAndroid Build Coastguard Worker "Dump resulting raygen shader after each successful lowering/optimization call" },
75*61046927SAndroid Build Coastguard Worker { "print_ahs", NIR_DEBUG_PRINT_AHS,
76*61046927SAndroid Build Coastguard Worker "Dump resulting any-hit shader after each successful lowering/optimization call" },
77*61046927SAndroid Build Coastguard Worker { "print_chs", NIR_DEBUG_PRINT_CHS,
78*61046927SAndroid Build Coastguard Worker "Dump resulting closest-hit shader after each successful lowering/optimization call" },
79*61046927SAndroid Build Coastguard Worker { "print_mhs", NIR_DEBUG_PRINT_MHS,
80*61046927SAndroid Build Coastguard Worker "Dump resulting miss-hit shader after each successful lowering/optimization call" },
81*61046927SAndroid Build Coastguard Worker { "print_is", NIR_DEBUG_PRINT_IS,
82*61046927SAndroid Build Coastguard Worker "Dump resulting intersection shader after each successful lowering/optimization call" },
83*61046927SAndroid Build Coastguard Worker { "print_cbs", NIR_DEBUG_PRINT_CBS,
84*61046927SAndroid Build Coastguard Worker "Dump resulting callable shader after each successful lowering/optimization call" },
85*61046927SAndroid Build Coastguard Worker { "print_ks", NIR_DEBUG_PRINT_KS,
86*61046927SAndroid Build Coastguard Worker "Dump resulting kernel shader after each successful lowering/optimization call" },
87*61046927SAndroid Build Coastguard Worker { "print_no_inline_consts", NIR_DEBUG_PRINT_NO_INLINE_CONSTS,
88*61046927SAndroid Build Coastguard Worker "Do not print const value near each use of const SSA variable" },
89*61046927SAndroid Build Coastguard Worker { "print_internal", NIR_DEBUG_PRINT_INTERNAL,
90*61046927SAndroid Build Coastguard Worker "Print shaders even if they are marked as internal" },
91*61046927SAndroid Build Coastguard Worker { "print_pass_flags", NIR_DEBUG_PRINT_PASS_FLAGS,
92*61046927SAndroid Build Coastguard Worker "Print pass_flags for every instruction when pass_flags are non-zero" },
93*61046927SAndroid Build Coastguard Worker DEBUG_NAMED_VALUE_END
94*61046927SAndroid Build Coastguard Worker };
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker DEBUG_GET_ONCE_FLAGS_OPTION(nir_debug, "NIR_DEBUG", nir_debug_control, 0)
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker static void
nir_process_debug_variable_once(void)99*61046927SAndroid Build Coastguard Worker nir_process_debug_variable_once(void)
100*61046927SAndroid Build Coastguard Worker {
101*61046927SAndroid Build Coastguard Worker nir_debug = debug_get_option_nir_debug();
102*61046927SAndroid Build Coastguard Worker
103*61046927SAndroid Build Coastguard Worker /* clang-format off */
104*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_VERTEX] = NIR_DEBUG(PRINT_VS);
105*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_TESS_CTRL] = NIR_DEBUG(PRINT_TCS);
106*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_TESS_EVAL] = NIR_DEBUG(PRINT_TES);
107*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_GEOMETRY] = NIR_DEBUG(PRINT_GS);
108*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_FRAGMENT] = NIR_DEBUG(PRINT_FS);
109*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_COMPUTE] = NIR_DEBUG(PRINT_CS);
110*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_TASK] = NIR_DEBUG(PRINT_TS);
111*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_MESH] = NIR_DEBUG(PRINT_MS);
112*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_RAYGEN] = NIR_DEBUG(PRINT_RGS);
113*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_ANY_HIT] = NIR_DEBUG(PRINT_AHS);
114*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_CLOSEST_HIT] = NIR_DEBUG(PRINT_CHS);
115*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_MISS] = NIR_DEBUG(PRINT_MHS);
116*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_INTERSECTION] = NIR_DEBUG(PRINT_IS);
117*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_CALLABLE] = NIR_DEBUG(PRINT_CBS);
118*61046927SAndroid Build Coastguard Worker nir_debug_print_shader[MESA_SHADER_KERNEL] = NIR_DEBUG(PRINT_KS);
119*61046927SAndroid Build Coastguard Worker /* clang-format on */
120*61046927SAndroid Build Coastguard Worker }
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker void
nir_process_debug_variable(void)123*61046927SAndroid Build Coastguard Worker nir_process_debug_variable(void)
124*61046927SAndroid Build Coastguard Worker {
125*61046927SAndroid Build Coastguard Worker static once_flag flag = ONCE_FLAG_INIT;
126*61046927SAndroid Build Coastguard Worker call_once(&flag, nir_process_debug_variable_once);
127*61046927SAndroid Build Coastguard Worker }
128*61046927SAndroid Build Coastguard Worker #endif
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker /** Return true if the component mask "mask" with bit size "old_bit_size" can
131*61046927SAndroid Build Coastguard Worker * be re-interpreted to be used with "new_bit_size".
132*61046927SAndroid Build Coastguard Worker */
133*61046927SAndroid Build Coastguard Worker bool
nir_component_mask_can_reinterpret(nir_component_mask_t mask,unsigned old_bit_size,unsigned new_bit_size)134*61046927SAndroid Build Coastguard Worker nir_component_mask_can_reinterpret(nir_component_mask_t mask,
135*61046927SAndroid Build Coastguard Worker unsigned old_bit_size,
136*61046927SAndroid Build Coastguard Worker unsigned new_bit_size)
137*61046927SAndroid Build Coastguard Worker {
138*61046927SAndroid Build Coastguard Worker assert(util_is_power_of_two_nonzero(old_bit_size));
139*61046927SAndroid Build Coastguard Worker assert(util_is_power_of_two_nonzero(new_bit_size));
140*61046927SAndroid Build Coastguard Worker
141*61046927SAndroid Build Coastguard Worker if (old_bit_size == new_bit_size)
142*61046927SAndroid Build Coastguard Worker return true;
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker if (old_bit_size == 1 || new_bit_size == 1)
145*61046927SAndroid Build Coastguard Worker return false;
146*61046927SAndroid Build Coastguard Worker
147*61046927SAndroid Build Coastguard Worker if (old_bit_size > new_bit_size) {
148*61046927SAndroid Build Coastguard Worker unsigned ratio = old_bit_size / new_bit_size;
149*61046927SAndroid Build Coastguard Worker return util_last_bit(mask) * ratio <= NIR_MAX_VEC_COMPONENTS;
150*61046927SAndroid Build Coastguard Worker }
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker unsigned iter = mask;
153*61046927SAndroid Build Coastguard Worker while (iter) {
154*61046927SAndroid Build Coastguard Worker int start, count;
155*61046927SAndroid Build Coastguard Worker u_bit_scan_consecutive_range(&iter, &start, &count);
156*61046927SAndroid Build Coastguard Worker start *= old_bit_size;
157*61046927SAndroid Build Coastguard Worker count *= old_bit_size;
158*61046927SAndroid Build Coastguard Worker if (start % new_bit_size != 0)
159*61046927SAndroid Build Coastguard Worker return false;
160*61046927SAndroid Build Coastguard Worker if (count % new_bit_size != 0)
161*61046927SAndroid Build Coastguard Worker return false;
162*61046927SAndroid Build Coastguard Worker }
163*61046927SAndroid Build Coastguard Worker return true;
164*61046927SAndroid Build Coastguard Worker }
165*61046927SAndroid Build Coastguard Worker
166*61046927SAndroid Build Coastguard Worker /** Re-interprets a component mask "mask" with bit size "old_bit_size" so that
167*61046927SAndroid Build Coastguard Worker * it can be used can be used with "new_bit_size".
168*61046927SAndroid Build Coastguard Worker */
169*61046927SAndroid Build Coastguard Worker nir_component_mask_t
nir_component_mask_reinterpret(nir_component_mask_t mask,unsigned old_bit_size,unsigned new_bit_size)170*61046927SAndroid Build Coastguard Worker nir_component_mask_reinterpret(nir_component_mask_t mask,
171*61046927SAndroid Build Coastguard Worker unsigned old_bit_size,
172*61046927SAndroid Build Coastguard Worker unsigned new_bit_size)
173*61046927SAndroid Build Coastguard Worker {
174*61046927SAndroid Build Coastguard Worker assert(nir_component_mask_can_reinterpret(mask, old_bit_size, new_bit_size));
175*61046927SAndroid Build Coastguard Worker
176*61046927SAndroid Build Coastguard Worker if (old_bit_size == new_bit_size)
177*61046927SAndroid Build Coastguard Worker return mask;
178*61046927SAndroid Build Coastguard Worker
179*61046927SAndroid Build Coastguard Worker nir_component_mask_t new_mask = 0;
180*61046927SAndroid Build Coastguard Worker unsigned iter = mask;
181*61046927SAndroid Build Coastguard Worker while (iter) {
182*61046927SAndroid Build Coastguard Worker int start, count;
183*61046927SAndroid Build Coastguard Worker u_bit_scan_consecutive_range(&iter, &start, &count);
184*61046927SAndroid Build Coastguard Worker start = start * old_bit_size / new_bit_size;
185*61046927SAndroid Build Coastguard Worker count = count * old_bit_size / new_bit_size;
186*61046927SAndroid Build Coastguard Worker new_mask |= BITFIELD_RANGE(start, count);
187*61046927SAndroid Build Coastguard Worker }
188*61046927SAndroid Build Coastguard Worker return new_mask;
189*61046927SAndroid Build Coastguard Worker }
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker nir_shader *
nir_shader_create(void * mem_ctx,gl_shader_stage stage,const nir_shader_compiler_options * options,shader_info * si)192*61046927SAndroid Build Coastguard Worker nir_shader_create(void *mem_ctx,
193*61046927SAndroid Build Coastguard Worker gl_shader_stage stage,
194*61046927SAndroid Build Coastguard Worker const nir_shader_compiler_options *options,
195*61046927SAndroid Build Coastguard Worker shader_info *si)
196*61046927SAndroid Build Coastguard Worker {
197*61046927SAndroid Build Coastguard Worker nir_shader *shader = rzalloc(mem_ctx, nir_shader);
198*61046927SAndroid Build Coastguard Worker
199*61046927SAndroid Build Coastguard Worker shader->gctx = gc_context(shader);
200*61046927SAndroid Build Coastguard Worker
201*61046927SAndroid Build Coastguard Worker #ifndef NDEBUG
202*61046927SAndroid Build Coastguard Worker nir_process_debug_variable();
203*61046927SAndroid Build Coastguard Worker #endif
204*61046927SAndroid Build Coastguard Worker
205*61046927SAndroid Build Coastguard Worker exec_list_make_empty(&shader->variables);
206*61046927SAndroid Build Coastguard Worker
207*61046927SAndroid Build Coastguard Worker shader->options = options;
208*61046927SAndroid Build Coastguard Worker
209*61046927SAndroid Build Coastguard Worker if (si) {
210*61046927SAndroid Build Coastguard Worker assert(si->stage == stage);
211*61046927SAndroid Build Coastguard Worker shader->info = *si;
212*61046927SAndroid Build Coastguard Worker } else {
213*61046927SAndroid Build Coastguard Worker shader->info.stage = stage;
214*61046927SAndroid Build Coastguard Worker }
215*61046927SAndroid Build Coastguard Worker
216*61046927SAndroid Build Coastguard Worker exec_list_make_empty(&shader->functions);
217*61046927SAndroid Build Coastguard Worker
218*61046927SAndroid Build Coastguard Worker shader->num_inputs = 0;
219*61046927SAndroid Build Coastguard Worker shader->num_outputs = 0;
220*61046927SAndroid Build Coastguard Worker shader->num_uniforms = 0;
221*61046927SAndroid Build Coastguard Worker
222*61046927SAndroid Build Coastguard Worker return shader;
223*61046927SAndroid Build Coastguard Worker }
224*61046927SAndroid Build Coastguard Worker
225*61046927SAndroid Build Coastguard Worker void
nir_shader_add_variable(nir_shader * shader,nir_variable * var)226*61046927SAndroid Build Coastguard Worker nir_shader_add_variable(nir_shader *shader, nir_variable *var)
227*61046927SAndroid Build Coastguard Worker {
228*61046927SAndroid Build Coastguard Worker switch (var->data.mode) {
229*61046927SAndroid Build Coastguard Worker case nir_var_function_temp:
230*61046927SAndroid Build Coastguard Worker assert(!"nir_shader_add_variable cannot be used for local variables");
231*61046927SAndroid Build Coastguard Worker return;
232*61046927SAndroid Build Coastguard Worker
233*61046927SAndroid Build Coastguard Worker case nir_var_shader_temp:
234*61046927SAndroid Build Coastguard Worker case nir_var_shader_in:
235*61046927SAndroid Build Coastguard Worker case nir_var_shader_out:
236*61046927SAndroid Build Coastguard Worker case nir_var_uniform:
237*61046927SAndroid Build Coastguard Worker case nir_var_mem_ubo:
238*61046927SAndroid Build Coastguard Worker case nir_var_mem_ssbo:
239*61046927SAndroid Build Coastguard Worker case nir_var_image:
240*61046927SAndroid Build Coastguard Worker case nir_var_mem_shared:
241*61046927SAndroid Build Coastguard Worker case nir_var_system_value:
242*61046927SAndroid Build Coastguard Worker case nir_var_mem_push_const:
243*61046927SAndroid Build Coastguard Worker case nir_var_mem_constant:
244*61046927SAndroid Build Coastguard Worker case nir_var_shader_call_data:
245*61046927SAndroid Build Coastguard Worker case nir_var_ray_hit_attrib:
246*61046927SAndroid Build Coastguard Worker case nir_var_mem_task_payload:
247*61046927SAndroid Build Coastguard Worker case nir_var_mem_node_payload:
248*61046927SAndroid Build Coastguard Worker case nir_var_mem_node_payload_in:
249*61046927SAndroid Build Coastguard Worker case nir_var_mem_global:
250*61046927SAndroid Build Coastguard Worker break;
251*61046927SAndroid Build Coastguard Worker
252*61046927SAndroid Build Coastguard Worker default:
253*61046927SAndroid Build Coastguard Worker assert(!"invalid mode");
254*61046927SAndroid Build Coastguard Worker return;
255*61046927SAndroid Build Coastguard Worker }
256*61046927SAndroid Build Coastguard Worker
257*61046927SAndroid Build Coastguard Worker exec_list_push_tail(&shader->variables, &var->node);
258*61046927SAndroid Build Coastguard Worker }
259*61046927SAndroid Build Coastguard Worker
260*61046927SAndroid Build Coastguard Worker nir_variable *
nir_variable_create(nir_shader * shader,nir_variable_mode mode,const struct glsl_type * type,const char * name)261*61046927SAndroid Build Coastguard Worker nir_variable_create(nir_shader *shader, nir_variable_mode mode,
262*61046927SAndroid Build Coastguard Worker const struct glsl_type *type, const char *name)
263*61046927SAndroid Build Coastguard Worker {
264*61046927SAndroid Build Coastguard Worker nir_variable *var = rzalloc(shader, nir_variable);
265*61046927SAndroid Build Coastguard Worker var->name = ralloc_strdup(var, name);
266*61046927SAndroid Build Coastguard Worker var->type = type;
267*61046927SAndroid Build Coastguard Worker var->data.mode = mode;
268*61046927SAndroid Build Coastguard Worker var->data.how_declared = nir_var_declared_normally;
269*61046927SAndroid Build Coastguard Worker
270*61046927SAndroid Build Coastguard Worker if ((mode == nir_var_shader_in &&
271*61046927SAndroid Build Coastguard Worker shader->info.stage != MESA_SHADER_VERTEX &&
272*61046927SAndroid Build Coastguard Worker shader->info.stage != MESA_SHADER_KERNEL) ||
273*61046927SAndroid Build Coastguard Worker (mode == nir_var_shader_out &&
274*61046927SAndroid Build Coastguard Worker shader->info.stage != MESA_SHADER_FRAGMENT))
275*61046927SAndroid Build Coastguard Worker var->data.interpolation = INTERP_MODE_SMOOTH;
276*61046927SAndroid Build Coastguard Worker
277*61046927SAndroid Build Coastguard Worker if (mode == nir_var_shader_in || mode == nir_var_uniform)
278*61046927SAndroid Build Coastguard Worker var->data.read_only = true;
279*61046927SAndroid Build Coastguard Worker
280*61046927SAndroid Build Coastguard Worker nir_shader_add_variable(shader, var);
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker return var;
283*61046927SAndroid Build Coastguard Worker }
284*61046927SAndroid Build Coastguard Worker
285*61046927SAndroid Build Coastguard Worker nir_variable *
nir_local_variable_create(nir_function_impl * impl,const struct glsl_type * type,const char * name)286*61046927SAndroid Build Coastguard Worker nir_local_variable_create(nir_function_impl *impl,
287*61046927SAndroid Build Coastguard Worker const struct glsl_type *type, const char *name)
288*61046927SAndroid Build Coastguard Worker {
289*61046927SAndroid Build Coastguard Worker nir_variable *var = rzalloc(impl->function->shader, nir_variable);
290*61046927SAndroid Build Coastguard Worker var->name = ralloc_strdup(var, name);
291*61046927SAndroid Build Coastguard Worker var->type = type;
292*61046927SAndroid Build Coastguard Worker var->data.mode = nir_var_function_temp;
293*61046927SAndroid Build Coastguard Worker
294*61046927SAndroid Build Coastguard Worker nir_function_impl_add_variable(impl, var);
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker return var;
297*61046927SAndroid Build Coastguard Worker }
298*61046927SAndroid Build Coastguard Worker
299*61046927SAndroid Build Coastguard Worker nir_variable *
nir_state_variable_create(nir_shader * shader,const struct glsl_type * type,const char * name,const gl_state_index16 tokens[STATE_LENGTH])300*61046927SAndroid Build Coastguard Worker nir_state_variable_create(nir_shader *shader,
301*61046927SAndroid Build Coastguard Worker const struct glsl_type *type,
302*61046927SAndroid Build Coastguard Worker const char *name,
303*61046927SAndroid Build Coastguard Worker const gl_state_index16 tokens[STATE_LENGTH])
304*61046927SAndroid Build Coastguard Worker {
305*61046927SAndroid Build Coastguard Worker nir_variable *var = nir_variable_create(shader, nir_var_uniform, type, name);
306*61046927SAndroid Build Coastguard Worker var->num_state_slots = 1;
307*61046927SAndroid Build Coastguard Worker var->state_slots = rzalloc_array(var, nir_state_slot, 1);
308*61046927SAndroid Build Coastguard Worker memcpy(var->state_slots[0].tokens, tokens,
309*61046927SAndroid Build Coastguard Worker sizeof(var->state_slots[0].tokens));
310*61046927SAndroid Build Coastguard Worker shader->num_uniforms++;
311*61046927SAndroid Build Coastguard Worker return var;
312*61046927SAndroid Build Coastguard Worker }
313*61046927SAndroid Build Coastguard Worker
314*61046927SAndroid Build Coastguard Worker nir_variable *
nir_create_variable_with_location(nir_shader * shader,nir_variable_mode mode,int location,const struct glsl_type * type)315*61046927SAndroid Build Coastguard Worker nir_create_variable_with_location(nir_shader *shader, nir_variable_mode mode, int location,
316*61046927SAndroid Build Coastguard Worker const struct glsl_type *type)
317*61046927SAndroid Build Coastguard Worker {
318*61046927SAndroid Build Coastguard Worker /* Only supporting non-array, or arrayed-io types, because otherwise we don't
319*61046927SAndroid Build Coastguard Worker * know how much to increment num_inputs/outputs
320*61046927SAndroid Build Coastguard Worker */
321*61046927SAndroid Build Coastguard Worker assert(glsl_type_is_vector_or_scalar(type) || glsl_type_is_unsized_array(type));
322*61046927SAndroid Build Coastguard Worker
323*61046927SAndroid Build Coastguard Worker const char *name;
324*61046927SAndroid Build Coastguard Worker switch (mode) {
325*61046927SAndroid Build Coastguard Worker case nir_var_shader_in:
326*61046927SAndroid Build Coastguard Worker if (shader->info.stage == MESA_SHADER_VERTEX)
327*61046927SAndroid Build Coastguard Worker name = gl_vert_attrib_name(location);
328*61046927SAndroid Build Coastguard Worker else
329*61046927SAndroid Build Coastguard Worker name = gl_varying_slot_name_for_stage(location, shader->info.stage);
330*61046927SAndroid Build Coastguard Worker break;
331*61046927SAndroid Build Coastguard Worker
332*61046927SAndroid Build Coastguard Worker case nir_var_shader_out:
333*61046927SAndroid Build Coastguard Worker if (shader->info.stage == MESA_SHADER_FRAGMENT)
334*61046927SAndroid Build Coastguard Worker name = gl_frag_result_name(location);
335*61046927SAndroid Build Coastguard Worker else
336*61046927SAndroid Build Coastguard Worker name = gl_varying_slot_name_for_stage(location, shader->info.stage);
337*61046927SAndroid Build Coastguard Worker break;
338*61046927SAndroid Build Coastguard Worker
339*61046927SAndroid Build Coastguard Worker case nir_var_system_value:
340*61046927SAndroid Build Coastguard Worker name = gl_system_value_name(location);
341*61046927SAndroid Build Coastguard Worker break;
342*61046927SAndroid Build Coastguard Worker
343*61046927SAndroid Build Coastguard Worker default:
344*61046927SAndroid Build Coastguard Worker unreachable("Unsupported variable mode");
345*61046927SAndroid Build Coastguard Worker }
346*61046927SAndroid Build Coastguard Worker
347*61046927SAndroid Build Coastguard Worker nir_variable *var = nir_variable_create(shader, mode, type, name);
348*61046927SAndroid Build Coastguard Worker var->data.location = location;
349*61046927SAndroid Build Coastguard Worker
350*61046927SAndroid Build Coastguard Worker switch (mode) {
351*61046927SAndroid Build Coastguard Worker case nir_var_shader_in:
352*61046927SAndroid Build Coastguard Worker var->data.driver_location = shader->num_inputs++;
353*61046927SAndroid Build Coastguard Worker break;
354*61046927SAndroid Build Coastguard Worker
355*61046927SAndroid Build Coastguard Worker case nir_var_shader_out:
356*61046927SAndroid Build Coastguard Worker var->data.driver_location = shader->num_outputs++;
357*61046927SAndroid Build Coastguard Worker break;
358*61046927SAndroid Build Coastguard Worker
359*61046927SAndroid Build Coastguard Worker case nir_var_system_value:
360*61046927SAndroid Build Coastguard Worker break;
361*61046927SAndroid Build Coastguard Worker
362*61046927SAndroid Build Coastguard Worker default:
363*61046927SAndroid Build Coastguard Worker unreachable("Unsupported variable mode");
364*61046927SAndroid Build Coastguard Worker }
365*61046927SAndroid Build Coastguard Worker
366*61046927SAndroid Build Coastguard Worker return var;
367*61046927SAndroid Build Coastguard Worker }
368*61046927SAndroid Build Coastguard Worker
369*61046927SAndroid Build Coastguard Worker nir_variable *
nir_get_variable_with_location(nir_shader * shader,nir_variable_mode mode,int location,const struct glsl_type * type)370*61046927SAndroid Build Coastguard Worker nir_get_variable_with_location(nir_shader *shader, nir_variable_mode mode, int location,
371*61046927SAndroid Build Coastguard Worker const struct glsl_type *type)
372*61046927SAndroid Build Coastguard Worker {
373*61046927SAndroid Build Coastguard Worker nir_variable *var = nir_find_variable_with_location(shader, mode, location);
374*61046927SAndroid Build Coastguard Worker if (var) {
375*61046927SAndroid Build Coastguard Worker /* If this shader has location_fracs, this builder function is not suitable. */
376*61046927SAndroid Build Coastguard Worker assert(var->data.location_frac == 0);
377*61046927SAndroid Build Coastguard Worker
378*61046927SAndroid Build Coastguard Worker /* The variable for the slot should match what we expected. */
379*61046927SAndroid Build Coastguard Worker assert(type == var->type);
380*61046927SAndroid Build Coastguard Worker return var;
381*61046927SAndroid Build Coastguard Worker }
382*61046927SAndroid Build Coastguard Worker
383*61046927SAndroid Build Coastguard Worker return nir_create_variable_with_location(shader, mode, location, type);
384*61046927SAndroid Build Coastguard Worker }
385*61046927SAndroid Build Coastguard Worker
386*61046927SAndroid Build Coastguard Worker nir_variable *
nir_find_variable_with_location(nir_shader * shader,nir_variable_mode mode,unsigned location)387*61046927SAndroid Build Coastguard Worker nir_find_variable_with_location(nir_shader *shader,
388*61046927SAndroid Build Coastguard Worker nir_variable_mode mode,
389*61046927SAndroid Build Coastguard Worker unsigned location)
390*61046927SAndroid Build Coastguard Worker {
391*61046927SAndroid Build Coastguard Worker assert(util_bitcount(mode) == 1 && mode != nir_var_function_temp);
392*61046927SAndroid Build Coastguard Worker nir_foreach_variable_with_modes(var, shader, mode) {
393*61046927SAndroid Build Coastguard Worker if (var->data.location == location)
394*61046927SAndroid Build Coastguard Worker return var;
395*61046927SAndroid Build Coastguard Worker }
396*61046927SAndroid Build Coastguard Worker return NULL;
397*61046927SAndroid Build Coastguard Worker }
398*61046927SAndroid Build Coastguard Worker
399*61046927SAndroid Build Coastguard Worker nir_variable *
nir_find_variable_with_driver_location(nir_shader * shader,nir_variable_mode mode,unsigned location)400*61046927SAndroid Build Coastguard Worker nir_find_variable_with_driver_location(nir_shader *shader,
401*61046927SAndroid Build Coastguard Worker nir_variable_mode mode,
402*61046927SAndroid Build Coastguard Worker unsigned location)
403*61046927SAndroid Build Coastguard Worker {
404*61046927SAndroid Build Coastguard Worker assert(util_bitcount(mode) == 1 && mode != nir_var_function_temp);
405*61046927SAndroid Build Coastguard Worker nir_foreach_variable_with_modes(var, shader, mode) {
406*61046927SAndroid Build Coastguard Worker if (var->data.driver_location == location)
407*61046927SAndroid Build Coastguard Worker return var;
408*61046927SAndroid Build Coastguard Worker }
409*61046927SAndroid Build Coastguard Worker return NULL;
410*61046927SAndroid Build Coastguard Worker }
411*61046927SAndroid Build Coastguard Worker
412*61046927SAndroid Build Coastguard Worker nir_variable *
nir_find_state_variable(nir_shader * s,gl_state_index16 tokens[STATE_LENGTH])413*61046927SAndroid Build Coastguard Worker nir_find_state_variable(nir_shader *s,
414*61046927SAndroid Build Coastguard Worker gl_state_index16 tokens[STATE_LENGTH])
415*61046927SAndroid Build Coastguard Worker {
416*61046927SAndroid Build Coastguard Worker nir_foreach_variable_with_modes(var, s, nir_var_uniform) {
417*61046927SAndroid Build Coastguard Worker if (var->num_state_slots == 1 &&
418*61046927SAndroid Build Coastguard Worker !memcmp(var->state_slots[0].tokens, tokens,
419*61046927SAndroid Build Coastguard Worker sizeof(var->state_slots[0].tokens)))
420*61046927SAndroid Build Coastguard Worker return var;
421*61046927SAndroid Build Coastguard Worker }
422*61046927SAndroid Build Coastguard Worker return NULL;
423*61046927SAndroid Build Coastguard Worker }
424*61046927SAndroid Build Coastguard Worker
nir_find_sampler_variable_with_tex_index(nir_shader * shader,unsigned texture_index)425*61046927SAndroid Build Coastguard Worker nir_variable *nir_find_sampler_variable_with_tex_index(nir_shader *shader,
426*61046927SAndroid Build Coastguard Worker unsigned texture_index)
427*61046927SAndroid Build Coastguard Worker {
428*61046927SAndroid Build Coastguard Worker nir_foreach_variable_with_modes(var, shader, nir_var_uniform) {
429*61046927SAndroid Build Coastguard Worker unsigned size =
430*61046927SAndroid Build Coastguard Worker glsl_type_is_array(var->type) ? glsl_array_size(var->type) : 1;
431*61046927SAndroid Build Coastguard Worker if ((glsl_type_is_texture(glsl_without_array(var->type)) ||
432*61046927SAndroid Build Coastguard Worker glsl_type_is_sampler(glsl_without_array(var->type))) &&
433*61046927SAndroid Build Coastguard Worker (var->data.binding == texture_index ||
434*61046927SAndroid Build Coastguard Worker (var->data.binding < texture_index &&
435*61046927SAndroid Build Coastguard Worker var->data.binding + size > texture_index)))
436*61046927SAndroid Build Coastguard Worker return var;
437*61046927SAndroid Build Coastguard Worker }
438*61046927SAndroid Build Coastguard Worker return NULL;
439*61046927SAndroid Build Coastguard Worker }
440*61046927SAndroid Build Coastguard Worker
441*61046927SAndroid Build Coastguard Worker /* Annoyingly, qsort_r is not in the C standard library and, in particular, we
442*61046927SAndroid Build Coastguard Worker * can't count on it on MSV and Android. So we stuff the CMP function into
443*61046927SAndroid Build Coastguard Worker * each array element. It's a bit messy and burns more memory but the list of
444*61046927SAndroid Build Coastguard Worker * variables should hever be all that long.
445*61046927SAndroid Build Coastguard Worker */
446*61046927SAndroid Build Coastguard Worker struct var_cmp {
447*61046927SAndroid Build Coastguard Worker nir_variable *var;
448*61046927SAndroid Build Coastguard Worker int (*cmp)(const nir_variable *, const nir_variable *);
449*61046927SAndroid Build Coastguard Worker };
450*61046927SAndroid Build Coastguard Worker
451*61046927SAndroid Build Coastguard Worker static int
var_sort_cmp(const void * _a,const void * _b,void * _cmp)452*61046927SAndroid Build Coastguard Worker var_sort_cmp(const void *_a, const void *_b, void *_cmp)
453*61046927SAndroid Build Coastguard Worker {
454*61046927SAndroid Build Coastguard Worker const struct var_cmp *a = _a;
455*61046927SAndroid Build Coastguard Worker const struct var_cmp *b = _b;
456*61046927SAndroid Build Coastguard Worker assert(a->cmp == b->cmp);
457*61046927SAndroid Build Coastguard Worker return a->cmp(a->var, b->var);
458*61046927SAndroid Build Coastguard Worker }
459*61046927SAndroid Build Coastguard Worker
460*61046927SAndroid Build Coastguard Worker void
nir_sort_variables_with_modes(nir_shader * shader,int (* cmp)(const nir_variable *,const nir_variable *),nir_variable_mode modes)461*61046927SAndroid Build Coastguard Worker nir_sort_variables_with_modes(nir_shader *shader,
462*61046927SAndroid Build Coastguard Worker int (*cmp)(const nir_variable *,
463*61046927SAndroid Build Coastguard Worker const nir_variable *),
464*61046927SAndroid Build Coastguard Worker nir_variable_mode modes)
465*61046927SAndroid Build Coastguard Worker {
466*61046927SAndroid Build Coastguard Worker unsigned num_vars = 0;
467*61046927SAndroid Build Coastguard Worker nir_foreach_variable_with_modes(var, shader, modes) {
468*61046927SAndroid Build Coastguard Worker ++num_vars;
469*61046927SAndroid Build Coastguard Worker }
470*61046927SAndroid Build Coastguard Worker struct var_cmp *vars = ralloc_array(shader, struct var_cmp, num_vars);
471*61046927SAndroid Build Coastguard Worker unsigned i = 0;
472*61046927SAndroid Build Coastguard Worker nir_foreach_variable_with_modes_safe(var, shader, modes) {
473*61046927SAndroid Build Coastguard Worker exec_node_remove(&var->node);
474*61046927SAndroid Build Coastguard Worker vars[i++] = (struct var_cmp){
475*61046927SAndroid Build Coastguard Worker .var = var,
476*61046927SAndroid Build Coastguard Worker .cmp = cmp,
477*61046927SAndroid Build Coastguard Worker };
478*61046927SAndroid Build Coastguard Worker }
479*61046927SAndroid Build Coastguard Worker assert(i == num_vars);
480*61046927SAndroid Build Coastguard Worker
481*61046927SAndroid Build Coastguard Worker util_qsort_r(vars, num_vars, sizeof(*vars), var_sort_cmp, cmp);
482*61046927SAndroid Build Coastguard Worker
483*61046927SAndroid Build Coastguard Worker for (i = 0; i < num_vars; i++)
484*61046927SAndroid Build Coastguard Worker exec_list_push_tail(&shader->variables, &vars[i].var->node);
485*61046927SAndroid Build Coastguard Worker
486*61046927SAndroid Build Coastguard Worker ralloc_free(vars);
487*61046927SAndroid Build Coastguard Worker }
488*61046927SAndroid Build Coastguard Worker
489*61046927SAndroid Build Coastguard Worker nir_function *
nir_function_create(nir_shader * shader,const char * name)490*61046927SAndroid Build Coastguard Worker nir_function_create(nir_shader *shader, const char *name)
491*61046927SAndroid Build Coastguard Worker {
492*61046927SAndroid Build Coastguard Worker nir_function *func = ralloc(shader, nir_function);
493*61046927SAndroid Build Coastguard Worker
494*61046927SAndroid Build Coastguard Worker exec_list_push_tail(&shader->functions, &func->node);
495*61046927SAndroid Build Coastguard Worker
496*61046927SAndroid Build Coastguard Worker func->name = ralloc_strdup(func, name);
497*61046927SAndroid Build Coastguard Worker func->shader = shader;
498*61046927SAndroid Build Coastguard Worker func->num_params = 0;
499*61046927SAndroid Build Coastguard Worker func->params = NULL;
500*61046927SAndroid Build Coastguard Worker func->impl = NULL;
501*61046927SAndroid Build Coastguard Worker func->is_entrypoint = false;
502*61046927SAndroid Build Coastguard Worker func->is_preamble = false;
503*61046927SAndroid Build Coastguard Worker func->dont_inline = false;
504*61046927SAndroid Build Coastguard Worker func->should_inline = false;
505*61046927SAndroid Build Coastguard Worker func->is_subroutine = false;
506*61046927SAndroid Build Coastguard Worker func->subroutine_index = 0;
507*61046927SAndroid Build Coastguard Worker func->num_subroutine_types = 0;
508*61046927SAndroid Build Coastguard Worker func->subroutine_types = NULL;
509*61046927SAndroid Build Coastguard Worker
510*61046927SAndroid Build Coastguard Worker /* Only meaningful for shader libraries, so don't export by default. */
511*61046927SAndroid Build Coastguard Worker func->is_exported = false;
512*61046927SAndroid Build Coastguard Worker
513*61046927SAndroid Build Coastguard Worker return func;
514*61046927SAndroid Build Coastguard Worker }
515*61046927SAndroid Build Coastguard Worker
516*61046927SAndroid Build Coastguard Worker void
nir_alu_src_copy(nir_alu_src * dest,const nir_alu_src * src)517*61046927SAndroid Build Coastguard Worker nir_alu_src_copy(nir_alu_src *dest, const nir_alu_src *src)
518*61046927SAndroid Build Coastguard Worker {
519*61046927SAndroid Build Coastguard Worker dest->src = nir_src_for_ssa(src->src.ssa);
520*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
521*61046927SAndroid Build Coastguard Worker dest->swizzle[i] = src->swizzle[i];
522*61046927SAndroid Build Coastguard Worker }
523*61046927SAndroid Build Coastguard Worker
524*61046927SAndroid Build Coastguard Worker bool
nir_alu_src_is_trivial_ssa(const nir_alu_instr * alu,unsigned srcn)525*61046927SAndroid Build Coastguard Worker nir_alu_src_is_trivial_ssa(const nir_alu_instr *alu, unsigned srcn)
526*61046927SAndroid Build Coastguard Worker {
527*61046927SAndroid Build Coastguard Worker static uint8_t trivial_swizzle[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
528*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ARRAY_SIZE(trivial_swizzle) == NIR_MAX_VEC_COMPONENTS);
529*61046927SAndroid Build Coastguard Worker
530*61046927SAndroid Build Coastguard Worker const nir_alu_src *src = &alu->src[srcn];
531*61046927SAndroid Build Coastguard Worker unsigned num_components = nir_ssa_alu_instr_src_components(alu, srcn);
532*61046927SAndroid Build Coastguard Worker
533*61046927SAndroid Build Coastguard Worker return (src->src.ssa->num_components == num_components) &&
534*61046927SAndroid Build Coastguard Worker (memcmp(src->swizzle, trivial_swizzle, num_components) == 0);
535*61046927SAndroid Build Coastguard Worker }
536*61046927SAndroid Build Coastguard Worker
537*61046927SAndroid Build Coastguard Worker static void
cf_init(nir_cf_node * node,nir_cf_node_type type)538*61046927SAndroid Build Coastguard Worker cf_init(nir_cf_node *node, nir_cf_node_type type)
539*61046927SAndroid Build Coastguard Worker {
540*61046927SAndroid Build Coastguard Worker exec_node_init(&node->node);
541*61046927SAndroid Build Coastguard Worker node->parent = NULL;
542*61046927SAndroid Build Coastguard Worker node->type = type;
543*61046927SAndroid Build Coastguard Worker }
544*61046927SAndroid Build Coastguard Worker
545*61046927SAndroid Build Coastguard Worker nir_function_impl *
nir_function_impl_create_bare(nir_shader * shader)546*61046927SAndroid Build Coastguard Worker nir_function_impl_create_bare(nir_shader *shader)
547*61046927SAndroid Build Coastguard Worker {
548*61046927SAndroid Build Coastguard Worker nir_function_impl *impl = ralloc(shader, nir_function_impl);
549*61046927SAndroid Build Coastguard Worker
550*61046927SAndroid Build Coastguard Worker impl->function = NULL;
551*61046927SAndroid Build Coastguard Worker impl->preamble = NULL;
552*61046927SAndroid Build Coastguard Worker
553*61046927SAndroid Build Coastguard Worker cf_init(&impl->cf_node, nir_cf_node_function);
554*61046927SAndroid Build Coastguard Worker
555*61046927SAndroid Build Coastguard Worker exec_list_make_empty(&impl->body);
556*61046927SAndroid Build Coastguard Worker exec_list_make_empty(&impl->locals);
557*61046927SAndroid Build Coastguard Worker impl->ssa_alloc = 0;
558*61046927SAndroid Build Coastguard Worker impl->num_blocks = 0;
559*61046927SAndroid Build Coastguard Worker impl->valid_metadata = nir_metadata_none;
560*61046927SAndroid Build Coastguard Worker impl->structured = true;
561*61046927SAndroid Build Coastguard Worker
562*61046927SAndroid Build Coastguard Worker /* create start & end blocks */
563*61046927SAndroid Build Coastguard Worker nir_block *start_block = nir_block_create(shader);
564*61046927SAndroid Build Coastguard Worker nir_block *end_block = nir_block_create(shader);
565*61046927SAndroid Build Coastguard Worker start_block->cf_node.parent = &impl->cf_node;
566*61046927SAndroid Build Coastguard Worker end_block->cf_node.parent = &impl->cf_node;
567*61046927SAndroid Build Coastguard Worker impl->end_block = end_block;
568*61046927SAndroid Build Coastguard Worker
569*61046927SAndroid Build Coastguard Worker exec_list_push_tail(&impl->body, &start_block->cf_node.node);
570*61046927SAndroid Build Coastguard Worker
571*61046927SAndroid Build Coastguard Worker start_block->successors[0] = end_block;
572*61046927SAndroid Build Coastguard Worker _mesa_set_add(end_block->predecessors, start_block);
573*61046927SAndroid Build Coastguard Worker return impl;
574*61046927SAndroid Build Coastguard Worker }
575*61046927SAndroid Build Coastguard Worker
576*61046927SAndroid Build Coastguard Worker nir_function_impl *
nir_function_impl_create(nir_function * function)577*61046927SAndroid Build Coastguard Worker nir_function_impl_create(nir_function *function)
578*61046927SAndroid Build Coastguard Worker {
579*61046927SAndroid Build Coastguard Worker assert(function->impl == NULL);
580*61046927SAndroid Build Coastguard Worker
581*61046927SAndroid Build Coastguard Worker nir_function_impl *impl = nir_function_impl_create_bare(function->shader);
582*61046927SAndroid Build Coastguard Worker nir_function_set_impl(function, impl);
583*61046927SAndroid Build Coastguard Worker return impl;
584*61046927SAndroid Build Coastguard Worker }
585*61046927SAndroid Build Coastguard Worker
586*61046927SAndroid Build Coastguard Worker nir_block *
nir_block_create(nir_shader * shader)587*61046927SAndroid Build Coastguard Worker nir_block_create(nir_shader *shader)
588*61046927SAndroid Build Coastguard Worker {
589*61046927SAndroid Build Coastguard Worker nir_block *block = rzalloc(shader, nir_block);
590*61046927SAndroid Build Coastguard Worker
591*61046927SAndroid Build Coastguard Worker cf_init(&block->cf_node, nir_cf_node_block);
592*61046927SAndroid Build Coastguard Worker
593*61046927SAndroid Build Coastguard Worker block->successors[0] = block->successors[1] = NULL;
594*61046927SAndroid Build Coastguard Worker block->predecessors = _mesa_pointer_set_create(block);
595*61046927SAndroid Build Coastguard Worker block->imm_dom = NULL;
596*61046927SAndroid Build Coastguard Worker /* XXX maybe it would be worth it to defer allocation? This
597*61046927SAndroid Build Coastguard Worker * way it doesn't get allocated for shader refs that never run
598*61046927SAndroid Build Coastguard Worker * nir_calc_dominance? For example, state-tracker creates an
599*61046927SAndroid Build Coastguard Worker * initial IR, clones that, runs appropriate lowering pass, passes
600*61046927SAndroid Build Coastguard Worker * to driver which does common lowering/opt, and then stores ref
601*61046927SAndroid Build Coastguard Worker * which is later used to do state specific lowering and futher
602*61046927SAndroid Build Coastguard Worker * opt. Do any of the references not need dominance metadata?
603*61046927SAndroid Build Coastguard Worker */
604*61046927SAndroid Build Coastguard Worker block->dom_frontier = _mesa_pointer_set_create(block);
605*61046927SAndroid Build Coastguard Worker
606*61046927SAndroid Build Coastguard Worker exec_list_make_empty(&block->instr_list);
607*61046927SAndroid Build Coastguard Worker
608*61046927SAndroid Build Coastguard Worker return block;
609*61046927SAndroid Build Coastguard Worker }
610*61046927SAndroid Build Coastguard Worker
611*61046927SAndroid Build Coastguard Worker static inline void
src_init(nir_src * src)612*61046927SAndroid Build Coastguard Worker src_init(nir_src *src)
613*61046927SAndroid Build Coastguard Worker {
614*61046927SAndroid Build Coastguard Worker src->ssa = NULL;
615*61046927SAndroid Build Coastguard Worker }
616*61046927SAndroid Build Coastguard Worker
617*61046927SAndroid Build Coastguard Worker nir_if *
nir_if_create(nir_shader * shader)618*61046927SAndroid Build Coastguard Worker nir_if_create(nir_shader *shader)
619*61046927SAndroid Build Coastguard Worker {
620*61046927SAndroid Build Coastguard Worker nir_if *if_stmt = ralloc(shader, nir_if);
621*61046927SAndroid Build Coastguard Worker
622*61046927SAndroid Build Coastguard Worker if_stmt->control = nir_selection_control_none;
623*61046927SAndroid Build Coastguard Worker
624*61046927SAndroid Build Coastguard Worker cf_init(&if_stmt->cf_node, nir_cf_node_if);
625*61046927SAndroid Build Coastguard Worker src_init(&if_stmt->condition);
626*61046927SAndroid Build Coastguard Worker
627*61046927SAndroid Build Coastguard Worker nir_block *then = nir_block_create(shader);
628*61046927SAndroid Build Coastguard Worker exec_list_make_empty(&if_stmt->then_list);
629*61046927SAndroid Build Coastguard Worker exec_list_push_tail(&if_stmt->then_list, &then->cf_node.node);
630*61046927SAndroid Build Coastguard Worker then->cf_node.parent = &if_stmt->cf_node;
631*61046927SAndroid Build Coastguard Worker
632*61046927SAndroid Build Coastguard Worker nir_block *else_stmt = nir_block_create(shader);
633*61046927SAndroid Build Coastguard Worker exec_list_make_empty(&if_stmt->else_list);
634*61046927SAndroid Build Coastguard Worker exec_list_push_tail(&if_stmt->else_list, &else_stmt->cf_node.node);
635*61046927SAndroid Build Coastguard Worker else_stmt->cf_node.parent = &if_stmt->cf_node;
636*61046927SAndroid Build Coastguard Worker
637*61046927SAndroid Build Coastguard Worker return if_stmt;
638*61046927SAndroid Build Coastguard Worker }
639*61046927SAndroid Build Coastguard Worker
640*61046927SAndroid Build Coastguard Worker nir_loop *
nir_loop_create(nir_shader * shader)641*61046927SAndroid Build Coastguard Worker nir_loop_create(nir_shader *shader)
642*61046927SAndroid Build Coastguard Worker {
643*61046927SAndroid Build Coastguard Worker nir_loop *loop = rzalloc(shader, nir_loop);
644*61046927SAndroid Build Coastguard Worker
645*61046927SAndroid Build Coastguard Worker cf_init(&loop->cf_node, nir_cf_node_loop);
646*61046927SAndroid Build Coastguard Worker /* Assume that loops are divergent until proven otherwise */
647*61046927SAndroid Build Coastguard Worker loop->divergent = true;
648*61046927SAndroid Build Coastguard Worker
649*61046927SAndroid Build Coastguard Worker nir_block *body = nir_block_create(shader);
650*61046927SAndroid Build Coastguard Worker exec_list_make_empty(&loop->body);
651*61046927SAndroid Build Coastguard Worker exec_list_push_tail(&loop->body, &body->cf_node.node);
652*61046927SAndroid Build Coastguard Worker body->cf_node.parent = &loop->cf_node;
653*61046927SAndroid Build Coastguard Worker
654*61046927SAndroid Build Coastguard Worker body->successors[0] = body;
655*61046927SAndroid Build Coastguard Worker _mesa_set_add(body->predecessors, body);
656*61046927SAndroid Build Coastguard Worker
657*61046927SAndroid Build Coastguard Worker exec_list_make_empty(&loop->continue_list);
658*61046927SAndroid Build Coastguard Worker
659*61046927SAndroid Build Coastguard Worker return loop;
660*61046927SAndroid Build Coastguard Worker }
661*61046927SAndroid Build Coastguard Worker
662*61046927SAndroid Build Coastguard Worker static void
instr_init(nir_instr * instr,nir_instr_type type)663*61046927SAndroid Build Coastguard Worker instr_init(nir_instr *instr, nir_instr_type type)
664*61046927SAndroid Build Coastguard Worker {
665*61046927SAndroid Build Coastguard Worker instr->type = type;
666*61046927SAndroid Build Coastguard Worker instr->block = NULL;
667*61046927SAndroid Build Coastguard Worker exec_node_init(&instr->node);
668*61046927SAndroid Build Coastguard Worker }
669*61046927SAndroid Build Coastguard Worker
670*61046927SAndroid Build Coastguard Worker static void
alu_src_init(nir_alu_src * src)671*61046927SAndroid Build Coastguard Worker alu_src_init(nir_alu_src *src)
672*61046927SAndroid Build Coastguard Worker {
673*61046927SAndroid Build Coastguard Worker src_init(&src->src);
674*61046927SAndroid Build Coastguard Worker for (int i = 0; i < NIR_MAX_VEC_COMPONENTS; ++i)
675*61046927SAndroid Build Coastguard Worker src->swizzle[i] = i;
676*61046927SAndroid Build Coastguard Worker }
677*61046927SAndroid Build Coastguard Worker
678*61046927SAndroid Build Coastguard Worker nir_alu_instr *
nir_alu_instr_create(nir_shader * shader,nir_op op)679*61046927SAndroid Build Coastguard Worker nir_alu_instr_create(nir_shader *shader, nir_op op)
680*61046927SAndroid Build Coastguard Worker {
681*61046927SAndroid Build Coastguard Worker unsigned num_srcs = nir_op_infos[op].num_inputs;
682*61046927SAndroid Build Coastguard Worker nir_alu_instr *instr = gc_zalloc_zla(shader->gctx, nir_alu_instr, nir_alu_src, num_srcs);
683*61046927SAndroid Build Coastguard Worker
684*61046927SAndroid Build Coastguard Worker instr_init(&instr->instr, nir_instr_type_alu);
685*61046927SAndroid Build Coastguard Worker instr->op = op;
686*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_srcs; i++)
687*61046927SAndroid Build Coastguard Worker alu_src_init(&instr->src[i]);
688*61046927SAndroid Build Coastguard Worker
689*61046927SAndroid Build Coastguard Worker return instr;
690*61046927SAndroid Build Coastguard Worker }
691*61046927SAndroid Build Coastguard Worker
692*61046927SAndroid Build Coastguard Worker nir_deref_instr *
nir_deref_instr_create(nir_shader * shader,nir_deref_type deref_type)693*61046927SAndroid Build Coastguard Worker nir_deref_instr_create(nir_shader *shader, nir_deref_type deref_type)
694*61046927SAndroid Build Coastguard Worker {
695*61046927SAndroid Build Coastguard Worker nir_deref_instr *instr = gc_zalloc(shader->gctx, nir_deref_instr, 1);
696*61046927SAndroid Build Coastguard Worker
697*61046927SAndroid Build Coastguard Worker instr_init(&instr->instr, nir_instr_type_deref);
698*61046927SAndroid Build Coastguard Worker
699*61046927SAndroid Build Coastguard Worker instr->deref_type = deref_type;
700*61046927SAndroid Build Coastguard Worker if (deref_type != nir_deref_type_var)
701*61046927SAndroid Build Coastguard Worker src_init(&instr->parent);
702*61046927SAndroid Build Coastguard Worker
703*61046927SAndroid Build Coastguard Worker if (deref_type == nir_deref_type_array ||
704*61046927SAndroid Build Coastguard Worker deref_type == nir_deref_type_ptr_as_array)
705*61046927SAndroid Build Coastguard Worker src_init(&instr->arr.index);
706*61046927SAndroid Build Coastguard Worker
707*61046927SAndroid Build Coastguard Worker return instr;
708*61046927SAndroid Build Coastguard Worker }
709*61046927SAndroid Build Coastguard Worker
710*61046927SAndroid Build Coastguard Worker nir_jump_instr *
nir_jump_instr_create(nir_shader * shader,nir_jump_type type)711*61046927SAndroid Build Coastguard Worker nir_jump_instr_create(nir_shader *shader, nir_jump_type type)
712*61046927SAndroid Build Coastguard Worker {
713*61046927SAndroid Build Coastguard Worker nir_jump_instr *instr = gc_alloc(shader->gctx, nir_jump_instr, 1);
714*61046927SAndroid Build Coastguard Worker instr_init(&instr->instr, nir_instr_type_jump);
715*61046927SAndroid Build Coastguard Worker src_init(&instr->condition);
716*61046927SAndroid Build Coastguard Worker instr->type = type;
717*61046927SAndroid Build Coastguard Worker instr->target = NULL;
718*61046927SAndroid Build Coastguard Worker instr->else_target = NULL;
719*61046927SAndroid Build Coastguard Worker
720*61046927SAndroid Build Coastguard Worker return instr;
721*61046927SAndroid Build Coastguard Worker }
722*61046927SAndroid Build Coastguard Worker
723*61046927SAndroid Build Coastguard Worker nir_load_const_instr *
nir_load_const_instr_create(nir_shader * shader,unsigned num_components,unsigned bit_size)724*61046927SAndroid Build Coastguard Worker nir_load_const_instr_create(nir_shader *shader, unsigned num_components,
725*61046927SAndroid Build Coastguard Worker unsigned bit_size)
726*61046927SAndroid Build Coastguard Worker {
727*61046927SAndroid Build Coastguard Worker nir_load_const_instr *instr =
728*61046927SAndroid Build Coastguard Worker gc_zalloc_zla(shader->gctx, nir_load_const_instr, nir_const_value, num_components);
729*61046927SAndroid Build Coastguard Worker instr_init(&instr->instr, nir_instr_type_load_const);
730*61046927SAndroid Build Coastguard Worker
731*61046927SAndroid Build Coastguard Worker nir_def_init(&instr->instr, &instr->def, num_components, bit_size);
732*61046927SAndroid Build Coastguard Worker
733*61046927SAndroid Build Coastguard Worker return instr;
734*61046927SAndroid Build Coastguard Worker }
735*61046927SAndroid Build Coastguard Worker
736*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *
nir_intrinsic_instr_create(nir_shader * shader,nir_intrinsic_op op)737*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr_create(nir_shader *shader, nir_intrinsic_op op)
738*61046927SAndroid Build Coastguard Worker {
739*61046927SAndroid Build Coastguard Worker unsigned num_srcs = nir_intrinsic_infos[op].num_srcs;
740*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *instr =
741*61046927SAndroid Build Coastguard Worker gc_zalloc_zla(shader->gctx, nir_intrinsic_instr, nir_src, num_srcs);
742*61046927SAndroid Build Coastguard Worker
743*61046927SAndroid Build Coastguard Worker instr_init(&instr->instr, nir_instr_type_intrinsic);
744*61046927SAndroid Build Coastguard Worker instr->intrinsic = op;
745*61046927SAndroid Build Coastguard Worker
746*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_srcs; i++)
747*61046927SAndroid Build Coastguard Worker src_init(&instr->src[i]);
748*61046927SAndroid Build Coastguard Worker
749*61046927SAndroid Build Coastguard Worker return instr;
750*61046927SAndroid Build Coastguard Worker }
751*61046927SAndroid Build Coastguard Worker
752*61046927SAndroid Build Coastguard Worker nir_call_instr *
nir_call_instr_create(nir_shader * shader,nir_function * callee)753*61046927SAndroid Build Coastguard Worker nir_call_instr_create(nir_shader *shader, nir_function *callee)
754*61046927SAndroid Build Coastguard Worker {
755*61046927SAndroid Build Coastguard Worker const unsigned num_params = callee->num_params;
756*61046927SAndroid Build Coastguard Worker nir_call_instr *instr =
757*61046927SAndroid Build Coastguard Worker gc_zalloc_zla(shader->gctx, nir_call_instr, nir_src, num_params);
758*61046927SAndroid Build Coastguard Worker
759*61046927SAndroid Build Coastguard Worker instr_init(&instr->instr, nir_instr_type_call);
760*61046927SAndroid Build Coastguard Worker instr->callee = callee;
761*61046927SAndroid Build Coastguard Worker instr->num_params = num_params;
762*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_params; i++)
763*61046927SAndroid Build Coastguard Worker src_init(&instr->params[i]);
764*61046927SAndroid Build Coastguard Worker
765*61046927SAndroid Build Coastguard Worker return instr;
766*61046927SAndroid Build Coastguard Worker }
767*61046927SAndroid Build Coastguard Worker
768*61046927SAndroid Build Coastguard Worker static int8_t default_tg4_offsets[4][2] = {
769*61046927SAndroid Build Coastguard Worker { 0, 1 },
770*61046927SAndroid Build Coastguard Worker { 1, 1 },
771*61046927SAndroid Build Coastguard Worker { 1, 0 },
772*61046927SAndroid Build Coastguard Worker { 0, 0 },
773*61046927SAndroid Build Coastguard Worker };
774*61046927SAndroid Build Coastguard Worker
775*61046927SAndroid Build Coastguard Worker nir_tex_instr *
nir_tex_instr_create(nir_shader * shader,unsigned num_srcs)776*61046927SAndroid Build Coastguard Worker nir_tex_instr_create(nir_shader *shader, unsigned num_srcs)
777*61046927SAndroid Build Coastguard Worker {
778*61046927SAndroid Build Coastguard Worker nir_tex_instr *instr = gc_zalloc(shader->gctx, nir_tex_instr, 1);
779*61046927SAndroid Build Coastguard Worker instr_init(&instr->instr, nir_instr_type_tex);
780*61046927SAndroid Build Coastguard Worker
781*61046927SAndroid Build Coastguard Worker instr->num_srcs = num_srcs;
782*61046927SAndroid Build Coastguard Worker instr->src = gc_alloc(shader->gctx, nir_tex_src, num_srcs);
783*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_srcs; i++)
784*61046927SAndroid Build Coastguard Worker src_init(&instr->src[i].src);
785*61046927SAndroid Build Coastguard Worker
786*61046927SAndroid Build Coastguard Worker instr->texture_index = 0;
787*61046927SAndroid Build Coastguard Worker instr->sampler_index = 0;
788*61046927SAndroid Build Coastguard Worker memcpy(instr->tg4_offsets, default_tg4_offsets, sizeof(instr->tg4_offsets));
789*61046927SAndroid Build Coastguard Worker
790*61046927SAndroid Build Coastguard Worker return instr;
791*61046927SAndroid Build Coastguard Worker }
792*61046927SAndroid Build Coastguard Worker
793*61046927SAndroid Build Coastguard Worker void
nir_tex_instr_add_src(nir_tex_instr * tex,nir_tex_src_type src_type,nir_def * src)794*61046927SAndroid Build Coastguard Worker nir_tex_instr_add_src(nir_tex_instr *tex,
795*61046927SAndroid Build Coastguard Worker nir_tex_src_type src_type,
796*61046927SAndroid Build Coastguard Worker nir_def *src)
797*61046927SAndroid Build Coastguard Worker {
798*61046927SAndroid Build Coastguard Worker nir_tex_src *new_srcs = gc_zalloc(gc_get_context(tex), nir_tex_src, tex->num_srcs + 1);
799*61046927SAndroid Build Coastguard Worker
800*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < tex->num_srcs; i++) {
801*61046927SAndroid Build Coastguard Worker new_srcs[i].src_type = tex->src[i].src_type;
802*61046927SAndroid Build Coastguard Worker nir_instr_move_src(&tex->instr, &new_srcs[i].src,
803*61046927SAndroid Build Coastguard Worker &tex->src[i].src);
804*61046927SAndroid Build Coastguard Worker }
805*61046927SAndroid Build Coastguard Worker
806*61046927SAndroid Build Coastguard Worker gc_free(tex->src);
807*61046927SAndroid Build Coastguard Worker tex->src = new_srcs;
808*61046927SAndroid Build Coastguard Worker
809*61046927SAndroid Build Coastguard Worker tex->src[tex->num_srcs].src_type = src_type;
810*61046927SAndroid Build Coastguard Worker nir_instr_init_src(&tex->instr, &tex->src[tex->num_srcs].src, src);
811*61046927SAndroid Build Coastguard Worker tex->num_srcs++;
812*61046927SAndroid Build Coastguard Worker }
813*61046927SAndroid Build Coastguard Worker
814*61046927SAndroid Build Coastguard Worker void
nir_tex_instr_remove_src(nir_tex_instr * tex,unsigned src_idx)815*61046927SAndroid Build Coastguard Worker nir_tex_instr_remove_src(nir_tex_instr *tex, unsigned src_idx)
816*61046927SAndroid Build Coastguard Worker {
817*61046927SAndroid Build Coastguard Worker assert(src_idx < tex->num_srcs);
818*61046927SAndroid Build Coastguard Worker
819*61046927SAndroid Build Coastguard Worker /* First rewrite the source to NIR_SRC_INIT */
820*61046927SAndroid Build Coastguard Worker nir_instr_clear_src(&tex->instr, &tex->src[src_idx].src);
821*61046927SAndroid Build Coastguard Worker
822*61046927SAndroid Build Coastguard Worker /* Now, move all of the other sources down */
823*61046927SAndroid Build Coastguard Worker for (unsigned i = src_idx + 1; i < tex->num_srcs; i++) {
824*61046927SAndroid Build Coastguard Worker tex->src[i - 1].src_type = tex->src[i].src_type;
825*61046927SAndroid Build Coastguard Worker nir_instr_move_src(&tex->instr, &tex->src[i - 1].src, &tex->src[i].src);
826*61046927SAndroid Build Coastguard Worker }
827*61046927SAndroid Build Coastguard Worker tex->num_srcs--;
828*61046927SAndroid Build Coastguard Worker }
829*61046927SAndroid Build Coastguard Worker
830*61046927SAndroid Build Coastguard Worker bool
nir_tex_instr_has_explicit_tg4_offsets(nir_tex_instr * tex)831*61046927SAndroid Build Coastguard Worker nir_tex_instr_has_explicit_tg4_offsets(nir_tex_instr *tex)
832*61046927SAndroid Build Coastguard Worker {
833*61046927SAndroid Build Coastguard Worker if (tex->op != nir_texop_tg4)
834*61046927SAndroid Build Coastguard Worker return false;
835*61046927SAndroid Build Coastguard Worker return memcmp(tex->tg4_offsets, default_tg4_offsets,
836*61046927SAndroid Build Coastguard Worker sizeof(tex->tg4_offsets)) != 0;
837*61046927SAndroid Build Coastguard Worker }
838*61046927SAndroid Build Coastguard Worker
839*61046927SAndroid Build Coastguard Worker nir_phi_instr *
nir_phi_instr_create(nir_shader * shader)840*61046927SAndroid Build Coastguard Worker nir_phi_instr_create(nir_shader *shader)
841*61046927SAndroid Build Coastguard Worker {
842*61046927SAndroid Build Coastguard Worker nir_phi_instr *instr = gc_alloc(shader->gctx, nir_phi_instr, 1);
843*61046927SAndroid Build Coastguard Worker instr_init(&instr->instr, nir_instr_type_phi);
844*61046927SAndroid Build Coastguard Worker
845*61046927SAndroid Build Coastguard Worker exec_list_make_empty(&instr->srcs);
846*61046927SAndroid Build Coastguard Worker
847*61046927SAndroid Build Coastguard Worker return instr;
848*61046927SAndroid Build Coastguard Worker }
849*61046927SAndroid Build Coastguard Worker
850*61046927SAndroid Build Coastguard Worker /**
851*61046927SAndroid Build Coastguard Worker * Adds a new source to a NIR instruction.
852*61046927SAndroid Build Coastguard Worker *
853*61046927SAndroid Build Coastguard Worker * Note that this does not update the def/use relationship for src, assuming
854*61046927SAndroid Build Coastguard Worker * that the instr is not in the shader. If it is, you have to do:
855*61046927SAndroid Build Coastguard Worker *
856*61046927SAndroid Build Coastguard Worker * list_addtail(&phi_src->src.use_link, &src.ssa->uses);
857*61046927SAndroid Build Coastguard Worker */
858*61046927SAndroid Build Coastguard Worker nir_phi_src *
nir_phi_instr_add_src(nir_phi_instr * instr,nir_block * pred,nir_def * src)859*61046927SAndroid Build Coastguard Worker nir_phi_instr_add_src(nir_phi_instr *instr, nir_block *pred, nir_def *src)
860*61046927SAndroid Build Coastguard Worker {
861*61046927SAndroid Build Coastguard Worker nir_phi_src *phi_src;
862*61046927SAndroid Build Coastguard Worker
863*61046927SAndroid Build Coastguard Worker phi_src = gc_zalloc(gc_get_context(instr), nir_phi_src, 1);
864*61046927SAndroid Build Coastguard Worker phi_src->pred = pred;
865*61046927SAndroid Build Coastguard Worker phi_src->src = nir_src_for_ssa(src);
866*61046927SAndroid Build Coastguard Worker nir_src_set_parent_instr(&phi_src->src, &instr->instr);
867*61046927SAndroid Build Coastguard Worker exec_list_push_tail(&instr->srcs, &phi_src->node);
868*61046927SAndroid Build Coastguard Worker
869*61046927SAndroid Build Coastguard Worker return phi_src;
870*61046927SAndroid Build Coastguard Worker }
871*61046927SAndroid Build Coastguard Worker
872*61046927SAndroid Build Coastguard Worker nir_parallel_copy_instr *
nir_parallel_copy_instr_create(nir_shader * shader)873*61046927SAndroid Build Coastguard Worker nir_parallel_copy_instr_create(nir_shader *shader)
874*61046927SAndroid Build Coastguard Worker {
875*61046927SAndroid Build Coastguard Worker nir_parallel_copy_instr *instr = gc_alloc(shader->gctx, nir_parallel_copy_instr, 1);
876*61046927SAndroid Build Coastguard Worker instr_init(&instr->instr, nir_instr_type_parallel_copy);
877*61046927SAndroid Build Coastguard Worker
878*61046927SAndroid Build Coastguard Worker exec_list_make_empty(&instr->entries);
879*61046927SAndroid Build Coastguard Worker
880*61046927SAndroid Build Coastguard Worker return instr;
881*61046927SAndroid Build Coastguard Worker }
882*61046927SAndroid Build Coastguard Worker
883*61046927SAndroid Build Coastguard Worker nir_debug_info_instr *
nir_debug_info_instr_create(nir_shader * shader,nir_debug_info_type type,uint32_t string_length)884*61046927SAndroid Build Coastguard Worker nir_debug_info_instr_create(nir_shader *shader, nir_debug_info_type type,
885*61046927SAndroid Build Coastguard Worker uint32_t string_length)
886*61046927SAndroid Build Coastguard Worker {
887*61046927SAndroid Build Coastguard Worker uint32_t additional_size = 0;
888*61046927SAndroid Build Coastguard Worker if (type == nir_debug_info_string)
889*61046927SAndroid Build Coastguard Worker additional_size = string_length + 1;
890*61046927SAndroid Build Coastguard Worker
891*61046927SAndroid Build Coastguard Worker nir_debug_info_instr *instr = gc_zalloc_size(
892*61046927SAndroid Build Coastguard Worker shader->gctx, sizeof(nir_debug_info_instr) + additional_size, 1);
893*61046927SAndroid Build Coastguard Worker instr_init(&instr->instr, nir_instr_type_debug_info);
894*61046927SAndroid Build Coastguard Worker
895*61046927SAndroid Build Coastguard Worker instr->type = type;
896*61046927SAndroid Build Coastguard Worker
897*61046927SAndroid Build Coastguard Worker if (type == nir_debug_info_string)
898*61046927SAndroid Build Coastguard Worker instr->string_length = string_length;
899*61046927SAndroid Build Coastguard Worker
900*61046927SAndroid Build Coastguard Worker return instr;
901*61046927SAndroid Build Coastguard Worker }
902*61046927SAndroid Build Coastguard Worker
903*61046927SAndroid Build Coastguard Worker nir_undef_instr *
nir_undef_instr_create(nir_shader * shader,unsigned num_components,unsigned bit_size)904*61046927SAndroid Build Coastguard Worker nir_undef_instr_create(nir_shader *shader,
905*61046927SAndroid Build Coastguard Worker unsigned num_components,
906*61046927SAndroid Build Coastguard Worker unsigned bit_size)
907*61046927SAndroid Build Coastguard Worker {
908*61046927SAndroid Build Coastguard Worker nir_undef_instr *instr = gc_alloc(shader->gctx, nir_undef_instr, 1);
909*61046927SAndroid Build Coastguard Worker instr_init(&instr->instr, nir_instr_type_undef);
910*61046927SAndroid Build Coastguard Worker
911*61046927SAndroid Build Coastguard Worker nir_def_init(&instr->instr, &instr->def, num_components, bit_size);
912*61046927SAndroid Build Coastguard Worker
913*61046927SAndroid Build Coastguard Worker return instr;
914*61046927SAndroid Build Coastguard Worker }
915*61046927SAndroid Build Coastguard Worker
916*61046927SAndroid Build Coastguard Worker static nir_const_value
const_value_float(double d,unsigned bit_size)917*61046927SAndroid Build Coastguard Worker const_value_float(double d, unsigned bit_size)
918*61046927SAndroid Build Coastguard Worker {
919*61046927SAndroid Build Coastguard Worker nir_const_value v;
920*61046927SAndroid Build Coastguard Worker memset(&v, 0, sizeof(v));
921*61046927SAndroid Build Coastguard Worker
922*61046927SAndroid Build Coastguard Worker /* clang-format off */
923*61046927SAndroid Build Coastguard Worker switch (bit_size) {
924*61046927SAndroid Build Coastguard Worker case 16: v.u16 = _mesa_float_to_half(d); break;
925*61046927SAndroid Build Coastguard Worker case 32: v.f32 = d; break;
926*61046927SAndroid Build Coastguard Worker case 64: v.f64 = d; break;
927*61046927SAndroid Build Coastguard Worker default:
928*61046927SAndroid Build Coastguard Worker unreachable("Invalid bit size");
929*61046927SAndroid Build Coastguard Worker }
930*61046927SAndroid Build Coastguard Worker /* clang-format on */
931*61046927SAndroid Build Coastguard Worker
932*61046927SAndroid Build Coastguard Worker return v;
933*61046927SAndroid Build Coastguard Worker }
934*61046927SAndroid Build Coastguard Worker
935*61046927SAndroid Build Coastguard Worker static nir_const_value
const_value_int(int64_t i,unsigned bit_size)936*61046927SAndroid Build Coastguard Worker const_value_int(int64_t i, unsigned bit_size)
937*61046927SAndroid Build Coastguard Worker {
938*61046927SAndroid Build Coastguard Worker nir_const_value v;
939*61046927SAndroid Build Coastguard Worker memset(&v, 0, sizeof(v));
940*61046927SAndroid Build Coastguard Worker
941*61046927SAndroid Build Coastguard Worker /* clang-format off */
942*61046927SAndroid Build Coastguard Worker switch (bit_size) {
943*61046927SAndroid Build Coastguard Worker case 1: v.b = i & 1; break;
944*61046927SAndroid Build Coastguard Worker case 8: v.i8 = i; break;
945*61046927SAndroid Build Coastguard Worker case 16: v.i16 = i; break;
946*61046927SAndroid Build Coastguard Worker case 32: v.i32 = i; break;
947*61046927SAndroid Build Coastguard Worker case 64: v.i64 = i; break;
948*61046927SAndroid Build Coastguard Worker default:
949*61046927SAndroid Build Coastguard Worker unreachable("Invalid bit size");
950*61046927SAndroid Build Coastguard Worker }
951*61046927SAndroid Build Coastguard Worker /* clang-format on */
952*61046927SAndroid Build Coastguard Worker
953*61046927SAndroid Build Coastguard Worker return v;
954*61046927SAndroid Build Coastguard Worker }
955*61046927SAndroid Build Coastguard Worker
956*61046927SAndroid Build Coastguard Worker nir_const_value
nir_alu_binop_identity(nir_op binop,unsigned bit_size)957*61046927SAndroid Build Coastguard Worker nir_alu_binop_identity(nir_op binop, unsigned bit_size)
958*61046927SAndroid Build Coastguard Worker {
959*61046927SAndroid Build Coastguard Worker const int64_t max_int = (1ull << (bit_size - 1)) - 1;
960*61046927SAndroid Build Coastguard Worker const int64_t min_int = -max_int - 1;
961*61046927SAndroid Build Coastguard Worker switch (binop) {
962*61046927SAndroid Build Coastguard Worker case nir_op_iadd:
963*61046927SAndroid Build Coastguard Worker return const_value_int(0, bit_size);
964*61046927SAndroid Build Coastguard Worker case nir_op_fadd:
965*61046927SAndroid Build Coastguard Worker return const_value_float(0, bit_size);
966*61046927SAndroid Build Coastguard Worker case nir_op_imul:
967*61046927SAndroid Build Coastguard Worker return const_value_int(1, bit_size);
968*61046927SAndroid Build Coastguard Worker case nir_op_fmul:
969*61046927SAndroid Build Coastguard Worker return const_value_float(1, bit_size);
970*61046927SAndroid Build Coastguard Worker case nir_op_imin:
971*61046927SAndroid Build Coastguard Worker return const_value_int(max_int, bit_size);
972*61046927SAndroid Build Coastguard Worker case nir_op_umin:
973*61046927SAndroid Build Coastguard Worker return const_value_int(~0ull, bit_size);
974*61046927SAndroid Build Coastguard Worker case nir_op_fmin:
975*61046927SAndroid Build Coastguard Worker return const_value_float(INFINITY, bit_size);
976*61046927SAndroid Build Coastguard Worker case nir_op_imax:
977*61046927SAndroid Build Coastguard Worker return const_value_int(min_int, bit_size);
978*61046927SAndroid Build Coastguard Worker case nir_op_umax:
979*61046927SAndroid Build Coastguard Worker return const_value_int(0, bit_size);
980*61046927SAndroid Build Coastguard Worker case nir_op_fmax:
981*61046927SAndroid Build Coastguard Worker return const_value_float(-INFINITY, bit_size);
982*61046927SAndroid Build Coastguard Worker case nir_op_iand:
983*61046927SAndroid Build Coastguard Worker return const_value_int(~0ull, bit_size);
984*61046927SAndroid Build Coastguard Worker case nir_op_ior:
985*61046927SAndroid Build Coastguard Worker return const_value_int(0, bit_size);
986*61046927SAndroid Build Coastguard Worker case nir_op_ixor:
987*61046927SAndroid Build Coastguard Worker return const_value_int(0, bit_size);
988*61046927SAndroid Build Coastguard Worker default:
989*61046927SAndroid Build Coastguard Worker unreachable("Invalid reduction operation");
990*61046927SAndroid Build Coastguard Worker }
991*61046927SAndroid Build Coastguard Worker }
992*61046927SAndroid Build Coastguard Worker
993*61046927SAndroid Build Coastguard Worker nir_function_impl *
nir_cf_node_get_function(nir_cf_node * node)994*61046927SAndroid Build Coastguard Worker nir_cf_node_get_function(nir_cf_node *node)
995*61046927SAndroid Build Coastguard Worker {
996*61046927SAndroid Build Coastguard Worker while (node->type != nir_cf_node_function) {
997*61046927SAndroid Build Coastguard Worker node = node->parent;
998*61046927SAndroid Build Coastguard Worker }
999*61046927SAndroid Build Coastguard Worker
1000*61046927SAndroid Build Coastguard Worker return nir_cf_node_as_function(node);
1001*61046927SAndroid Build Coastguard Worker }
1002*61046927SAndroid Build Coastguard Worker
1003*61046927SAndroid Build Coastguard Worker /* Reduces a cursor by trying to convert everything to after and trying to
1004*61046927SAndroid Build Coastguard Worker * go up to block granularity when possible.
1005*61046927SAndroid Build Coastguard Worker */
1006*61046927SAndroid Build Coastguard Worker static nir_cursor
reduce_cursor(nir_cursor cursor)1007*61046927SAndroid Build Coastguard Worker reduce_cursor(nir_cursor cursor)
1008*61046927SAndroid Build Coastguard Worker {
1009*61046927SAndroid Build Coastguard Worker switch (cursor.option) {
1010*61046927SAndroid Build Coastguard Worker case nir_cursor_before_block:
1011*61046927SAndroid Build Coastguard Worker if (exec_list_is_empty(&cursor.block->instr_list)) {
1012*61046927SAndroid Build Coastguard Worker /* Empty block. After is as good as before. */
1013*61046927SAndroid Build Coastguard Worker cursor.option = nir_cursor_after_block;
1014*61046927SAndroid Build Coastguard Worker }
1015*61046927SAndroid Build Coastguard Worker return cursor;
1016*61046927SAndroid Build Coastguard Worker
1017*61046927SAndroid Build Coastguard Worker case nir_cursor_after_block:
1018*61046927SAndroid Build Coastguard Worker return cursor;
1019*61046927SAndroid Build Coastguard Worker
1020*61046927SAndroid Build Coastguard Worker case nir_cursor_before_instr: {
1021*61046927SAndroid Build Coastguard Worker nir_instr *prev_instr = nir_instr_prev(cursor.instr);
1022*61046927SAndroid Build Coastguard Worker if (prev_instr) {
1023*61046927SAndroid Build Coastguard Worker /* Before this instruction is after the previous */
1024*61046927SAndroid Build Coastguard Worker cursor.instr = prev_instr;
1025*61046927SAndroid Build Coastguard Worker cursor.option = nir_cursor_after_instr;
1026*61046927SAndroid Build Coastguard Worker } else {
1027*61046927SAndroid Build Coastguard Worker /* No previous instruction. Switch to before block */
1028*61046927SAndroid Build Coastguard Worker cursor.block = cursor.instr->block;
1029*61046927SAndroid Build Coastguard Worker cursor.option = nir_cursor_before_block;
1030*61046927SAndroid Build Coastguard Worker }
1031*61046927SAndroid Build Coastguard Worker return reduce_cursor(cursor);
1032*61046927SAndroid Build Coastguard Worker }
1033*61046927SAndroid Build Coastguard Worker
1034*61046927SAndroid Build Coastguard Worker case nir_cursor_after_instr:
1035*61046927SAndroid Build Coastguard Worker if (nir_instr_next(cursor.instr) == NULL) {
1036*61046927SAndroid Build Coastguard Worker /* This is the last instruction, switch to after block */
1037*61046927SAndroid Build Coastguard Worker cursor.option = nir_cursor_after_block;
1038*61046927SAndroid Build Coastguard Worker cursor.block = cursor.instr->block;
1039*61046927SAndroid Build Coastguard Worker }
1040*61046927SAndroid Build Coastguard Worker return cursor;
1041*61046927SAndroid Build Coastguard Worker
1042*61046927SAndroid Build Coastguard Worker default:
1043*61046927SAndroid Build Coastguard Worker unreachable("Inavlid cursor option");
1044*61046927SAndroid Build Coastguard Worker }
1045*61046927SAndroid Build Coastguard Worker }
1046*61046927SAndroid Build Coastguard Worker
1047*61046927SAndroid Build Coastguard Worker bool
nir_cursors_equal(nir_cursor a,nir_cursor b)1048*61046927SAndroid Build Coastguard Worker nir_cursors_equal(nir_cursor a, nir_cursor b)
1049*61046927SAndroid Build Coastguard Worker {
1050*61046927SAndroid Build Coastguard Worker /* Reduced cursors should be unique */
1051*61046927SAndroid Build Coastguard Worker a = reduce_cursor(a);
1052*61046927SAndroid Build Coastguard Worker b = reduce_cursor(b);
1053*61046927SAndroid Build Coastguard Worker
1054*61046927SAndroid Build Coastguard Worker return a.block == b.block && a.option == b.option;
1055*61046927SAndroid Build Coastguard Worker }
1056*61046927SAndroid Build Coastguard Worker
1057*61046927SAndroid Build Coastguard Worker static bool
add_use_cb(nir_src * src,void * state)1058*61046927SAndroid Build Coastguard Worker add_use_cb(nir_src *src, void *state)
1059*61046927SAndroid Build Coastguard Worker {
1060*61046927SAndroid Build Coastguard Worker nir_instr *instr = state;
1061*61046927SAndroid Build Coastguard Worker
1062*61046927SAndroid Build Coastguard Worker nir_src_set_parent_instr(src, instr);
1063*61046927SAndroid Build Coastguard Worker list_addtail(&src->use_link, &src->ssa->uses);
1064*61046927SAndroid Build Coastguard Worker
1065*61046927SAndroid Build Coastguard Worker return true;
1066*61046927SAndroid Build Coastguard Worker }
1067*61046927SAndroid Build Coastguard Worker
1068*61046927SAndroid Build Coastguard Worker static bool
add_ssa_def_cb(nir_def * def,void * state)1069*61046927SAndroid Build Coastguard Worker add_ssa_def_cb(nir_def *def, void *state)
1070*61046927SAndroid Build Coastguard Worker {
1071*61046927SAndroid Build Coastguard Worker nir_instr *instr = state;
1072*61046927SAndroid Build Coastguard Worker
1073*61046927SAndroid Build Coastguard Worker if (instr->block && def->index == UINT_MAX) {
1074*61046927SAndroid Build Coastguard Worker nir_function_impl *impl =
1075*61046927SAndroid Build Coastguard Worker nir_cf_node_get_function(&instr->block->cf_node);
1076*61046927SAndroid Build Coastguard Worker
1077*61046927SAndroid Build Coastguard Worker def->index = impl->ssa_alloc++;
1078*61046927SAndroid Build Coastguard Worker
1079*61046927SAndroid Build Coastguard Worker impl->valid_metadata &= ~nir_metadata_live_defs;
1080*61046927SAndroid Build Coastguard Worker }
1081*61046927SAndroid Build Coastguard Worker
1082*61046927SAndroid Build Coastguard Worker return true;
1083*61046927SAndroid Build Coastguard Worker }
1084*61046927SAndroid Build Coastguard Worker
1085*61046927SAndroid Build Coastguard Worker static void
add_defs_uses(nir_instr * instr)1086*61046927SAndroid Build Coastguard Worker add_defs_uses(nir_instr *instr)
1087*61046927SAndroid Build Coastguard Worker {
1088*61046927SAndroid Build Coastguard Worker nir_foreach_src(instr, add_use_cb, instr);
1089*61046927SAndroid Build Coastguard Worker nir_foreach_def(instr, add_ssa_def_cb, instr);
1090*61046927SAndroid Build Coastguard Worker }
1091*61046927SAndroid Build Coastguard Worker
1092*61046927SAndroid Build Coastguard Worker void
nir_instr_insert(nir_cursor cursor,nir_instr * instr)1093*61046927SAndroid Build Coastguard Worker nir_instr_insert(nir_cursor cursor, nir_instr *instr)
1094*61046927SAndroid Build Coastguard Worker {
1095*61046927SAndroid Build Coastguard Worker switch (cursor.option) {
1096*61046927SAndroid Build Coastguard Worker case nir_cursor_before_block:
1097*61046927SAndroid Build Coastguard Worker /* Only allow inserting jumps into empty blocks. */
1098*61046927SAndroid Build Coastguard Worker if (instr->type == nir_instr_type_jump)
1099*61046927SAndroid Build Coastguard Worker assert(exec_list_is_empty(&cursor.block->instr_list));
1100*61046927SAndroid Build Coastguard Worker
1101*61046927SAndroid Build Coastguard Worker instr->block = cursor.block;
1102*61046927SAndroid Build Coastguard Worker add_defs_uses(instr);
1103*61046927SAndroid Build Coastguard Worker exec_list_push_head(&cursor.block->instr_list, &instr->node);
1104*61046927SAndroid Build Coastguard Worker break;
1105*61046927SAndroid Build Coastguard Worker case nir_cursor_after_block: {
1106*61046927SAndroid Build Coastguard Worker /* Inserting instructions after a jump is illegal. */
1107*61046927SAndroid Build Coastguard Worker nir_instr *last = nir_block_last_instr(cursor.block);
1108*61046927SAndroid Build Coastguard Worker assert(last == NULL || last->type != nir_instr_type_jump);
1109*61046927SAndroid Build Coastguard Worker (void)last;
1110*61046927SAndroid Build Coastguard Worker
1111*61046927SAndroid Build Coastguard Worker instr->block = cursor.block;
1112*61046927SAndroid Build Coastguard Worker add_defs_uses(instr);
1113*61046927SAndroid Build Coastguard Worker exec_list_push_tail(&cursor.block->instr_list, &instr->node);
1114*61046927SAndroid Build Coastguard Worker break;
1115*61046927SAndroid Build Coastguard Worker }
1116*61046927SAndroid Build Coastguard Worker case nir_cursor_before_instr:
1117*61046927SAndroid Build Coastguard Worker assert(instr->type != nir_instr_type_jump);
1118*61046927SAndroid Build Coastguard Worker instr->block = cursor.instr->block;
1119*61046927SAndroid Build Coastguard Worker add_defs_uses(instr);
1120*61046927SAndroid Build Coastguard Worker exec_node_insert_node_before(&cursor.instr->node, &instr->node);
1121*61046927SAndroid Build Coastguard Worker break;
1122*61046927SAndroid Build Coastguard Worker case nir_cursor_after_instr:
1123*61046927SAndroid Build Coastguard Worker /* Inserting instructions after a jump is illegal. */
1124*61046927SAndroid Build Coastguard Worker assert(cursor.instr->type != nir_instr_type_jump);
1125*61046927SAndroid Build Coastguard Worker
1126*61046927SAndroid Build Coastguard Worker /* Only allow inserting jumps at the end of the block. */
1127*61046927SAndroid Build Coastguard Worker if (instr->type == nir_instr_type_jump)
1128*61046927SAndroid Build Coastguard Worker assert(cursor.instr == nir_block_last_instr(cursor.instr->block));
1129*61046927SAndroid Build Coastguard Worker
1130*61046927SAndroid Build Coastguard Worker instr->block = cursor.instr->block;
1131*61046927SAndroid Build Coastguard Worker add_defs_uses(instr);
1132*61046927SAndroid Build Coastguard Worker exec_node_insert_after(&cursor.instr->node, &instr->node);
1133*61046927SAndroid Build Coastguard Worker break;
1134*61046927SAndroid Build Coastguard Worker }
1135*61046927SAndroid Build Coastguard Worker
1136*61046927SAndroid Build Coastguard Worker if (instr->type == nir_instr_type_jump)
1137*61046927SAndroid Build Coastguard Worker nir_handle_add_jump(instr->block);
1138*61046927SAndroid Build Coastguard Worker
1139*61046927SAndroid Build Coastguard Worker nir_function_impl *impl = nir_cf_node_get_function(&instr->block->cf_node);
1140*61046927SAndroid Build Coastguard Worker impl->valid_metadata &= ~nir_metadata_instr_index;
1141*61046927SAndroid Build Coastguard Worker }
1142*61046927SAndroid Build Coastguard Worker
1143*61046927SAndroid Build Coastguard Worker bool
nir_instr_move(nir_cursor cursor,nir_instr * instr)1144*61046927SAndroid Build Coastguard Worker nir_instr_move(nir_cursor cursor, nir_instr *instr)
1145*61046927SAndroid Build Coastguard Worker {
1146*61046927SAndroid Build Coastguard Worker /* If the cursor happens to refer to this instruction (either before or
1147*61046927SAndroid Build Coastguard Worker * after), don't do anything.
1148*61046927SAndroid Build Coastguard Worker */
1149*61046927SAndroid Build Coastguard Worker if ((cursor.option == nir_cursor_before_instr ||
1150*61046927SAndroid Build Coastguard Worker cursor.option == nir_cursor_after_instr) &&
1151*61046927SAndroid Build Coastguard Worker cursor.instr == instr)
1152*61046927SAndroid Build Coastguard Worker return false;
1153*61046927SAndroid Build Coastguard Worker
1154*61046927SAndroid Build Coastguard Worker nir_instr_remove(instr);
1155*61046927SAndroid Build Coastguard Worker nir_instr_insert(cursor, instr);
1156*61046927SAndroid Build Coastguard Worker return true;
1157*61046927SAndroid Build Coastguard Worker }
1158*61046927SAndroid Build Coastguard Worker
1159*61046927SAndroid Build Coastguard Worker static bool
src_is_valid(const nir_src * src)1160*61046927SAndroid Build Coastguard Worker src_is_valid(const nir_src *src)
1161*61046927SAndroid Build Coastguard Worker {
1162*61046927SAndroid Build Coastguard Worker return (src->ssa != NULL);
1163*61046927SAndroid Build Coastguard Worker }
1164*61046927SAndroid Build Coastguard Worker
1165*61046927SAndroid Build Coastguard Worker static bool
remove_use_cb(nir_src * src,void * state)1166*61046927SAndroid Build Coastguard Worker remove_use_cb(nir_src *src, void *state)
1167*61046927SAndroid Build Coastguard Worker {
1168*61046927SAndroid Build Coastguard Worker (void)state;
1169*61046927SAndroid Build Coastguard Worker
1170*61046927SAndroid Build Coastguard Worker if (src_is_valid(src))
1171*61046927SAndroid Build Coastguard Worker list_del(&src->use_link);
1172*61046927SAndroid Build Coastguard Worker
1173*61046927SAndroid Build Coastguard Worker return true;
1174*61046927SAndroid Build Coastguard Worker }
1175*61046927SAndroid Build Coastguard Worker
1176*61046927SAndroid Build Coastguard Worker static void
remove_defs_uses(nir_instr * instr)1177*61046927SAndroid Build Coastguard Worker remove_defs_uses(nir_instr *instr)
1178*61046927SAndroid Build Coastguard Worker {
1179*61046927SAndroid Build Coastguard Worker nir_foreach_src(instr, remove_use_cb, instr);
1180*61046927SAndroid Build Coastguard Worker }
1181*61046927SAndroid Build Coastguard Worker
1182*61046927SAndroid Build Coastguard Worker void
nir_instr_remove_v(nir_instr * instr)1183*61046927SAndroid Build Coastguard Worker nir_instr_remove_v(nir_instr *instr)
1184*61046927SAndroid Build Coastguard Worker {
1185*61046927SAndroid Build Coastguard Worker remove_defs_uses(instr);
1186*61046927SAndroid Build Coastguard Worker exec_node_remove(&instr->node);
1187*61046927SAndroid Build Coastguard Worker
1188*61046927SAndroid Build Coastguard Worker if (instr->type == nir_instr_type_jump) {
1189*61046927SAndroid Build Coastguard Worker nir_jump_instr *jump_instr = nir_instr_as_jump(instr);
1190*61046927SAndroid Build Coastguard Worker nir_handle_remove_jump(instr->block, jump_instr->type);
1191*61046927SAndroid Build Coastguard Worker }
1192*61046927SAndroid Build Coastguard Worker }
1193*61046927SAndroid Build Coastguard Worker
1194*61046927SAndroid Build Coastguard Worker void
nir_instr_free(nir_instr * instr)1195*61046927SAndroid Build Coastguard Worker nir_instr_free(nir_instr *instr)
1196*61046927SAndroid Build Coastguard Worker {
1197*61046927SAndroid Build Coastguard Worker switch (instr->type) {
1198*61046927SAndroid Build Coastguard Worker case nir_instr_type_tex:
1199*61046927SAndroid Build Coastguard Worker gc_free(nir_instr_as_tex(instr)->src);
1200*61046927SAndroid Build Coastguard Worker break;
1201*61046927SAndroid Build Coastguard Worker
1202*61046927SAndroid Build Coastguard Worker case nir_instr_type_phi: {
1203*61046927SAndroid Build Coastguard Worker nir_phi_instr *phi = nir_instr_as_phi(instr);
1204*61046927SAndroid Build Coastguard Worker nir_foreach_phi_src_safe(phi_src, phi)
1205*61046927SAndroid Build Coastguard Worker gc_free(phi_src);
1206*61046927SAndroid Build Coastguard Worker break;
1207*61046927SAndroid Build Coastguard Worker }
1208*61046927SAndroid Build Coastguard Worker
1209*61046927SAndroid Build Coastguard Worker default:
1210*61046927SAndroid Build Coastguard Worker break;
1211*61046927SAndroid Build Coastguard Worker }
1212*61046927SAndroid Build Coastguard Worker
1213*61046927SAndroid Build Coastguard Worker gc_free(instr);
1214*61046927SAndroid Build Coastguard Worker }
1215*61046927SAndroid Build Coastguard Worker
1216*61046927SAndroid Build Coastguard Worker void
nir_instr_free_list(struct exec_list * list)1217*61046927SAndroid Build Coastguard Worker nir_instr_free_list(struct exec_list *list)
1218*61046927SAndroid Build Coastguard Worker {
1219*61046927SAndroid Build Coastguard Worker struct exec_node *node;
1220*61046927SAndroid Build Coastguard Worker while ((node = exec_list_pop_head(list))) {
1221*61046927SAndroid Build Coastguard Worker nir_instr *removed_instr = exec_node_data(nir_instr, node, node);
1222*61046927SAndroid Build Coastguard Worker nir_instr_free(removed_instr);
1223*61046927SAndroid Build Coastguard Worker }
1224*61046927SAndroid Build Coastguard Worker }
1225*61046927SAndroid Build Coastguard Worker
1226*61046927SAndroid Build Coastguard Worker static bool
nir_instr_free_and_dce_live_cb(nir_def * def,void * state)1227*61046927SAndroid Build Coastguard Worker nir_instr_free_and_dce_live_cb(nir_def *def, void *state)
1228*61046927SAndroid Build Coastguard Worker {
1229*61046927SAndroid Build Coastguard Worker bool *live = state;
1230*61046927SAndroid Build Coastguard Worker
1231*61046927SAndroid Build Coastguard Worker if (!nir_def_is_unused(def)) {
1232*61046927SAndroid Build Coastguard Worker *live = true;
1233*61046927SAndroid Build Coastguard Worker return false;
1234*61046927SAndroid Build Coastguard Worker } else {
1235*61046927SAndroid Build Coastguard Worker return true;
1236*61046927SAndroid Build Coastguard Worker }
1237*61046927SAndroid Build Coastguard Worker }
1238*61046927SAndroid Build Coastguard Worker
1239*61046927SAndroid Build Coastguard Worker static bool
nir_instr_free_and_dce_is_live(nir_instr * instr)1240*61046927SAndroid Build Coastguard Worker nir_instr_free_and_dce_is_live(nir_instr *instr)
1241*61046927SAndroid Build Coastguard Worker {
1242*61046927SAndroid Build Coastguard Worker /* Note: don't have to worry about jumps because they don't have dests to
1243*61046927SAndroid Build Coastguard Worker * become unused.
1244*61046927SAndroid Build Coastguard Worker */
1245*61046927SAndroid Build Coastguard Worker if (instr->type == nir_instr_type_intrinsic) {
1246*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
1247*61046927SAndroid Build Coastguard Worker const nir_intrinsic_info *info = &nir_intrinsic_infos[intr->intrinsic];
1248*61046927SAndroid Build Coastguard Worker if (!(info->flags & NIR_INTRINSIC_CAN_ELIMINATE))
1249*61046927SAndroid Build Coastguard Worker return true;
1250*61046927SAndroid Build Coastguard Worker }
1251*61046927SAndroid Build Coastguard Worker
1252*61046927SAndroid Build Coastguard Worker bool live = false;
1253*61046927SAndroid Build Coastguard Worker nir_foreach_def(instr, nir_instr_free_and_dce_live_cb, &live);
1254*61046927SAndroid Build Coastguard Worker return live;
1255*61046927SAndroid Build Coastguard Worker }
1256*61046927SAndroid Build Coastguard Worker
1257*61046927SAndroid Build Coastguard Worker static bool
nir_instr_dce_add_dead_srcs_cb(nir_src * src,void * state)1258*61046927SAndroid Build Coastguard Worker nir_instr_dce_add_dead_srcs_cb(nir_src *src, void *state)
1259*61046927SAndroid Build Coastguard Worker {
1260*61046927SAndroid Build Coastguard Worker nir_instr_worklist *wl = state;
1261*61046927SAndroid Build Coastguard Worker
1262*61046927SAndroid Build Coastguard Worker list_del(&src->use_link);
1263*61046927SAndroid Build Coastguard Worker if (!nir_instr_free_and_dce_is_live(src->ssa->parent_instr))
1264*61046927SAndroid Build Coastguard Worker nir_instr_worklist_push_tail(wl, src->ssa->parent_instr);
1265*61046927SAndroid Build Coastguard Worker
1266*61046927SAndroid Build Coastguard Worker /* Stop nir_instr_remove from trying to delete the link again. */
1267*61046927SAndroid Build Coastguard Worker src->ssa = NULL;
1268*61046927SAndroid Build Coastguard Worker
1269*61046927SAndroid Build Coastguard Worker return true;
1270*61046927SAndroid Build Coastguard Worker }
1271*61046927SAndroid Build Coastguard Worker
1272*61046927SAndroid Build Coastguard Worker static void
nir_instr_dce_add_dead_ssa_srcs(nir_instr_worklist * wl,nir_instr * instr)1273*61046927SAndroid Build Coastguard Worker nir_instr_dce_add_dead_ssa_srcs(nir_instr_worklist *wl, nir_instr *instr)
1274*61046927SAndroid Build Coastguard Worker {
1275*61046927SAndroid Build Coastguard Worker nir_foreach_src(instr, nir_instr_dce_add_dead_srcs_cb, wl);
1276*61046927SAndroid Build Coastguard Worker }
1277*61046927SAndroid Build Coastguard Worker
1278*61046927SAndroid Build Coastguard Worker /**
1279*61046927SAndroid Build Coastguard Worker * Frees an instruction and any SSA defs that it used that are now dead,
1280*61046927SAndroid Build Coastguard Worker * returning a nir_cursor where the instruction previously was.
1281*61046927SAndroid Build Coastguard Worker */
1282*61046927SAndroid Build Coastguard Worker nir_cursor
nir_instr_free_and_dce(nir_instr * instr)1283*61046927SAndroid Build Coastguard Worker nir_instr_free_and_dce(nir_instr *instr)
1284*61046927SAndroid Build Coastguard Worker {
1285*61046927SAndroid Build Coastguard Worker nir_instr_worklist *worklist = nir_instr_worklist_create();
1286*61046927SAndroid Build Coastguard Worker
1287*61046927SAndroid Build Coastguard Worker nir_instr_dce_add_dead_ssa_srcs(worklist, instr);
1288*61046927SAndroid Build Coastguard Worker nir_cursor c = nir_instr_remove(instr);
1289*61046927SAndroid Build Coastguard Worker
1290*61046927SAndroid Build Coastguard Worker struct exec_list to_free;
1291*61046927SAndroid Build Coastguard Worker exec_list_make_empty(&to_free);
1292*61046927SAndroid Build Coastguard Worker
1293*61046927SAndroid Build Coastguard Worker nir_instr *dce_instr;
1294*61046927SAndroid Build Coastguard Worker while ((dce_instr = nir_instr_worklist_pop_head(worklist))) {
1295*61046927SAndroid Build Coastguard Worker nir_instr_dce_add_dead_ssa_srcs(worklist, dce_instr);
1296*61046927SAndroid Build Coastguard Worker
1297*61046927SAndroid Build Coastguard Worker /* If we're removing the instr where our cursor is, then we have to
1298*61046927SAndroid Build Coastguard Worker * point the cursor elsewhere.
1299*61046927SAndroid Build Coastguard Worker */
1300*61046927SAndroid Build Coastguard Worker if ((c.option == nir_cursor_before_instr ||
1301*61046927SAndroid Build Coastguard Worker c.option == nir_cursor_after_instr) &&
1302*61046927SAndroid Build Coastguard Worker c.instr == dce_instr)
1303*61046927SAndroid Build Coastguard Worker c = nir_instr_remove(dce_instr);
1304*61046927SAndroid Build Coastguard Worker else
1305*61046927SAndroid Build Coastguard Worker nir_instr_remove(dce_instr);
1306*61046927SAndroid Build Coastguard Worker exec_list_push_tail(&to_free, &dce_instr->node);
1307*61046927SAndroid Build Coastguard Worker }
1308*61046927SAndroid Build Coastguard Worker
1309*61046927SAndroid Build Coastguard Worker nir_instr_free_list(&to_free);
1310*61046927SAndroid Build Coastguard Worker
1311*61046927SAndroid Build Coastguard Worker nir_instr_worklist_destroy(worklist);
1312*61046927SAndroid Build Coastguard Worker
1313*61046927SAndroid Build Coastguard Worker return c;
1314*61046927SAndroid Build Coastguard Worker }
1315*61046927SAndroid Build Coastguard Worker
1316*61046927SAndroid Build Coastguard Worker /*@}*/
1317*61046927SAndroid Build Coastguard Worker
1318*61046927SAndroid Build Coastguard Worker nir_def *
nir_instr_def(nir_instr * instr)1319*61046927SAndroid Build Coastguard Worker nir_instr_def(nir_instr *instr)
1320*61046927SAndroid Build Coastguard Worker {
1321*61046927SAndroid Build Coastguard Worker switch (instr->type) {
1322*61046927SAndroid Build Coastguard Worker case nir_instr_type_alu:
1323*61046927SAndroid Build Coastguard Worker return &nir_instr_as_alu(instr)->def;
1324*61046927SAndroid Build Coastguard Worker
1325*61046927SAndroid Build Coastguard Worker case nir_instr_type_deref:
1326*61046927SAndroid Build Coastguard Worker return &nir_instr_as_deref(instr)->def;
1327*61046927SAndroid Build Coastguard Worker
1328*61046927SAndroid Build Coastguard Worker case nir_instr_type_tex:
1329*61046927SAndroid Build Coastguard Worker return &nir_instr_as_tex(instr)->def;
1330*61046927SAndroid Build Coastguard Worker
1331*61046927SAndroid Build Coastguard Worker case nir_instr_type_intrinsic: {
1332*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
1333*61046927SAndroid Build Coastguard Worker if (nir_intrinsic_infos[intrin->intrinsic].has_dest) {
1334*61046927SAndroid Build Coastguard Worker return &intrin->def;
1335*61046927SAndroid Build Coastguard Worker } else {
1336*61046927SAndroid Build Coastguard Worker return NULL;
1337*61046927SAndroid Build Coastguard Worker }
1338*61046927SAndroid Build Coastguard Worker }
1339*61046927SAndroid Build Coastguard Worker
1340*61046927SAndroid Build Coastguard Worker case nir_instr_type_phi:
1341*61046927SAndroid Build Coastguard Worker return &nir_instr_as_phi(instr)->def;
1342*61046927SAndroid Build Coastguard Worker
1343*61046927SAndroid Build Coastguard Worker case nir_instr_type_parallel_copy:
1344*61046927SAndroid Build Coastguard Worker unreachable("Parallel copies are unsupported by this function");
1345*61046927SAndroid Build Coastguard Worker
1346*61046927SAndroid Build Coastguard Worker case nir_instr_type_load_const:
1347*61046927SAndroid Build Coastguard Worker return &nir_instr_as_load_const(instr)->def;
1348*61046927SAndroid Build Coastguard Worker
1349*61046927SAndroid Build Coastguard Worker case nir_instr_type_undef:
1350*61046927SAndroid Build Coastguard Worker return &nir_instr_as_undef(instr)->def;
1351*61046927SAndroid Build Coastguard Worker
1352*61046927SAndroid Build Coastguard Worker case nir_instr_type_call:
1353*61046927SAndroid Build Coastguard Worker case nir_instr_type_jump:
1354*61046927SAndroid Build Coastguard Worker case nir_instr_type_debug_info:
1355*61046927SAndroid Build Coastguard Worker return NULL;
1356*61046927SAndroid Build Coastguard Worker }
1357*61046927SAndroid Build Coastguard Worker
1358*61046927SAndroid Build Coastguard Worker unreachable("Invalid instruction type");
1359*61046927SAndroid Build Coastguard Worker }
1360*61046927SAndroid Build Coastguard Worker
1361*61046927SAndroid Build Coastguard Worker bool
nir_foreach_phi_src_leaving_block(nir_block * block,nir_foreach_src_cb cb,void * state)1362*61046927SAndroid Build Coastguard Worker nir_foreach_phi_src_leaving_block(nir_block *block,
1363*61046927SAndroid Build Coastguard Worker nir_foreach_src_cb cb,
1364*61046927SAndroid Build Coastguard Worker void *state)
1365*61046927SAndroid Build Coastguard Worker {
1366*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(block->successors); i++) {
1367*61046927SAndroid Build Coastguard Worker if (block->successors[i] == NULL)
1368*61046927SAndroid Build Coastguard Worker continue;
1369*61046927SAndroid Build Coastguard Worker
1370*61046927SAndroid Build Coastguard Worker nir_foreach_phi(phi, block->successors[i]) {
1371*61046927SAndroid Build Coastguard Worker nir_foreach_phi_src(phi_src, phi) {
1372*61046927SAndroid Build Coastguard Worker if (phi_src->pred == block) {
1373*61046927SAndroid Build Coastguard Worker if (!cb(&phi_src->src, state))
1374*61046927SAndroid Build Coastguard Worker return false;
1375*61046927SAndroid Build Coastguard Worker }
1376*61046927SAndroid Build Coastguard Worker }
1377*61046927SAndroid Build Coastguard Worker }
1378*61046927SAndroid Build Coastguard Worker }
1379*61046927SAndroid Build Coastguard Worker
1380*61046927SAndroid Build Coastguard Worker return true;
1381*61046927SAndroid Build Coastguard Worker }
1382*61046927SAndroid Build Coastguard Worker
1383*61046927SAndroid Build Coastguard Worker nir_const_value
nir_const_value_for_float(double f,unsigned bit_size)1384*61046927SAndroid Build Coastguard Worker nir_const_value_for_float(double f, unsigned bit_size)
1385*61046927SAndroid Build Coastguard Worker {
1386*61046927SAndroid Build Coastguard Worker nir_const_value v;
1387*61046927SAndroid Build Coastguard Worker memset(&v, 0, sizeof(v));
1388*61046927SAndroid Build Coastguard Worker
1389*61046927SAndroid Build Coastguard Worker /* clang-format off */
1390*61046927SAndroid Build Coastguard Worker switch (bit_size) {
1391*61046927SAndroid Build Coastguard Worker case 16: v.u16 = _mesa_float_to_half(f); break;
1392*61046927SAndroid Build Coastguard Worker case 32: v.f32 = f; break;
1393*61046927SAndroid Build Coastguard Worker case 64: v.f64 = f; break;
1394*61046927SAndroid Build Coastguard Worker default: unreachable("Invalid bit size");
1395*61046927SAndroid Build Coastguard Worker }
1396*61046927SAndroid Build Coastguard Worker /* clang-format on */
1397*61046927SAndroid Build Coastguard Worker
1398*61046927SAndroid Build Coastguard Worker return v;
1399*61046927SAndroid Build Coastguard Worker }
1400*61046927SAndroid Build Coastguard Worker
1401*61046927SAndroid Build Coastguard Worker double
nir_const_value_as_float(nir_const_value value,unsigned bit_size)1402*61046927SAndroid Build Coastguard Worker nir_const_value_as_float(nir_const_value value, unsigned bit_size)
1403*61046927SAndroid Build Coastguard Worker {
1404*61046927SAndroid Build Coastguard Worker /* clang-format off */
1405*61046927SAndroid Build Coastguard Worker switch (bit_size) {
1406*61046927SAndroid Build Coastguard Worker case 16: return _mesa_half_to_float(value.u16);
1407*61046927SAndroid Build Coastguard Worker case 32: return value.f32;
1408*61046927SAndroid Build Coastguard Worker case 64: return value.f64;
1409*61046927SAndroid Build Coastguard Worker default: unreachable("Invalid bit size");
1410*61046927SAndroid Build Coastguard Worker }
1411*61046927SAndroid Build Coastguard Worker /* clang-format on */
1412*61046927SAndroid Build Coastguard Worker }
1413*61046927SAndroid Build Coastguard Worker
1414*61046927SAndroid Build Coastguard Worker nir_const_value *
nir_src_as_const_value(nir_src src)1415*61046927SAndroid Build Coastguard Worker nir_src_as_const_value(nir_src src)
1416*61046927SAndroid Build Coastguard Worker {
1417*61046927SAndroid Build Coastguard Worker if (src.ssa->parent_instr->type != nir_instr_type_load_const)
1418*61046927SAndroid Build Coastguard Worker return NULL;
1419*61046927SAndroid Build Coastguard Worker
1420*61046927SAndroid Build Coastguard Worker nir_load_const_instr *load = nir_instr_as_load_const(src.ssa->parent_instr);
1421*61046927SAndroid Build Coastguard Worker
1422*61046927SAndroid Build Coastguard Worker return load->value;
1423*61046927SAndroid Build Coastguard Worker }
1424*61046927SAndroid Build Coastguard Worker
1425*61046927SAndroid Build Coastguard Worker const char *
nir_src_as_string(nir_src src)1426*61046927SAndroid Build Coastguard Worker nir_src_as_string(nir_src src)
1427*61046927SAndroid Build Coastguard Worker {
1428*61046927SAndroid Build Coastguard Worker nir_debug_info_instr *di = nir_src_as_debug_info(src);
1429*61046927SAndroid Build Coastguard Worker if (di && di->type == nir_debug_info_string)
1430*61046927SAndroid Build Coastguard Worker return di->string;
1431*61046927SAndroid Build Coastguard Worker
1432*61046927SAndroid Build Coastguard Worker return NULL;
1433*61046927SAndroid Build Coastguard Worker }
1434*61046927SAndroid Build Coastguard Worker
1435*61046927SAndroid Build Coastguard Worker /**
1436*61046927SAndroid Build Coastguard Worker * Returns true if the source is known to be always uniform. Otherwise it
1437*61046927SAndroid Build Coastguard Worker * returns false which means it may or may not be uniform but it can't be
1438*61046927SAndroid Build Coastguard Worker * determined.
1439*61046927SAndroid Build Coastguard Worker *
1440*61046927SAndroid Build Coastguard Worker * For a more precise analysis of uniform values, use nir_divergence_analysis.
1441*61046927SAndroid Build Coastguard Worker */
1442*61046927SAndroid Build Coastguard Worker bool
nir_src_is_always_uniform(nir_src src)1443*61046927SAndroid Build Coastguard Worker nir_src_is_always_uniform(nir_src src)
1444*61046927SAndroid Build Coastguard Worker {
1445*61046927SAndroid Build Coastguard Worker /* Constants are trivially uniform */
1446*61046927SAndroid Build Coastguard Worker if (src.ssa->parent_instr->type == nir_instr_type_load_const)
1447*61046927SAndroid Build Coastguard Worker return true;
1448*61046927SAndroid Build Coastguard Worker
1449*61046927SAndroid Build Coastguard Worker if (src.ssa->parent_instr->type == nir_instr_type_intrinsic) {
1450*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *intr = nir_instr_as_intrinsic(src.ssa->parent_instr);
1451*61046927SAndroid Build Coastguard Worker /* As are uniform variables */
1452*61046927SAndroid Build Coastguard Worker if (intr->intrinsic == nir_intrinsic_load_uniform &&
1453*61046927SAndroid Build Coastguard Worker nir_src_is_always_uniform(intr->src[0]))
1454*61046927SAndroid Build Coastguard Worker return true;
1455*61046927SAndroid Build Coastguard Worker /* From the Vulkan specification 15.6.1. Push Constant Interface:
1456*61046927SAndroid Build Coastguard Worker * "Any member of a push constant block that is declared as an array must
1457*61046927SAndroid Build Coastguard Worker * only be accessed with dynamically uniform indices."
1458*61046927SAndroid Build Coastguard Worker */
1459*61046927SAndroid Build Coastguard Worker if (intr->intrinsic == nir_intrinsic_load_push_constant)
1460*61046927SAndroid Build Coastguard Worker return true;
1461*61046927SAndroid Build Coastguard Worker if (intr->intrinsic == nir_intrinsic_load_deref &&
1462*61046927SAndroid Build Coastguard Worker nir_deref_mode_is(nir_src_as_deref(intr->src[0]), nir_var_mem_push_const))
1463*61046927SAndroid Build Coastguard Worker return true;
1464*61046927SAndroid Build Coastguard Worker }
1465*61046927SAndroid Build Coastguard Worker
1466*61046927SAndroid Build Coastguard Worker /* Operating together uniform expressions produces a uniform result */
1467*61046927SAndroid Build Coastguard Worker if (src.ssa->parent_instr->type == nir_instr_type_alu) {
1468*61046927SAndroid Build Coastguard Worker nir_alu_instr *alu = nir_instr_as_alu(src.ssa->parent_instr);
1469*61046927SAndroid Build Coastguard Worker for (int i = 0; i < nir_op_infos[alu->op].num_inputs; i++) {
1470*61046927SAndroid Build Coastguard Worker if (!nir_src_is_always_uniform(alu->src[i].src))
1471*61046927SAndroid Build Coastguard Worker return false;
1472*61046927SAndroid Build Coastguard Worker }
1473*61046927SAndroid Build Coastguard Worker
1474*61046927SAndroid Build Coastguard Worker return true;
1475*61046927SAndroid Build Coastguard Worker }
1476*61046927SAndroid Build Coastguard Worker
1477*61046927SAndroid Build Coastguard Worker /* XXX: this could have many more tests, such as when a sampler function is
1478*61046927SAndroid Build Coastguard Worker * called with uniform arguments.
1479*61046927SAndroid Build Coastguard Worker */
1480*61046927SAndroid Build Coastguard Worker return false;
1481*61046927SAndroid Build Coastguard Worker }
1482*61046927SAndroid Build Coastguard Worker
1483*61046927SAndroid Build Coastguard Worker nir_block *
nir_src_get_block(nir_src * src)1484*61046927SAndroid Build Coastguard Worker nir_src_get_block(nir_src *src)
1485*61046927SAndroid Build Coastguard Worker {
1486*61046927SAndroid Build Coastguard Worker if (nir_src_is_if(src))
1487*61046927SAndroid Build Coastguard Worker return nir_cf_node_cf_tree_prev(&nir_src_parent_if(src)->cf_node);
1488*61046927SAndroid Build Coastguard Worker else if (nir_src_parent_instr(src)->type == nir_instr_type_phi)
1489*61046927SAndroid Build Coastguard Worker return list_entry(src, nir_phi_src, src)->pred;
1490*61046927SAndroid Build Coastguard Worker else
1491*61046927SAndroid Build Coastguard Worker return nir_src_parent_instr(src)->block;
1492*61046927SAndroid Build Coastguard Worker }
1493*61046927SAndroid Build Coastguard Worker
1494*61046927SAndroid Build Coastguard Worker static void
src_remove_all_uses(nir_src * src)1495*61046927SAndroid Build Coastguard Worker src_remove_all_uses(nir_src *src)
1496*61046927SAndroid Build Coastguard Worker {
1497*61046927SAndroid Build Coastguard Worker if (src && src_is_valid(src))
1498*61046927SAndroid Build Coastguard Worker list_del(&src->use_link);
1499*61046927SAndroid Build Coastguard Worker }
1500*61046927SAndroid Build Coastguard Worker
1501*61046927SAndroid Build Coastguard Worker static void
src_add_all_uses(nir_src * src,nir_instr * parent_instr,nir_if * parent_if)1502*61046927SAndroid Build Coastguard Worker src_add_all_uses(nir_src *src, nir_instr *parent_instr, nir_if *parent_if)
1503*61046927SAndroid Build Coastguard Worker {
1504*61046927SAndroid Build Coastguard Worker if (!src)
1505*61046927SAndroid Build Coastguard Worker return;
1506*61046927SAndroid Build Coastguard Worker
1507*61046927SAndroid Build Coastguard Worker if (!src_is_valid(src))
1508*61046927SAndroid Build Coastguard Worker return;
1509*61046927SAndroid Build Coastguard Worker
1510*61046927SAndroid Build Coastguard Worker if (parent_instr) {
1511*61046927SAndroid Build Coastguard Worker nir_src_set_parent_instr(src, parent_instr);
1512*61046927SAndroid Build Coastguard Worker } else {
1513*61046927SAndroid Build Coastguard Worker assert(parent_if);
1514*61046927SAndroid Build Coastguard Worker nir_src_set_parent_if(src, parent_if);
1515*61046927SAndroid Build Coastguard Worker }
1516*61046927SAndroid Build Coastguard Worker
1517*61046927SAndroid Build Coastguard Worker list_addtail(&src->use_link, &src->ssa->uses);
1518*61046927SAndroid Build Coastguard Worker }
1519*61046927SAndroid Build Coastguard Worker
1520*61046927SAndroid Build Coastguard Worker void
nir_instr_init_src(nir_instr * instr,nir_src * src,nir_def * def)1521*61046927SAndroid Build Coastguard Worker nir_instr_init_src(nir_instr *instr, nir_src *src, nir_def *def)
1522*61046927SAndroid Build Coastguard Worker {
1523*61046927SAndroid Build Coastguard Worker *src = nir_src_for_ssa(def);
1524*61046927SAndroid Build Coastguard Worker src_add_all_uses(src, instr, NULL);
1525*61046927SAndroid Build Coastguard Worker }
1526*61046927SAndroid Build Coastguard Worker
1527*61046927SAndroid Build Coastguard Worker void
nir_instr_clear_src(nir_instr * instr,nir_src * src)1528*61046927SAndroid Build Coastguard Worker nir_instr_clear_src(nir_instr *instr, nir_src *src)
1529*61046927SAndroid Build Coastguard Worker {
1530*61046927SAndroid Build Coastguard Worker src_remove_all_uses(src);
1531*61046927SAndroid Build Coastguard Worker *src = NIR_SRC_INIT;
1532*61046927SAndroid Build Coastguard Worker }
1533*61046927SAndroid Build Coastguard Worker
1534*61046927SAndroid Build Coastguard Worker void
nir_instr_move_src(nir_instr * dest_instr,nir_src * dest,nir_src * src)1535*61046927SAndroid Build Coastguard Worker nir_instr_move_src(nir_instr *dest_instr, nir_src *dest, nir_src *src)
1536*61046927SAndroid Build Coastguard Worker {
1537*61046927SAndroid Build Coastguard Worker assert(!src_is_valid(dest) || nir_src_parent_instr(dest) == dest_instr);
1538*61046927SAndroid Build Coastguard Worker
1539*61046927SAndroid Build Coastguard Worker src_remove_all_uses(dest);
1540*61046927SAndroid Build Coastguard Worker src_remove_all_uses(src);
1541*61046927SAndroid Build Coastguard Worker *dest = *src;
1542*61046927SAndroid Build Coastguard Worker *src = NIR_SRC_INIT;
1543*61046927SAndroid Build Coastguard Worker src_add_all_uses(dest, dest_instr, NULL);
1544*61046927SAndroid Build Coastguard Worker }
1545*61046927SAndroid Build Coastguard Worker
1546*61046927SAndroid Build Coastguard Worker void
nir_def_init(nir_instr * instr,nir_def * def,unsigned num_components,unsigned bit_size)1547*61046927SAndroid Build Coastguard Worker nir_def_init(nir_instr *instr, nir_def *def,
1548*61046927SAndroid Build Coastguard Worker unsigned num_components,
1549*61046927SAndroid Build Coastguard Worker unsigned bit_size)
1550*61046927SAndroid Build Coastguard Worker {
1551*61046927SAndroid Build Coastguard Worker def->parent_instr = instr;
1552*61046927SAndroid Build Coastguard Worker list_inithead(&def->uses);
1553*61046927SAndroid Build Coastguard Worker def->num_components = num_components;
1554*61046927SAndroid Build Coastguard Worker def->bit_size = bit_size;
1555*61046927SAndroid Build Coastguard Worker def->divergent = true; /* This is the safer default */
1556*61046927SAndroid Build Coastguard Worker
1557*61046927SAndroid Build Coastguard Worker if (instr->block) {
1558*61046927SAndroid Build Coastguard Worker nir_function_impl *impl =
1559*61046927SAndroid Build Coastguard Worker nir_cf_node_get_function(&instr->block->cf_node);
1560*61046927SAndroid Build Coastguard Worker
1561*61046927SAndroid Build Coastguard Worker def->index = impl->ssa_alloc++;
1562*61046927SAndroid Build Coastguard Worker
1563*61046927SAndroid Build Coastguard Worker impl->valid_metadata &= ~nir_metadata_live_defs;
1564*61046927SAndroid Build Coastguard Worker } else {
1565*61046927SAndroid Build Coastguard Worker def->index = UINT_MAX;
1566*61046927SAndroid Build Coastguard Worker }
1567*61046927SAndroid Build Coastguard Worker }
1568*61046927SAndroid Build Coastguard Worker
1569*61046927SAndroid Build Coastguard Worker void
nir_def_rewrite_uses(nir_def * def,nir_def * new_ssa)1570*61046927SAndroid Build Coastguard Worker nir_def_rewrite_uses(nir_def *def, nir_def *new_ssa)
1571*61046927SAndroid Build Coastguard Worker {
1572*61046927SAndroid Build Coastguard Worker assert(def != new_ssa);
1573*61046927SAndroid Build Coastguard Worker nir_foreach_use_including_if_safe(use_src, def) {
1574*61046927SAndroid Build Coastguard Worker nir_src_rewrite(use_src, new_ssa);
1575*61046927SAndroid Build Coastguard Worker }
1576*61046927SAndroid Build Coastguard Worker }
1577*61046927SAndroid Build Coastguard Worker
1578*61046927SAndroid Build Coastguard Worker void
nir_def_rewrite_uses_src(nir_def * def,nir_src new_src)1579*61046927SAndroid Build Coastguard Worker nir_def_rewrite_uses_src(nir_def *def, nir_src new_src)
1580*61046927SAndroid Build Coastguard Worker {
1581*61046927SAndroid Build Coastguard Worker nir_def_rewrite_uses(def, new_src.ssa);
1582*61046927SAndroid Build Coastguard Worker }
1583*61046927SAndroid Build Coastguard Worker
1584*61046927SAndroid Build Coastguard Worker static bool
is_instr_between(nir_instr * start,nir_instr * end,nir_instr * between)1585*61046927SAndroid Build Coastguard Worker is_instr_between(nir_instr *start, nir_instr *end, nir_instr *between)
1586*61046927SAndroid Build Coastguard Worker {
1587*61046927SAndroid Build Coastguard Worker assert(start->block == end->block);
1588*61046927SAndroid Build Coastguard Worker
1589*61046927SAndroid Build Coastguard Worker if (between->block != start->block)
1590*61046927SAndroid Build Coastguard Worker return false;
1591*61046927SAndroid Build Coastguard Worker
1592*61046927SAndroid Build Coastguard Worker /* Search backwards looking for "between" */
1593*61046927SAndroid Build Coastguard Worker while (start != end) {
1594*61046927SAndroid Build Coastguard Worker if (between == end)
1595*61046927SAndroid Build Coastguard Worker return true;
1596*61046927SAndroid Build Coastguard Worker
1597*61046927SAndroid Build Coastguard Worker end = nir_instr_prev(end);
1598*61046927SAndroid Build Coastguard Worker assert(end);
1599*61046927SAndroid Build Coastguard Worker }
1600*61046927SAndroid Build Coastguard Worker
1601*61046927SAndroid Build Coastguard Worker return false;
1602*61046927SAndroid Build Coastguard Worker }
1603*61046927SAndroid Build Coastguard Worker
1604*61046927SAndroid Build Coastguard Worker /* Replaces all uses of the given SSA def with the given source but only if
1605*61046927SAndroid Build Coastguard Worker * the use comes after the after_me instruction. This can be useful if you
1606*61046927SAndroid Build Coastguard Worker * are emitting code to fix up the result of some instruction: you can freely
1607*61046927SAndroid Build Coastguard Worker * use the result in that code and then call rewrite_uses_after and pass the
1608*61046927SAndroid Build Coastguard Worker * last fixup instruction as after_me and it will replace all of the uses you
1609*61046927SAndroid Build Coastguard Worker * want without touching the fixup code.
1610*61046927SAndroid Build Coastguard Worker *
1611*61046927SAndroid Build Coastguard Worker * This function assumes that after_me is in the same block as
1612*61046927SAndroid Build Coastguard Worker * def->parent_instr and that after_me comes after def->parent_instr.
1613*61046927SAndroid Build Coastguard Worker */
1614*61046927SAndroid Build Coastguard Worker void
nir_def_rewrite_uses_after(nir_def * def,nir_def * new_ssa,nir_instr * after_me)1615*61046927SAndroid Build Coastguard Worker nir_def_rewrite_uses_after(nir_def *def, nir_def *new_ssa,
1616*61046927SAndroid Build Coastguard Worker nir_instr *after_me)
1617*61046927SAndroid Build Coastguard Worker {
1618*61046927SAndroid Build Coastguard Worker if (def == new_ssa)
1619*61046927SAndroid Build Coastguard Worker return;
1620*61046927SAndroid Build Coastguard Worker
1621*61046927SAndroid Build Coastguard Worker nir_foreach_use_including_if_safe(use_src, def) {
1622*61046927SAndroid Build Coastguard Worker if (!nir_src_is_if(use_src)) {
1623*61046927SAndroid Build Coastguard Worker assert(nir_src_parent_instr(use_src) != def->parent_instr);
1624*61046927SAndroid Build Coastguard Worker
1625*61046927SAndroid Build Coastguard Worker /* Since def already dominates all of its uses, the only way a use can
1626*61046927SAndroid Build Coastguard Worker * not be dominated by after_me is if it is between def and after_me in
1627*61046927SAndroid Build Coastguard Worker * the instruction list.
1628*61046927SAndroid Build Coastguard Worker */
1629*61046927SAndroid Build Coastguard Worker if (is_instr_between(def->parent_instr, after_me, nir_src_parent_instr(use_src)))
1630*61046927SAndroid Build Coastguard Worker continue;
1631*61046927SAndroid Build Coastguard Worker }
1632*61046927SAndroid Build Coastguard Worker
1633*61046927SAndroid Build Coastguard Worker nir_src_rewrite(use_src, new_ssa);
1634*61046927SAndroid Build Coastguard Worker }
1635*61046927SAndroid Build Coastguard Worker }
1636*61046927SAndroid Build Coastguard Worker
1637*61046927SAndroid Build Coastguard Worker static nir_def *
get_store_value(nir_intrinsic_instr * intrin)1638*61046927SAndroid Build Coastguard Worker get_store_value(nir_intrinsic_instr *intrin)
1639*61046927SAndroid Build Coastguard Worker {
1640*61046927SAndroid Build Coastguard Worker assert(nir_intrinsic_has_write_mask(intrin));
1641*61046927SAndroid Build Coastguard Worker /* deref stores have the deref in src[0] and the store value in src[1] */
1642*61046927SAndroid Build Coastguard Worker if (intrin->intrinsic == nir_intrinsic_store_deref ||
1643*61046927SAndroid Build Coastguard Worker intrin->intrinsic == nir_intrinsic_store_deref_block_intel)
1644*61046927SAndroid Build Coastguard Worker return intrin->src[1].ssa;
1645*61046927SAndroid Build Coastguard Worker
1646*61046927SAndroid Build Coastguard Worker /* all other stores have the store value in src[0] */
1647*61046927SAndroid Build Coastguard Worker return intrin->src[0].ssa;
1648*61046927SAndroid Build Coastguard Worker }
1649*61046927SAndroid Build Coastguard Worker
1650*61046927SAndroid Build Coastguard Worker nir_component_mask_t
nir_src_components_read(const nir_src * src)1651*61046927SAndroid Build Coastguard Worker nir_src_components_read(const nir_src *src)
1652*61046927SAndroid Build Coastguard Worker {
1653*61046927SAndroid Build Coastguard Worker assert(nir_src_parent_instr(src));
1654*61046927SAndroid Build Coastguard Worker
1655*61046927SAndroid Build Coastguard Worker if (nir_src_parent_instr(src)->type == nir_instr_type_alu) {
1656*61046927SAndroid Build Coastguard Worker nir_alu_instr *alu = nir_instr_as_alu(nir_src_parent_instr(src));
1657*61046927SAndroid Build Coastguard Worker nir_alu_src *alu_src = exec_node_data(nir_alu_src, src, src);
1658*61046927SAndroid Build Coastguard Worker int src_idx = alu_src - &alu->src[0];
1659*61046927SAndroid Build Coastguard Worker assert(src_idx >= 0 && src_idx < nir_op_infos[alu->op].num_inputs);
1660*61046927SAndroid Build Coastguard Worker return nir_alu_instr_src_read_mask(alu, src_idx);
1661*61046927SAndroid Build Coastguard Worker } else if (nir_src_parent_instr(src)->type == nir_instr_type_intrinsic) {
1662*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(nir_src_parent_instr(src));
1663*61046927SAndroid Build Coastguard Worker if (nir_intrinsic_has_write_mask(intrin) && src->ssa == get_store_value(intrin))
1664*61046927SAndroid Build Coastguard Worker return nir_intrinsic_write_mask(intrin);
1665*61046927SAndroid Build Coastguard Worker else
1666*61046927SAndroid Build Coastguard Worker return (1 << src->ssa->num_components) - 1;
1667*61046927SAndroid Build Coastguard Worker } else {
1668*61046927SAndroid Build Coastguard Worker return (1 << src->ssa->num_components) - 1;
1669*61046927SAndroid Build Coastguard Worker }
1670*61046927SAndroid Build Coastguard Worker }
1671*61046927SAndroid Build Coastguard Worker
1672*61046927SAndroid Build Coastguard Worker nir_component_mask_t
nir_def_components_read(const nir_def * def)1673*61046927SAndroid Build Coastguard Worker nir_def_components_read(const nir_def *def)
1674*61046927SAndroid Build Coastguard Worker {
1675*61046927SAndroid Build Coastguard Worker nir_component_mask_t read_mask = 0;
1676*61046927SAndroid Build Coastguard Worker
1677*61046927SAndroid Build Coastguard Worker nir_foreach_use_including_if(use, def) {
1678*61046927SAndroid Build Coastguard Worker read_mask |= nir_src_is_if(use) ? 1 : nir_src_components_read(use);
1679*61046927SAndroid Build Coastguard Worker
1680*61046927SAndroid Build Coastguard Worker if (read_mask == (1 << def->num_components) - 1)
1681*61046927SAndroid Build Coastguard Worker return read_mask;
1682*61046927SAndroid Build Coastguard Worker }
1683*61046927SAndroid Build Coastguard Worker
1684*61046927SAndroid Build Coastguard Worker return read_mask;
1685*61046927SAndroid Build Coastguard Worker }
1686*61046927SAndroid Build Coastguard Worker
1687*61046927SAndroid Build Coastguard Worker bool
nir_def_all_uses_are_fsat(const nir_def * def)1688*61046927SAndroid Build Coastguard Worker nir_def_all_uses_are_fsat(const nir_def *def)
1689*61046927SAndroid Build Coastguard Worker {
1690*61046927SAndroid Build Coastguard Worker nir_foreach_use(src, def) {
1691*61046927SAndroid Build Coastguard Worker if (nir_src_is_if(src))
1692*61046927SAndroid Build Coastguard Worker return false;
1693*61046927SAndroid Build Coastguard Worker
1694*61046927SAndroid Build Coastguard Worker nir_instr *use = nir_src_parent_instr(src);
1695*61046927SAndroid Build Coastguard Worker if (use->type != nir_instr_type_alu)
1696*61046927SAndroid Build Coastguard Worker return false;
1697*61046927SAndroid Build Coastguard Worker
1698*61046927SAndroid Build Coastguard Worker nir_alu_instr *alu = nir_instr_as_alu(use);
1699*61046927SAndroid Build Coastguard Worker if (alu->op != nir_op_fsat)
1700*61046927SAndroid Build Coastguard Worker return false;
1701*61046927SAndroid Build Coastguard Worker }
1702*61046927SAndroid Build Coastguard Worker
1703*61046927SAndroid Build Coastguard Worker return true;
1704*61046927SAndroid Build Coastguard Worker }
1705*61046927SAndroid Build Coastguard Worker
1706*61046927SAndroid Build Coastguard Worker nir_block *
nir_block_unstructured_next(nir_block * block)1707*61046927SAndroid Build Coastguard Worker nir_block_unstructured_next(nir_block *block)
1708*61046927SAndroid Build Coastguard Worker {
1709*61046927SAndroid Build Coastguard Worker if (block == NULL) {
1710*61046927SAndroid Build Coastguard Worker /* nir_foreach_block_unstructured_safe() will call this function on a
1711*61046927SAndroid Build Coastguard Worker * NULL block after the last iteration, but it won't use the result so
1712*61046927SAndroid Build Coastguard Worker * just return NULL here.
1713*61046927SAndroid Build Coastguard Worker */
1714*61046927SAndroid Build Coastguard Worker return NULL;
1715*61046927SAndroid Build Coastguard Worker }
1716*61046927SAndroid Build Coastguard Worker
1717*61046927SAndroid Build Coastguard Worker nir_cf_node *cf_next = nir_cf_node_next(&block->cf_node);
1718*61046927SAndroid Build Coastguard Worker if (cf_next == NULL && block->cf_node.parent->type == nir_cf_node_function)
1719*61046927SAndroid Build Coastguard Worker return NULL;
1720*61046927SAndroid Build Coastguard Worker
1721*61046927SAndroid Build Coastguard Worker if (cf_next && cf_next->type == nir_cf_node_block)
1722*61046927SAndroid Build Coastguard Worker return nir_cf_node_as_block(cf_next);
1723*61046927SAndroid Build Coastguard Worker
1724*61046927SAndroid Build Coastguard Worker return nir_block_cf_tree_next(block);
1725*61046927SAndroid Build Coastguard Worker }
1726*61046927SAndroid Build Coastguard Worker
1727*61046927SAndroid Build Coastguard Worker nir_block *
nir_unstructured_start_block(nir_function_impl * impl)1728*61046927SAndroid Build Coastguard Worker nir_unstructured_start_block(nir_function_impl *impl)
1729*61046927SAndroid Build Coastguard Worker {
1730*61046927SAndroid Build Coastguard Worker return nir_start_block(impl);
1731*61046927SAndroid Build Coastguard Worker }
1732*61046927SAndroid Build Coastguard Worker
1733*61046927SAndroid Build Coastguard Worker nir_block *
nir_block_cf_tree_next(nir_block * block)1734*61046927SAndroid Build Coastguard Worker nir_block_cf_tree_next(nir_block *block)
1735*61046927SAndroid Build Coastguard Worker {
1736*61046927SAndroid Build Coastguard Worker if (block == NULL) {
1737*61046927SAndroid Build Coastguard Worker /* nir_foreach_block_safe() will call this function on a NULL block
1738*61046927SAndroid Build Coastguard Worker * after the last iteration, but it won't use the result so just return
1739*61046927SAndroid Build Coastguard Worker * NULL here.
1740*61046927SAndroid Build Coastguard Worker */
1741*61046927SAndroid Build Coastguard Worker return NULL;
1742*61046927SAndroid Build Coastguard Worker }
1743*61046927SAndroid Build Coastguard Worker
1744*61046927SAndroid Build Coastguard Worker assert(nir_cf_node_get_function(&block->cf_node)->structured);
1745*61046927SAndroid Build Coastguard Worker
1746*61046927SAndroid Build Coastguard Worker nir_cf_node *cf_next = nir_cf_node_next(&block->cf_node);
1747*61046927SAndroid Build Coastguard Worker if (cf_next)
1748*61046927SAndroid Build Coastguard Worker return nir_cf_node_cf_tree_first(cf_next);
1749*61046927SAndroid Build Coastguard Worker
1750*61046927SAndroid Build Coastguard Worker nir_cf_node *parent = block->cf_node.parent;
1751*61046927SAndroid Build Coastguard Worker if (parent->type == nir_cf_node_function)
1752*61046927SAndroid Build Coastguard Worker return NULL;
1753*61046927SAndroid Build Coastguard Worker
1754*61046927SAndroid Build Coastguard Worker /* Is this the last block of a cf_node? Return the following block */
1755*61046927SAndroid Build Coastguard Worker if (block == nir_cf_node_cf_tree_last(parent))
1756*61046927SAndroid Build Coastguard Worker return nir_cf_node_as_block(nir_cf_node_next(parent));
1757*61046927SAndroid Build Coastguard Worker
1758*61046927SAndroid Build Coastguard Worker switch (parent->type) {
1759*61046927SAndroid Build Coastguard Worker case nir_cf_node_if: {
1760*61046927SAndroid Build Coastguard Worker /* We are at the end of the if. Go to the beginning of the else */
1761*61046927SAndroid Build Coastguard Worker nir_if *if_stmt = nir_cf_node_as_if(parent);
1762*61046927SAndroid Build Coastguard Worker assert(block == nir_if_last_then_block(if_stmt));
1763*61046927SAndroid Build Coastguard Worker return nir_if_first_else_block(if_stmt);
1764*61046927SAndroid Build Coastguard Worker }
1765*61046927SAndroid Build Coastguard Worker
1766*61046927SAndroid Build Coastguard Worker case nir_cf_node_loop: {
1767*61046927SAndroid Build Coastguard Worker /* We are at the end of the body and there is a continue construct */
1768*61046927SAndroid Build Coastguard Worker nir_loop *loop = nir_cf_node_as_loop(parent);
1769*61046927SAndroid Build Coastguard Worker assert(block == nir_loop_last_block(loop) &&
1770*61046927SAndroid Build Coastguard Worker nir_loop_has_continue_construct(loop));
1771*61046927SAndroid Build Coastguard Worker return nir_loop_first_continue_block(loop);
1772*61046927SAndroid Build Coastguard Worker }
1773*61046927SAndroid Build Coastguard Worker
1774*61046927SAndroid Build Coastguard Worker default:
1775*61046927SAndroid Build Coastguard Worker unreachable("unknown cf node type");
1776*61046927SAndroid Build Coastguard Worker }
1777*61046927SAndroid Build Coastguard Worker }
1778*61046927SAndroid Build Coastguard Worker
1779*61046927SAndroid Build Coastguard Worker nir_block *
nir_block_cf_tree_prev(nir_block * block)1780*61046927SAndroid Build Coastguard Worker nir_block_cf_tree_prev(nir_block *block)
1781*61046927SAndroid Build Coastguard Worker {
1782*61046927SAndroid Build Coastguard Worker if (block == NULL) {
1783*61046927SAndroid Build Coastguard Worker /* do this for consistency with nir_block_cf_tree_next() */
1784*61046927SAndroid Build Coastguard Worker return NULL;
1785*61046927SAndroid Build Coastguard Worker }
1786*61046927SAndroid Build Coastguard Worker
1787*61046927SAndroid Build Coastguard Worker assert(nir_cf_node_get_function(&block->cf_node)->structured);
1788*61046927SAndroid Build Coastguard Worker
1789*61046927SAndroid Build Coastguard Worker nir_cf_node *cf_prev = nir_cf_node_prev(&block->cf_node);
1790*61046927SAndroid Build Coastguard Worker if (cf_prev)
1791*61046927SAndroid Build Coastguard Worker return nir_cf_node_cf_tree_last(cf_prev);
1792*61046927SAndroid Build Coastguard Worker
1793*61046927SAndroid Build Coastguard Worker nir_cf_node *parent = block->cf_node.parent;
1794*61046927SAndroid Build Coastguard Worker if (parent->type == nir_cf_node_function)
1795*61046927SAndroid Build Coastguard Worker return NULL;
1796*61046927SAndroid Build Coastguard Worker
1797*61046927SAndroid Build Coastguard Worker /* Is this the first block of a cf_node? Return the previous block */
1798*61046927SAndroid Build Coastguard Worker if (block == nir_cf_node_cf_tree_first(parent))
1799*61046927SAndroid Build Coastguard Worker return nir_cf_node_as_block(nir_cf_node_prev(parent));
1800*61046927SAndroid Build Coastguard Worker
1801*61046927SAndroid Build Coastguard Worker switch (parent->type) {
1802*61046927SAndroid Build Coastguard Worker case nir_cf_node_if: {
1803*61046927SAndroid Build Coastguard Worker /* We are at the beginning of the else. Go to the end of the if */
1804*61046927SAndroid Build Coastguard Worker nir_if *if_stmt = nir_cf_node_as_if(parent);
1805*61046927SAndroid Build Coastguard Worker assert(block == nir_if_first_else_block(if_stmt));
1806*61046927SAndroid Build Coastguard Worker return nir_if_last_then_block(if_stmt);
1807*61046927SAndroid Build Coastguard Worker }
1808*61046927SAndroid Build Coastguard Worker case nir_cf_node_loop: {
1809*61046927SAndroid Build Coastguard Worker /* We are at the beginning of the continue construct. */
1810*61046927SAndroid Build Coastguard Worker nir_loop *loop = nir_cf_node_as_loop(parent);
1811*61046927SAndroid Build Coastguard Worker assert(nir_loop_has_continue_construct(loop) &&
1812*61046927SAndroid Build Coastguard Worker block == nir_loop_first_continue_block(loop));
1813*61046927SAndroid Build Coastguard Worker return nir_loop_last_block(loop);
1814*61046927SAndroid Build Coastguard Worker }
1815*61046927SAndroid Build Coastguard Worker
1816*61046927SAndroid Build Coastguard Worker default:
1817*61046927SAndroid Build Coastguard Worker unreachable("unknown cf node type");
1818*61046927SAndroid Build Coastguard Worker }
1819*61046927SAndroid Build Coastguard Worker }
1820*61046927SAndroid Build Coastguard Worker
1821*61046927SAndroid Build Coastguard Worker nir_block *
nir_cf_node_cf_tree_first(nir_cf_node * node)1822*61046927SAndroid Build Coastguard Worker nir_cf_node_cf_tree_first(nir_cf_node *node)
1823*61046927SAndroid Build Coastguard Worker {
1824*61046927SAndroid Build Coastguard Worker switch (node->type) {
1825*61046927SAndroid Build Coastguard Worker case nir_cf_node_function: {
1826*61046927SAndroid Build Coastguard Worker nir_function_impl *impl = nir_cf_node_as_function(node);
1827*61046927SAndroid Build Coastguard Worker return nir_start_block(impl);
1828*61046927SAndroid Build Coastguard Worker }
1829*61046927SAndroid Build Coastguard Worker
1830*61046927SAndroid Build Coastguard Worker case nir_cf_node_if: {
1831*61046927SAndroid Build Coastguard Worker nir_if *if_stmt = nir_cf_node_as_if(node);
1832*61046927SAndroid Build Coastguard Worker return nir_if_first_then_block(if_stmt);
1833*61046927SAndroid Build Coastguard Worker }
1834*61046927SAndroid Build Coastguard Worker
1835*61046927SAndroid Build Coastguard Worker case nir_cf_node_loop: {
1836*61046927SAndroid Build Coastguard Worker nir_loop *loop = nir_cf_node_as_loop(node);
1837*61046927SAndroid Build Coastguard Worker return nir_loop_first_block(loop);
1838*61046927SAndroid Build Coastguard Worker }
1839*61046927SAndroid Build Coastguard Worker
1840*61046927SAndroid Build Coastguard Worker case nir_cf_node_block: {
1841*61046927SAndroid Build Coastguard Worker return nir_cf_node_as_block(node);
1842*61046927SAndroid Build Coastguard Worker }
1843*61046927SAndroid Build Coastguard Worker
1844*61046927SAndroid Build Coastguard Worker default:
1845*61046927SAndroid Build Coastguard Worker unreachable("unknown node type");
1846*61046927SAndroid Build Coastguard Worker }
1847*61046927SAndroid Build Coastguard Worker }
1848*61046927SAndroid Build Coastguard Worker
1849*61046927SAndroid Build Coastguard Worker nir_block *
nir_cf_node_cf_tree_last(nir_cf_node * node)1850*61046927SAndroid Build Coastguard Worker nir_cf_node_cf_tree_last(nir_cf_node *node)
1851*61046927SAndroid Build Coastguard Worker {
1852*61046927SAndroid Build Coastguard Worker switch (node->type) {
1853*61046927SAndroid Build Coastguard Worker case nir_cf_node_function: {
1854*61046927SAndroid Build Coastguard Worker nir_function_impl *impl = nir_cf_node_as_function(node);
1855*61046927SAndroid Build Coastguard Worker return nir_impl_last_block(impl);
1856*61046927SAndroid Build Coastguard Worker }
1857*61046927SAndroid Build Coastguard Worker
1858*61046927SAndroid Build Coastguard Worker case nir_cf_node_if: {
1859*61046927SAndroid Build Coastguard Worker nir_if *if_stmt = nir_cf_node_as_if(node);
1860*61046927SAndroid Build Coastguard Worker return nir_if_last_else_block(if_stmt);
1861*61046927SAndroid Build Coastguard Worker }
1862*61046927SAndroid Build Coastguard Worker
1863*61046927SAndroid Build Coastguard Worker case nir_cf_node_loop: {
1864*61046927SAndroid Build Coastguard Worker nir_loop *loop = nir_cf_node_as_loop(node);
1865*61046927SAndroid Build Coastguard Worker if (nir_loop_has_continue_construct(loop))
1866*61046927SAndroid Build Coastguard Worker return nir_loop_last_continue_block(loop);
1867*61046927SAndroid Build Coastguard Worker else
1868*61046927SAndroid Build Coastguard Worker return nir_loop_last_block(loop);
1869*61046927SAndroid Build Coastguard Worker }
1870*61046927SAndroid Build Coastguard Worker
1871*61046927SAndroid Build Coastguard Worker case nir_cf_node_block: {
1872*61046927SAndroid Build Coastguard Worker return nir_cf_node_as_block(node);
1873*61046927SAndroid Build Coastguard Worker }
1874*61046927SAndroid Build Coastguard Worker
1875*61046927SAndroid Build Coastguard Worker default:
1876*61046927SAndroid Build Coastguard Worker unreachable("unknown node type");
1877*61046927SAndroid Build Coastguard Worker }
1878*61046927SAndroid Build Coastguard Worker }
1879*61046927SAndroid Build Coastguard Worker
1880*61046927SAndroid Build Coastguard Worker nir_block *
nir_cf_node_cf_tree_next(nir_cf_node * node)1881*61046927SAndroid Build Coastguard Worker nir_cf_node_cf_tree_next(nir_cf_node *node)
1882*61046927SAndroid Build Coastguard Worker {
1883*61046927SAndroid Build Coastguard Worker if (node->type == nir_cf_node_block)
1884*61046927SAndroid Build Coastguard Worker return nir_block_cf_tree_next(nir_cf_node_as_block(node));
1885*61046927SAndroid Build Coastguard Worker else if (node->type == nir_cf_node_function)
1886*61046927SAndroid Build Coastguard Worker return NULL;
1887*61046927SAndroid Build Coastguard Worker else
1888*61046927SAndroid Build Coastguard Worker return nir_cf_node_as_block(nir_cf_node_next(node));
1889*61046927SAndroid Build Coastguard Worker }
1890*61046927SAndroid Build Coastguard Worker
1891*61046927SAndroid Build Coastguard Worker nir_block *
nir_cf_node_cf_tree_prev(nir_cf_node * node)1892*61046927SAndroid Build Coastguard Worker nir_cf_node_cf_tree_prev(nir_cf_node *node)
1893*61046927SAndroid Build Coastguard Worker {
1894*61046927SAndroid Build Coastguard Worker if (node->type == nir_cf_node_block)
1895*61046927SAndroid Build Coastguard Worker return nir_block_cf_tree_prev(nir_cf_node_as_block(node));
1896*61046927SAndroid Build Coastguard Worker else if (node->type == nir_cf_node_function)
1897*61046927SAndroid Build Coastguard Worker return NULL;
1898*61046927SAndroid Build Coastguard Worker else
1899*61046927SAndroid Build Coastguard Worker return nir_cf_node_as_block(nir_cf_node_prev(node));
1900*61046927SAndroid Build Coastguard Worker }
1901*61046927SAndroid Build Coastguard Worker
1902*61046927SAndroid Build Coastguard Worker nir_if *
nir_block_get_following_if(nir_block * block)1903*61046927SAndroid Build Coastguard Worker nir_block_get_following_if(nir_block *block)
1904*61046927SAndroid Build Coastguard Worker {
1905*61046927SAndroid Build Coastguard Worker if (exec_node_is_tail_sentinel(&block->cf_node.node))
1906*61046927SAndroid Build Coastguard Worker return NULL;
1907*61046927SAndroid Build Coastguard Worker
1908*61046927SAndroid Build Coastguard Worker if (nir_cf_node_is_last(&block->cf_node))
1909*61046927SAndroid Build Coastguard Worker return NULL;
1910*61046927SAndroid Build Coastguard Worker
1911*61046927SAndroid Build Coastguard Worker nir_cf_node *next_node = nir_cf_node_next(&block->cf_node);
1912*61046927SAndroid Build Coastguard Worker
1913*61046927SAndroid Build Coastguard Worker if (next_node->type != nir_cf_node_if)
1914*61046927SAndroid Build Coastguard Worker return NULL;
1915*61046927SAndroid Build Coastguard Worker
1916*61046927SAndroid Build Coastguard Worker return nir_cf_node_as_if(next_node);
1917*61046927SAndroid Build Coastguard Worker }
1918*61046927SAndroid Build Coastguard Worker
1919*61046927SAndroid Build Coastguard Worker nir_loop *
nir_block_get_following_loop(nir_block * block)1920*61046927SAndroid Build Coastguard Worker nir_block_get_following_loop(nir_block *block)
1921*61046927SAndroid Build Coastguard Worker {
1922*61046927SAndroid Build Coastguard Worker if (exec_node_is_tail_sentinel(&block->cf_node.node))
1923*61046927SAndroid Build Coastguard Worker return NULL;
1924*61046927SAndroid Build Coastguard Worker
1925*61046927SAndroid Build Coastguard Worker if (nir_cf_node_is_last(&block->cf_node))
1926*61046927SAndroid Build Coastguard Worker return NULL;
1927*61046927SAndroid Build Coastguard Worker
1928*61046927SAndroid Build Coastguard Worker nir_cf_node *next_node = nir_cf_node_next(&block->cf_node);
1929*61046927SAndroid Build Coastguard Worker
1930*61046927SAndroid Build Coastguard Worker if (next_node->type != nir_cf_node_loop)
1931*61046927SAndroid Build Coastguard Worker return NULL;
1932*61046927SAndroid Build Coastguard Worker
1933*61046927SAndroid Build Coastguard Worker return nir_cf_node_as_loop(next_node);
1934*61046927SAndroid Build Coastguard Worker }
1935*61046927SAndroid Build Coastguard Worker
1936*61046927SAndroid Build Coastguard Worker static int
compare_block_index(const void * p1,const void * p2)1937*61046927SAndroid Build Coastguard Worker compare_block_index(const void *p1, const void *p2)
1938*61046927SAndroid Build Coastguard Worker {
1939*61046927SAndroid Build Coastguard Worker const nir_block *block1 = *((const nir_block **)p1);
1940*61046927SAndroid Build Coastguard Worker const nir_block *block2 = *((const nir_block **)p2);
1941*61046927SAndroid Build Coastguard Worker
1942*61046927SAndroid Build Coastguard Worker return (int)block1->index - (int)block2->index;
1943*61046927SAndroid Build Coastguard Worker }
1944*61046927SAndroid Build Coastguard Worker
1945*61046927SAndroid Build Coastguard Worker nir_block **
nir_block_get_predecessors_sorted(const nir_block * block,void * mem_ctx)1946*61046927SAndroid Build Coastguard Worker nir_block_get_predecessors_sorted(const nir_block *block, void *mem_ctx)
1947*61046927SAndroid Build Coastguard Worker {
1948*61046927SAndroid Build Coastguard Worker nir_block **preds =
1949*61046927SAndroid Build Coastguard Worker ralloc_array(mem_ctx, nir_block *, block->predecessors->entries);
1950*61046927SAndroid Build Coastguard Worker
1951*61046927SAndroid Build Coastguard Worker unsigned i = 0;
1952*61046927SAndroid Build Coastguard Worker set_foreach(block->predecessors, entry)
1953*61046927SAndroid Build Coastguard Worker preds[i++] = (nir_block *)entry->key;
1954*61046927SAndroid Build Coastguard Worker assert(i == block->predecessors->entries);
1955*61046927SAndroid Build Coastguard Worker
1956*61046927SAndroid Build Coastguard Worker qsort(preds, block->predecessors->entries, sizeof(nir_block *),
1957*61046927SAndroid Build Coastguard Worker compare_block_index);
1958*61046927SAndroid Build Coastguard Worker
1959*61046927SAndroid Build Coastguard Worker return preds;
1960*61046927SAndroid Build Coastguard Worker }
1961*61046927SAndroid Build Coastguard Worker
1962*61046927SAndroid Build Coastguard Worker void
nir_index_blocks(nir_function_impl * impl)1963*61046927SAndroid Build Coastguard Worker nir_index_blocks(nir_function_impl *impl)
1964*61046927SAndroid Build Coastguard Worker {
1965*61046927SAndroid Build Coastguard Worker unsigned index = 0;
1966*61046927SAndroid Build Coastguard Worker
1967*61046927SAndroid Build Coastguard Worker if (impl->valid_metadata & nir_metadata_block_index)
1968*61046927SAndroid Build Coastguard Worker return;
1969*61046927SAndroid Build Coastguard Worker
1970*61046927SAndroid Build Coastguard Worker nir_foreach_block_unstructured(block, impl) {
1971*61046927SAndroid Build Coastguard Worker block->index = index++;
1972*61046927SAndroid Build Coastguard Worker }
1973*61046927SAndroid Build Coastguard Worker
1974*61046927SAndroid Build Coastguard Worker /* The end_block isn't really part of the program, which is why its index
1975*61046927SAndroid Build Coastguard Worker * is >= num_blocks.
1976*61046927SAndroid Build Coastguard Worker */
1977*61046927SAndroid Build Coastguard Worker impl->num_blocks = impl->end_block->index = index;
1978*61046927SAndroid Build Coastguard Worker }
1979*61046927SAndroid Build Coastguard Worker
1980*61046927SAndroid Build Coastguard Worker static bool
index_ssa_def_cb(nir_def * def,void * state)1981*61046927SAndroid Build Coastguard Worker index_ssa_def_cb(nir_def *def, void *state)
1982*61046927SAndroid Build Coastguard Worker {
1983*61046927SAndroid Build Coastguard Worker unsigned *index = (unsigned *)state;
1984*61046927SAndroid Build Coastguard Worker def->index = (*index)++;
1985*61046927SAndroid Build Coastguard Worker
1986*61046927SAndroid Build Coastguard Worker return true;
1987*61046927SAndroid Build Coastguard Worker }
1988*61046927SAndroid Build Coastguard Worker
1989*61046927SAndroid Build Coastguard Worker /**
1990*61046927SAndroid Build Coastguard Worker * The indices are applied top-to-bottom which has the very nice property
1991*61046927SAndroid Build Coastguard Worker * that, if A dominates B, then A->index <= B->index.
1992*61046927SAndroid Build Coastguard Worker */
1993*61046927SAndroid Build Coastguard Worker void
nir_index_ssa_defs(nir_function_impl * impl)1994*61046927SAndroid Build Coastguard Worker nir_index_ssa_defs(nir_function_impl *impl)
1995*61046927SAndroid Build Coastguard Worker {
1996*61046927SAndroid Build Coastguard Worker unsigned index = 0;
1997*61046927SAndroid Build Coastguard Worker
1998*61046927SAndroid Build Coastguard Worker impl->valid_metadata &= ~nir_metadata_live_defs;
1999*61046927SAndroid Build Coastguard Worker
2000*61046927SAndroid Build Coastguard Worker nir_foreach_block_unstructured(block, impl) {
2001*61046927SAndroid Build Coastguard Worker nir_foreach_instr(instr, block)
2002*61046927SAndroid Build Coastguard Worker nir_foreach_def(instr, index_ssa_def_cb, &index);
2003*61046927SAndroid Build Coastguard Worker }
2004*61046927SAndroid Build Coastguard Worker
2005*61046927SAndroid Build Coastguard Worker impl->ssa_alloc = index;
2006*61046927SAndroid Build Coastguard Worker }
2007*61046927SAndroid Build Coastguard Worker
2008*61046927SAndroid Build Coastguard Worker /**
2009*61046927SAndroid Build Coastguard Worker * The indices are applied top-to-bottom which has the very nice property
2010*61046927SAndroid Build Coastguard Worker * that, if A dominates B, then A->index <= B->index.
2011*61046927SAndroid Build Coastguard Worker */
2012*61046927SAndroid Build Coastguard Worker unsigned
nir_index_instrs(nir_function_impl * impl)2013*61046927SAndroid Build Coastguard Worker nir_index_instrs(nir_function_impl *impl)
2014*61046927SAndroid Build Coastguard Worker {
2015*61046927SAndroid Build Coastguard Worker unsigned index = 0;
2016*61046927SAndroid Build Coastguard Worker
2017*61046927SAndroid Build Coastguard Worker nir_foreach_block(block, impl) {
2018*61046927SAndroid Build Coastguard Worker block->start_ip = index++;
2019*61046927SAndroid Build Coastguard Worker
2020*61046927SAndroid Build Coastguard Worker nir_foreach_instr(instr, block)
2021*61046927SAndroid Build Coastguard Worker instr->index = index++;
2022*61046927SAndroid Build Coastguard Worker
2023*61046927SAndroid Build Coastguard Worker block->end_ip = index++;
2024*61046927SAndroid Build Coastguard Worker }
2025*61046927SAndroid Build Coastguard Worker
2026*61046927SAndroid Build Coastguard Worker return index;
2027*61046927SAndroid Build Coastguard Worker }
2028*61046927SAndroid Build Coastguard Worker
2029*61046927SAndroid Build Coastguard Worker void
nir_shader_clear_pass_flags(nir_shader * shader)2030*61046927SAndroid Build Coastguard Worker nir_shader_clear_pass_flags(nir_shader *shader)
2031*61046927SAndroid Build Coastguard Worker {
2032*61046927SAndroid Build Coastguard Worker nir_foreach_function_impl(impl, shader) {
2033*61046927SAndroid Build Coastguard Worker nir_foreach_block(block, impl) {
2034*61046927SAndroid Build Coastguard Worker nir_foreach_instr(instr, block) {
2035*61046927SAndroid Build Coastguard Worker instr->pass_flags = 0;
2036*61046927SAndroid Build Coastguard Worker }
2037*61046927SAndroid Build Coastguard Worker }
2038*61046927SAndroid Build Coastguard Worker }
2039*61046927SAndroid Build Coastguard Worker }
2040*61046927SAndroid Build Coastguard Worker
2041*61046927SAndroid Build Coastguard Worker unsigned
nir_shader_index_vars(nir_shader * shader,nir_variable_mode modes)2042*61046927SAndroid Build Coastguard Worker nir_shader_index_vars(nir_shader *shader, nir_variable_mode modes)
2043*61046927SAndroid Build Coastguard Worker {
2044*61046927SAndroid Build Coastguard Worker unsigned count = 0;
2045*61046927SAndroid Build Coastguard Worker nir_foreach_variable_with_modes(var, shader, modes)
2046*61046927SAndroid Build Coastguard Worker var->index = count++;
2047*61046927SAndroid Build Coastguard Worker return count;
2048*61046927SAndroid Build Coastguard Worker }
2049*61046927SAndroid Build Coastguard Worker
2050*61046927SAndroid Build Coastguard Worker unsigned
nir_function_impl_index_vars(nir_function_impl * impl)2051*61046927SAndroid Build Coastguard Worker nir_function_impl_index_vars(nir_function_impl *impl)
2052*61046927SAndroid Build Coastguard Worker {
2053*61046927SAndroid Build Coastguard Worker unsigned count = 0;
2054*61046927SAndroid Build Coastguard Worker nir_foreach_function_temp_variable(var, impl)
2055*61046927SAndroid Build Coastguard Worker var->index = count++;
2056*61046927SAndroid Build Coastguard Worker return count;
2057*61046927SAndroid Build Coastguard Worker }
2058*61046927SAndroid Build Coastguard Worker
2059*61046927SAndroid Build Coastguard Worker static nir_instr *
cursor_next_instr(nir_cursor cursor)2060*61046927SAndroid Build Coastguard Worker cursor_next_instr(nir_cursor cursor)
2061*61046927SAndroid Build Coastguard Worker {
2062*61046927SAndroid Build Coastguard Worker switch (cursor.option) {
2063*61046927SAndroid Build Coastguard Worker case nir_cursor_before_block:
2064*61046927SAndroid Build Coastguard Worker for (nir_block *block = cursor.block; block;
2065*61046927SAndroid Build Coastguard Worker block = nir_block_cf_tree_next(block)) {
2066*61046927SAndroid Build Coastguard Worker nir_instr *instr = nir_block_first_instr(block);
2067*61046927SAndroid Build Coastguard Worker if (instr)
2068*61046927SAndroid Build Coastguard Worker return instr;
2069*61046927SAndroid Build Coastguard Worker }
2070*61046927SAndroid Build Coastguard Worker return NULL;
2071*61046927SAndroid Build Coastguard Worker
2072*61046927SAndroid Build Coastguard Worker case nir_cursor_after_block:
2073*61046927SAndroid Build Coastguard Worker cursor.block = nir_block_cf_tree_next(cursor.block);
2074*61046927SAndroid Build Coastguard Worker if (cursor.block == NULL)
2075*61046927SAndroid Build Coastguard Worker return NULL;
2076*61046927SAndroid Build Coastguard Worker
2077*61046927SAndroid Build Coastguard Worker cursor.option = nir_cursor_before_block;
2078*61046927SAndroid Build Coastguard Worker return cursor_next_instr(cursor);
2079*61046927SAndroid Build Coastguard Worker
2080*61046927SAndroid Build Coastguard Worker case nir_cursor_before_instr:
2081*61046927SAndroid Build Coastguard Worker return cursor.instr;
2082*61046927SAndroid Build Coastguard Worker
2083*61046927SAndroid Build Coastguard Worker case nir_cursor_after_instr:
2084*61046927SAndroid Build Coastguard Worker if (nir_instr_next(cursor.instr))
2085*61046927SAndroid Build Coastguard Worker return nir_instr_next(cursor.instr);
2086*61046927SAndroid Build Coastguard Worker
2087*61046927SAndroid Build Coastguard Worker cursor.option = nir_cursor_after_block;
2088*61046927SAndroid Build Coastguard Worker cursor.block = cursor.instr->block;
2089*61046927SAndroid Build Coastguard Worker return cursor_next_instr(cursor);
2090*61046927SAndroid Build Coastguard Worker }
2091*61046927SAndroid Build Coastguard Worker
2092*61046927SAndroid Build Coastguard Worker unreachable("Inavlid cursor option");
2093*61046927SAndroid Build Coastguard Worker }
2094*61046927SAndroid Build Coastguard Worker
2095*61046927SAndroid Build Coastguard Worker bool
nir_function_impl_lower_instructions(nir_function_impl * impl,nir_instr_filter_cb filter,nir_lower_instr_cb lower,void * cb_data)2096*61046927SAndroid Build Coastguard Worker nir_function_impl_lower_instructions(nir_function_impl *impl,
2097*61046927SAndroid Build Coastguard Worker nir_instr_filter_cb filter,
2098*61046927SAndroid Build Coastguard Worker nir_lower_instr_cb lower,
2099*61046927SAndroid Build Coastguard Worker void *cb_data)
2100*61046927SAndroid Build Coastguard Worker {
2101*61046927SAndroid Build Coastguard Worker nir_builder b = nir_builder_create(impl);
2102*61046927SAndroid Build Coastguard Worker
2103*61046927SAndroid Build Coastguard Worker nir_metadata preserved = nir_metadata_control_flow;
2104*61046927SAndroid Build Coastguard Worker
2105*61046927SAndroid Build Coastguard Worker bool progress = false;
2106*61046927SAndroid Build Coastguard Worker nir_cursor iter = nir_before_impl(impl);
2107*61046927SAndroid Build Coastguard Worker nir_instr *instr;
2108*61046927SAndroid Build Coastguard Worker while ((instr = cursor_next_instr(iter)) != NULL) {
2109*61046927SAndroid Build Coastguard Worker if (filter && !filter(instr, cb_data)) {
2110*61046927SAndroid Build Coastguard Worker iter = nir_after_instr(instr);
2111*61046927SAndroid Build Coastguard Worker continue;
2112*61046927SAndroid Build Coastguard Worker }
2113*61046927SAndroid Build Coastguard Worker
2114*61046927SAndroid Build Coastguard Worker nir_def *old_def = nir_instr_def(instr);
2115*61046927SAndroid Build Coastguard Worker struct list_head old_uses;
2116*61046927SAndroid Build Coastguard Worker if (old_def != NULL) {
2117*61046927SAndroid Build Coastguard Worker /* We're about to ask the callback to generate a replacement for instr.
2118*61046927SAndroid Build Coastguard Worker * Save off the uses from instr's SSA def so we know what uses to
2119*61046927SAndroid Build Coastguard Worker * rewrite later. If we use nir_def_rewrite_uses, it fails in the
2120*61046927SAndroid Build Coastguard Worker * case where the generated replacement code uses the result of instr
2121*61046927SAndroid Build Coastguard Worker * itself. If we use nir_def_rewrite_uses_after (which is the
2122*61046927SAndroid Build Coastguard Worker * normal solution to this problem), it doesn't work well if control-
2123*61046927SAndroid Build Coastguard Worker * flow is inserted as part of the replacement, doesn't handle cases
2124*61046927SAndroid Build Coastguard Worker * where the replacement is something consumed by instr, and suffers
2125*61046927SAndroid Build Coastguard Worker * from performance issues. This is the only way to 100% guarantee
2126*61046927SAndroid Build Coastguard Worker * that we rewrite the correct set efficiently.
2127*61046927SAndroid Build Coastguard Worker */
2128*61046927SAndroid Build Coastguard Worker
2129*61046927SAndroid Build Coastguard Worker list_replace(&old_def->uses, &old_uses);
2130*61046927SAndroid Build Coastguard Worker list_inithead(&old_def->uses);
2131*61046927SAndroid Build Coastguard Worker }
2132*61046927SAndroid Build Coastguard Worker
2133*61046927SAndroid Build Coastguard Worker b.cursor = nir_after_instr(instr);
2134*61046927SAndroid Build Coastguard Worker nir_def *new_def = lower(&b, instr, cb_data);
2135*61046927SAndroid Build Coastguard Worker if (new_def && new_def != NIR_LOWER_INSTR_PROGRESS &&
2136*61046927SAndroid Build Coastguard Worker new_def != NIR_LOWER_INSTR_PROGRESS_REPLACE) {
2137*61046927SAndroid Build Coastguard Worker assert(old_def != NULL);
2138*61046927SAndroid Build Coastguard Worker if (new_def->parent_instr->block != instr->block)
2139*61046927SAndroid Build Coastguard Worker preserved = nir_metadata_none;
2140*61046927SAndroid Build Coastguard Worker
2141*61046927SAndroid Build Coastguard Worker list_for_each_entry_safe(nir_src, use_src, &old_uses, use_link)
2142*61046927SAndroid Build Coastguard Worker nir_src_rewrite(use_src, new_def);
2143*61046927SAndroid Build Coastguard Worker
2144*61046927SAndroid Build Coastguard Worker if (nir_def_is_unused(old_def)) {
2145*61046927SAndroid Build Coastguard Worker iter = nir_instr_free_and_dce(instr);
2146*61046927SAndroid Build Coastguard Worker } else {
2147*61046927SAndroid Build Coastguard Worker iter = nir_after_instr(instr);
2148*61046927SAndroid Build Coastguard Worker }
2149*61046927SAndroid Build Coastguard Worker progress = true;
2150*61046927SAndroid Build Coastguard Worker } else {
2151*61046927SAndroid Build Coastguard Worker /* We didn't end up lowering after all. Put the uses back */
2152*61046927SAndroid Build Coastguard Worker if (old_def)
2153*61046927SAndroid Build Coastguard Worker list_replace(&old_uses, &old_def->uses);
2154*61046927SAndroid Build Coastguard Worker
2155*61046927SAndroid Build Coastguard Worker if (new_def == NIR_LOWER_INSTR_PROGRESS_REPLACE) {
2156*61046927SAndroid Build Coastguard Worker /* Only instructions without a return value can be removed like this */
2157*61046927SAndroid Build Coastguard Worker assert(!old_def);
2158*61046927SAndroid Build Coastguard Worker iter = nir_instr_free_and_dce(instr);
2159*61046927SAndroid Build Coastguard Worker progress = true;
2160*61046927SAndroid Build Coastguard Worker } else
2161*61046927SAndroid Build Coastguard Worker iter = nir_after_instr(instr);
2162*61046927SAndroid Build Coastguard Worker
2163*61046927SAndroid Build Coastguard Worker if (new_def == NIR_LOWER_INSTR_PROGRESS)
2164*61046927SAndroid Build Coastguard Worker progress = true;
2165*61046927SAndroid Build Coastguard Worker }
2166*61046927SAndroid Build Coastguard Worker }
2167*61046927SAndroid Build Coastguard Worker
2168*61046927SAndroid Build Coastguard Worker if (progress) {
2169*61046927SAndroid Build Coastguard Worker nir_metadata_preserve(impl, preserved);
2170*61046927SAndroid Build Coastguard Worker } else {
2171*61046927SAndroid Build Coastguard Worker nir_metadata_preserve(impl, nir_metadata_all);
2172*61046927SAndroid Build Coastguard Worker }
2173*61046927SAndroid Build Coastguard Worker
2174*61046927SAndroid Build Coastguard Worker return progress;
2175*61046927SAndroid Build Coastguard Worker }
2176*61046927SAndroid Build Coastguard Worker
2177*61046927SAndroid Build Coastguard Worker bool
nir_shader_lower_instructions(nir_shader * shader,nir_instr_filter_cb filter,nir_lower_instr_cb lower,void * cb_data)2178*61046927SAndroid Build Coastguard Worker nir_shader_lower_instructions(nir_shader *shader,
2179*61046927SAndroid Build Coastguard Worker nir_instr_filter_cb filter,
2180*61046927SAndroid Build Coastguard Worker nir_lower_instr_cb lower,
2181*61046927SAndroid Build Coastguard Worker void *cb_data)
2182*61046927SAndroid Build Coastguard Worker {
2183*61046927SAndroid Build Coastguard Worker bool progress = false;
2184*61046927SAndroid Build Coastguard Worker
2185*61046927SAndroid Build Coastguard Worker nir_foreach_function_impl(impl, shader) {
2186*61046927SAndroid Build Coastguard Worker if (nir_function_impl_lower_instructions(impl, filter, lower, cb_data))
2187*61046927SAndroid Build Coastguard Worker progress = true;
2188*61046927SAndroid Build Coastguard Worker }
2189*61046927SAndroid Build Coastguard Worker
2190*61046927SAndroid Build Coastguard Worker return progress;
2191*61046927SAndroid Build Coastguard Worker }
2192*61046927SAndroid Build Coastguard Worker
2193*61046927SAndroid Build Coastguard Worker /**
2194*61046927SAndroid Build Coastguard Worker * Returns true if the shader supports quad-based implicit derivatives on
2195*61046927SAndroid Build Coastguard Worker * texture sampling.
2196*61046927SAndroid Build Coastguard Worker */
2197*61046927SAndroid Build Coastguard Worker bool
nir_shader_supports_implicit_lod(nir_shader * shader)2198*61046927SAndroid Build Coastguard Worker nir_shader_supports_implicit_lod(nir_shader *shader)
2199*61046927SAndroid Build Coastguard Worker {
2200*61046927SAndroid Build Coastguard Worker return (shader->info.stage == MESA_SHADER_FRAGMENT ||
2201*61046927SAndroid Build Coastguard Worker (gl_shader_stage_uses_workgroup(shader->info.stage) &&
2202*61046927SAndroid Build Coastguard Worker shader->info.derivative_group != DERIVATIVE_GROUP_NONE));
2203*61046927SAndroid Build Coastguard Worker }
2204*61046927SAndroid Build Coastguard Worker
2205*61046927SAndroid Build Coastguard Worker nir_intrinsic_op
nir_intrinsic_from_system_value(gl_system_value val)2206*61046927SAndroid Build Coastguard Worker nir_intrinsic_from_system_value(gl_system_value val)
2207*61046927SAndroid Build Coastguard Worker {
2208*61046927SAndroid Build Coastguard Worker switch (val) {
2209*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_VERTEX_ID:
2210*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_vertex_id;
2211*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_INSTANCE_ID:
2212*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_instance_id;
2213*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_DRAW_ID:
2214*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_draw_id;
2215*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_BASE_INSTANCE:
2216*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_base_instance;
2217*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE:
2218*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_vertex_id_zero_base;
2219*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_IS_INDEXED_DRAW:
2220*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_is_indexed_draw;
2221*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_FIRST_VERTEX:
2222*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_first_vertex;
2223*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_BASE_VERTEX:
2224*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_base_vertex;
2225*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_INVOCATION_ID:
2226*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_invocation_id;
2227*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_FRAG_COORD:
2228*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_frag_coord;
2229*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_POINT_COORD:
2230*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_point_coord;
2231*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_LINE_COORD:
2232*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_line_coord;
2233*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_FRONT_FACE:
2234*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_front_face;
2235*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SAMPLE_ID:
2236*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_sample_id;
2237*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SAMPLE_POS:
2238*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_sample_pos;
2239*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SAMPLE_POS_OR_CENTER:
2240*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_sample_pos_or_center;
2241*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SAMPLE_MASK_IN:
2242*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_sample_mask_in;
2243*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_LAYER_ID:
2244*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_layer_id;
2245*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_LOCAL_INVOCATION_ID:
2246*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_local_invocation_id;
2247*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_LOCAL_INVOCATION_INDEX:
2248*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_local_invocation_index;
2249*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_WORKGROUP_ID:
2250*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_workgroup_id;
2251*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_BASE_WORKGROUP_ID:
2252*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_base_workgroup_id;
2253*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_WORKGROUP_INDEX:
2254*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_workgroup_index;
2255*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_NUM_WORKGROUPS:
2256*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_num_workgroups;
2257*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_PRIMITIVE_ID:
2258*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_primitive_id;
2259*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_TESS_COORD:
2260*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_tess_coord;
2261*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_TESS_LEVEL_OUTER:
2262*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_tess_level_outer;
2263*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_TESS_LEVEL_INNER:
2264*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_tess_level_inner;
2265*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_TESS_LEVEL_OUTER_DEFAULT:
2266*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_tess_level_outer_default;
2267*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_TESS_LEVEL_INNER_DEFAULT:
2268*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_tess_level_inner_default;
2269*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_VERTICES_IN:
2270*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_patch_vertices_in;
2271*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_HELPER_INVOCATION:
2272*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_helper_invocation;
2273*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_COLOR0:
2274*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_color0;
2275*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_COLOR1:
2276*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_color1;
2277*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_VIEW_INDEX:
2278*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_view_index;
2279*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SUBGROUP_SIZE:
2280*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_subgroup_size;
2281*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SUBGROUP_INVOCATION:
2282*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_subgroup_invocation;
2283*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SUBGROUP_EQ_MASK:
2284*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_subgroup_eq_mask;
2285*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SUBGROUP_GE_MASK:
2286*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_subgroup_ge_mask;
2287*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SUBGROUP_GT_MASK:
2288*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_subgroup_gt_mask;
2289*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SUBGROUP_LE_MASK:
2290*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_subgroup_le_mask;
2291*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SUBGROUP_LT_MASK:
2292*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_subgroup_lt_mask;
2293*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_NUM_SUBGROUPS:
2294*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_num_subgroups;
2295*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SUBGROUP_ID:
2296*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_subgroup_id;
2297*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_WORKGROUP_SIZE:
2298*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_workgroup_size;
2299*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_GLOBAL_INVOCATION_ID:
2300*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_global_invocation_id;
2301*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_BASE_GLOBAL_INVOCATION_ID:
2302*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_base_global_invocation_id;
2303*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_GLOBAL_INVOCATION_INDEX:
2304*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_global_invocation_index;
2305*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_GLOBAL_GROUP_SIZE:
2306*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_global_size;
2307*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_WORK_DIM:
2308*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_work_dim;
2309*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_USER_DATA_AMD:
2310*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_user_data_amd;
2311*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_LAUNCH_ID:
2312*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_launch_id;
2313*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_LAUNCH_SIZE:
2314*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_launch_size;
2315*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_WORLD_ORIGIN:
2316*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_world_origin;
2317*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_WORLD_DIRECTION:
2318*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_world_direction;
2319*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_OBJECT_ORIGIN:
2320*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_object_origin;
2321*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_OBJECT_DIRECTION:
2322*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_object_direction;
2323*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_T_MIN:
2324*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_t_min;
2325*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_T_MAX:
2326*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_t_max;
2327*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_OBJECT_TO_WORLD:
2328*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_object_to_world;
2329*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_WORLD_TO_OBJECT:
2330*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_world_to_object;
2331*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_HIT_KIND:
2332*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_hit_kind;
2333*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_FLAGS:
2334*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_flags;
2335*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_GEOMETRY_INDEX:
2336*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_geometry_index;
2337*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_INSTANCE_CUSTOM_INDEX:
2338*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_instance_custom_index;
2339*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_CULL_MASK:
2340*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_cull_mask;
2341*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_RAY_TRIANGLE_VERTEX_POSITIONS:
2342*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_ray_triangle_vertex_positions;
2343*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_MESH_VIEW_COUNT:
2344*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_mesh_view_count;
2345*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_FRAG_SHADING_RATE:
2346*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_frag_shading_rate;
2347*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_FULLY_COVERED:
2348*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_fully_covered;
2349*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_FRAG_SIZE:
2350*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_frag_size;
2351*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_FRAG_INVOCATION_COUNT:
2352*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_frag_invocation_count;
2353*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SHADER_INDEX:
2354*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_shader_index;
2355*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_COALESCED_INPUT_COUNT:
2356*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_coalesced_input_count;
2357*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_WARPS_PER_SM_NV:
2358*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_warps_per_sm_nv;
2359*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SM_COUNT_NV:
2360*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_sm_count_nv;
2361*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_WARP_ID_NV:
2362*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_warp_id_nv;
2363*61046927SAndroid Build Coastguard Worker case SYSTEM_VALUE_SM_ID_NV:
2364*61046927SAndroid Build Coastguard Worker return nir_intrinsic_load_sm_id_nv;
2365*61046927SAndroid Build Coastguard Worker default:
2366*61046927SAndroid Build Coastguard Worker unreachable("system value does not directly correspond to intrinsic");
2367*61046927SAndroid Build Coastguard Worker }
2368*61046927SAndroid Build Coastguard Worker }
2369*61046927SAndroid Build Coastguard Worker
2370*61046927SAndroid Build Coastguard Worker gl_system_value
nir_system_value_from_intrinsic(nir_intrinsic_op intrin)2371*61046927SAndroid Build Coastguard Worker nir_system_value_from_intrinsic(nir_intrinsic_op intrin)
2372*61046927SAndroid Build Coastguard Worker {
2373*61046927SAndroid Build Coastguard Worker switch (intrin) {
2374*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_vertex_id:
2375*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_VERTEX_ID;
2376*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_instance_id:
2377*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_INSTANCE_ID;
2378*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_draw_id:
2379*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_DRAW_ID;
2380*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_base_instance:
2381*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_BASE_INSTANCE;
2382*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_vertex_id_zero_base:
2383*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_VERTEX_ID_ZERO_BASE;
2384*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_first_vertex:
2385*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_FIRST_VERTEX;
2386*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_is_indexed_draw:
2387*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_IS_INDEXED_DRAW;
2388*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_base_vertex:
2389*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_BASE_VERTEX;
2390*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_invocation_id:
2391*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_INVOCATION_ID;
2392*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_frag_coord:
2393*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_FRAG_COORD;
2394*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_point_coord:
2395*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_POINT_COORD;
2396*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_line_coord:
2397*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_LINE_COORD;
2398*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_front_face:
2399*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_FRONT_FACE;
2400*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_sample_id:
2401*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SAMPLE_ID;
2402*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_sample_pos:
2403*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SAMPLE_POS;
2404*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_sample_pos_or_center:
2405*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SAMPLE_POS_OR_CENTER;
2406*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_sample_mask_in:
2407*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SAMPLE_MASK_IN;
2408*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_layer_id:
2409*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_LAYER_ID;
2410*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_local_invocation_id:
2411*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_LOCAL_INVOCATION_ID;
2412*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_local_invocation_index:
2413*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_LOCAL_INVOCATION_INDEX;
2414*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_num_workgroups:
2415*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_NUM_WORKGROUPS;
2416*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_workgroup_id:
2417*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_WORKGROUP_ID;
2418*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_base_workgroup_id:
2419*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_BASE_WORKGROUP_ID;
2420*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_workgroup_index:
2421*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_WORKGROUP_INDEX;
2422*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_primitive_id:
2423*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_PRIMITIVE_ID;
2424*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_tess_coord:
2425*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_tess_coord_xy:
2426*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_TESS_COORD;
2427*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_tess_level_outer:
2428*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_TESS_LEVEL_OUTER;
2429*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_tess_level_inner:
2430*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_TESS_LEVEL_INNER;
2431*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_tess_level_outer_default:
2432*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_TESS_LEVEL_OUTER_DEFAULT;
2433*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_tess_level_inner_default:
2434*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_TESS_LEVEL_INNER_DEFAULT;
2435*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_patch_vertices_in:
2436*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_VERTICES_IN;
2437*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_helper_invocation:
2438*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_HELPER_INVOCATION;
2439*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_color0:
2440*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_COLOR0;
2441*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_color1:
2442*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_COLOR1;
2443*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_view_index:
2444*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_VIEW_INDEX;
2445*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_subgroup_size:
2446*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SUBGROUP_SIZE;
2447*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_subgroup_invocation:
2448*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SUBGROUP_INVOCATION;
2449*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_subgroup_eq_mask:
2450*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SUBGROUP_EQ_MASK;
2451*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_subgroup_ge_mask:
2452*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SUBGROUP_GE_MASK;
2453*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_subgroup_gt_mask:
2454*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SUBGROUP_GT_MASK;
2455*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_subgroup_le_mask:
2456*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SUBGROUP_LE_MASK;
2457*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_subgroup_lt_mask:
2458*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SUBGROUP_LT_MASK;
2459*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_num_subgroups:
2460*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_NUM_SUBGROUPS;
2461*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_subgroup_id:
2462*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SUBGROUP_ID;
2463*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_workgroup_size:
2464*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_WORKGROUP_SIZE;
2465*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_global_invocation_id:
2466*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_GLOBAL_INVOCATION_ID;
2467*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_base_global_invocation_id:
2468*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_BASE_GLOBAL_INVOCATION_ID;
2469*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_global_invocation_index:
2470*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_GLOBAL_INVOCATION_INDEX;
2471*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_global_size:
2472*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_GLOBAL_GROUP_SIZE;
2473*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_work_dim:
2474*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_WORK_DIM;
2475*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_user_data_amd:
2476*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_USER_DATA_AMD;
2477*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_barycentric_model:
2478*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_BARYCENTRIC_PULL_MODEL;
2479*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_gs_header_ir3:
2480*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_GS_HEADER_IR3;
2481*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_tcs_header_ir3:
2482*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_TCS_HEADER_IR3;
2483*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_launch_id:
2484*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_LAUNCH_ID;
2485*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_launch_size:
2486*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_LAUNCH_SIZE;
2487*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_world_origin:
2488*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_WORLD_ORIGIN;
2489*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_world_direction:
2490*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_WORLD_DIRECTION;
2491*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_object_origin:
2492*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_OBJECT_ORIGIN;
2493*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_object_direction:
2494*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_OBJECT_DIRECTION;
2495*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_t_min:
2496*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_T_MIN;
2497*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_t_max:
2498*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_T_MAX;
2499*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_object_to_world:
2500*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_OBJECT_TO_WORLD;
2501*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_world_to_object:
2502*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_WORLD_TO_OBJECT;
2503*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_hit_kind:
2504*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_HIT_KIND;
2505*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_flags:
2506*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_FLAGS;
2507*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_geometry_index:
2508*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_GEOMETRY_INDEX;
2509*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_instance_custom_index:
2510*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_INSTANCE_CUSTOM_INDEX;
2511*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_cull_mask:
2512*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_CULL_MASK;
2513*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_ray_triangle_vertex_positions:
2514*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_RAY_TRIANGLE_VERTEX_POSITIONS;
2515*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_frag_shading_rate:
2516*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_FRAG_SHADING_RATE;
2517*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_mesh_view_count:
2518*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_MESH_VIEW_COUNT;
2519*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_fully_covered:
2520*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_FULLY_COVERED;
2521*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_frag_size:
2522*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_FRAG_SIZE;
2523*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_frag_invocation_count:
2524*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_FRAG_INVOCATION_COUNT;
2525*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_shader_index:
2526*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SHADER_INDEX;
2527*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_coalesced_input_count:
2528*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_COALESCED_INPUT_COUNT;
2529*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_warps_per_sm_nv:
2530*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_WARPS_PER_SM_NV;
2531*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_sm_count_nv:
2532*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SM_COUNT_NV;
2533*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_warp_id_nv:
2534*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_WARP_ID_NV;
2535*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_sm_id_nv:
2536*61046927SAndroid Build Coastguard Worker return SYSTEM_VALUE_SM_ID_NV;
2537*61046927SAndroid Build Coastguard Worker default:
2538*61046927SAndroid Build Coastguard Worker unreachable("intrinsic doesn't produce a system value");
2539*61046927SAndroid Build Coastguard Worker }
2540*61046927SAndroid Build Coastguard Worker }
2541*61046927SAndroid Build Coastguard Worker
2542*61046927SAndroid Build Coastguard Worker /* OpenGL utility method that remaps the location attributes if they are
2543*61046927SAndroid Build Coastguard Worker * doubles. Not needed for vulkan due the differences on the input location
2544*61046927SAndroid Build Coastguard Worker * count for doubles on vulkan vs OpenGL
2545*61046927SAndroid Build Coastguard Worker *
2546*61046927SAndroid Build Coastguard Worker * The bitfield returned in dual_slot is one bit for each double input slot in
2547*61046927SAndroid Build Coastguard Worker * the original OpenGL single-slot input numbering. The mapping from old
2548*61046927SAndroid Build Coastguard Worker * locations to new locations is as follows:
2549*61046927SAndroid Build Coastguard Worker *
2550*61046927SAndroid Build Coastguard Worker * new_loc = loc + util_bitcount(dual_slot & BITFIELD64_MASK(loc))
2551*61046927SAndroid Build Coastguard Worker */
2552*61046927SAndroid Build Coastguard Worker void
nir_remap_dual_slot_attributes(nir_shader * shader,uint64_t * dual_slot)2553*61046927SAndroid Build Coastguard Worker nir_remap_dual_slot_attributes(nir_shader *shader, uint64_t *dual_slot)
2554*61046927SAndroid Build Coastguard Worker {
2555*61046927SAndroid Build Coastguard Worker assert(shader->info.stage == MESA_SHADER_VERTEX);
2556*61046927SAndroid Build Coastguard Worker
2557*61046927SAndroid Build Coastguard Worker *dual_slot = 0;
2558*61046927SAndroid Build Coastguard Worker nir_foreach_shader_in_variable(var, shader) {
2559*61046927SAndroid Build Coastguard Worker if (glsl_type_is_dual_slot(glsl_without_array(var->type))) {
2560*61046927SAndroid Build Coastguard Worker unsigned slots = glsl_count_attribute_slots(var->type, true);
2561*61046927SAndroid Build Coastguard Worker *dual_slot |= BITFIELD64_MASK(slots) << var->data.location;
2562*61046927SAndroid Build Coastguard Worker }
2563*61046927SAndroid Build Coastguard Worker }
2564*61046927SAndroid Build Coastguard Worker
2565*61046927SAndroid Build Coastguard Worker nir_foreach_shader_in_variable(var, shader) {
2566*61046927SAndroid Build Coastguard Worker var->data.location +=
2567*61046927SAndroid Build Coastguard Worker util_bitcount64(*dual_slot & BITFIELD64_MASK(var->data.location));
2568*61046927SAndroid Build Coastguard Worker }
2569*61046927SAndroid Build Coastguard Worker }
2570*61046927SAndroid Build Coastguard Worker
2571*61046927SAndroid Build Coastguard Worker /* Returns an attribute mask that has been re-compacted using the given
2572*61046927SAndroid Build Coastguard Worker * dual_slot mask.
2573*61046927SAndroid Build Coastguard Worker */
2574*61046927SAndroid Build Coastguard Worker uint64_t
nir_get_single_slot_attribs_mask(uint64_t attribs,uint64_t dual_slot)2575*61046927SAndroid Build Coastguard Worker nir_get_single_slot_attribs_mask(uint64_t attribs, uint64_t dual_slot)
2576*61046927SAndroid Build Coastguard Worker {
2577*61046927SAndroid Build Coastguard Worker while (dual_slot) {
2578*61046927SAndroid Build Coastguard Worker unsigned loc = u_bit_scan64(&dual_slot);
2579*61046927SAndroid Build Coastguard Worker /* mask of all bits up to and including loc */
2580*61046927SAndroid Build Coastguard Worker uint64_t mask = BITFIELD64_MASK(loc + 1);
2581*61046927SAndroid Build Coastguard Worker attribs = (attribs & mask) | ((attribs & ~mask) >> 1);
2582*61046927SAndroid Build Coastguard Worker }
2583*61046927SAndroid Build Coastguard Worker return attribs;
2584*61046927SAndroid Build Coastguard Worker }
2585*61046927SAndroid Build Coastguard Worker
2586*61046927SAndroid Build Coastguard Worker void
nir_rewrite_image_intrinsic(nir_intrinsic_instr * intrin,nir_def * src,bool bindless)2587*61046927SAndroid Build Coastguard Worker nir_rewrite_image_intrinsic(nir_intrinsic_instr *intrin, nir_def *src,
2588*61046927SAndroid Build Coastguard Worker bool bindless)
2589*61046927SAndroid Build Coastguard Worker {
2590*61046927SAndroid Build Coastguard Worker enum gl_access_qualifier access = nir_intrinsic_access(intrin);
2591*61046927SAndroid Build Coastguard Worker
2592*61046927SAndroid Build Coastguard Worker /* Image intrinsics only have one of these */
2593*61046927SAndroid Build Coastguard Worker assert(!nir_intrinsic_has_src_type(intrin) ||
2594*61046927SAndroid Build Coastguard Worker !nir_intrinsic_has_dest_type(intrin));
2595*61046927SAndroid Build Coastguard Worker
2596*61046927SAndroid Build Coastguard Worker nir_alu_type data_type = nir_type_invalid;
2597*61046927SAndroid Build Coastguard Worker if (nir_intrinsic_has_src_type(intrin))
2598*61046927SAndroid Build Coastguard Worker data_type = nir_intrinsic_src_type(intrin);
2599*61046927SAndroid Build Coastguard Worker if (nir_intrinsic_has_dest_type(intrin))
2600*61046927SAndroid Build Coastguard Worker data_type = nir_intrinsic_dest_type(intrin);
2601*61046927SAndroid Build Coastguard Worker
2602*61046927SAndroid Build Coastguard Worker nir_atomic_op atomic_op = 0;
2603*61046927SAndroid Build Coastguard Worker if (nir_intrinsic_has_atomic_op(intrin))
2604*61046927SAndroid Build Coastguard Worker atomic_op = nir_intrinsic_atomic_op(intrin);
2605*61046927SAndroid Build Coastguard Worker
2606*61046927SAndroid Build Coastguard Worker switch (intrin->intrinsic) {
2607*61046927SAndroid Build Coastguard Worker #define CASE(op) \
2608*61046927SAndroid Build Coastguard Worker case nir_intrinsic_image_deref_##op: \
2609*61046927SAndroid Build Coastguard Worker intrin->intrinsic = bindless ? nir_intrinsic_bindless_image_##op \
2610*61046927SAndroid Build Coastguard Worker : nir_intrinsic_image_##op; \
2611*61046927SAndroid Build Coastguard Worker break;
2612*61046927SAndroid Build Coastguard Worker CASE(load)
2613*61046927SAndroid Build Coastguard Worker CASE(sparse_load)
2614*61046927SAndroid Build Coastguard Worker CASE(store)
2615*61046927SAndroid Build Coastguard Worker CASE(atomic)
2616*61046927SAndroid Build Coastguard Worker CASE(atomic_swap)
2617*61046927SAndroid Build Coastguard Worker CASE(size)
2618*61046927SAndroid Build Coastguard Worker CASE(samples)
2619*61046927SAndroid Build Coastguard Worker CASE(load_raw_intel)
2620*61046927SAndroid Build Coastguard Worker CASE(store_raw_intel)
2621*61046927SAndroid Build Coastguard Worker CASE(fragment_mask_load_amd)
2622*61046927SAndroid Build Coastguard Worker CASE(store_block_agx)
2623*61046927SAndroid Build Coastguard Worker #undef CASE
2624*61046927SAndroid Build Coastguard Worker default:
2625*61046927SAndroid Build Coastguard Worker unreachable("Unhanded image intrinsic");
2626*61046927SAndroid Build Coastguard Worker }
2627*61046927SAndroid Build Coastguard Worker
2628*61046927SAndroid Build Coastguard Worker nir_variable *var = nir_intrinsic_get_var(intrin, 0);
2629*61046927SAndroid Build Coastguard Worker
2630*61046927SAndroid Build Coastguard Worker /* Only update the format if the intrinsic doesn't have one set */
2631*61046927SAndroid Build Coastguard Worker if (nir_intrinsic_format(intrin) == PIPE_FORMAT_NONE)
2632*61046927SAndroid Build Coastguard Worker nir_intrinsic_set_format(intrin, var->data.image.format);
2633*61046927SAndroid Build Coastguard Worker
2634*61046927SAndroid Build Coastguard Worker nir_intrinsic_set_access(intrin, access | var->data.access);
2635*61046927SAndroid Build Coastguard Worker if (nir_intrinsic_has_src_type(intrin))
2636*61046927SAndroid Build Coastguard Worker nir_intrinsic_set_src_type(intrin, data_type);
2637*61046927SAndroid Build Coastguard Worker if (nir_intrinsic_has_dest_type(intrin))
2638*61046927SAndroid Build Coastguard Worker nir_intrinsic_set_dest_type(intrin, data_type);
2639*61046927SAndroid Build Coastguard Worker
2640*61046927SAndroid Build Coastguard Worker if (nir_intrinsic_has_atomic_op(intrin))
2641*61046927SAndroid Build Coastguard Worker nir_intrinsic_set_atomic_op(intrin, atomic_op);
2642*61046927SAndroid Build Coastguard Worker
2643*61046927SAndroid Build Coastguard Worker nir_src_rewrite(&intrin->src[0], src);
2644*61046927SAndroid Build Coastguard Worker }
2645*61046927SAndroid Build Coastguard Worker
2646*61046927SAndroid Build Coastguard Worker unsigned
nir_image_intrinsic_coord_components(const nir_intrinsic_instr * instr)2647*61046927SAndroid Build Coastguard Worker nir_image_intrinsic_coord_components(const nir_intrinsic_instr *instr)
2648*61046927SAndroid Build Coastguard Worker {
2649*61046927SAndroid Build Coastguard Worker enum glsl_sampler_dim dim = nir_intrinsic_image_dim(instr);
2650*61046927SAndroid Build Coastguard Worker int coords = glsl_get_sampler_dim_coordinate_components(dim);
2651*61046927SAndroid Build Coastguard Worker if (dim == GLSL_SAMPLER_DIM_CUBE)
2652*61046927SAndroid Build Coastguard Worker return coords;
2653*61046927SAndroid Build Coastguard Worker else
2654*61046927SAndroid Build Coastguard Worker return coords + nir_intrinsic_image_array(instr);
2655*61046927SAndroid Build Coastguard Worker }
2656*61046927SAndroid Build Coastguard Worker
2657*61046927SAndroid Build Coastguard Worker nir_src *
nir_get_shader_call_payload_src(nir_intrinsic_instr * call)2658*61046927SAndroid Build Coastguard Worker nir_get_shader_call_payload_src(nir_intrinsic_instr *call)
2659*61046927SAndroid Build Coastguard Worker {
2660*61046927SAndroid Build Coastguard Worker switch (call->intrinsic) {
2661*61046927SAndroid Build Coastguard Worker case nir_intrinsic_trace_ray:
2662*61046927SAndroid Build Coastguard Worker case nir_intrinsic_rt_trace_ray:
2663*61046927SAndroid Build Coastguard Worker return &call->src[10];
2664*61046927SAndroid Build Coastguard Worker case nir_intrinsic_execute_callable:
2665*61046927SAndroid Build Coastguard Worker case nir_intrinsic_rt_execute_callable:
2666*61046927SAndroid Build Coastguard Worker return &call->src[1];
2667*61046927SAndroid Build Coastguard Worker default:
2668*61046927SAndroid Build Coastguard Worker unreachable("Not a call intrinsic");
2669*61046927SAndroid Build Coastguard Worker return NULL;
2670*61046927SAndroid Build Coastguard Worker }
2671*61046927SAndroid Build Coastguard Worker }
2672*61046927SAndroid Build Coastguard Worker
2673*61046927SAndroid Build Coastguard Worker nir_binding
nir_chase_binding(nir_src rsrc)2674*61046927SAndroid Build Coastguard Worker nir_chase_binding(nir_src rsrc)
2675*61046927SAndroid Build Coastguard Worker {
2676*61046927SAndroid Build Coastguard Worker nir_binding res = { 0 };
2677*61046927SAndroid Build Coastguard Worker if (rsrc.ssa->parent_instr->type == nir_instr_type_deref) {
2678*61046927SAndroid Build Coastguard Worker const struct glsl_type *type = glsl_without_array(nir_src_as_deref(rsrc)->type);
2679*61046927SAndroid Build Coastguard Worker bool is_image = glsl_type_is_image(type) || glsl_type_is_sampler(type);
2680*61046927SAndroid Build Coastguard Worker while (rsrc.ssa->parent_instr->type == nir_instr_type_deref) {
2681*61046927SAndroid Build Coastguard Worker nir_deref_instr *deref = nir_src_as_deref(rsrc);
2682*61046927SAndroid Build Coastguard Worker
2683*61046927SAndroid Build Coastguard Worker if (deref->deref_type == nir_deref_type_var) {
2684*61046927SAndroid Build Coastguard Worker res.success = true;
2685*61046927SAndroid Build Coastguard Worker res.var = deref->var;
2686*61046927SAndroid Build Coastguard Worker res.desc_set = deref->var->data.descriptor_set;
2687*61046927SAndroid Build Coastguard Worker res.binding = deref->var->data.binding;
2688*61046927SAndroid Build Coastguard Worker return res;
2689*61046927SAndroid Build Coastguard Worker } else if (deref->deref_type == nir_deref_type_array && is_image) {
2690*61046927SAndroid Build Coastguard Worker if (res.num_indices == ARRAY_SIZE(res.indices))
2691*61046927SAndroid Build Coastguard Worker return (nir_binding){ 0 };
2692*61046927SAndroid Build Coastguard Worker res.indices[res.num_indices++] = deref->arr.index;
2693*61046927SAndroid Build Coastguard Worker }
2694*61046927SAndroid Build Coastguard Worker
2695*61046927SAndroid Build Coastguard Worker rsrc = deref->parent;
2696*61046927SAndroid Build Coastguard Worker }
2697*61046927SAndroid Build Coastguard Worker }
2698*61046927SAndroid Build Coastguard Worker
2699*61046927SAndroid Build Coastguard Worker /* Skip copies and trimming. Trimming can appear as nir_op_mov instructions
2700*61046927SAndroid Build Coastguard Worker * when removing the offset from addresses. We also consider
2701*61046927SAndroid Build Coastguard Worker * nir_op_is_vec_or_mov() instructions to skip trimming of
2702*61046927SAndroid Build Coastguard Worker * vec2_index_32bit_offset addresses after lowering ALU to scalar.
2703*61046927SAndroid Build Coastguard Worker */
2704*61046927SAndroid Build Coastguard Worker unsigned num_components = nir_src_num_components(rsrc);
2705*61046927SAndroid Build Coastguard Worker while (true) {
2706*61046927SAndroid Build Coastguard Worker nir_alu_instr *alu = nir_src_as_alu_instr(rsrc);
2707*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *intrin = nir_src_as_intrinsic(rsrc);
2708*61046927SAndroid Build Coastguard Worker if (alu && alu->op == nir_op_mov) {
2709*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_components; i++) {
2710*61046927SAndroid Build Coastguard Worker if (alu->src[0].swizzle[i] != i)
2711*61046927SAndroid Build Coastguard Worker return (nir_binding){ 0 };
2712*61046927SAndroid Build Coastguard Worker }
2713*61046927SAndroid Build Coastguard Worker rsrc = alu->src[0].src;
2714*61046927SAndroid Build Coastguard Worker } else if (alu && nir_op_is_vec(alu->op)) {
2715*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_components; i++) {
2716*61046927SAndroid Build Coastguard Worker if (alu->src[i].swizzle[0] != i || alu->src[i].src.ssa != alu->src[0].src.ssa)
2717*61046927SAndroid Build Coastguard Worker return (nir_binding){ 0 };
2718*61046927SAndroid Build Coastguard Worker }
2719*61046927SAndroid Build Coastguard Worker rsrc = alu->src[0].src;
2720*61046927SAndroid Build Coastguard Worker } else if (intrin && intrin->intrinsic == nir_intrinsic_read_first_invocation) {
2721*61046927SAndroid Build Coastguard Worker /* The caller might want to be aware if only the first invocation of
2722*61046927SAndroid Build Coastguard Worker * the indices are used.
2723*61046927SAndroid Build Coastguard Worker */
2724*61046927SAndroid Build Coastguard Worker res.read_first_invocation = true;
2725*61046927SAndroid Build Coastguard Worker rsrc = intrin->src[0];
2726*61046927SAndroid Build Coastguard Worker } else {
2727*61046927SAndroid Build Coastguard Worker break;
2728*61046927SAndroid Build Coastguard Worker }
2729*61046927SAndroid Build Coastguard Worker }
2730*61046927SAndroid Build Coastguard Worker
2731*61046927SAndroid Build Coastguard Worker if (nir_src_is_const(rsrc)) {
2732*61046927SAndroid Build Coastguard Worker /* GL binding model after deref lowering */
2733*61046927SAndroid Build Coastguard Worker res.success = true;
2734*61046927SAndroid Build Coastguard Worker /* Can't use just nir_src_as_uint. Vulkan resource index produces a
2735*61046927SAndroid Build Coastguard Worker * vec2. Some drivers lower it to vec1 (to handle get_ssbo_size for
2736*61046927SAndroid Build Coastguard Worker * example) but others just keep it around as a vec2 (v3dv).
2737*61046927SAndroid Build Coastguard Worker */
2738*61046927SAndroid Build Coastguard Worker res.binding = nir_src_comp_as_uint(rsrc, 0);
2739*61046927SAndroid Build Coastguard Worker return res;
2740*61046927SAndroid Build Coastguard Worker }
2741*61046927SAndroid Build Coastguard Worker
2742*61046927SAndroid Build Coastguard Worker /* otherwise, must be Vulkan binding model after deref lowering or GL bindless */
2743*61046927SAndroid Build Coastguard Worker
2744*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *intrin = nir_src_as_intrinsic(rsrc);
2745*61046927SAndroid Build Coastguard Worker if (!intrin)
2746*61046927SAndroid Build Coastguard Worker return (nir_binding){ 0 };
2747*61046927SAndroid Build Coastguard Worker
2748*61046927SAndroid Build Coastguard Worker /* Intel resource, similar to load_vulkan_descriptor after it has been
2749*61046927SAndroid Build Coastguard Worker * lowered.
2750*61046927SAndroid Build Coastguard Worker */
2751*61046927SAndroid Build Coastguard Worker if (intrin->intrinsic == nir_intrinsic_resource_intel) {
2752*61046927SAndroid Build Coastguard Worker res.success = true;
2753*61046927SAndroid Build Coastguard Worker res.desc_set = nir_intrinsic_desc_set(intrin);
2754*61046927SAndroid Build Coastguard Worker res.binding = nir_intrinsic_binding(intrin);
2755*61046927SAndroid Build Coastguard Worker /* nir_intrinsic_resource_intel has 3 sources, but src[2] is included in
2756*61046927SAndroid Build Coastguard Worker * src[1], it is kept around for other purposes.
2757*61046927SAndroid Build Coastguard Worker */
2758*61046927SAndroid Build Coastguard Worker res.num_indices = 2;
2759*61046927SAndroid Build Coastguard Worker res.indices[0] = intrin->src[0];
2760*61046927SAndroid Build Coastguard Worker res.indices[1] = intrin->src[1];
2761*61046927SAndroid Build Coastguard Worker return res;
2762*61046927SAndroid Build Coastguard Worker }
2763*61046927SAndroid Build Coastguard Worker
2764*61046927SAndroid Build Coastguard Worker /* skip load_vulkan_descriptor */
2765*61046927SAndroid Build Coastguard Worker if (intrin->intrinsic == nir_intrinsic_load_vulkan_descriptor) {
2766*61046927SAndroid Build Coastguard Worker intrin = nir_src_as_intrinsic(intrin->src[0]);
2767*61046927SAndroid Build Coastguard Worker if (!intrin)
2768*61046927SAndroid Build Coastguard Worker return (nir_binding){ 0 };
2769*61046927SAndroid Build Coastguard Worker }
2770*61046927SAndroid Build Coastguard Worker
2771*61046927SAndroid Build Coastguard Worker if (intrin->intrinsic != nir_intrinsic_vulkan_resource_index)
2772*61046927SAndroid Build Coastguard Worker return (nir_binding){ 0 };
2773*61046927SAndroid Build Coastguard Worker
2774*61046927SAndroid Build Coastguard Worker assert(res.num_indices == 0);
2775*61046927SAndroid Build Coastguard Worker res.success = true;
2776*61046927SAndroid Build Coastguard Worker res.desc_set = nir_intrinsic_desc_set(intrin);
2777*61046927SAndroid Build Coastguard Worker res.binding = nir_intrinsic_binding(intrin);
2778*61046927SAndroid Build Coastguard Worker res.num_indices = 1;
2779*61046927SAndroid Build Coastguard Worker res.indices[0] = intrin->src[0];
2780*61046927SAndroid Build Coastguard Worker return res;
2781*61046927SAndroid Build Coastguard Worker }
2782*61046927SAndroid Build Coastguard Worker
2783*61046927SAndroid Build Coastguard Worker nir_variable *
nir_get_binding_variable(nir_shader * shader,nir_binding binding)2784*61046927SAndroid Build Coastguard Worker nir_get_binding_variable(nir_shader *shader, nir_binding binding)
2785*61046927SAndroid Build Coastguard Worker {
2786*61046927SAndroid Build Coastguard Worker nir_variable *binding_var = NULL;
2787*61046927SAndroid Build Coastguard Worker unsigned count = 0;
2788*61046927SAndroid Build Coastguard Worker
2789*61046927SAndroid Build Coastguard Worker if (!binding.success)
2790*61046927SAndroid Build Coastguard Worker return NULL;
2791*61046927SAndroid Build Coastguard Worker
2792*61046927SAndroid Build Coastguard Worker if (binding.var)
2793*61046927SAndroid Build Coastguard Worker return binding.var;
2794*61046927SAndroid Build Coastguard Worker
2795*61046927SAndroid Build Coastguard Worker nir_foreach_variable_with_modes(var, shader, nir_var_mem_ubo | nir_var_mem_ssbo) {
2796*61046927SAndroid Build Coastguard Worker if (var->data.descriptor_set == binding.desc_set && var->data.binding == binding.binding) {
2797*61046927SAndroid Build Coastguard Worker binding_var = var;
2798*61046927SAndroid Build Coastguard Worker count++;
2799*61046927SAndroid Build Coastguard Worker }
2800*61046927SAndroid Build Coastguard Worker }
2801*61046927SAndroid Build Coastguard Worker
2802*61046927SAndroid Build Coastguard Worker /* Be conservative if another variable is using the same binding/desc_set
2803*61046927SAndroid Build Coastguard Worker * because the access mask might be different and we can't get it reliably.
2804*61046927SAndroid Build Coastguard Worker */
2805*61046927SAndroid Build Coastguard Worker if (count > 1)
2806*61046927SAndroid Build Coastguard Worker return NULL;
2807*61046927SAndroid Build Coastguard Worker
2808*61046927SAndroid Build Coastguard Worker return binding_var;
2809*61046927SAndroid Build Coastguard Worker }
2810*61046927SAndroid Build Coastguard Worker
2811*61046927SAndroid Build Coastguard Worker nir_scalar
nir_scalar_chase_movs(nir_scalar s)2812*61046927SAndroid Build Coastguard Worker nir_scalar_chase_movs(nir_scalar s)
2813*61046927SAndroid Build Coastguard Worker {
2814*61046927SAndroid Build Coastguard Worker while (nir_scalar_is_alu(s)) {
2815*61046927SAndroid Build Coastguard Worker nir_alu_instr *alu = nir_instr_as_alu(s.def->parent_instr);
2816*61046927SAndroid Build Coastguard Worker if (alu->op == nir_op_mov) {
2817*61046927SAndroid Build Coastguard Worker s.def = alu->src[0].src.ssa;
2818*61046927SAndroid Build Coastguard Worker s.comp = alu->src[0].swizzle[s.comp];
2819*61046927SAndroid Build Coastguard Worker } else if (nir_op_is_vec(alu->op)) {
2820*61046927SAndroid Build Coastguard Worker s.def = alu->src[s.comp].src.ssa;
2821*61046927SAndroid Build Coastguard Worker s.comp = alu->src[s.comp].swizzle[0];
2822*61046927SAndroid Build Coastguard Worker } else {
2823*61046927SAndroid Build Coastguard Worker break;
2824*61046927SAndroid Build Coastguard Worker }
2825*61046927SAndroid Build Coastguard Worker }
2826*61046927SAndroid Build Coastguard Worker
2827*61046927SAndroid Build Coastguard Worker return s;
2828*61046927SAndroid Build Coastguard Worker }
2829*61046927SAndroid Build Coastguard Worker
2830*61046927SAndroid Build Coastguard Worker nir_alu_type
nir_get_nir_type_for_glsl_base_type(enum glsl_base_type base_type)2831*61046927SAndroid Build Coastguard Worker nir_get_nir_type_for_glsl_base_type(enum glsl_base_type base_type)
2832*61046927SAndroid Build Coastguard Worker {
2833*61046927SAndroid Build Coastguard Worker switch (base_type) {
2834*61046927SAndroid Build Coastguard Worker /* clang-format off */
2835*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL: return nir_type_bool1;
2836*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT: return nir_type_uint32;
2837*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT: return nir_type_int32;
2838*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16: return nir_type_uint16;
2839*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16: return nir_type_int16;
2840*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT8: return nir_type_uint8;
2841*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT8: return nir_type_int8;
2842*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64: return nir_type_uint64;
2843*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64: return nir_type_int64;
2844*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT: return nir_type_float32;
2845*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16: return nir_type_float16;
2846*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE: return nir_type_float64;
2847*61046927SAndroid Build Coastguard Worker /* clang-format on */
2848*61046927SAndroid Build Coastguard Worker
2849*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_COOPERATIVE_MATRIX:
2850*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
2851*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_TEXTURE:
2852*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
2853*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_ATOMIC_UINT:
2854*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_STRUCT:
2855*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INTERFACE:
2856*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_ARRAY:
2857*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_VOID:
2858*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SUBROUTINE:
2859*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_ERROR:
2860*61046927SAndroid Build Coastguard Worker return nir_type_invalid;
2861*61046927SAndroid Build Coastguard Worker }
2862*61046927SAndroid Build Coastguard Worker
2863*61046927SAndroid Build Coastguard Worker unreachable("unknown type");
2864*61046927SAndroid Build Coastguard Worker }
2865*61046927SAndroid Build Coastguard Worker
2866*61046927SAndroid Build Coastguard Worker enum glsl_base_type
nir_get_glsl_base_type_for_nir_type(nir_alu_type base_type)2867*61046927SAndroid Build Coastguard Worker nir_get_glsl_base_type_for_nir_type(nir_alu_type base_type)
2868*61046927SAndroid Build Coastguard Worker {
2869*61046927SAndroid Build Coastguard Worker /* clang-format off */
2870*61046927SAndroid Build Coastguard Worker switch (base_type) {
2871*61046927SAndroid Build Coastguard Worker case nir_type_bool1: return GLSL_TYPE_BOOL;
2872*61046927SAndroid Build Coastguard Worker case nir_type_uint32: return GLSL_TYPE_UINT;
2873*61046927SAndroid Build Coastguard Worker case nir_type_int32: return GLSL_TYPE_INT;
2874*61046927SAndroid Build Coastguard Worker case nir_type_uint16: return GLSL_TYPE_UINT16;
2875*61046927SAndroid Build Coastguard Worker case nir_type_int16: return GLSL_TYPE_INT16;
2876*61046927SAndroid Build Coastguard Worker case nir_type_uint8: return GLSL_TYPE_UINT8;
2877*61046927SAndroid Build Coastguard Worker case nir_type_int8: return GLSL_TYPE_INT8;
2878*61046927SAndroid Build Coastguard Worker case nir_type_uint64: return GLSL_TYPE_UINT64;
2879*61046927SAndroid Build Coastguard Worker case nir_type_int64: return GLSL_TYPE_INT64;
2880*61046927SAndroid Build Coastguard Worker case nir_type_float32: return GLSL_TYPE_FLOAT;
2881*61046927SAndroid Build Coastguard Worker case nir_type_float16: return GLSL_TYPE_FLOAT16;
2882*61046927SAndroid Build Coastguard Worker case nir_type_float64: return GLSL_TYPE_DOUBLE;
2883*61046927SAndroid Build Coastguard Worker default: unreachable("Not a sized nir_alu_type");
2884*61046927SAndroid Build Coastguard Worker }
2885*61046927SAndroid Build Coastguard Worker /* clang-format on */
2886*61046927SAndroid Build Coastguard Worker }
2887*61046927SAndroid Build Coastguard Worker
2888*61046927SAndroid Build Coastguard Worker nir_op
nir_op_vec(unsigned num_components)2889*61046927SAndroid Build Coastguard Worker nir_op_vec(unsigned num_components)
2890*61046927SAndroid Build Coastguard Worker {
2891*61046927SAndroid Build Coastguard Worker /* clang-format off */
2892*61046927SAndroid Build Coastguard Worker switch (num_components) {
2893*61046927SAndroid Build Coastguard Worker case 1: return nir_op_mov;
2894*61046927SAndroid Build Coastguard Worker case 2: return nir_op_vec2;
2895*61046927SAndroid Build Coastguard Worker case 3: return nir_op_vec3;
2896*61046927SAndroid Build Coastguard Worker case 4: return nir_op_vec4;
2897*61046927SAndroid Build Coastguard Worker case 5: return nir_op_vec5;
2898*61046927SAndroid Build Coastguard Worker case 8: return nir_op_vec8;
2899*61046927SAndroid Build Coastguard Worker case 16: return nir_op_vec16;
2900*61046927SAndroid Build Coastguard Worker default: unreachable("bad component count");
2901*61046927SAndroid Build Coastguard Worker }
2902*61046927SAndroid Build Coastguard Worker /* clang-format on */
2903*61046927SAndroid Build Coastguard Worker }
2904*61046927SAndroid Build Coastguard Worker
2905*61046927SAndroid Build Coastguard Worker bool
nir_op_is_vec(nir_op op)2906*61046927SAndroid Build Coastguard Worker nir_op_is_vec(nir_op op)
2907*61046927SAndroid Build Coastguard Worker {
2908*61046927SAndroid Build Coastguard Worker switch (op) {
2909*61046927SAndroid Build Coastguard Worker case nir_op_vec2:
2910*61046927SAndroid Build Coastguard Worker case nir_op_vec3:
2911*61046927SAndroid Build Coastguard Worker case nir_op_vec4:
2912*61046927SAndroid Build Coastguard Worker case nir_op_vec5:
2913*61046927SAndroid Build Coastguard Worker case nir_op_vec8:
2914*61046927SAndroid Build Coastguard Worker case nir_op_vec16:
2915*61046927SAndroid Build Coastguard Worker return true;
2916*61046927SAndroid Build Coastguard Worker default:
2917*61046927SAndroid Build Coastguard Worker return false;
2918*61046927SAndroid Build Coastguard Worker }
2919*61046927SAndroid Build Coastguard Worker }
2920*61046927SAndroid Build Coastguard Worker
2921*61046927SAndroid Build Coastguard Worker nir_component_mask_t
nir_alu_instr_src_read_mask(const nir_alu_instr * instr,unsigned src)2922*61046927SAndroid Build Coastguard Worker nir_alu_instr_src_read_mask(const nir_alu_instr *instr, unsigned src)
2923*61046927SAndroid Build Coastguard Worker {
2924*61046927SAndroid Build Coastguard Worker nir_component_mask_t read_mask = 0;
2925*61046927SAndroid Build Coastguard Worker for (unsigned c = 0; c < NIR_MAX_VEC_COMPONENTS; c++) {
2926*61046927SAndroid Build Coastguard Worker if (!nir_alu_instr_channel_used(instr, src, c))
2927*61046927SAndroid Build Coastguard Worker continue;
2928*61046927SAndroid Build Coastguard Worker
2929*61046927SAndroid Build Coastguard Worker read_mask |= (1 << instr->src[src].swizzle[c]);
2930*61046927SAndroid Build Coastguard Worker }
2931*61046927SAndroid Build Coastguard Worker return read_mask;
2932*61046927SAndroid Build Coastguard Worker }
2933*61046927SAndroid Build Coastguard Worker
2934*61046927SAndroid Build Coastguard Worker unsigned
nir_ssa_alu_instr_src_components(const nir_alu_instr * instr,unsigned src)2935*61046927SAndroid Build Coastguard Worker nir_ssa_alu_instr_src_components(const nir_alu_instr *instr, unsigned src)
2936*61046927SAndroid Build Coastguard Worker {
2937*61046927SAndroid Build Coastguard Worker if (nir_op_infos[instr->op].input_sizes[src] > 0)
2938*61046927SAndroid Build Coastguard Worker return nir_op_infos[instr->op].input_sizes[src];
2939*61046927SAndroid Build Coastguard Worker
2940*61046927SAndroid Build Coastguard Worker return instr->def.num_components;
2941*61046927SAndroid Build Coastguard Worker }
2942*61046927SAndroid Build Coastguard Worker
2943*61046927SAndroid Build Coastguard Worker #define CASE_ALL_SIZES(op) \
2944*61046927SAndroid Build Coastguard Worker case op: \
2945*61046927SAndroid Build Coastguard Worker case op##8: \
2946*61046927SAndroid Build Coastguard Worker case op##16: \
2947*61046927SAndroid Build Coastguard Worker case op##32:
2948*61046927SAndroid Build Coastguard Worker
2949*61046927SAndroid Build Coastguard Worker bool
nir_alu_instr_is_comparison(const nir_alu_instr * instr)2950*61046927SAndroid Build Coastguard Worker nir_alu_instr_is_comparison(const nir_alu_instr *instr)
2951*61046927SAndroid Build Coastguard Worker {
2952*61046927SAndroid Build Coastguard Worker switch (instr->op) {
2953*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_flt)
2954*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_fge)
2955*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_fltu)
2956*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_fgeu)
2957*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_feq)
2958*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_fneu)
2959*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_fequ)
2960*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_fneo)
2961*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_funord)
2962*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_ford)
2963*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_ilt)
2964*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_ult)
2965*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_ige)
2966*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_uge)
2967*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_ieq)
2968*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_ine)
2969*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_bitz)
2970*61046927SAndroid Build Coastguard Worker CASE_ALL_SIZES(nir_op_bitnz)
2971*61046927SAndroid Build Coastguard Worker case nir_op_inot:
2972*61046927SAndroid Build Coastguard Worker return true;
2973*61046927SAndroid Build Coastguard Worker default:
2974*61046927SAndroid Build Coastguard Worker return false;
2975*61046927SAndroid Build Coastguard Worker }
2976*61046927SAndroid Build Coastguard Worker }
2977*61046927SAndroid Build Coastguard Worker
2978*61046927SAndroid Build Coastguard Worker #undef CASE_ALL_SIZES
2979*61046927SAndroid Build Coastguard Worker
2980*61046927SAndroid Build Coastguard Worker unsigned
nir_intrinsic_src_components(const nir_intrinsic_instr * intr,unsigned srcn)2981*61046927SAndroid Build Coastguard Worker nir_intrinsic_src_components(const nir_intrinsic_instr *intr, unsigned srcn)
2982*61046927SAndroid Build Coastguard Worker {
2983*61046927SAndroid Build Coastguard Worker const nir_intrinsic_info *info = &nir_intrinsic_infos[intr->intrinsic];
2984*61046927SAndroid Build Coastguard Worker assert(srcn < info->num_srcs);
2985*61046927SAndroid Build Coastguard Worker if (info->src_components[srcn] > 0)
2986*61046927SAndroid Build Coastguard Worker return info->src_components[srcn];
2987*61046927SAndroid Build Coastguard Worker else if (info->src_components[srcn] == 0)
2988*61046927SAndroid Build Coastguard Worker return intr->num_components;
2989*61046927SAndroid Build Coastguard Worker else
2990*61046927SAndroid Build Coastguard Worker return nir_src_num_components(intr->src[srcn]);
2991*61046927SAndroid Build Coastguard Worker }
2992*61046927SAndroid Build Coastguard Worker
2993*61046927SAndroid Build Coastguard Worker unsigned
nir_intrinsic_dest_components(nir_intrinsic_instr * intr)2994*61046927SAndroid Build Coastguard Worker nir_intrinsic_dest_components(nir_intrinsic_instr *intr)
2995*61046927SAndroid Build Coastguard Worker {
2996*61046927SAndroid Build Coastguard Worker const nir_intrinsic_info *info = &nir_intrinsic_infos[intr->intrinsic];
2997*61046927SAndroid Build Coastguard Worker if (!info->has_dest)
2998*61046927SAndroid Build Coastguard Worker return 0;
2999*61046927SAndroid Build Coastguard Worker else if (info->dest_components)
3000*61046927SAndroid Build Coastguard Worker return info->dest_components;
3001*61046927SAndroid Build Coastguard Worker else
3002*61046927SAndroid Build Coastguard Worker return intr->num_components;
3003*61046927SAndroid Build Coastguard Worker }
3004*61046927SAndroid Build Coastguard Worker
3005*61046927SAndroid Build Coastguard Worker nir_alu_type
nir_intrinsic_instr_src_type(const nir_intrinsic_instr * intrin,unsigned src)3006*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr_src_type(const nir_intrinsic_instr *intrin, unsigned src)
3007*61046927SAndroid Build Coastguard Worker {
3008*61046927SAndroid Build Coastguard Worker /* We could go nuts here, but we'll just handle a few simple
3009*61046927SAndroid Build Coastguard Worker * cases and let everything else be untyped.
3010*61046927SAndroid Build Coastguard Worker */
3011*61046927SAndroid Build Coastguard Worker switch (intrin->intrinsic) {
3012*61046927SAndroid Build Coastguard Worker case nir_intrinsic_store_deref: {
3013*61046927SAndroid Build Coastguard Worker nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
3014*61046927SAndroid Build Coastguard Worker if (src == 1)
3015*61046927SAndroid Build Coastguard Worker return nir_get_nir_type_for_glsl_type(deref->type);
3016*61046927SAndroid Build Coastguard Worker break;
3017*61046927SAndroid Build Coastguard Worker }
3018*61046927SAndroid Build Coastguard Worker
3019*61046927SAndroid Build Coastguard Worker case nir_intrinsic_store_output:
3020*61046927SAndroid Build Coastguard Worker if (src == 0)
3021*61046927SAndroid Build Coastguard Worker return nir_intrinsic_src_type(intrin);
3022*61046927SAndroid Build Coastguard Worker break;
3023*61046927SAndroid Build Coastguard Worker
3024*61046927SAndroid Build Coastguard Worker default:
3025*61046927SAndroid Build Coastguard Worker break;
3026*61046927SAndroid Build Coastguard Worker }
3027*61046927SAndroid Build Coastguard Worker
3028*61046927SAndroid Build Coastguard Worker /* For the most part, we leave other intrinsics alone. Most
3029*61046927SAndroid Build Coastguard Worker * of them don't matter in OpenGL ES 2.0 drivers anyway.
3030*61046927SAndroid Build Coastguard Worker * However, we should at least check if this is some sort of
3031*61046927SAndroid Build Coastguard Worker * IO intrinsic and flag it's offset and index sources.
3032*61046927SAndroid Build Coastguard Worker */
3033*61046927SAndroid Build Coastguard Worker {
3034*61046927SAndroid Build Coastguard Worker int offset_src_idx = nir_get_io_offset_src_number(intrin);
3035*61046927SAndroid Build Coastguard Worker if (src == offset_src_idx) {
3036*61046927SAndroid Build Coastguard Worker const nir_src *offset_src = offset_src_idx >= 0 ? &intrin->src[offset_src_idx] : NULL;
3037*61046927SAndroid Build Coastguard Worker if (offset_src)
3038*61046927SAndroid Build Coastguard Worker return nir_type_int;
3039*61046927SAndroid Build Coastguard Worker }
3040*61046927SAndroid Build Coastguard Worker }
3041*61046927SAndroid Build Coastguard Worker
3042*61046927SAndroid Build Coastguard Worker return nir_type_invalid;
3043*61046927SAndroid Build Coastguard Worker }
3044*61046927SAndroid Build Coastguard Worker
3045*61046927SAndroid Build Coastguard Worker nir_alu_type
nir_intrinsic_instr_dest_type(const nir_intrinsic_instr * intrin)3046*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr_dest_type(const nir_intrinsic_instr *intrin)
3047*61046927SAndroid Build Coastguard Worker {
3048*61046927SAndroid Build Coastguard Worker /* We could go nuts here, but we'll just handle a few simple
3049*61046927SAndroid Build Coastguard Worker * cases and let everything else be untyped.
3050*61046927SAndroid Build Coastguard Worker */
3051*61046927SAndroid Build Coastguard Worker switch (intrin->intrinsic) {
3052*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_deref: {
3053*61046927SAndroid Build Coastguard Worker nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
3054*61046927SAndroid Build Coastguard Worker return nir_get_nir_type_for_glsl_type(deref->type);
3055*61046927SAndroid Build Coastguard Worker }
3056*61046927SAndroid Build Coastguard Worker
3057*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_input:
3058*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_per_primitive_input:
3059*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_uniform:
3060*61046927SAndroid Build Coastguard Worker return nir_intrinsic_dest_type(intrin);
3061*61046927SAndroid Build Coastguard Worker
3062*61046927SAndroid Build Coastguard Worker default:
3063*61046927SAndroid Build Coastguard Worker break;
3064*61046927SAndroid Build Coastguard Worker }
3065*61046927SAndroid Build Coastguard Worker
3066*61046927SAndroid Build Coastguard Worker return nir_type_invalid;
3067*61046927SAndroid Build Coastguard Worker }
3068*61046927SAndroid Build Coastguard Worker
3069*61046927SAndroid Build Coastguard Worker /**
3070*61046927SAndroid Build Coastguard Worker * Helper to copy const_index[] from src to dst, without assuming they
3071*61046927SAndroid Build Coastguard Worker * match in order.
3072*61046927SAndroid Build Coastguard Worker */
3073*61046927SAndroid Build Coastguard Worker void
nir_intrinsic_copy_const_indices(nir_intrinsic_instr * dst,nir_intrinsic_instr * src)3074*61046927SAndroid Build Coastguard Worker nir_intrinsic_copy_const_indices(nir_intrinsic_instr *dst, nir_intrinsic_instr *src)
3075*61046927SAndroid Build Coastguard Worker {
3076*61046927SAndroid Build Coastguard Worker if (src->intrinsic == dst->intrinsic) {
3077*61046927SAndroid Build Coastguard Worker memcpy(dst->const_index, src->const_index, sizeof(dst->const_index));
3078*61046927SAndroid Build Coastguard Worker return;
3079*61046927SAndroid Build Coastguard Worker }
3080*61046927SAndroid Build Coastguard Worker
3081*61046927SAndroid Build Coastguard Worker const nir_intrinsic_info *src_info = &nir_intrinsic_infos[src->intrinsic];
3082*61046927SAndroid Build Coastguard Worker const nir_intrinsic_info *dst_info = &nir_intrinsic_infos[dst->intrinsic];
3083*61046927SAndroid Build Coastguard Worker
3084*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < NIR_INTRINSIC_NUM_INDEX_FLAGS; i++) {
3085*61046927SAndroid Build Coastguard Worker if (src_info->index_map[i] == 0)
3086*61046927SAndroid Build Coastguard Worker continue;
3087*61046927SAndroid Build Coastguard Worker
3088*61046927SAndroid Build Coastguard Worker /* require that dst instruction also uses the same const_index[]: */
3089*61046927SAndroid Build Coastguard Worker assert(dst_info->index_map[i] > 0);
3090*61046927SAndroid Build Coastguard Worker
3091*61046927SAndroid Build Coastguard Worker dst->const_index[dst_info->index_map[i] - 1] =
3092*61046927SAndroid Build Coastguard Worker src->const_index[src_info->index_map[i] - 1];
3093*61046927SAndroid Build Coastguard Worker }
3094*61046927SAndroid Build Coastguard Worker }
3095*61046927SAndroid Build Coastguard Worker
3096*61046927SAndroid Build Coastguard Worker bool
nir_tex_instr_need_sampler(const nir_tex_instr * instr)3097*61046927SAndroid Build Coastguard Worker nir_tex_instr_need_sampler(const nir_tex_instr *instr)
3098*61046927SAndroid Build Coastguard Worker {
3099*61046927SAndroid Build Coastguard Worker switch (instr->op) {
3100*61046927SAndroid Build Coastguard Worker case nir_texop_txf:
3101*61046927SAndroid Build Coastguard Worker case nir_texop_txf_ms:
3102*61046927SAndroid Build Coastguard Worker case nir_texop_txs:
3103*61046927SAndroid Build Coastguard Worker case nir_texop_query_levels:
3104*61046927SAndroid Build Coastguard Worker case nir_texop_texture_samples:
3105*61046927SAndroid Build Coastguard Worker case nir_texop_samples_identical:
3106*61046927SAndroid Build Coastguard Worker case nir_texop_descriptor_amd:
3107*61046927SAndroid Build Coastguard Worker return false;
3108*61046927SAndroid Build Coastguard Worker default:
3109*61046927SAndroid Build Coastguard Worker return true;
3110*61046927SAndroid Build Coastguard Worker }
3111*61046927SAndroid Build Coastguard Worker }
3112*61046927SAndroid Build Coastguard Worker
3113*61046927SAndroid Build Coastguard Worker unsigned
nir_tex_instr_result_size(const nir_tex_instr * instr)3114*61046927SAndroid Build Coastguard Worker nir_tex_instr_result_size(const nir_tex_instr *instr)
3115*61046927SAndroid Build Coastguard Worker {
3116*61046927SAndroid Build Coastguard Worker switch (instr->op) {
3117*61046927SAndroid Build Coastguard Worker case nir_texop_txs: {
3118*61046927SAndroid Build Coastguard Worker unsigned ret;
3119*61046927SAndroid Build Coastguard Worker switch (instr->sampler_dim) {
3120*61046927SAndroid Build Coastguard Worker case GLSL_SAMPLER_DIM_1D:
3121*61046927SAndroid Build Coastguard Worker case GLSL_SAMPLER_DIM_BUF:
3122*61046927SAndroid Build Coastguard Worker ret = 1;
3123*61046927SAndroid Build Coastguard Worker break;
3124*61046927SAndroid Build Coastguard Worker case GLSL_SAMPLER_DIM_2D:
3125*61046927SAndroid Build Coastguard Worker case GLSL_SAMPLER_DIM_CUBE:
3126*61046927SAndroid Build Coastguard Worker case GLSL_SAMPLER_DIM_MS:
3127*61046927SAndroid Build Coastguard Worker case GLSL_SAMPLER_DIM_RECT:
3128*61046927SAndroid Build Coastguard Worker case GLSL_SAMPLER_DIM_EXTERNAL:
3129*61046927SAndroid Build Coastguard Worker case GLSL_SAMPLER_DIM_SUBPASS:
3130*61046927SAndroid Build Coastguard Worker case GLSL_SAMPLER_DIM_SUBPASS_MS:
3131*61046927SAndroid Build Coastguard Worker ret = 2;
3132*61046927SAndroid Build Coastguard Worker break;
3133*61046927SAndroid Build Coastguard Worker case GLSL_SAMPLER_DIM_3D:
3134*61046927SAndroid Build Coastguard Worker ret = 3;
3135*61046927SAndroid Build Coastguard Worker break;
3136*61046927SAndroid Build Coastguard Worker default:
3137*61046927SAndroid Build Coastguard Worker unreachable("not reached");
3138*61046927SAndroid Build Coastguard Worker }
3139*61046927SAndroid Build Coastguard Worker if (instr->is_array)
3140*61046927SAndroid Build Coastguard Worker ret++;
3141*61046927SAndroid Build Coastguard Worker return ret;
3142*61046927SAndroid Build Coastguard Worker }
3143*61046927SAndroid Build Coastguard Worker
3144*61046927SAndroid Build Coastguard Worker case nir_texop_lod:
3145*61046927SAndroid Build Coastguard Worker return 2;
3146*61046927SAndroid Build Coastguard Worker
3147*61046927SAndroid Build Coastguard Worker case nir_texop_texture_samples:
3148*61046927SAndroid Build Coastguard Worker case nir_texop_query_levels:
3149*61046927SAndroid Build Coastguard Worker case nir_texop_samples_identical:
3150*61046927SAndroid Build Coastguard Worker case nir_texop_fragment_mask_fetch_amd:
3151*61046927SAndroid Build Coastguard Worker case nir_texop_lod_bias_agx:
3152*61046927SAndroid Build Coastguard Worker case nir_texop_has_custom_border_color_agx:
3153*61046927SAndroid Build Coastguard Worker return 1;
3154*61046927SAndroid Build Coastguard Worker
3155*61046927SAndroid Build Coastguard Worker case nir_texop_descriptor_amd:
3156*61046927SAndroid Build Coastguard Worker return instr->sampler_dim == GLSL_SAMPLER_DIM_BUF ? 4 : 8;
3157*61046927SAndroid Build Coastguard Worker
3158*61046927SAndroid Build Coastguard Worker case nir_texop_sampler_descriptor_amd:
3159*61046927SAndroid Build Coastguard Worker return 4;
3160*61046927SAndroid Build Coastguard Worker
3161*61046927SAndroid Build Coastguard Worker case nir_texop_hdr_dim_nv:
3162*61046927SAndroid Build Coastguard Worker case nir_texop_tex_type_nv:
3163*61046927SAndroid Build Coastguard Worker return 4;
3164*61046927SAndroid Build Coastguard Worker
3165*61046927SAndroid Build Coastguard Worker case nir_texop_custom_border_color_agx:
3166*61046927SAndroid Build Coastguard Worker return 4;
3167*61046927SAndroid Build Coastguard Worker
3168*61046927SAndroid Build Coastguard Worker default:
3169*61046927SAndroid Build Coastguard Worker if (instr->is_shadow && instr->is_new_style_shadow)
3170*61046927SAndroid Build Coastguard Worker return 1;
3171*61046927SAndroid Build Coastguard Worker
3172*61046927SAndroid Build Coastguard Worker return 4;
3173*61046927SAndroid Build Coastguard Worker }
3174*61046927SAndroid Build Coastguard Worker }
3175*61046927SAndroid Build Coastguard Worker
3176*61046927SAndroid Build Coastguard Worker bool
nir_tex_instr_is_query(const nir_tex_instr * instr)3177*61046927SAndroid Build Coastguard Worker nir_tex_instr_is_query(const nir_tex_instr *instr)
3178*61046927SAndroid Build Coastguard Worker {
3179*61046927SAndroid Build Coastguard Worker switch (instr->op) {
3180*61046927SAndroid Build Coastguard Worker case nir_texop_txs:
3181*61046927SAndroid Build Coastguard Worker case nir_texop_lod:
3182*61046927SAndroid Build Coastguard Worker case nir_texop_texture_samples:
3183*61046927SAndroid Build Coastguard Worker case nir_texop_query_levels:
3184*61046927SAndroid Build Coastguard Worker case nir_texop_descriptor_amd:
3185*61046927SAndroid Build Coastguard Worker case nir_texop_sampler_descriptor_amd:
3186*61046927SAndroid Build Coastguard Worker case nir_texop_lod_bias_agx:
3187*61046927SAndroid Build Coastguard Worker case nir_texop_custom_border_color_agx:
3188*61046927SAndroid Build Coastguard Worker case nir_texop_has_custom_border_color_agx:
3189*61046927SAndroid Build Coastguard Worker case nir_texop_hdr_dim_nv:
3190*61046927SAndroid Build Coastguard Worker case nir_texop_tex_type_nv:
3191*61046927SAndroid Build Coastguard Worker return true;
3192*61046927SAndroid Build Coastguard Worker case nir_texop_tex:
3193*61046927SAndroid Build Coastguard Worker case nir_texop_txb:
3194*61046927SAndroid Build Coastguard Worker case nir_texop_txl:
3195*61046927SAndroid Build Coastguard Worker case nir_texop_txd:
3196*61046927SAndroid Build Coastguard Worker case nir_texop_txf:
3197*61046927SAndroid Build Coastguard Worker case nir_texop_txf_ms:
3198*61046927SAndroid Build Coastguard Worker case nir_texop_txf_ms_fb:
3199*61046927SAndroid Build Coastguard Worker case nir_texop_txf_ms_mcs_intel:
3200*61046927SAndroid Build Coastguard Worker case nir_texop_tg4:
3201*61046927SAndroid Build Coastguard Worker case nir_texop_samples_identical:
3202*61046927SAndroid Build Coastguard Worker case nir_texop_fragment_mask_fetch_amd:
3203*61046927SAndroid Build Coastguard Worker case nir_texop_fragment_fetch_amd:
3204*61046927SAndroid Build Coastguard Worker return false;
3205*61046927SAndroid Build Coastguard Worker default:
3206*61046927SAndroid Build Coastguard Worker unreachable("Invalid texture opcode");
3207*61046927SAndroid Build Coastguard Worker }
3208*61046927SAndroid Build Coastguard Worker }
3209*61046927SAndroid Build Coastguard Worker
3210*61046927SAndroid Build Coastguard Worker bool
nir_tex_instr_has_implicit_derivative(const nir_tex_instr * instr)3211*61046927SAndroid Build Coastguard Worker nir_tex_instr_has_implicit_derivative(const nir_tex_instr *instr)
3212*61046927SAndroid Build Coastguard Worker {
3213*61046927SAndroid Build Coastguard Worker switch (instr->op) {
3214*61046927SAndroid Build Coastguard Worker case nir_texop_tex:
3215*61046927SAndroid Build Coastguard Worker case nir_texop_txb:
3216*61046927SAndroid Build Coastguard Worker case nir_texop_lod:
3217*61046927SAndroid Build Coastguard Worker return true;
3218*61046927SAndroid Build Coastguard Worker case nir_texop_tg4:
3219*61046927SAndroid Build Coastguard Worker return instr->is_gather_implicit_lod;
3220*61046927SAndroid Build Coastguard Worker default:
3221*61046927SAndroid Build Coastguard Worker return false;
3222*61046927SAndroid Build Coastguard Worker }
3223*61046927SAndroid Build Coastguard Worker }
3224*61046927SAndroid Build Coastguard Worker
3225*61046927SAndroid Build Coastguard Worker nir_alu_type
nir_tex_instr_src_type(const nir_tex_instr * instr,unsigned src)3226*61046927SAndroid Build Coastguard Worker nir_tex_instr_src_type(const nir_tex_instr *instr, unsigned src)
3227*61046927SAndroid Build Coastguard Worker {
3228*61046927SAndroid Build Coastguard Worker switch (instr->src[src].src_type) {
3229*61046927SAndroid Build Coastguard Worker case nir_tex_src_coord:
3230*61046927SAndroid Build Coastguard Worker switch (instr->op) {
3231*61046927SAndroid Build Coastguard Worker case nir_texop_txf:
3232*61046927SAndroid Build Coastguard Worker case nir_texop_txf_ms:
3233*61046927SAndroid Build Coastguard Worker case nir_texop_txf_ms_fb:
3234*61046927SAndroid Build Coastguard Worker case nir_texop_txf_ms_mcs_intel:
3235*61046927SAndroid Build Coastguard Worker case nir_texop_samples_identical:
3236*61046927SAndroid Build Coastguard Worker case nir_texop_fragment_fetch_amd:
3237*61046927SAndroid Build Coastguard Worker case nir_texop_fragment_mask_fetch_amd:
3238*61046927SAndroid Build Coastguard Worker return nir_type_int;
3239*61046927SAndroid Build Coastguard Worker
3240*61046927SAndroid Build Coastguard Worker default:
3241*61046927SAndroid Build Coastguard Worker return nir_type_float;
3242*61046927SAndroid Build Coastguard Worker }
3243*61046927SAndroid Build Coastguard Worker
3244*61046927SAndroid Build Coastguard Worker case nir_tex_src_lod:
3245*61046927SAndroid Build Coastguard Worker switch (instr->op) {
3246*61046927SAndroid Build Coastguard Worker case nir_texop_txs:
3247*61046927SAndroid Build Coastguard Worker case nir_texop_txf:
3248*61046927SAndroid Build Coastguard Worker case nir_texop_txf_ms:
3249*61046927SAndroid Build Coastguard Worker case nir_texop_fragment_fetch_amd:
3250*61046927SAndroid Build Coastguard Worker case nir_texop_fragment_mask_fetch_amd:
3251*61046927SAndroid Build Coastguard Worker return nir_type_int;
3252*61046927SAndroid Build Coastguard Worker
3253*61046927SAndroid Build Coastguard Worker default:
3254*61046927SAndroid Build Coastguard Worker return nir_type_float;
3255*61046927SAndroid Build Coastguard Worker }
3256*61046927SAndroid Build Coastguard Worker
3257*61046927SAndroid Build Coastguard Worker case nir_tex_src_projector:
3258*61046927SAndroid Build Coastguard Worker case nir_tex_src_comparator:
3259*61046927SAndroid Build Coastguard Worker case nir_tex_src_bias:
3260*61046927SAndroid Build Coastguard Worker case nir_tex_src_min_lod:
3261*61046927SAndroid Build Coastguard Worker case nir_tex_src_ddx:
3262*61046927SAndroid Build Coastguard Worker case nir_tex_src_ddy:
3263*61046927SAndroid Build Coastguard Worker case nir_tex_src_backend1:
3264*61046927SAndroid Build Coastguard Worker case nir_tex_src_backend2:
3265*61046927SAndroid Build Coastguard Worker return nir_type_float;
3266*61046927SAndroid Build Coastguard Worker
3267*61046927SAndroid Build Coastguard Worker case nir_tex_src_offset:
3268*61046927SAndroid Build Coastguard Worker case nir_tex_src_ms_index:
3269*61046927SAndroid Build Coastguard Worker case nir_tex_src_plane:
3270*61046927SAndroid Build Coastguard Worker return nir_type_int;
3271*61046927SAndroid Build Coastguard Worker
3272*61046927SAndroid Build Coastguard Worker case nir_tex_src_sampler_deref_intrinsic:
3273*61046927SAndroid Build Coastguard Worker case nir_tex_src_texture_deref_intrinsic:
3274*61046927SAndroid Build Coastguard Worker case nir_tex_src_ms_mcs_intel:
3275*61046927SAndroid Build Coastguard Worker case nir_tex_src_texture_deref:
3276*61046927SAndroid Build Coastguard Worker case nir_tex_src_sampler_deref:
3277*61046927SAndroid Build Coastguard Worker case nir_tex_src_texture_offset:
3278*61046927SAndroid Build Coastguard Worker case nir_tex_src_sampler_offset:
3279*61046927SAndroid Build Coastguard Worker case nir_tex_src_texture_handle:
3280*61046927SAndroid Build Coastguard Worker case nir_tex_src_sampler_handle:
3281*61046927SAndroid Build Coastguard Worker return nir_type_uint;
3282*61046927SAndroid Build Coastguard Worker
3283*61046927SAndroid Build Coastguard Worker case nir_num_tex_src_types:
3284*61046927SAndroid Build Coastguard Worker unreachable("nir_num_tex_src_types is not a valid source type");
3285*61046927SAndroid Build Coastguard Worker }
3286*61046927SAndroid Build Coastguard Worker
3287*61046927SAndroid Build Coastguard Worker unreachable("Invalid texture source type");
3288*61046927SAndroid Build Coastguard Worker }
3289*61046927SAndroid Build Coastguard Worker
3290*61046927SAndroid Build Coastguard Worker unsigned
nir_tex_instr_src_size(const nir_tex_instr * instr,unsigned src)3291*61046927SAndroid Build Coastguard Worker nir_tex_instr_src_size(const nir_tex_instr *instr, unsigned src)
3292*61046927SAndroid Build Coastguard Worker {
3293*61046927SAndroid Build Coastguard Worker if (instr->src[src].src_type == nir_tex_src_coord)
3294*61046927SAndroid Build Coastguard Worker return instr->coord_components;
3295*61046927SAndroid Build Coastguard Worker
3296*61046927SAndroid Build Coastguard Worker /* The MCS value is expected to be a vec4 returned by a txf_ms_mcs_intel */
3297*61046927SAndroid Build Coastguard Worker if (instr->src[src].src_type == nir_tex_src_ms_mcs_intel)
3298*61046927SAndroid Build Coastguard Worker return 4;
3299*61046927SAndroid Build Coastguard Worker
3300*61046927SAndroid Build Coastguard Worker if (instr->src[src].src_type == nir_tex_src_ddx ||
3301*61046927SAndroid Build Coastguard Worker instr->src[src].src_type == nir_tex_src_ddy) {
3302*61046927SAndroid Build Coastguard Worker
3303*61046927SAndroid Build Coastguard Worker if (instr->is_array && !instr->array_is_lowered_cube)
3304*61046927SAndroid Build Coastguard Worker return instr->coord_components - 1;
3305*61046927SAndroid Build Coastguard Worker else
3306*61046927SAndroid Build Coastguard Worker return instr->coord_components;
3307*61046927SAndroid Build Coastguard Worker }
3308*61046927SAndroid Build Coastguard Worker
3309*61046927SAndroid Build Coastguard Worker if (instr->src[src].src_type == nir_tex_src_offset) {
3310*61046927SAndroid Build Coastguard Worker if (instr->is_array)
3311*61046927SAndroid Build Coastguard Worker return instr->coord_components - 1;
3312*61046927SAndroid Build Coastguard Worker else
3313*61046927SAndroid Build Coastguard Worker return instr->coord_components;
3314*61046927SAndroid Build Coastguard Worker }
3315*61046927SAndroid Build Coastguard Worker
3316*61046927SAndroid Build Coastguard Worker if (instr->src[src].src_type == nir_tex_src_backend1 ||
3317*61046927SAndroid Build Coastguard Worker instr->src[src].src_type == nir_tex_src_backend2)
3318*61046927SAndroid Build Coastguard Worker return nir_src_num_components(instr->src[src].src);
3319*61046927SAndroid Build Coastguard Worker
3320*61046927SAndroid Build Coastguard Worker /* For AMD, this can be a vec8/vec4 image/sampler descriptor. */
3321*61046927SAndroid Build Coastguard Worker if (instr->src[src].src_type == nir_tex_src_texture_handle ||
3322*61046927SAndroid Build Coastguard Worker instr->src[src].src_type == nir_tex_src_sampler_handle)
3323*61046927SAndroid Build Coastguard Worker return 0;
3324*61046927SAndroid Build Coastguard Worker
3325*61046927SAndroid Build Coastguard Worker return 1;
3326*61046927SAndroid Build Coastguard Worker }
3327*61046927SAndroid Build Coastguard Worker
3328*61046927SAndroid Build Coastguard Worker /**
3329*61046927SAndroid Build Coastguard Worker * Return which components are written into transform feedback buffers.
3330*61046927SAndroid Build Coastguard Worker * The result is relative to 0, not "component".
3331*61046927SAndroid Build Coastguard Worker */
3332*61046927SAndroid Build Coastguard Worker unsigned
nir_instr_xfb_write_mask(nir_intrinsic_instr * instr)3333*61046927SAndroid Build Coastguard Worker nir_instr_xfb_write_mask(nir_intrinsic_instr *instr)
3334*61046927SAndroid Build Coastguard Worker {
3335*61046927SAndroid Build Coastguard Worker unsigned mask = 0;
3336*61046927SAndroid Build Coastguard Worker
3337*61046927SAndroid Build Coastguard Worker if (nir_intrinsic_has_io_xfb(instr)) {
3338*61046927SAndroid Build Coastguard Worker unsigned wr_mask = nir_intrinsic_write_mask(instr) << nir_intrinsic_component(instr);
3339*61046927SAndroid Build Coastguard Worker assert((wr_mask & ~0xf) == 0); /* only 4 components allowed */
3340*61046927SAndroid Build Coastguard Worker
3341*61046927SAndroid Build Coastguard Worker unsigned iter_mask = wr_mask;
3342*61046927SAndroid Build Coastguard Worker while (iter_mask) {
3343*61046927SAndroid Build Coastguard Worker unsigned i = u_bit_scan(&iter_mask);
3344*61046927SAndroid Build Coastguard Worker nir_io_xfb xfb = i < 2 ? nir_intrinsic_io_xfb(instr) : nir_intrinsic_io_xfb2(instr);
3345*61046927SAndroid Build Coastguard Worker if (xfb.out[i % 2].num_components)
3346*61046927SAndroid Build Coastguard Worker mask |= BITFIELD_RANGE(i, xfb.out[i % 2].num_components) & wr_mask;
3347*61046927SAndroid Build Coastguard Worker }
3348*61046927SAndroid Build Coastguard Worker }
3349*61046927SAndroid Build Coastguard Worker
3350*61046927SAndroid Build Coastguard Worker return mask;
3351*61046927SAndroid Build Coastguard Worker }
3352*61046927SAndroid Build Coastguard Worker
3353*61046927SAndroid Build Coastguard Worker /**
3354*61046927SAndroid Build Coastguard Worker * Whether an output slot is consumed by fixed-function logic.
3355*61046927SAndroid Build Coastguard Worker */
3356*61046927SAndroid Build Coastguard Worker bool
nir_slot_is_sysval_output(gl_varying_slot slot,gl_shader_stage next_shader)3357*61046927SAndroid Build Coastguard Worker nir_slot_is_sysval_output(gl_varying_slot slot, gl_shader_stage next_shader)
3358*61046927SAndroid Build Coastguard Worker {
3359*61046927SAndroid Build Coastguard Worker switch (next_shader) {
3360*61046927SAndroid Build Coastguard Worker case MESA_SHADER_FRAGMENT:
3361*61046927SAndroid Build Coastguard Worker return slot == VARYING_SLOT_POS ||
3362*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_PSIZ ||
3363*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_EDGE ||
3364*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_CLIP_VERTEX ||
3365*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_CLIP_DIST0 ||
3366*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_CLIP_DIST1 ||
3367*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_CULL_DIST0 ||
3368*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_CULL_DIST1 ||
3369*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_LAYER ||
3370*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_VIEWPORT ||
3371*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_VIEW_INDEX ||
3372*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_VIEWPORT_MASK ||
3373*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_PRIMITIVE_SHADING_RATE ||
3374*61046927SAndroid Build Coastguard Worker /* NV_mesh_shader_only */
3375*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_PRIMITIVE_COUNT ||
3376*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_PRIMITIVE_INDICES;
3377*61046927SAndroid Build Coastguard Worker
3378*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TESS_EVAL:
3379*61046927SAndroid Build Coastguard Worker return slot == VARYING_SLOT_TESS_LEVEL_OUTER ||
3380*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_TESS_LEVEL_INNER ||
3381*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_BOUNDING_BOX0 ||
3382*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_BOUNDING_BOX1;
3383*61046927SAndroid Build Coastguard Worker
3384*61046927SAndroid Build Coastguard Worker case MESA_SHADER_MESH:
3385*61046927SAndroid Build Coastguard Worker /* NV_mesh_shader only */
3386*61046927SAndroid Build Coastguard Worker return slot == VARYING_SLOT_TASK_COUNT;
3387*61046927SAndroid Build Coastguard Worker
3388*61046927SAndroid Build Coastguard Worker case MESA_SHADER_NONE:
3389*61046927SAndroid Build Coastguard Worker /* NONE means unknown. Check all possibilities. */
3390*61046927SAndroid Build Coastguard Worker return nir_slot_is_sysval_output(slot, MESA_SHADER_FRAGMENT) ||
3391*61046927SAndroid Build Coastguard Worker nir_slot_is_sysval_output(slot, MESA_SHADER_TESS_EVAL) ||
3392*61046927SAndroid Build Coastguard Worker nir_slot_is_sysval_output(slot, MESA_SHADER_MESH);
3393*61046927SAndroid Build Coastguard Worker
3394*61046927SAndroid Build Coastguard Worker default:
3395*61046927SAndroid Build Coastguard Worker /* No other shaders have preceding shaders with sysval outputs. */
3396*61046927SAndroid Build Coastguard Worker return false;
3397*61046927SAndroid Build Coastguard Worker }
3398*61046927SAndroid Build Coastguard Worker }
3399*61046927SAndroid Build Coastguard Worker
3400*61046927SAndroid Build Coastguard Worker /**
3401*61046927SAndroid Build Coastguard Worker * Whether an input/output slot is consumed by the next shader stage,
3402*61046927SAndroid Build Coastguard Worker * or written by the previous shader stage.
3403*61046927SAndroid Build Coastguard Worker */
3404*61046927SAndroid Build Coastguard Worker bool
nir_slot_is_varying(gl_varying_slot slot)3405*61046927SAndroid Build Coastguard Worker nir_slot_is_varying(gl_varying_slot slot)
3406*61046927SAndroid Build Coastguard Worker {
3407*61046927SAndroid Build Coastguard Worker return slot >= VARYING_SLOT_VAR0 ||
3408*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_COL0 ||
3409*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_COL1 ||
3410*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_BFC0 ||
3411*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_BFC1 ||
3412*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_FOGC ||
3413*61046927SAndroid Build Coastguard Worker (slot >= VARYING_SLOT_TEX0 && slot <= VARYING_SLOT_TEX7) ||
3414*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_PNTC ||
3415*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_CLIP_DIST0 ||
3416*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_CLIP_DIST1 ||
3417*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_CULL_DIST0 ||
3418*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_CULL_DIST1 ||
3419*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_PRIMITIVE_ID ||
3420*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_LAYER ||
3421*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_VIEWPORT ||
3422*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_TESS_LEVEL_OUTER ||
3423*61046927SAndroid Build Coastguard Worker slot == VARYING_SLOT_TESS_LEVEL_INNER;
3424*61046927SAndroid Build Coastguard Worker }
3425*61046927SAndroid Build Coastguard Worker
3426*61046927SAndroid Build Coastguard Worker bool
nir_slot_is_sysval_output_and_varying(gl_varying_slot slot,gl_shader_stage next_shader)3427*61046927SAndroid Build Coastguard Worker nir_slot_is_sysval_output_and_varying(gl_varying_slot slot,
3428*61046927SAndroid Build Coastguard Worker gl_shader_stage next_shader)
3429*61046927SAndroid Build Coastguard Worker {
3430*61046927SAndroid Build Coastguard Worker return nir_slot_is_sysval_output(slot, next_shader) &&
3431*61046927SAndroid Build Coastguard Worker nir_slot_is_varying(slot);
3432*61046927SAndroid Build Coastguard Worker }
3433*61046927SAndroid Build Coastguard Worker
3434*61046927SAndroid Build Coastguard Worker /**
3435*61046927SAndroid Build Coastguard Worker * This marks the output store instruction as not feeding the next shader
3436*61046927SAndroid Build Coastguard Worker * stage. If the instruction has no other use, it's removed.
3437*61046927SAndroid Build Coastguard Worker */
3438*61046927SAndroid Build Coastguard Worker bool
nir_remove_varying(nir_intrinsic_instr * intr,gl_shader_stage next_shader)3439*61046927SAndroid Build Coastguard Worker nir_remove_varying(nir_intrinsic_instr *intr, gl_shader_stage next_shader)
3440*61046927SAndroid Build Coastguard Worker {
3441*61046927SAndroid Build Coastguard Worker nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
3442*61046927SAndroid Build Coastguard Worker
3443*61046927SAndroid Build Coastguard Worker if ((!sem.no_sysval_output &&
3444*61046927SAndroid Build Coastguard Worker nir_slot_is_sysval_output(sem.location, next_shader)) ||
3445*61046927SAndroid Build Coastguard Worker nir_instr_xfb_write_mask(intr)) {
3446*61046927SAndroid Build Coastguard Worker /* Demote the store instruction. */
3447*61046927SAndroid Build Coastguard Worker sem.no_varying = true;
3448*61046927SAndroid Build Coastguard Worker nir_intrinsic_set_io_semantics(intr, sem);
3449*61046927SAndroid Build Coastguard Worker return false;
3450*61046927SAndroid Build Coastguard Worker } else {
3451*61046927SAndroid Build Coastguard Worker nir_instr_remove(&intr->instr);
3452*61046927SAndroid Build Coastguard Worker return true;
3453*61046927SAndroid Build Coastguard Worker }
3454*61046927SAndroid Build Coastguard Worker }
3455*61046927SAndroid Build Coastguard Worker
3456*61046927SAndroid Build Coastguard Worker /**
3457*61046927SAndroid Build Coastguard Worker * This marks the output store instruction as not feeding fixed-function
3458*61046927SAndroid Build Coastguard Worker * logic. If the instruction has no other use, it's removed.
3459*61046927SAndroid Build Coastguard Worker */
3460*61046927SAndroid Build Coastguard Worker bool
nir_remove_sysval_output(nir_intrinsic_instr * intr)3461*61046927SAndroid Build Coastguard Worker nir_remove_sysval_output(nir_intrinsic_instr *intr)
3462*61046927SAndroid Build Coastguard Worker {
3463*61046927SAndroid Build Coastguard Worker nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
3464*61046927SAndroid Build Coastguard Worker
3465*61046927SAndroid Build Coastguard Worker if ((!sem.no_varying && nir_slot_is_varying(sem.location)) ||
3466*61046927SAndroid Build Coastguard Worker nir_instr_xfb_write_mask(intr)) {
3467*61046927SAndroid Build Coastguard Worker /* Demote the store instruction. */
3468*61046927SAndroid Build Coastguard Worker sem.no_sysval_output = true;
3469*61046927SAndroid Build Coastguard Worker nir_intrinsic_set_io_semantics(intr, sem);
3470*61046927SAndroid Build Coastguard Worker return false;
3471*61046927SAndroid Build Coastguard Worker } else {
3472*61046927SAndroid Build Coastguard Worker nir_instr_remove(&intr->instr);
3473*61046927SAndroid Build Coastguard Worker return true;
3474*61046927SAndroid Build Coastguard Worker }
3475*61046927SAndroid Build Coastguard Worker }
3476*61046927SAndroid Build Coastguard Worker
3477*61046927SAndroid Build Coastguard Worker void
nir_remove_non_entrypoints(nir_shader * nir)3478*61046927SAndroid Build Coastguard Worker nir_remove_non_entrypoints(nir_shader *nir)
3479*61046927SAndroid Build Coastguard Worker {
3480*61046927SAndroid Build Coastguard Worker nir_foreach_function_safe(func, nir) {
3481*61046927SAndroid Build Coastguard Worker if (!func->is_entrypoint)
3482*61046927SAndroid Build Coastguard Worker exec_node_remove(&func->node);
3483*61046927SAndroid Build Coastguard Worker }
3484*61046927SAndroid Build Coastguard Worker assert(exec_list_length(&nir->functions) == 1);
3485*61046927SAndroid Build Coastguard Worker }
3486*61046927SAndroid Build Coastguard Worker
3487*61046927SAndroid Build Coastguard Worker void
nir_remove_non_exported(nir_shader * nir)3488*61046927SAndroid Build Coastguard Worker nir_remove_non_exported(nir_shader *nir)
3489*61046927SAndroid Build Coastguard Worker {
3490*61046927SAndroid Build Coastguard Worker nir_foreach_function_safe(func, nir) {
3491*61046927SAndroid Build Coastguard Worker if (!func->is_exported)
3492*61046927SAndroid Build Coastguard Worker exec_node_remove(&func->node);
3493*61046927SAndroid Build Coastguard Worker }
3494*61046927SAndroid Build Coastguard Worker }
3495*61046927SAndroid Build Coastguard Worker
3496*61046927SAndroid Build Coastguard Worker unsigned
nir_static_workgroup_size(const nir_shader * s)3497*61046927SAndroid Build Coastguard Worker nir_static_workgroup_size(const nir_shader *s)
3498*61046927SAndroid Build Coastguard Worker {
3499*61046927SAndroid Build Coastguard Worker return s->info.workgroup_size[0] * s->info.workgroup_size[1] *
3500*61046927SAndroid Build Coastguard Worker s->info.workgroup_size[2];
3501*61046927SAndroid Build Coastguard Worker }
3502*61046927SAndroid Build Coastguard Worker
3503*61046927SAndroid Build Coastguard Worker bool
nir_block_contains_work(nir_block * block)3504*61046927SAndroid Build Coastguard Worker nir_block_contains_work(nir_block *block)
3505*61046927SAndroid Build Coastguard Worker {
3506*61046927SAndroid Build Coastguard Worker if (!nir_cf_node_is_last(&block->cf_node))
3507*61046927SAndroid Build Coastguard Worker return true;
3508*61046927SAndroid Build Coastguard Worker
3509*61046927SAndroid Build Coastguard Worker nir_foreach_instr(instr, block) {
3510*61046927SAndroid Build Coastguard Worker if (instr->type == nir_instr_type_phi)
3511*61046927SAndroid Build Coastguard Worker continue;
3512*61046927SAndroid Build Coastguard Worker if (instr->type != nir_instr_type_alu ||
3513*61046927SAndroid Build Coastguard Worker !nir_op_is_vec_or_mov(nir_instr_as_alu(instr)->op))
3514*61046927SAndroid Build Coastguard Worker return true;
3515*61046927SAndroid Build Coastguard Worker }
3516*61046927SAndroid Build Coastguard Worker
3517*61046927SAndroid Build Coastguard Worker return false;
3518*61046927SAndroid Build Coastguard Worker }
3519