blob: fbc84c474f5bc53fa34b3f4fc6e0a484fa7edbac [file] [log] [blame]
Kenneth Graunke89c1feb2015-04-07 15:15:09 -07001/*
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"
Kenneth Graunke6c33d6bb2015-08-12 14:29:25 -070025#include "brw_shader.h"
Juan A. Suarez Romerod6281a92016-04-15 12:51:05 +020026#include "compiler/glsl_types.h"
Emil Velikova39a8fb2016-01-18 12:54:03 +020027#include "compiler/nir/nir_builder.h"
Kenneth Graunke89c1feb2015-04-07 15:15:09 -070028
Kenneth Graunke8c4deb12015-12-09 02:37:52 -080029static bool
30is_input(nir_intrinsic_instr *intrin)
31{
32 return intrin->intrinsic == nir_intrinsic_load_input ||
Kenneth Graunke1eef0b72016-07-12 03:57:25 -070033 intrin->intrinsic == nir_intrinsic_load_per_vertex_input ||
34 intrin->intrinsic == nir_intrinsic_load_interpolated_input;
Kenneth Graunke8c4deb12015-12-09 02:37:52 -080035}
36
37static bool
38is_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 */
Kenneth Graunkebd198b92015-08-14 16:01:33 -070057
Jason Ekstrand78b81be2015-11-25 14:14:05 -080058static bool
Connor Abbott7efff102016-04-12 22:56:14 -040059add_const_offset_to_base_block(nir_block *block, nir_builder *b,
60 nir_variable_mode mode)
Jason Ekstrand78b81be2015-11-25 14:14:05 -080061{
Jason Ekstrand707e72f2016-04-26 18:34:19 -070062 nir_foreach_instr_safe(instr, block) {
Kenneth Graunkebd198b92015-08-14 16:01:33 -070063 if (instr->type != nir_instr_type_intrinsic)
64 continue;
65
66 nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
67
Connor Abbott7efff102016-04-12 22:56:14 -040068 if ((mode == nir_var_shader_in && is_input(intrin)) ||
69 (mode == nir_var_shader_out && is_output(intrin))) {
Kenneth Graunke8c4deb12015-12-09 02:37:52 -080070 nir_src *offset = nir_get_io_offset_src(intrin);
71 nir_const_value *const_offset = nir_src_as_const_value(*offset);
72
73 if (const_offset) {
Iago Toral Quiroga084b24f2016-03-16 12:11:34 +010074 intrin->const_index[0] += const_offset->u32[0];
Kenneth Graunke8c4deb12015-12-09 02:37:52 -080075 b->cursor = nir_before_instr(&intrin->instr);
76 nir_instr_rewrite_src(&intrin->instr, offset,
77 nir_src_for_ssa(nir_imm_int(b, 0)));
78 }
79 }
80 }
81 return true;
Kenneth Graunkea3500f92016-01-13 15:04:39 -080082}
Kenneth Graunke8c4deb12015-12-09 02:37:52 -080083
Kenneth Graunkea3500f92016-01-13 15:04:39 -080084static void
85add_const_offset_to_base(nir_shader *nir, nir_variable_mode mode)
86{
Jason Ekstrand9464d8c2016-04-26 20:26:42 -070087 nir_foreach_function(f, nir) {
Kenneth Graunkea3500f92016-01-13 15:04:39 -080088 if (f->impl) {
Connor Abbott7efff102016-04-12 22:56:14 -040089 nir_builder b;
90 nir_builder_init(&b, f->impl);
91 nir_foreach_block(block, f->impl) {
92 add_const_offset_to_base_block(block, &b, mode);
93 }
Kenneth Graunkea3500f92016-01-13 15:04:39 -080094 }
95 }
Kenneth Graunke8c4deb12015-12-09 02:37:52 -080096}
97
98static bool
Juan A. Suarez Romerob0fb08e2016-04-01 17:25:03 +020099remap_vs_attrs(nir_block *block, struct nir_shader_info *nir_info)
Kenneth Graunke8c4deb12015-12-09 02:37:52 -0800100{
Jason Ekstrand707e72f2016-04-26 18:34:19 -0700101 nir_foreach_instr(instr, block) {
Kenneth Graunke8c4deb12015-12-09 02:37:52 -0800102 if (instr->type != nir_instr_type_intrinsic)
103 continue;
104
105 nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
106
Kenneth Graunkebd198b92015-08-14 16:01:33 -0700107 if (intrin->intrinsic == nir_intrinsic_load_input) {
108 /* Attributes come in a contiguous block, ordered by their
109 * gl_vert_attrib value. That means we can compute the slot
110 * number for an attribute by masking out the enabled attributes
111 * before it and counting the bits.
112 */
Kenneth Graunke8c4deb12015-12-09 02:37:52 -0800113 int attr = intrin->const_index[0];
Juan A. Suarez Romerob0fb08e2016-04-01 17:25:03 +0200114 int slot = _mesa_bitcount_64(nir_info->inputs_read &
115 BITFIELD64_MASK(attr));
116 int dslot = _mesa_bitcount_64(nir_info->double_inputs_read &
117 BITFIELD64_MASK(attr));
118 intrin->const_index[0] = 4 * (slot + dslot);
Kenneth Graunkebd198b92015-08-14 16:01:33 -0700119 }
120 }
121 return true;
122}
123
Kenneth Graunke9f3917b2015-12-09 18:26:19 -0800124static bool
Connor Abbott7efff102016-04-12 22:56:14 -0400125remap_inputs_with_vue_map(nir_block *block, const struct brw_vue_map *vue_map)
Kenneth Graunke9f3917b2015-12-09 18:26:19 -0800126{
Jason Ekstrand707e72f2016-04-26 18:34:19 -0700127 nir_foreach_instr(instr, block) {
Kenneth Graunke9f3917b2015-12-09 18:26:19 -0800128 if (instr->type != nir_instr_type_intrinsic)
129 continue;
130
131 nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
132
133 if (intrin->intrinsic == nir_intrinsic_load_input ||
134 intrin->intrinsic == nir_intrinsic_load_per_vertex_input) {
135 int vue_slot = vue_map->varying_to_slot[intrin->const_index[0]];
136 assert(vue_slot != -1);
137 intrin->const_index[0] = vue_slot;
138 }
139 }
140 return true;
141}
142
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800143static bool
Connor Abbott7efff102016-04-12 22:56:14 -0400144remap_patch_urb_offsets(nir_block *block, nir_builder *b,
145 const struct brw_vue_map *vue_map)
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800146{
Jason Ekstrand707e72f2016-04-26 18:34:19 -0700147 nir_foreach_instr_safe(instr, block) {
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800148 if (instr->type != nir_instr_type_intrinsic)
149 continue;
150
151 nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
152
Connor Abbott7efff102016-04-12 22:56:14 -0400153 gl_shader_stage stage = b->shader->stage;
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800154
155 if ((stage == MESA_SHADER_TESS_CTRL && is_output(intrin)) ||
156 (stage == MESA_SHADER_TESS_EVAL && is_input(intrin))) {
Connor Abbott7efff102016-04-12 22:56:14 -0400157 int vue_slot = vue_map->varying_to_slot[intrin->const_index[0]];
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800158 assert(vue_slot != -1);
159 intrin->const_index[0] = vue_slot;
160
161 nir_src *vertex = nir_get_io_vertex_index_src(intrin);
162 if (vertex) {
163 nir_const_value *const_vertex = nir_src_as_const_value(*vertex);
164 if (const_vertex) {
Iago Toral Quiroga084b24f2016-03-16 12:11:34 +0100165 intrin->const_index[0] += const_vertex->u32[0] *
Connor Abbott7efff102016-04-12 22:56:14 -0400166 vue_map->num_per_vertex_slots;
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800167 } else {
Connor Abbott7efff102016-04-12 22:56:14 -0400168 b->cursor = nir_before_instr(&intrin->instr);
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800169
170 /* Multiply by the number of per-vertex slots. */
171 nir_ssa_def *vertex_offset =
Connor Abbott7efff102016-04-12 22:56:14 -0400172 nir_imul(b,
173 nir_ssa_for_src(b, *vertex, 1),
174 nir_imm_int(b,
175 vue_map->num_per_vertex_slots));
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800176
177 /* Add it to the existing offset */
178 nir_src *offset = nir_get_io_offset_src(intrin);
179 nir_ssa_def *total_offset =
Connor Abbott7efff102016-04-12 22:56:14 -0400180 nir_iadd(b, vertex_offset,
181 nir_ssa_for_src(b, *offset, 1));
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800182
183 nir_instr_rewrite_src(&intrin->instr, offset,
184 nir_src_for_ssa(total_offset));
185 }
186 }
187 }
188 }
189 return true;
190}
191
Kenneth Graunkecfbd9832016-02-24 22:11:35 -0800192void
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800193brw_nir_lower_vs_inputs(nir_shader *nir,
Jason Ekstrand527f3712016-08-22 15:01:08 -0700194 const struct gen_device_info *devinfo,
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800195 bool is_scalar,
196 bool use_legacy_snorm_formula,
197 const uint8_t *vs_attrib_wa_flags)
Kenneth Graunke193d2952015-08-26 03:07:29 -0700198{
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800199 /* Start with the location of the variable's base. */
200 foreach_list_typed(nir_variable, var, node, &nir->inputs) {
201 var->data.driver_location = var->data.location;
Kenneth Graunkec9541a72015-09-23 20:52:19 -0700202 }
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800203
Juan A. Suarez Romerob0fb08e2016-04-01 17:25:03 +0200204 /* Now use nir_lower_io to walk dereference chains. Attribute arrays are
205 * loaded as one vec4 or dvec4 per element (or matrix column), depending on
206 * whether it is a double-precision type or not.
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800207 */
Jason Ekstranded65e6e2016-09-14 10:29:38 -0700208 nir_lower_io(nir, nir_var_shader_in, type_size_vs_input, 0);
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800209
210 /* This pass needs actual constants */
211 nir_opt_constant_folding(nir);
212
213 add_const_offset_to_base(nir, nir_var_shader_in);
214
215 brw_nir_apply_attribute_workarounds(nir, use_legacy_snorm_formula,
216 vs_attrib_wa_flags);
217
218 if (is_scalar) {
Juan A. Suarez Romerob0fb08e2016-04-01 17:25:03 +0200219 /* Finally, translate VERT_ATTRIB_* values into the actual registers. */
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800220
Jason Ekstrand9464d8c2016-04-26 20:26:42 -0700221 nir_foreach_function(function, nir) {
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800222 if (function->impl) {
Connor Abbott7efff102016-04-12 22:56:14 -0400223 nir_foreach_block(block, function->impl) {
Juan A. Suarez Romerob0fb08e2016-04-01 17:25:03 +0200224 remap_vs_attrs(block, &nir->info);
Connor Abbott7efff102016-04-12 22:56:14 -0400225 }
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800226 }
227 }
228 }
229}
230
Kenneth Graunkecfbd9832016-02-24 22:11:35 -0800231void
Kenneth Graunke81510032016-02-24 23:43:17 -0800232brw_nir_lower_vue_inputs(nir_shader *nir, bool is_scalar,
233 const struct brw_vue_map *vue_map)
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800234{
Kenneth Graunkea0294c22016-02-24 23:44:46 -0800235 foreach_list_typed(nir_variable, var, node, &nir->inputs) {
236 var->data.driver_location = var->data.location;
237 }
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800238
Kenneth Graunkea0294c22016-02-24 23:44:46 -0800239 /* Inputs are stored in vec4 slots, so use type_size_vec4(). */
Jason Ekstranded65e6e2016-09-14 10:29:38 -0700240 nir_lower_io(nir, nir_var_shader_in, type_size_vec4, 0);
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800241
Kenneth Graunkea0294c22016-02-24 23:44:46 -0800242 if (is_scalar || nir->stage != MESA_SHADER_GEOMETRY) {
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800243 /* This pass needs actual constants */
244 nir_opt_constant_folding(nir);
245
Kenneth Graunkea3500f92016-01-13 15:04:39 -0800246 add_const_offset_to_base(nir, nir_var_shader_in);
247
Jason Ekstrand9464d8c2016-04-26 20:26:42 -0700248 nir_foreach_function(function, nir) {
Jason Ekstrand237f2f22015-12-26 10:00:47 -0800249 if (function->impl) {
Connor Abbott7efff102016-04-12 22:56:14 -0400250 nir_foreach_block(block, function->impl) {
251 remap_inputs_with_vue_map(block, vue_map);
252 }
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800253 }
254 }
Kenneth Graunkebee42cc2015-12-09 21:41:35 -0800255 }
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800256}
257
Kenneth Graunkecfbd9832016-02-24 22:11:35 -0800258void
Kenneth Graunke15b36392016-02-24 22:34:51 -0800259brw_nir_lower_tes_inputs(nir_shader *nir, const struct brw_vue_map *vue_map)
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800260{
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800261 foreach_list_typed(nir_variable, var, node, &nir->inputs) {
262 var->data.driver_location = var->data.location;
263 }
264
Jason Ekstranded65e6e2016-09-14 10:29:38 -0700265 nir_lower_io(nir, nir_var_shader_in, type_size_vec4, 0);
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800266
267 /* This pass needs actual constants */
268 nir_opt_constant_folding(nir);
269
270 add_const_offset_to_base(nir, nir_var_shader_in);
271
Jason Ekstrand9464d8c2016-04-26 20:26:42 -0700272 nir_foreach_function(function, nir) {
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800273 if (function->impl) {
Connor Abbott7efff102016-04-12 22:56:14 -0400274 nir_builder b;
275 nir_builder_init(&b, function->impl);
276 nir_foreach_block(block, function->impl) {
277 remap_patch_urb_offsets(block, &b, vue_map);
278 }
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800279 }
280 }
281}
282
Kenneth Graunkecfbd9832016-02-24 22:11:35 -0800283void
Jason Ekstrand246db002016-09-14 10:39:52 -0700284brw_nir_lower_fs_inputs(nir_shader *nir,
Jason Ekstrand111f6b22016-09-14 10:42:42 -0700285 const struct gen_device_info *devinfo,
Jason Ekstrand246db002016-09-14 10:39:52 -0700286 const struct brw_wm_prog_key *key)
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800287{
Kenneth Graunke1eef0b72016-07-12 03:57:25 -0700288 foreach_list_typed(nir_variable, var, node, &nir->inputs) {
289 var->data.driver_location = var->data.location;
Jason Ekstrand111f6b22016-09-14 10:42:42 -0700290
291 /* Apply default interpolation mode.
292 *
293 * Everything defaults to smooth except for the legacy GL color
294 * built-in variables, which might be flat depending on API state.
295 */
296 if (var->data.interpolation == INTERP_MODE_NONE) {
297 const bool flat = key->flat_shade &&
298 (var->data.location == VARYING_SLOT_COL0 ||
299 var->data.location == VARYING_SLOT_COL1);
300
301 var->data.interpolation = flat ? INTERP_MODE_FLAT
302 : INTERP_MODE_SMOOTH;
303 }
304
305 /* On Ironlake and below, there is only one interpolation mode.
306 * Centroid interpolation doesn't mean anything on this hardware --
307 * there is no multisampling.
308 */
309 if (devinfo->gen < 6) {
310 var->data.centroid = false;
311 var->data.sample = false;
312 }
Kenneth Graunke1eef0b72016-07-12 03:57:25 -0700313 }
314
Jason Ekstrand246db002016-09-14 10:39:52 -0700315 nir_lower_io_options lower_io_options = 0;
316 if (key->persample_interp)
317 lower_io_options |= nir_lower_io_force_sample_interpolation;
318
319 nir_lower_io(nir, nir_var_shader_in, type_size_vec4, lower_io_options);
Kenneth Graunke1eef0b72016-07-12 03:57:25 -0700320
321 /* This pass needs actual constants */
322 nir_opt_constant_folding(nir);
323
324 add_const_offset_to_base(nir, nir_var_shader_in);
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800325}
326
Kenneth Graunkecfbd9832016-02-24 22:11:35 -0800327void
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800328brw_nir_lower_vue_outputs(nir_shader *nir,
329 bool is_scalar)
330{
331 if (is_scalar) {
332 nir_assign_var_locations(&nir->outputs, &nir->num_outputs,
Timothy Arceri448adfb2016-05-18 10:26:05 +1000333 VARYING_SLOT_VAR0,
Timothy Arceri7f53fea2016-05-23 16:48:05 +1000334 type_size_vec4_times_4);
Jason Ekstranded65e6e2016-09-14 10:29:38 -0700335 nir_lower_io(nir, nir_var_shader_out, type_size_vec4_times_4, 0);
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800336 } else {
337 nir_foreach_variable(var, &nir->outputs)
338 var->data.driver_location = var->data.location;
Jason Ekstranded65e6e2016-09-14 10:29:38 -0700339 nir_lower_io(nir, nir_var_shader_out, type_size_vec4, 0);
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800340 }
341}
342
Kenneth Graunkecfbd9832016-02-24 22:11:35 -0800343void
Kenneth Graunke15b36392016-02-24 22:34:51 -0800344brw_nir_lower_tcs_outputs(nir_shader *nir, const struct brw_vue_map *vue_map)
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800345{
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800346 nir_foreach_variable(var, &nir->outputs) {
347 var->data.driver_location = var->data.location;
348 }
349
Jason Ekstranded65e6e2016-09-14 10:29:38 -0700350 nir_lower_io(nir, nir_var_shader_out, type_size_vec4, 0);
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800351
352 /* This pass needs actual constants */
353 nir_opt_constant_folding(nir);
354
355 add_const_offset_to_base(nir, nir_var_shader_out);
356
Jason Ekstrand9464d8c2016-04-26 20:26:42 -0700357 nir_foreach_function(function, nir) {
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800358 if (function->impl) {
Connor Abbott7efff102016-04-12 22:56:14 -0400359 nir_builder b;
360 nir_builder_init(&b, function->impl);
361 nir_foreach_block(block, function->impl) {
362 remap_patch_urb_offsets(block, &b, vue_map);
363 }
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800364 }
365 }
366}
367
Kenneth Graunkecfbd9832016-02-24 22:11:35 -0800368void
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800369brw_nir_lower_fs_outputs(nir_shader *nir)
370{
Francisco Jerez7dac8822016-07-21 21:26:20 -0700371 nir_foreach_variable(var, &nir->outputs) {
372 var->data.driver_location =
373 SET_FIELD(var->data.index, BRW_NIR_FRAG_OUTPUT_INDEX) |
374 SET_FIELD(var->data.location, BRW_NIR_FRAG_OUTPUT_LOCATION);
375 }
376
Jason Ekstranded65e6e2016-09-14 10:29:38 -0700377 nir_lower_io(nir, nir_var_shader_out, type_size_dvec4, 0);
Kenneth Graunkeb96ddd22016-02-24 22:02:28 -0800378}
379
Jordan Justen7d021cb2016-01-18 09:45:46 -0800380void
381brw_nir_lower_cs_shared(nir_shader *nir)
382{
Timothy Arceri448adfb2016-05-18 10:26:05 +1000383 nir_assign_var_locations(&nir->shared, &nir->num_shared, 0,
Jordan Justen7d021cb2016-01-18 09:45:46 -0800384 type_size_scalar_bytes);
Jason Ekstranded65e6e2016-09-14 10:29:38 -0700385 nir_lower_io(nir, nir_var_shared, type_size_scalar_bytes, 0);
Jordan Justen7d021cb2016-01-18 09:45:46 -0800386}
387
Rob Clark317628d2015-11-18 16:33:41 -0500388#define OPT(pass, ...) ({ \
389 bool this_progress = false; \
390 NIR_PASS(this_progress, nir, pass, ##__VA_ARGS__); \
391 if (this_progress) \
392 progress = true; \
393 this_progress; \
394})
Rob Clarkd278e312015-11-18 16:43:31 -0500395
Rob Clark317628d2015-11-18 16:33:41 -0500396#define OPT_V(pass, ...) NIR_PASS_V(nir, pass, ##__VA_ARGS__)
Kenneth Graunke7bc09782015-11-03 00:31:15 -0800397
Jason Ekstrand0bee3ac2015-11-16 11:48:05 -0800398static nir_shader *
Alejandro Piñeiro9e5d8272015-06-25 09:52:35 +0200399nir_optimize(nir_shader *nir, bool is_scalar)
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700400{
401 bool progress;
402 do {
403 progress = false;
Kenneth Graunke7bc09782015-11-03 00:31:15 -0800404 OPT_V(nir_lower_vars_to_ssa);
Alejandro Piñeiro9e5d8272015-06-25 09:52:35 +0200405
406 if (is_scalar) {
Kenneth Graunke32630e22016-09-13 15:14:28 -0700407 OPT(nir_lower_alu_to_scalar);
Alejandro Piñeiro9e5d8272015-06-25 09:52:35 +0200408 }
409
Kenneth Graunke7bc09782015-11-03 00:31:15 -0800410 OPT(nir_copy_prop);
Iago Toral Quirogada1b1bf2015-07-15 09:32:17 +0200411
412 if (is_scalar) {
Kenneth Graunke2d8a3fa2016-09-13 15:14:28 -0700413 OPT(nir_lower_phis_to_scalar);
Iago Toral Quirogada1b1bf2015-07-15 09:32:17 +0200414 }
415
Kenneth Graunke7bc09782015-11-03 00:31:15 -0800416 OPT(nir_copy_prop);
417 OPT(nir_opt_dce);
418 OPT(nir_opt_cse);
419 OPT(nir_opt_peephole_select);
420 OPT(nir_opt_algebraic);
421 OPT(nir_opt_constant_folding);
422 OPT(nir_opt_dead_cf);
423 OPT(nir_opt_remove_phis);
424 OPT(nir_opt_undef);
Connor Abbottbea2f8b2015-08-03 15:02:05 -0700425 OPT_V(nir_lower_doubles, nir_lower_drcp |
426 nir_lower_dsqrt |
427 nir_lower_drsq |
428 nir_lower_dtrunc |
429 nir_lower_dfloor |
430 nir_lower_dceil |
431 nir_lower_dfract |
432 nir_lower_dround_even |
433 nir_lower_dmod);
Connor Abbott30424fd2015-08-07 08:45:49 -0700434 OPT_V(nir_lower_double_pack);
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700435 } while (progress);
Jason Ekstrand0bee3ac2015-11-16 11:48:05 -0800436
437 return nir;
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700438}
439
Jason Ekstrand9cf108192015-11-11 09:40:51 -0800440/* Does some simple lowering and runs the standard suite of optimizations
441 *
442 * This is intended to be called more-or-less directly after you get the
443 * shader out of GLSL or some other source. While it is geared towards i965,
444 * it is not at all generator-specific except for the is_scalar flag. Even
445 * there, it is safe to call with is_scalar = false for a shader that is
446 * intended for the FS backend as long as nir_optimize is called again with
447 * is_scalar = true to scalarize everything prior to code gen.
448 */
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700449nir_shader *
Kenneth Graunkeb0dffdc2016-04-07 15:09:56 -0700450brw_preprocess_nir(const struct brw_compiler *compiler, nir_shader *nir)
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700451{
Jason Ekstrand9cf108192015-11-11 09:40:51 -0800452 bool progress; /* Written by OPT and OPT_V */
453 (void)progress;
454
Kenneth Graunkeb0dffdc2016-04-07 15:09:56 -0700455 const bool is_scalar = compiler->scalar_stage[nir->stage];
456
Jason Ekstrand9cf108192015-11-11 09:40:51 -0800457 if (nir->stage == MESA_SHADER_GEOMETRY)
458 OPT(nir_lower_gs_intrinsics);
459
Kenneth Graunkebfd17c72016-04-07 15:04:35 -0700460 if (compiler->precise_trig)
461 OPT(brw_nir_apply_trig_workarounds);
462
Rob Clarkfaf5f172015-09-16 12:56:58 -0400463 static const nir_lower_tex_options tex_options = {
464 .lower_txp = ~0,
Jason Ekstrand9f327212016-07-21 12:55:21 -0700465 .lower_txf_offset = true,
466 .lower_rect_offset = true,
Rob Clarkfaf5f172015-09-16 12:56:58 -0400467 };
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700468
Jason Ekstrand1417f6a2015-11-11 10:46:09 -0800469 OPT(nir_lower_tex, &tex_options);
Kenneth Graunke7bc09782015-11-03 00:31:15 -0800470 OPT(nir_normalize_cubemap_coords);
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700471
Jason Ekstrand9cf108192015-11-11 09:40:51 -0800472 OPT(nir_lower_global_vars_to_local);
473
Kenneth Graunke7bc09782015-11-03 00:31:15 -0800474 OPT(nir_split_var_copies);
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700475
Jason Ekstrand0bee3ac2015-11-16 11:48:05 -0800476 nir = nir_optimize(nir, is_scalar);
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700477
Kenneth Graunke74f956c2016-01-21 16:37:20 -0800478 if (is_scalar) {
479 OPT_V(nir_lower_load_const_to_scalar);
480 }
481
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700482 /* Lower a bunch of stuff */
Kenneth Graunke7bc09782015-11-03 00:31:15 -0800483 OPT_V(nir_lower_var_copies);
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700484
485 /* Get rid of split copies */
Jason Ekstrand0bee3ac2015-11-16 11:48:05 -0800486 nir = nir_optimize(nir, is_scalar);
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700487
Jason Ekstrandb63a98b2016-03-25 14:26:11 -0700488 OPT(nir_remove_dead_variables, nir_var_local);
Jason Ekstrand9cf108192015-11-11 09:40:51 -0800489
490 return nir;
491}
492
Jason Ekstrand9cf108192015-11-11 09:40:51 -0800493/* Prepare the given shader for codegen
494 *
495 * This function is intended to be called right before going into the actual
496 * backend and is highly backend-specific. Also, once this function has been
497 * called on a shader, it will no longer be in SSA form so most optimizations
498 * will not work.
499 */
500nir_shader *
501brw_postprocess_nir(nir_shader *nir,
Jason Ekstrand527f3712016-08-22 15:01:08 -0700502 const struct gen_device_info *devinfo,
Jason Ekstrand9cf108192015-11-11 09:40:51 -0800503 bool is_scalar)
504{
505 bool debug_enabled =
506 (INTEL_DEBUG & intel_debug_flag_for_shader_stage(nir->stage));
507
508 bool progress; /* Written by OPT and OPT_V */
509 (void)progress;
510
Kenneth Graunke51f87972016-02-24 21:40:37 -0800511 nir = nir_optimize(nir, is_scalar);
512
Jason Ekstrand9cf108192015-11-11 09:40:51 -0800513 if (devinfo->gen >= 6) {
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700514 /* Try and fuse multiply-adds */
Kenneth Graunke7bc09782015-11-03 00:31:15 -0800515 OPT(brw_nir_opt_peephole_ffma);
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700516 }
517
Kenneth Graunke7bc09782015-11-03 00:31:15 -0800518 OPT(nir_opt_algebraic_late);
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700519
Kenneth Graunke7bc09782015-11-03 00:31:15 -0800520 OPT(nir_lower_locals_to_regs);
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700521
Kenneth Graunke7bc09782015-11-03 00:31:15 -0800522 OPT_V(nir_lower_to_source_mods);
523 OPT(nir_copy_prop);
524 OPT(nir_opt_dce);
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700525
526 if (unlikely(debug_enabled)) {
Kenneth Graunkef4310cd2015-06-10 01:46:13 -0700527 /* Re-index SSA defs so we print more sensible numbers. */
Jason Ekstrand9464d8c2016-04-26 20:26:42 -0700528 nir_foreach_function(function, nir) {
Jason Ekstrand237f2f22015-12-26 10:00:47 -0800529 if (function->impl)
530 nir_index_ssa_defs(function->impl);
Kenneth Graunkef4310cd2015-06-10 01:46:13 -0700531 }
532
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700533 fprintf(stderr, "NIR (SSA form) for %s shader:\n",
Jason Ekstrand9cf108192015-11-11 09:40:51 -0800534 _mesa_shader_stage_to_string(nir->stage));
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700535 nir_print_shader(nir, stderr);
536 }
537
Kenneth Graunke7bc09782015-11-03 00:31:15 -0800538 OPT_V(nir_convert_from_ssa, true);
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700539
Antia Puentese4f02f42015-06-16 22:58:15 +0200540 if (!is_scalar) {
Kenneth Graunke7bc09782015-11-03 00:31:15 -0800541 OPT_V(nir_move_vec_src_uses_to_dest);
542 OPT(nir_lower_vec_to_movs);
Antia Puentese4f02f42015-06-16 22:58:15 +0200543 }
544
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700545 /* This is the last pass we run before we start emitting stuff. It
546 * determines when we need to insert boolean resolves on Gen <= 5. We
547 * run it last because it stashes data in instr->pass_flags and we don't
548 * want that to be squashed by other NIR passes.
549 */
Jason Ekstrand9cf108192015-11-11 09:40:51 -0800550 if (devinfo->gen <= 5)
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700551 brw_nir_analyze_boolean_resolves(nir);
552
553 nir_sweep(nir);
554
555 if (unlikely(debug_enabled)) {
556 fprintf(stderr, "NIR (final form) for %s shader:\n",
Jason Ekstrand9cf108192015-11-11 09:40:51 -0800557 _mesa_shader_stage_to_string(nir->stage));
Kenneth Graunke89c1feb2015-04-07 15:15:09 -0700558 nir_print_shader(nir, stderr);
559 }
560
561 return nir;
562}
Eduardo Lima Mitev97e205f2015-04-17 18:10:50 +0200563
Jason Ekstrand9cf108192015-11-11 09:40:51 -0800564nir_shader *
Jason Ekstrand6c8ba592015-11-11 11:01:59 -0800565brw_nir_apply_sampler_key(nir_shader *nir,
Jason Ekstrand527f3712016-08-22 15:01:08 -0700566 const struct gen_device_info *devinfo,
Jason Ekstrand6c8ba592015-11-11 11:01:59 -0800567 const struct brw_sampler_prog_key_data *key_tex,
568 bool is_scalar)
569{
570 nir_lower_tex_options tex_options = { 0 };
571
572 /* Iron Lake and prior require lowering of all rectangle textures */
573 if (devinfo->gen < 6)
574 tex_options.lower_rect = true;
575
576 /* Prior to Broadwell, our hardware can't actually do GL_CLAMP */
577 if (devinfo->gen < 8) {
578 tex_options.saturate_s = key_tex->gl_clamp_mask[0];
579 tex_options.saturate_t = key_tex->gl_clamp_mask[1];
580 tex_options.saturate_r = key_tex->gl_clamp_mask[2];
581 }
582
Jason Ekstrandd9b8fde2015-11-11 18:41:37 -0800583 /* Prior to Haswell, we have to fake texture swizzle */
584 for (unsigned s = 0; s < MAX_SAMPLERS; s++) {
585 if (key_tex->swizzles[s] == SWIZZLE_NOOP)
586 continue;
587
588 tex_options.swizzle_result |= (1 << s);
589 for (unsigned c = 0; c < 4; c++)
590 tex_options.swizzles[s][c] = GET_SWZ(key_tex->swizzles[s], c);
591 }
592
Kristian Høgsberg Kristensen654e9502016-05-01 21:22:54 -0700593 tex_options.lower_y_uv_external = key_tex->y_uv_image_mask;
594 tex_options.lower_y_u_v_external = key_tex->y_u_v_image_mask;
595 tex_options.lower_yx_xuxv_external = key_tex->yx_xuxv_image_mask;
596
Jason Ekstrand6c8ba592015-11-11 11:01:59 -0800597 if (nir_lower_tex(nir, &tex_options)) {
598 nir_validate_shader(nir);
599 nir = nir_optimize(nir, is_scalar);
600 }
601
602 return nir;
603}
604
Eduardo Lima Mitev97e205f2015-04-17 18:10:50 +0200605enum brw_reg_type
606brw_type_for_nir_type(nir_alu_type type)
607{
608 switch (type) {
Jason Ekstrandf5881382015-05-15 09:14:47 -0700609 case nir_type_uint:
Connor Abbott9076c4e2015-08-14 10:45:06 -0700610 case nir_type_uint32:
Eduardo Lima Mitev97e205f2015-04-17 18:10:50 +0200611 return BRW_REGISTER_TYPE_UD;
612 case nir_type_bool:
613 case nir_type_int:
Connor Abbott9076c4e2015-08-14 10:45:06 -0700614 case nir_type_bool32:
615 case nir_type_int32:
Eduardo Lima Mitev97e205f2015-04-17 18:10:50 +0200616 return BRW_REGISTER_TYPE_D;
617 case nir_type_float:
Connor Abbott9076c4e2015-08-14 10:45:06 -0700618 case nir_type_float32:
Eduardo Lima Mitev97e205f2015-04-17 18:10:50 +0200619 return BRW_REGISTER_TYPE_F;
Connor Abbott9076c4e2015-08-14 10:45:06 -0700620 case nir_type_float64:
621 return BRW_REGISTER_TYPE_DF;
622 case nir_type_int64:
623 case nir_type_uint64:
624 /* TODO we should only see these in moves, so for now it's ok, but when
625 * we add actual 64-bit integer support we should fix this.
626 */
627 return BRW_REGISTER_TYPE_DF;
Eduardo Lima Mitev97e205f2015-04-17 18:10:50 +0200628 default:
629 unreachable("unknown type");
630 }
631
632 return BRW_REGISTER_TYPE_F;
633}
Eduardo Lima Mitevdb8a6de2015-06-17 10:59:10 +0200634
635/* Returns the glsl_base_type corresponding to a nir_alu_type.
636 * This is used by both brw_vec4_nir and brw_fs_nir.
637 */
638enum glsl_base_type
639brw_glsl_base_type_for_nir_type(nir_alu_type type)
640{
641 switch (type) {
642 case nir_type_float:
Connor Abbott9076c4e2015-08-14 10:45:06 -0700643 case nir_type_float32:
Eduardo Lima Mitevdb8a6de2015-06-17 10:59:10 +0200644 return GLSL_TYPE_FLOAT;
645
Connor Abbott9076c4e2015-08-14 10:45:06 -0700646 case nir_type_float64:
647 return GLSL_TYPE_DOUBLE;
648
Eduardo Lima Mitevdb8a6de2015-06-17 10:59:10 +0200649 case nir_type_int:
Connor Abbott9076c4e2015-08-14 10:45:06 -0700650 case nir_type_int32:
Eduardo Lima Mitevdb8a6de2015-06-17 10:59:10 +0200651 return GLSL_TYPE_INT;
652
Jason Ekstrandf5881382015-05-15 09:14:47 -0700653 case nir_type_uint:
Connor Abbott9076c4e2015-08-14 10:45:06 -0700654 case nir_type_uint32:
Eduardo Lima Mitevdb8a6de2015-06-17 10:59:10 +0200655 return GLSL_TYPE_UINT;
656
657 default:
658 unreachable("bad type");
659 }
660}