OSDN Git Service

41059b3227e53ab74d0ee8d28fb0cd83493f57b7
[android-x86/external-mesa.git] / src / mesa / drivers / dri / i965 / brw_nir.c
1 /*
2  * Copyright © 2014 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23
24 #include "brw_nir.h"
25 #include "brw_shader.h"
26 #include "compiler/nir/glsl_to_nir.h"
27 #include "compiler/nir/nir_builder.h"
28 #include "program/prog_to_nir.h"
29
30 static bool
31 is_input(nir_intrinsic_instr *intrin)
32 {
33    return intrin->intrinsic == nir_intrinsic_load_input ||
34           intrin->intrinsic == nir_intrinsic_load_per_vertex_input;
35 }
36
37 static bool
38 is_output(nir_intrinsic_instr *intrin)
39 {
40    return intrin->intrinsic == nir_intrinsic_load_output ||
41           intrin->intrinsic == nir_intrinsic_load_per_vertex_output ||
42           intrin->intrinsic == nir_intrinsic_store_output ||
43           intrin->intrinsic == nir_intrinsic_store_per_vertex_output;
44 }
45
46 /**
47  * In many cases, we just add the base and offset together, so there's no
48  * reason to keep them separate.  Sometimes, combining them is essential:
49  * if a shader only accesses part of a compound variable (such as a matrix
50  * or array), the variable's base may not actually exist in the VUE map.
51  *
52  * This pass adds constant offsets to instr->const_index[0], and resets
53  * the offset source to 0.  Non-constant offsets remain unchanged - since
54  * we don't know what part of a compound variable is accessed, we allocate
55  * storage for the entire thing.
56  */
57 struct add_const_offset_to_base_params {
58    nir_builder b;
59    nir_variable_mode mode;
60 };
61
62 static bool
63 add_const_offset_to_base_block(nir_block *block, void *closure)
64 {
65    struct add_const_offset_to_base_params *params = closure;
66    nir_builder *b = &params->b;
67
68    nir_foreach_instr_safe(block, instr) {
69       if (instr->type != nir_instr_type_intrinsic)
70          continue;
71
72       nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
73
74       if ((params->mode == nir_var_shader_in && is_input(intrin)) ||
75           (params->mode == nir_var_shader_out && is_output(intrin))) {
76          nir_src *offset = nir_get_io_offset_src(intrin);
77          nir_const_value *const_offset = nir_src_as_const_value(*offset);
78
79          if (const_offset) {
80             intrin->const_index[0] += const_offset->u[0];
81             b->cursor = nir_before_instr(&intrin->instr);
82             nir_instr_rewrite_src(&intrin->instr, offset,
83                                   nir_src_for_ssa(nir_imm_int(b, 0)));
84          }
85       }
86    }
87    return true;
88 }
89
90 static void
91 add_const_offset_to_base(nir_shader *nir, nir_variable_mode mode)
92 {
93    struct add_const_offset_to_base_params params = { .mode = mode };
94
95    nir_foreach_function(nir, f) {
96       if (f->impl) {
97          nir_builder_init(&params.b, f->impl);
98          nir_foreach_block(f->impl, add_const_offset_to_base_block, &params);
99       }
100    }
101 }
102
103 static bool
104 remap_vs_attrs(nir_block *block, void *closure)
105 {
106    GLbitfield64 inputs_read = *((GLbitfield64 *) closure);
107
108    nir_foreach_instr(block, instr) {
109       if (instr->type != nir_instr_type_intrinsic)
110          continue;
111
112       nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
113
114       if (intrin->intrinsic == nir_intrinsic_load_input) {
115          /* Attributes come in a contiguous block, ordered by their
116           * gl_vert_attrib value.  That means we can compute the slot
117           * number for an attribute by masking out the enabled attributes
118           * before it and counting the bits.
119           */
120          int attr = intrin->const_index[0];
121          int slot = _mesa_bitcount_64(inputs_read & BITFIELD64_MASK(attr));
122
123          intrin->const_index[0] = 4 * slot;
124       }
125    }
126    return true;
127 }
128
129 static bool
130 remap_inputs_with_vue_map(nir_block *block, void *closure)
131 {
132    const struct brw_vue_map *vue_map = closure;
133
134    nir_foreach_instr(block, instr) {
135       if (instr->type != nir_instr_type_intrinsic)
136          continue;
137
138       nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
139
140       if (intrin->intrinsic == nir_intrinsic_load_input ||
141           intrin->intrinsic == nir_intrinsic_load_per_vertex_input) {
142          int vue_slot = vue_map->varying_to_slot[intrin->const_index[0]];
143          assert(vue_slot != -1);
144          intrin->const_index[0] = vue_slot;
145       }
146    }
147    return true;
148 }
149
150 struct remap_patch_urb_offsets_state {
151    nir_builder b;
152    struct brw_vue_map vue_map;
153 };
154
155 static bool
156 remap_patch_urb_offsets(nir_block *block, void *closure)
157 {
158    struct remap_patch_urb_offsets_state *state = closure;
159
160    nir_foreach_instr_safe(block, instr) {
161       if (instr->type != nir_instr_type_intrinsic)
162          continue;
163
164       nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
165
166       gl_shader_stage stage = state->b.shader->stage;
167
168       if ((stage == MESA_SHADER_TESS_CTRL && is_output(intrin)) ||
169           (stage == MESA_SHADER_TESS_EVAL && is_input(intrin))) {
170          int vue_slot = state->vue_map.varying_to_slot[intrin->const_index[0]];
171          assert(vue_slot != -1);
172          intrin->const_index[0] = vue_slot;
173
174          nir_src *vertex = nir_get_io_vertex_index_src(intrin);
175          if (vertex) {
176             nir_const_value *const_vertex = nir_src_as_const_value(*vertex);
177             if (const_vertex) {
178                intrin->const_index[0] += const_vertex->u[0] *
179                                          state->vue_map.num_per_vertex_slots;
180             } else {
181                state->b.cursor = nir_before_instr(&intrin->instr);
182
183                /* Multiply by the number of per-vertex slots. */
184                nir_ssa_def *vertex_offset =
185                   nir_imul(&state->b,
186                            nir_ssa_for_src(&state->b, *vertex, 1),
187                            nir_imm_int(&state->b,
188                                        state->vue_map.num_per_vertex_slots));
189
190                /* Add it to the existing offset */
191                nir_src *offset = nir_get_io_offset_src(intrin);
192                nir_ssa_def *total_offset =
193                   nir_iadd(&state->b, vertex_offset,
194                            nir_ssa_for_src(&state->b, *offset, 1));
195
196                nir_instr_rewrite_src(&intrin->instr, offset,
197                                      nir_src_for_ssa(total_offset));
198             }
199          }
200       }
201    }
202    return true;
203 }
204
205 static void
206 brw_nir_lower_inputs(nir_shader *nir,
207                      const struct brw_device_info *devinfo,
208                      bool is_scalar,
209                      bool use_legacy_snorm_formula,
210                      const uint8_t *vs_attrib_wa_flags)
211 {
212    switch (nir->stage) {
213    case MESA_SHADER_VERTEX:
214       /* Start with the location of the variable's base. */
215       foreach_list_typed(nir_variable, var, node, &nir->inputs) {
216          var->data.driver_location = var->data.location;
217       }
218
219       /* Now use nir_lower_io to walk dereference chains.  Attribute arrays
220        * are loaded as one vec4 per element (or matrix column), so we use
221        * type_size_vec4 here.
222        */
223       nir_lower_io(nir, nir_var_shader_in, type_size_vec4);
224
225       /* This pass needs actual constants */
226       nir_opt_constant_folding(nir);
227
228       add_const_offset_to_base(nir, nir_var_shader_in);
229
230       brw_nir_apply_attribute_workarounds(nir, use_legacy_snorm_formula,
231                                           vs_attrib_wa_flags);
232
233       if (is_scalar) {
234          /* Finally, translate VERT_ATTRIB_* values into the actual registers.
235           *
236           * Note that we can use nir->info.inputs_read instead of
237           * key->inputs_read since the two are identical aside from Gen4-5
238           * edge flag differences.
239           */
240          GLbitfield64 inputs_read = nir->info.inputs_read;
241
242          nir_foreach_function(nir, function) {
243             if (function->impl) {
244                nir_foreach_block(function->impl, remap_vs_attrs, &inputs_read);
245             }
246          }
247       }
248       break;
249    case MESA_SHADER_TESS_CTRL:
250    case MESA_SHADER_GEOMETRY: {
251       if (!is_scalar && nir->stage == MESA_SHADER_GEOMETRY) {
252          foreach_list_typed(nir_variable, var, node, &nir->inputs) {
253             var->data.driver_location = var->data.location;
254          }
255       } else {
256          /* The GLSL linker will have already matched up GS inputs and
257           * the outputs of prior stages.  The driver does extend VS outputs
258           * in some cases, but only for legacy OpenGL or Gen4-5 hardware,
259           * neither of which offer geometry shader support.  So we can
260           * safely ignore that.
261           *
262           * For SSO pipelines, we use a fixed VUE map layout based on variable
263           * locations, so we can rely on rendezvous-by-location to make this
264           * work.
265           *
266           * However, we need to ignore VARYING_SLOT_PRIMITIVE_ID, as it's not
267           * written by previous stages and shows up via payload magic.
268           */
269          struct brw_vue_map input_vue_map;
270          GLbitfield64 inputs_read =
271             nir->info.inputs_read & ~VARYING_BIT_PRIMITIVE_ID;
272          brw_compute_vue_map(devinfo, &input_vue_map, inputs_read,
273                              nir->info.separate_shader ||
274                              nir->stage == MESA_SHADER_TESS_CTRL);
275
276          foreach_list_typed(nir_variable, var, node, &nir->inputs) {
277             var->data.driver_location = var->data.location;
278          }
279
280          /* Inputs are stored in vec4 slots, so use type_size_vec4(). */
281          nir_lower_io(nir, nir_var_shader_in, type_size_vec4);
282
283          /* This pass needs actual constants */
284          nir_opt_constant_folding(nir);
285
286          add_const_offset_to_base(nir, nir_var_shader_in);
287
288          nir_foreach_function(nir, function) {
289             if (function->impl) {
290                nir_foreach_block(function->impl, remap_inputs_with_vue_map,
291                                  &input_vue_map);
292             }
293          }
294       }
295       break;
296    }
297    case MESA_SHADER_TESS_EVAL: {
298       struct remap_patch_urb_offsets_state state;
299       brw_compute_tess_vue_map(&state.vue_map,
300                                nir->info.inputs_read & ~VARYING_BIT_PRIMITIVE_ID,
301                                nir->info.patch_inputs_read);
302
303       foreach_list_typed(nir_variable, var, node, &nir->inputs) {
304          var->data.driver_location = var->data.location;
305       }
306
307       nir_lower_io(nir, nir_var_shader_in, type_size_vec4);
308
309       /* This pass needs actual constants */
310       nir_opt_constant_folding(nir);
311
312       add_const_offset_to_base(nir, nir_var_shader_in);
313
314       nir_foreach_function(nir, function) {
315          if (function->impl) {
316             nir_builder_init(&state.b, function->impl);
317             nir_foreach_block(function->impl, remap_patch_urb_offsets, &state);
318          }
319       }
320       break;
321    }
322    case MESA_SHADER_FRAGMENT:
323       assert(is_scalar);
324       nir_assign_var_locations(&nir->inputs, &nir->num_inputs,
325                                type_size_scalar);
326       break;
327    case MESA_SHADER_COMPUTE:
328       /* Compute shaders have no inputs. */
329       assert(exec_list_is_empty(&nir->inputs));
330       break;
331    default:
332       unreachable("unsupported shader stage");
333    }
334 }
335
336 static void
337 brw_nir_lower_outputs(nir_shader *nir,
338                       const struct brw_device_info *devinfo,
339                       bool is_scalar)
340 {
341    switch (nir->stage) {
342    case MESA_SHADER_VERTEX:
343    case MESA_SHADER_TESS_EVAL:
344    case MESA_SHADER_GEOMETRY:
345       if (is_scalar) {
346          nir_assign_var_locations(&nir->outputs, &nir->num_outputs,
347                                   type_size_vec4_times_4);
348          nir_lower_io(nir, nir_var_shader_out, type_size_vec4_times_4);
349       } else {
350          nir_foreach_variable(var, &nir->outputs)
351             var->data.driver_location = var->data.location;
352       }
353       break;
354    case MESA_SHADER_TESS_CTRL: {
355       struct remap_patch_urb_offsets_state state;
356       brw_compute_tess_vue_map(&state.vue_map, nir->info.outputs_written,
357                                nir->info.patch_outputs_written);
358
359       nir_foreach_variable(var, &nir->outputs) {
360          var->data.driver_location = var->data.location;
361       }
362
363       nir_lower_io(nir, nir_var_shader_out, type_size_vec4);
364
365       /* This pass needs actual constants */
366       nir_opt_constant_folding(nir);
367
368       add_const_offset_to_base(nir, nir_var_shader_out);
369
370       nir_foreach_function(nir, function) {
371          if (function->impl) {
372             nir_builder_init(&state.b, function->impl);
373             nir_foreach_block(function->impl, remap_patch_urb_offsets, &state);
374          }
375       }
376       break;
377    }
378    case MESA_SHADER_FRAGMENT:
379       nir_assign_var_locations(&nir->outputs, &nir->num_outputs,
380                                type_size_scalar);
381       break;
382    case MESA_SHADER_COMPUTE:
383       /* Compute shaders have no outputs. */
384       assert(exec_list_is_empty(&nir->outputs));
385       break;
386    default:
387       unreachable("unsupported shader stage");
388    }
389 }
390
391 static int
392 type_size_scalar_bytes(const struct glsl_type *type)
393 {
394    return type_size_scalar(type) * 4;
395 }
396
397 static int
398 type_size_vec4_bytes(const struct glsl_type *type)
399 {
400    return type_size_vec4(type) * 16;
401 }
402
403 static void
404 brw_nir_lower_uniforms(nir_shader *nir, bool is_scalar)
405 {
406    if (is_scalar) {
407       nir_assign_var_locations(&nir->uniforms, &nir->num_uniforms,
408                                type_size_scalar_bytes);
409       nir_lower_io(nir, nir_var_uniform, type_size_scalar_bytes);
410    } else {
411       nir_assign_var_locations(&nir->uniforms, &nir->num_uniforms,
412                                type_size_vec4_bytes);
413       nir_lower_io(nir, nir_var_uniform, type_size_vec4_bytes);
414    }
415 }
416
417 #define OPT(pass, ...) ({                                  \
418    bool this_progress = false;                             \
419    NIR_PASS(this_progress, nir, pass, ##__VA_ARGS__);      \
420    if (this_progress)                                      \
421       progress = true;                                     \
422    this_progress;                                          \
423 })
424
425 #define OPT_V(pass, ...) NIR_PASS_V(nir, pass, ##__VA_ARGS__)
426
427 static nir_shader *
428 nir_optimize(nir_shader *nir, bool is_scalar)
429 {
430    bool progress;
431    do {
432       progress = false;
433       OPT_V(nir_lower_vars_to_ssa);
434
435       if (is_scalar) {
436          OPT_V(nir_lower_alu_to_scalar);
437       }
438
439       OPT(nir_copy_prop);
440
441       if (is_scalar) {
442          OPT_V(nir_lower_phis_to_scalar);
443       }
444
445       OPT(nir_copy_prop);
446       OPT(nir_opt_dce);
447       OPT(nir_opt_cse);
448       OPT(nir_opt_peephole_select);
449       OPT(nir_opt_algebraic);
450       OPT(nir_opt_constant_folding);
451       OPT(nir_opt_dead_cf);
452       OPT(nir_opt_remove_phis);
453       OPT(nir_opt_undef);
454    } while (progress);
455
456    return nir;
457 }
458
459 /* Does some simple lowering and runs the standard suite of optimizations
460  *
461  * This is intended to be called more-or-less directly after you get the
462  * shader out of GLSL or some other source.  While it is geared towards i965,
463  * it is not at all generator-specific except for the is_scalar flag.  Even
464  * there, it is safe to call with is_scalar = false for a shader that is
465  * intended for the FS backend as long as nir_optimize is called again with
466  * is_scalar = true to scalarize everything prior to code gen.
467  */
468 nir_shader *
469 brw_preprocess_nir(nir_shader *nir, bool is_scalar)
470 {
471    bool progress; /* Written by OPT and OPT_V */
472    (void)progress;
473
474    if (nir->stage == MESA_SHADER_GEOMETRY)
475       OPT(nir_lower_gs_intrinsics);
476
477    static const nir_lower_tex_options tex_options = {
478       .lower_txp = ~0,
479    };
480
481    OPT(nir_lower_tex, &tex_options);
482    OPT(nir_normalize_cubemap_coords);
483
484    OPT(nir_lower_global_vars_to_local);
485
486    OPT(nir_split_var_copies);
487
488    nir = nir_optimize(nir, is_scalar);
489
490    if (is_scalar) {
491       OPT_V(nir_lower_load_const_to_scalar);
492    }
493
494    /* Lower a bunch of stuff */
495    OPT_V(nir_lower_var_copies);
496
497    /* Get rid of split copies */
498    nir = nir_optimize(nir, is_scalar);
499
500    OPT(nir_remove_dead_variables);
501
502    return nir;
503 }
504
505 /** Lower input and output loads and stores for i965. */
506 nir_shader *
507 brw_nir_lower_io(nir_shader *nir,
508                  const struct brw_device_info *devinfo,
509                  bool is_scalar,
510                  bool use_legacy_snorm_formula,
511                  const uint8_t *vs_attrib_wa_flags)
512 {
513    bool progress; /* Written by OPT and OPT_V */
514    (void)progress;
515
516    OPT_V(brw_nir_lower_inputs, devinfo, is_scalar,
517          use_legacy_snorm_formula, vs_attrib_wa_flags);
518    OPT_V(brw_nir_lower_outputs, devinfo, is_scalar);
519    OPT_V(nir_lower_io, nir_var_all, is_scalar ? type_size_scalar : type_size_vec4);
520
521    return nir_optimize(nir, is_scalar);
522 }
523
524 /* Prepare the given shader for codegen
525  *
526  * This function is intended to be called right before going into the actual
527  * backend and is highly backend-specific.  Also, once this function has been
528  * called on a shader, it will no longer be in SSA form so most optimizations
529  * will not work.
530  */
531 nir_shader *
532 brw_postprocess_nir(nir_shader *nir,
533                     const struct brw_device_info *devinfo,
534                     bool is_scalar)
535 {
536    bool debug_enabled =
537       (INTEL_DEBUG & intel_debug_flag_for_shader_stage(nir->stage));
538
539    bool progress; /* Written by OPT and OPT_V */
540    (void)progress;
541
542    if (devinfo->gen >= 6) {
543       /* Try and fuse multiply-adds */
544       OPT(brw_nir_opt_peephole_ffma);
545    }
546
547    OPT(nir_opt_algebraic_late);
548
549    OPT(nir_lower_locals_to_regs);
550
551    OPT_V(nir_lower_to_source_mods);
552    OPT(nir_copy_prop);
553    OPT(nir_opt_dce);
554
555    if (unlikely(debug_enabled)) {
556       /* Re-index SSA defs so we print more sensible numbers. */
557       nir_foreach_function(nir, function) {
558          if (function->impl)
559             nir_index_ssa_defs(function->impl);
560       }
561
562       fprintf(stderr, "NIR (SSA form) for %s shader:\n",
563               _mesa_shader_stage_to_string(nir->stage));
564       nir_print_shader(nir, stderr);
565    }
566
567    OPT_V(nir_convert_from_ssa, true);
568
569    if (!is_scalar) {
570       OPT_V(nir_move_vec_src_uses_to_dest);
571       OPT(nir_lower_vec_to_movs);
572    }
573
574    /* This is the last pass we run before we start emitting stuff.  It
575     * determines when we need to insert boolean resolves on Gen <= 5.  We
576     * run it last because it stashes data in instr->pass_flags and we don't
577     * want that to be squashed by other NIR passes.
578     */
579    if (devinfo->gen <= 5)
580       brw_nir_analyze_boolean_resolves(nir);
581
582    nir_sweep(nir);
583
584    if (unlikely(debug_enabled)) {
585       fprintf(stderr, "NIR (final form) for %s shader:\n",
586               _mesa_shader_stage_to_string(nir->stage));
587       nir_print_shader(nir, stderr);
588    }
589
590    return nir;
591 }
592
593 nir_shader *
594 brw_create_nir(struct brw_context *brw,
595                const struct gl_shader_program *shader_prog,
596                const struct gl_program *prog,
597                gl_shader_stage stage,
598                bool is_scalar)
599 {
600    struct gl_context *ctx = &brw->ctx;
601    const struct brw_device_info *devinfo = brw->intelScreen->devinfo;
602    const nir_shader_compiler_options *options =
603       ctx->Const.ShaderCompilerOptions[stage].NirOptions;
604    bool progress;
605    nir_shader *nir;
606
607    /* First, lower the GLSL IR or Mesa IR to NIR */
608    if (shader_prog) {
609       nir = glsl_to_nir(shader_prog, stage, options);
610    } else {
611       nir = prog_to_nir(prog, options);
612       OPT_V(nir_convert_to_ssa); /* turn registers into SSA */
613    }
614    nir_validate_shader(nir);
615
616    (void)progress;
617
618    nir = brw_preprocess_nir(nir, is_scalar);
619
620    OPT(nir_lower_system_values);
621    OPT_V(brw_nir_lower_uniforms, is_scalar);
622
623    if (shader_prog) {
624       OPT_V(nir_lower_samplers, shader_prog);
625       OPT_V(nir_lower_atomics, shader_prog);
626    }
627
628    if (nir->stage != MESA_SHADER_VERTEX &&
629        nir->stage != MESA_SHADER_TESS_CTRL &&
630        nir->stage != MESA_SHADER_TESS_EVAL) {
631       nir = brw_nir_lower_io(nir, devinfo, is_scalar, false, NULL);
632    }
633
634    return nir;
635 }
636
637 nir_shader *
638 brw_nir_apply_sampler_key(nir_shader *nir,
639                           const struct brw_device_info *devinfo,
640                           const struct brw_sampler_prog_key_data *key_tex,
641                           bool is_scalar)
642 {
643    nir_lower_tex_options tex_options = { 0 };
644
645    /* Iron Lake and prior require lowering of all rectangle textures */
646    if (devinfo->gen < 6)
647       tex_options.lower_rect = true;
648
649    /* Prior to Broadwell, our hardware can't actually do GL_CLAMP */
650    if (devinfo->gen < 8) {
651       tex_options.saturate_s = key_tex->gl_clamp_mask[0];
652       tex_options.saturate_t = key_tex->gl_clamp_mask[1];
653       tex_options.saturate_r = key_tex->gl_clamp_mask[2];
654    }
655
656    /* Prior to Haswell, we have to fake texture swizzle */
657    for (unsigned s = 0; s < MAX_SAMPLERS; s++) {
658       if (key_tex->swizzles[s] == SWIZZLE_NOOP)
659          continue;
660
661       tex_options.swizzle_result |= (1 << s);
662       for (unsigned c = 0; c < 4; c++)
663          tex_options.swizzles[s][c] = GET_SWZ(key_tex->swizzles[s], c);
664    }
665
666    if (nir_lower_tex(nir, &tex_options)) {
667       nir_validate_shader(nir);
668       nir = nir_optimize(nir, is_scalar);
669    }
670
671    return nir;
672 }
673
674 enum brw_reg_type
675 brw_type_for_nir_type(nir_alu_type type)
676 {
677    switch (type) {
678    case nir_type_uint:
679       return BRW_REGISTER_TYPE_UD;
680    case nir_type_bool:
681    case nir_type_int:
682       return BRW_REGISTER_TYPE_D;
683    case nir_type_float:
684       return BRW_REGISTER_TYPE_F;
685    default:
686       unreachable("unknown type");
687    }
688
689    return BRW_REGISTER_TYPE_F;
690 }
691
692 /* Returns the glsl_base_type corresponding to a nir_alu_type.
693  * This is used by both brw_vec4_nir and brw_fs_nir.
694  */
695 enum glsl_base_type
696 brw_glsl_base_type_for_nir_type(nir_alu_type type)
697 {
698    switch (type) {
699    case nir_type_float:
700       return GLSL_TYPE_FLOAT;
701
702    case nir_type_int:
703       return GLSL_TYPE_INT;
704
705    case nir_type_uint:
706       return GLSL_TYPE_UINT;
707
708    default:
709       unreachable("bad type");
710    }
711 }