• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016 Broadcom
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "nir.h"
25 #include "nir_builder.h"
26 #include "nir_deref.h"
27 
28 /** @file nir_lower_io_to_scalar.c
29  *
30  * Replaces nir_load_input/nir_store_output operations with num_components !=
31  * 1 with individual per-channel operations.
32  */
33 
34 static void
set_io_semantics(nir_intrinsic_instr * scalar_intr,nir_intrinsic_instr * vec_intr,unsigned component)35 set_io_semantics(nir_intrinsic_instr *scalar_intr,
36                  nir_intrinsic_instr *vec_intr, unsigned component)
37 {
38    nir_io_semantics sem = nir_intrinsic_io_semantics(vec_intr);
39    sem.gs_streams = (sem.gs_streams >> (component * 2)) & 0x3;
40    nir_intrinsic_set_io_semantics(scalar_intr, sem);
41 }
42 
43 static void
lower_load_input_to_scalar(nir_builder * b,nir_intrinsic_instr * intr)44 lower_load_input_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
45 {
46    b->cursor = nir_before_instr(&intr->instr);
47 
48    nir_def *loads[NIR_MAX_VEC_COMPONENTS];
49 
50    for (unsigned i = 0; i < intr->num_components; i++) {
51       bool is_64bit = (nir_intrinsic_instr_dest_type(intr) & NIR_ALU_TYPE_SIZE_MASK) == 64;
52       unsigned newi = is_64bit ? i * 2 : i;
53       unsigned newc = nir_intrinsic_component(intr);
54       nir_intrinsic_instr *chan_intr =
55          nir_intrinsic_instr_create(b->shader, intr->intrinsic);
56       nir_def_init(&chan_intr->instr, &chan_intr->def, 1,
57                    intr->def.bit_size);
58       chan_intr->num_components = 1;
59 
60       if (intr->name)
61          chan_intr->name = intr->name;
62       nir_intrinsic_set_base(chan_intr, nir_intrinsic_base(intr));
63       nir_intrinsic_set_component(chan_intr, (newc + newi) % 4);
64       nir_intrinsic_set_dest_type(chan_intr, nir_intrinsic_dest_type(intr));
65       set_io_semantics(chan_intr, intr, i);
66       /* offset and vertex (if needed) */
67       for (unsigned j = 0; j < nir_intrinsic_infos[intr->intrinsic].num_srcs; ++j)
68          chan_intr->src[j] = nir_src_for_ssa(intr->src[j].ssa);
69       if (newc + newi > 3) {
70          nir_src *src = nir_get_io_offset_src(chan_intr);
71          nir_def *offset = nir_iadd_imm(b, src->ssa, (newc + newi) / 4);
72          *src = nir_src_for_ssa(offset);
73       }
74 
75       nir_builder_instr_insert(b, &chan_intr->instr);
76 
77       loads[i] = &chan_intr->def;
78    }
79 
80    nir_def_replace(&intr->def, nir_vec(b, loads, intr->num_components));
81 }
82 
83 static void
lower_load_to_scalar(nir_builder * b,nir_intrinsic_instr * intr)84 lower_load_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
85 {
86    b->cursor = nir_before_instr(&intr->instr);
87 
88    nir_def *loads[NIR_MAX_VEC_COMPONENTS];
89    nir_def *base_offset = nir_get_io_offset_src(intr)->ssa;
90 
91    for (unsigned i = 0; i < intr->num_components; i++) {
92       nir_intrinsic_instr *chan_intr =
93          nir_intrinsic_instr_create(b->shader, intr->intrinsic);
94       nir_def_init(&chan_intr->instr, &chan_intr->def, 1,
95                    intr->def.bit_size);
96       chan_intr->num_components = 1;
97 
98       if (intr->name)
99          chan_intr->name = intr->name;
100       nir_intrinsic_set_align_offset(chan_intr,
101                                      (nir_intrinsic_align_offset(intr) +
102                                       i * (intr->def.bit_size / 8)) %
103                                         nir_intrinsic_align_mul(intr));
104       nir_intrinsic_set_align_mul(chan_intr, nir_intrinsic_align_mul(intr));
105       if (nir_intrinsic_has_access(intr))
106          nir_intrinsic_set_access(chan_intr, nir_intrinsic_access(intr));
107       if (nir_intrinsic_has_range(intr))
108          nir_intrinsic_set_range(chan_intr, nir_intrinsic_range(intr));
109       if (nir_intrinsic_has_range_base(intr))
110          nir_intrinsic_set_range_base(chan_intr, nir_intrinsic_range_base(intr));
111       if (nir_intrinsic_has_base(intr))
112          nir_intrinsic_set_base(chan_intr, nir_intrinsic_base(intr));
113       for (unsigned j = 0; j < nir_intrinsic_infos[intr->intrinsic].num_srcs - 1; j++)
114          chan_intr->src[j] = nir_src_for_ssa(intr->src[j].ssa);
115 
116       /* increment offset per component */
117       nir_def *offset = nir_iadd_imm(b, base_offset, i * (intr->def.bit_size / 8));
118       *nir_get_io_offset_src(chan_intr) = nir_src_for_ssa(offset);
119 
120       nir_builder_instr_insert(b, &chan_intr->instr);
121 
122       loads[i] = &chan_intr->def;
123    }
124 
125    nir_def_replace(&intr->def, nir_vec(b, loads, intr->num_components));
126 }
127 
128 static void
lower_store_output_to_scalar(nir_builder * b,nir_intrinsic_instr * intr)129 lower_store_output_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
130 {
131    b->cursor = nir_before_instr(&intr->instr);
132 
133    nir_def *value = intr->src[0].ssa;
134 
135    for (unsigned i = 0; i < intr->num_components; i++) {
136       if (!(nir_intrinsic_write_mask(intr) & (1 << i)))
137          continue;
138 
139       bool is_64bit = (nir_intrinsic_instr_src_type(intr, 0) & NIR_ALU_TYPE_SIZE_MASK) == 64;
140       unsigned newi = is_64bit ? i * 2 : i;
141       unsigned newc = nir_intrinsic_component(intr);
142       unsigned new_component = (newc + newi) % 4;
143       nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
144       bool has_xfb = false;
145 
146       if (nir_intrinsic_has_io_xfb(intr)) {
147          /* Find out which components are written via xfb. */
148          for (unsigned c = 0; c <= new_component; c++) {
149             nir_io_xfb xfb = c < 2 ? nir_intrinsic_io_xfb(intr) : nir_intrinsic_io_xfb2(intr);
150 
151             if (new_component < c + xfb.out[c % 2].num_components) {
152                has_xfb = true;
153                break;
154             }
155          }
156       }
157 
158       /* After scalarization, some channels might not write anywhere - i.e.
159        * they are not a sysval output, they don't feed the next shader, and
160        * they don't write xfb. Don't create such stores.
161        */
162       if ((sem.no_sysval_output ||
163            !nir_slot_is_sysval_output(sem.location, MESA_SHADER_NONE)) &&
164           (sem.no_varying ||
165            !nir_slot_is_varying(sem.location, MESA_SHADER_NONE)) &&
166           !has_xfb)
167          continue;
168 
169       nir_intrinsic_instr *chan_intr =
170          nir_intrinsic_instr_create(b->shader, intr->intrinsic);
171       chan_intr->num_components = 1;
172 
173       if (intr->name)
174          chan_intr->name = intr->name;
175       nir_intrinsic_set_base(chan_intr, nir_intrinsic_base(intr));
176       nir_intrinsic_set_write_mask(chan_intr, 0x1);
177       nir_intrinsic_set_component(chan_intr, new_component);
178       nir_intrinsic_set_src_type(chan_intr, nir_intrinsic_src_type(intr));
179       set_io_semantics(chan_intr, intr, i);
180 
181       if (nir_intrinsic_has_io_xfb(intr)) {
182          /* Scalarize transform feedback info. */
183          for (unsigned c = 0; c <= new_component; c++) {
184             nir_io_xfb xfb = c < 2 ? nir_intrinsic_io_xfb(intr) : nir_intrinsic_io_xfb2(intr);
185 
186             if (new_component < c + xfb.out[c % 2].num_components) {
187                nir_io_xfb scalar_xfb;
188 
189                memset(&scalar_xfb, 0, sizeof(scalar_xfb));
190                scalar_xfb.out[new_component % 2].num_components = is_64bit ? 2 : 1;
191                scalar_xfb.out[new_component % 2].buffer = xfb.out[c % 2].buffer;
192                scalar_xfb.out[new_component % 2].offset = xfb.out[c % 2].offset +
193                                                           new_component - c;
194                if (new_component < 2)
195                   nir_intrinsic_set_io_xfb(chan_intr, scalar_xfb);
196                else
197                   nir_intrinsic_set_io_xfb2(chan_intr, scalar_xfb);
198                break;
199             }
200          }
201       }
202 
203       /* value */
204       chan_intr->src[0] = nir_src_for_ssa(nir_channel(b, value, i));
205       /* offset and vertex (if needed) */
206       for (unsigned j = 1; j < nir_intrinsic_infos[intr->intrinsic].num_srcs; ++j)
207          chan_intr->src[j] = nir_src_for_ssa(intr->src[j].ssa);
208       if (newc + newi > 3) {
209          nir_src *src = nir_get_io_offset_src(chan_intr);
210          nir_def *offset = nir_iadd_imm(b, src->ssa, (newc + newi) / 4);
211          *src = nir_src_for_ssa(offset);
212       }
213 
214       nir_builder_instr_insert(b, &chan_intr->instr);
215    }
216 
217    nir_instr_remove(&intr->instr);
218 }
219 
220 static void
lower_store_to_scalar(nir_builder * b,nir_intrinsic_instr * intr)221 lower_store_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
222 {
223    b->cursor = nir_before_instr(&intr->instr);
224 
225    nir_def *value = intr->src[0].ssa;
226    nir_def *base_offset = nir_get_io_offset_src(intr)->ssa;
227 
228    /* iterate wrmask instead of num_components to handle split components */
229    u_foreach_bit(i, nir_intrinsic_write_mask(intr)) {
230       nir_intrinsic_instr *chan_intr =
231          nir_intrinsic_instr_create(b->shader, intr->intrinsic);
232       chan_intr->num_components = 1;
233 
234       if (intr->name)
235          chan_intr->name = intr->name;
236       nir_intrinsic_set_write_mask(chan_intr, 0x1);
237       nir_intrinsic_set_align_offset(chan_intr,
238                                      (nir_intrinsic_align_offset(intr) +
239                                       i * (value->bit_size / 8)) %
240                                         nir_intrinsic_align_mul(intr));
241       nir_intrinsic_set_align_mul(chan_intr, nir_intrinsic_align_mul(intr));
242       if (nir_intrinsic_has_access(intr))
243          nir_intrinsic_set_access(chan_intr, nir_intrinsic_access(intr));
244       if (nir_intrinsic_has_base(intr))
245          nir_intrinsic_set_base(chan_intr, nir_intrinsic_base(intr));
246 
247       /* value */
248       chan_intr->src[0] = nir_src_for_ssa(nir_channel(b, value, i));
249       for (unsigned j = 1; j < nir_intrinsic_infos[intr->intrinsic].num_srcs - 1; j++)
250          chan_intr->src[j] = nir_src_for_ssa(intr->src[j].ssa);
251 
252       /* increment offset per component */
253       nir_def *offset = nir_iadd_imm(b, base_offset, i * (value->bit_size / 8));
254       *nir_get_io_offset_src(chan_intr) = nir_src_for_ssa(offset);
255 
256       nir_builder_instr_insert(b, &chan_intr->instr);
257    }
258 
259    nir_instr_remove(&intr->instr);
260 }
261 
262 struct scalarize_state {
263    nir_variable_mode mask;
264    nir_instr_filter_cb filter;
265    void *filter_data;
266 };
267 
268 static bool
nir_lower_io_to_scalar_instr(nir_builder * b,nir_instr * instr,void * data)269 nir_lower_io_to_scalar_instr(nir_builder *b, nir_instr *instr, void *data)
270 {
271    struct scalarize_state *state = data;
272 
273    if (instr->type != nir_instr_type_intrinsic)
274       return false;
275 
276    nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
277 
278    if (intr->num_components == 1)
279       return false;
280 
281    if ((intr->intrinsic == nir_intrinsic_load_input ||
282         intr->intrinsic == nir_intrinsic_load_per_primitive_input ||
283         intr->intrinsic == nir_intrinsic_load_per_vertex_input ||
284         intr->intrinsic == nir_intrinsic_load_interpolated_input ||
285         intr->intrinsic == nir_intrinsic_load_input_vertex) &&
286        (state->mask & nir_var_shader_in) &&
287        (!state->filter || state->filter(instr, state->filter_data))) {
288       lower_load_input_to_scalar(b, intr);
289       return true;
290    }
291 
292    if ((intr->intrinsic == nir_intrinsic_load_output ||
293         intr->intrinsic == nir_intrinsic_load_per_vertex_output ||
294         intr->intrinsic == nir_intrinsic_load_per_view_output ||
295         intr->intrinsic == nir_intrinsic_load_per_primitive_output) &&
296        (state->mask & nir_var_shader_out) &&
297        (!state->filter || state->filter(instr, state->filter_data))) {
298       lower_load_input_to_scalar(b, intr);
299       return true;
300    }
301 
302    if (((intr->intrinsic == nir_intrinsic_load_ubo && (state->mask & nir_var_mem_ubo)) ||
303         (intr->intrinsic == nir_intrinsic_load_ssbo && (state->mask & nir_var_mem_ssbo)) ||
304         (intr->intrinsic == nir_intrinsic_load_global && (state->mask & nir_var_mem_global)) ||
305         (intr->intrinsic == nir_intrinsic_load_shared && (state->mask & nir_var_mem_shared))) &&
306        (!state->filter || state->filter(instr, state->filter_data))) {
307       lower_load_to_scalar(b, intr);
308       return true;
309    }
310 
311    if ((intr->intrinsic == nir_intrinsic_store_output ||
312         intr->intrinsic == nir_intrinsic_store_per_vertex_output ||
313         intr->intrinsic == nir_intrinsic_store_per_view_output ||
314         intr->intrinsic == nir_intrinsic_store_per_primitive_output) &&
315        state->mask & nir_var_shader_out &&
316        (!state->filter || state->filter(instr, state->filter_data))) {
317       lower_store_output_to_scalar(b, intr);
318       return true;
319    }
320 
321    if (((intr->intrinsic == nir_intrinsic_store_ssbo && (state->mask & nir_var_mem_ssbo)) ||
322         (intr->intrinsic == nir_intrinsic_store_global && (state->mask & nir_var_mem_global)) ||
323         (intr->intrinsic == nir_intrinsic_store_shared && (state->mask & nir_var_mem_shared))) &&
324        (!state->filter || state->filter(instr, state->filter_data))) {
325       lower_store_to_scalar(b, intr);
326       return true;
327    }
328 
329    return false;
330 }
331 
332 bool
nir_lower_io_to_scalar(nir_shader * shader,nir_variable_mode mask,nir_instr_filter_cb filter,void * filter_data)333 nir_lower_io_to_scalar(nir_shader *shader, nir_variable_mode mask, nir_instr_filter_cb filter, void *filter_data)
334 {
335    struct scalarize_state state = {
336       mask,
337       filter,
338       filter_data
339    };
340    return nir_shader_instructions_pass(shader,
341                                        nir_lower_io_to_scalar_instr,
342                                        nir_metadata_control_flow,
343                                        &state);
344 }
345 
346 static nir_variable **
get_channel_variables(struct hash_table * ht,nir_variable * var)347 get_channel_variables(struct hash_table *ht, nir_variable *var)
348 {
349    nir_variable **chan_vars;
350    struct hash_entry *entry = _mesa_hash_table_search(ht, var);
351    if (!entry) {
352       chan_vars = (nir_variable **)calloc(4, sizeof(nir_variable *));
353       _mesa_hash_table_insert(ht, var, chan_vars);
354    } else {
355       chan_vars = (nir_variable **)entry->data;
356    }
357 
358    return chan_vars;
359 }
360 
361 /*
362  * Note that the src deref that we are cloning is the head of the
363  * chain of deref instructions from the original intrinsic, but
364  * the dst we are cloning to is the tail (because chains of deref
365  * instructions are created back to front)
366  */
367 
368 static nir_deref_instr *
clone_deref_array(nir_builder * b,nir_deref_instr * dst_tail,const nir_deref_instr * src_head)369 clone_deref_array(nir_builder *b, nir_deref_instr *dst_tail,
370                   const nir_deref_instr *src_head)
371 {
372    const nir_deref_instr *parent = nir_deref_instr_parent(src_head);
373 
374    if (!parent)
375       return dst_tail;
376 
377    assert(src_head->deref_type == nir_deref_type_array);
378 
379    dst_tail = clone_deref_array(b, dst_tail, parent);
380 
381    return nir_build_deref_array(b, dst_tail,
382                                 src_head->arr.index.ssa);
383 }
384 
385 static void
lower_load_to_scalar_early(nir_builder * b,nir_intrinsic_instr * intr,nir_variable * var,struct hash_table * split_inputs,struct hash_table * split_outputs)386 lower_load_to_scalar_early(nir_builder *b, nir_intrinsic_instr *intr,
387                            nir_variable *var, struct hash_table *split_inputs,
388                            struct hash_table *split_outputs)
389 {
390    b->cursor = nir_before_instr(&intr->instr);
391 
392    nir_def *loads[NIR_MAX_VEC_COMPONENTS];
393 
394    nir_variable **chan_vars;
395    if (var->data.mode == nir_var_shader_in) {
396       chan_vars = get_channel_variables(split_inputs, var);
397    } else {
398       chan_vars = get_channel_variables(split_outputs, var);
399    }
400 
401    for (unsigned i = 0; i < intr->num_components; i++) {
402       nir_variable *chan_var = chan_vars[var->data.location_frac + i];
403       if (!chan_vars[var->data.location_frac + i]) {
404          chan_var = nir_variable_clone(var, b->shader);
405          chan_var->data.location_frac = var->data.location_frac + i;
406          chan_var->type = glsl_channel_type(chan_var->type);
407 
408          chan_vars[var->data.location_frac + i] = chan_var;
409 
410          nir_shader_add_variable(b->shader, chan_var);
411       }
412 
413       nir_intrinsic_instr *chan_intr =
414          nir_intrinsic_instr_create(b->shader, intr->intrinsic);
415       nir_def_init(&chan_intr->instr, &chan_intr->def, 1,
416                    intr->def.bit_size);
417       chan_intr->num_components = 1;
418 
419       nir_deref_instr *deref = nir_build_deref_var(b, chan_var);
420 
421       deref = clone_deref_array(b, deref, nir_src_as_deref(intr->src[0]));
422 
423       chan_intr->src[0] = nir_src_for_ssa(&deref->def);
424 
425       if (intr->intrinsic == nir_intrinsic_interp_deref_at_offset ||
426           intr->intrinsic == nir_intrinsic_interp_deref_at_sample ||
427           intr->intrinsic == nir_intrinsic_interp_deref_at_vertex)
428          chan_intr->src[1] = nir_src_for_ssa(intr->src[1].ssa);
429 
430       nir_builder_instr_insert(b, &chan_intr->instr);
431 
432       loads[i] = &chan_intr->def;
433    }
434 
435    nir_def_replace(&intr->def, nir_vec(b, loads, intr->num_components));
436 }
437 
438 static void
lower_store_output_to_scalar_early(nir_builder * b,nir_intrinsic_instr * intr,nir_variable * var,struct hash_table * split_outputs)439 lower_store_output_to_scalar_early(nir_builder *b, nir_intrinsic_instr *intr,
440                                    nir_variable *var,
441                                    struct hash_table *split_outputs)
442 {
443    b->cursor = nir_before_instr(&intr->instr);
444 
445    nir_def *value = intr->src[1].ssa;
446 
447    nir_variable **chan_vars = get_channel_variables(split_outputs, var);
448    for (unsigned i = 0; i < intr->num_components; i++) {
449       if (!(nir_intrinsic_write_mask(intr) & (1 << i)))
450          continue;
451 
452       nir_variable *chan_var = chan_vars[var->data.location_frac + i];
453       if (!chan_vars[var->data.location_frac + i]) {
454          chan_var = nir_variable_clone(var, b->shader);
455          chan_var->data.location_frac = var->data.location_frac + i;
456          chan_var->type = glsl_channel_type(chan_var->type);
457 
458          chan_vars[var->data.location_frac + i] = chan_var;
459 
460          nir_shader_add_variable(b->shader, chan_var);
461       }
462 
463       nir_intrinsic_instr *chan_intr =
464          nir_intrinsic_instr_create(b->shader, intr->intrinsic);
465       chan_intr->num_components = 1;
466 
467       nir_intrinsic_set_write_mask(chan_intr, 0x1);
468 
469       nir_deref_instr *deref = nir_build_deref_var(b, chan_var);
470 
471       deref = clone_deref_array(b, deref, nir_src_as_deref(intr->src[0]));
472 
473       chan_intr->src[0] = nir_src_for_ssa(&deref->def);
474       chan_intr->src[1] = nir_src_for_ssa(nir_channel(b, value, i));
475 
476       nir_builder_instr_insert(b, &chan_intr->instr);
477    }
478 
479    /* Remove the old store intrinsic */
480    nir_instr_remove(&intr->instr);
481 }
482 
483 struct io_to_scalar_early_state {
484    struct hash_table *split_inputs, *split_outputs;
485    nir_variable_mode mask;
486 };
487 
488 static bool
nir_lower_io_to_scalar_early_instr(nir_builder * b,nir_instr * instr,void * data)489 nir_lower_io_to_scalar_early_instr(nir_builder *b, nir_instr *instr, void *data)
490 {
491    struct io_to_scalar_early_state *state = data;
492 
493    if (instr->type != nir_instr_type_intrinsic)
494       return false;
495 
496    nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
497 
498    if (intr->num_components == 1)
499       return false;
500 
501    if (intr->intrinsic != nir_intrinsic_load_deref &&
502        intr->intrinsic != nir_intrinsic_store_deref &&
503        intr->intrinsic != nir_intrinsic_interp_deref_at_centroid &&
504        intr->intrinsic != nir_intrinsic_interp_deref_at_sample &&
505        intr->intrinsic != nir_intrinsic_interp_deref_at_offset &&
506        intr->intrinsic != nir_intrinsic_interp_deref_at_vertex)
507       return false;
508 
509    nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
510    if (!nir_deref_mode_is_one_of(deref, state->mask))
511       return false;
512 
513    nir_variable *var = nir_deref_instr_get_variable(deref);
514    nir_variable_mode mode = var->data.mode;
515 
516    /* TODO: add patch support */
517    if (var->data.patch)
518       return false;
519 
520    /* TODO: add doubles support */
521    if (glsl_type_is_64bit(glsl_without_array(var->type)))
522       return false;
523 
524    if (!(b->shader->info.stage == MESA_SHADER_VERTEX &&
525          mode == nir_var_shader_in) &&
526        var->data.location < VARYING_SLOT_VAR0 &&
527        var->data.location >= 0)
528       return false;
529 
530    /* Don't bother splitting if we can't opt away any unused
531     * components.
532     */
533    if (var->data.always_active_io)
534       return false;
535 
536    if (var->data.must_be_shader_input)
537       return false;
538 
539    /* Skip types we cannot split */
540    if (glsl_type_is_matrix(glsl_without_array(var->type)) ||
541        glsl_type_is_struct_or_ifc(glsl_without_array(var->type)))
542       return false;
543 
544    switch (intr->intrinsic) {
545    case nir_intrinsic_interp_deref_at_centroid:
546    case nir_intrinsic_interp_deref_at_sample:
547    case nir_intrinsic_interp_deref_at_offset:
548    case nir_intrinsic_interp_deref_at_vertex:
549    case nir_intrinsic_load_deref:
550       if ((state->mask & nir_var_shader_in && mode == nir_var_shader_in) ||
551           (state->mask & nir_var_shader_out && mode == nir_var_shader_out)) {
552          lower_load_to_scalar_early(b, intr, var, state->split_inputs,
553                                     state->split_outputs);
554          return true;
555       }
556       break;
557    case nir_intrinsic_store_deref:
558       if (state->mask & nir_var_shader_out &&
559           mode == nir_var_shader_out) {
560          lower_store_output_to_scalar_early(b, intr, var, state->split_outputs);
561          return true;
562       }
563       break;
564    default:
565       break;
566    }
567 
568    return false;
569 }
570 
571 /*
572  * This function is intended to be called earlier than nir_lower_io_to_scalar()
573  * i.e. before nir_lower_io() is called.
574  */
575 bool
nir_lower_io_to_scalar_early(nir_shader * shader,nir_variable_mode mask)576 nir_lower_io_to_scalar_early(nir_shader *shader, nir_variable_mode mask)
577 {
578    struct io_to_scalar_early_state state = {
579       .split_inputs = _mesa_pointer_hash_table_create(NULL),
580       .split_outputs = _mesa_pointer_hash_table_create(NULL),
581       .mask = mask
582    };
583 
584    bool progress = nir_shader_instructions_pass(shader,
585                                                 nir_lower_io_to_scalar_early_instr,
586                                                 nir_metadata_control_flow,
587                                                 &state);
588 
589    /* Remove old input from the shaders inputs list */
590    hash_table_foreach(state.split_inputs, entry) {
591       nir_variable *var = (nir_variable *)entry->key;
592       exec_node_remove(&var->node);
593 
594       free(entry->data);
595    }
596 
597    /* Remove old output from the shaders outputs list */
598    hash_table_foreach(state.split_outputs, entry) {
599       nir_variable *var = (nir_variable *)entry->key;
600       exec_node_remove(&var->node);
601 
602       free(entry->data);
603    }
604 
605    _mesa_hash_table_destroy(state.split_inputs, NULL);
606    _mesa_hash_table_destroy(state.split_outputs, NULL);
607 
608    nir_remove_dead_derefs(shader);
609 
610    return progress;
611 }
612