1 /*
2 * Copyright © 2015 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 #ifndef BRW_NIR_H
25 #define BRW_NIR_H
26
27 #include "brw_reg.h"
28 #include "compiler/nir/nir.h"
29 #include "brw_compiler.h"
30 #include "nir_builder.h"
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 extern const struct nir_shader_compiler_options brw_scalar_nir_options;
37
38 int type_size_vec4(const struct glsl_type *type, bool bindless);
39 int type_size_dvec4(const struct glsl_type *type, bool bindless);
40
41 static inline int
type_size_scalar_bytes(const struct glsl_type * type,bool bindless)42 type_size_scalar_bytes(const struct glsl_type *type, bool bindless)
43 {
44 return glsl_count_dword_slots(type, bindless) * 4;
45 }
46
47 static inline int
type_size_vec4_bytes(const struct glsl_type * type,bool bindless)48 type_size_vec4_bytes(const struct glsl_type *type, bool bindless)
49 {
50 return type_size_vec4(type, bindless) * 16;
51 }
52
53 struct brw_nir_compiler_opts {
54 /* Soft floating point implementation shader */
55 const nir_shader *softfp64;
56
57 /* Whether robust image access is enabled */
58 bool robust_image_access;
59
60 /* Input vertices for TCS stage (0 means dynamic) */
61 unsigned input_vertices;
62 };
63
64 /* UBO surface index can come in 2 flavors :
65 * - nir_intrinsic_resource_intel
66 * - anything else
67 *
68 * In the first case, checking that the surface index is const requires
69 * checking resource_intel::src[1]. In any other case it's a simple
70 * nir_src_is_const().
71 *
72 * This function should only be called on src[0] of load_ubo intrinsics.
73 */
74 static inline bool
brw_nir_ubo_surface_index_is_pushable(nir_src src)75 brw_nir_ubo_surface_index_is_pushable(nir_src src)
76 {
77 nir_intrinsic_instr *intrin =
78 src.ssa->parent_instr->type == nir_instr_type_intrinsic ?
79 nir_instr_as_intrinsic(src.ssa->parent_instr) : NULL;
80
81 if (intrin && intrin->intrinsic == nir_intrinsic_resource_intel) {
82 return (nir_intrinsic_resource_access_intel(intrin) &
83 nir_resource_intel_pushable);
84 }
85
86 return nir_src_is_const(src);
87 }
88
89 static inline unsigned
brw_nir_ubo_surface_index_get_push_block(nir_src src)90 brw_nir_ubo_surface_index_get_push_block(nir_src src)
91 {
92 if (nir_src_is_const(src))
93 return nir_src_as_uint(src);
94
95 if (!brw_nir_ubo_surface_index_is_pushable(src))
96 return UINT32_MAX;
97
98 assert(src.ssa->parent_instr->type == nir_instr_type_intrinsic);
99
100 nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(src.ssa->parent_instr);
101 assert(intrin->intrinsic == nir_intrinsic_resource_intel);
102
103 return nir_intrinsic_resource_block_intel(intrin);
104 }
105
106 /* This helper return the binding table index of a surface access (any
107 * buffer/image/etc...). It works off the source of one of the intrinsics
108 * (load_ubo, load_ssbo, store_ssbo, load_image, store_image, etc...).
109 *
110 * If the source is constant, then this is the binding table index. If we're
111 * going through a resource_intel intel intrinsic, then we need to check
112 * src[1] of that intrinsic.
113 */
114 static inline unsigned
brw_nir_ubo_surface_index_get_bti(nir_src src)115 brw_nir_ubo_surface_index_get_bti(nir_src src)
116 {
117 if (nir_src_is_const(src))
118 return nir_src_as_uint(src);
119
120 assert(src.ssa->parent_instr->type == nir_instr_type_intrinsic);
121
122 nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(src.ssa->parent_instr);
123 if (!intrin || intrin->intrinsic != nir_intrinsic_resource_intel)
124 return UINT32_MAX;
125
126 /* In practice we could even drop this intrinsic because the bindless
127 * access always operate from a base offset coming from a push constant, so
128 * they can never be constant.
129 */
130 if (nir_intrinsic_resource_access_intel(intrin) &
131 nir_resource_intel_bindless)
132 return UINT32_MAX;
133
134 if (!nir_src_is_const(intrin->src[1]))
135 return UINT32_MAX;
136
137 return nir_src_as_uint(intrin->src[1]);
138 }
139
140 void brw_preprocess_nir(const struct brw_compiler *compiler,
141 nir_shader *nir,
142 const struct brw_nir_compiler_opts *opts);
143
144 void
145 brw_nir_link_shaders(const struct brw_compiler *compiler,
146 nir_shader *producer, nir_shader *consumer);
147
148 bool brw_nir_lower_cs_intrinsics(nir_shader *nir,
149 const struct intel_device_info *devinfo,
150 struct brw_cs_prog_data *prog_data);
151 bool brw_nir_lower_alpha_to_coverage(nir_shader *shader,
152 const struct brw_wm_prog_key *key,
153 const struct brw_wm_prog_data *prog_data);
154 void brw_nir_lower_vs_inputs(nir_shader *nir);
155 void brw_nir_lower_vue_inputs(nir_shader *nir,
156 const struct intel_vue_map *vue_map);
157 void brw_nir_lower_tes_inputs(nir_shader *nir, const struct intel_vue_map *vue);
158 void brw_nir_lower_fs_inputs(nir_shader *nir,
159 const struct intel_device_info *devinfo,
160 const struct brw_wm_prog_key *key);
161 void brw_nir_lower_vue_outputs(nir_shader *nir);
162 void brw_nir_lower_tcs_outputs(nir_shader *nir, const struct intel_vue_map *vue,
163 enum tess_primitive_mode tes_primitive_mode);
164 void brw_nir_lower_fs_outputs(nir_shader *nir);
165
166 bool brw_nir_lower_cmat(nir_shader *nir, unsigned subgroup_size);
167
168 struct brw_nir_lower_storage_image_opts {
169 const struct intel_device_info *devinfo;
170
171 bool lower_loads;
172 bool lower_stores;
173 };
174
175 bool brw_nir_lower_storage_image(nir_shader *nir,
176 const struct brw_nir_lower_storage_image_opts *opts);
177
178 bool brw_nir_lower_mem_access_bit_sizes(nir_shader *shader,
179 const struct
180 intel_device_info *devinfo);
181
182 void brw_postprocess_nir(nir_shader *nir,
183 const struct brw_compiler *compiler,
184 bool debug_enabled,
185 enum brw_robustness_flags robust_flags);
186
187 bool brw_nir_apply_attribute_workarounds(nir_shader *nir,
188 const uint8_t *attrib_wa_flags);
189
190 bool brw_nir_apply_trig_workarounds(nir_shader *nir);
191
192 bool brw_nir_limit_trig_input_range_workaround(nir_shader *nir);
193
194 bool brw_nir_lower_fsign(nir_shader *nir);
195
196 bool brw_nir_opt_fsat(nir_shader *);
197
198 void brw_nir_apply_key(nir_shader *nir,
199 const struct brw_compiler *compiler,
200 const struct brw_base_prog_key *key,
201 unsigned max_subgroup_size);
202
203 unsigned brw_nir_api_subgroup_size(const nir_shader *nir,
204 unsigned hw_subgroup_size);
205
206 enum brw_conditional_mod brw_cmod_for_nir_comparison(nir_op op);
207 enum lsc_opcode lsc_op_for_nir_intrinsic(const nir_intrinsic_instr *intrin);
208 enum brw_reg_type brw_type_for_nir_type(const struct intel_device_info *devinfo,
209 nir_alu_type type);
210
211 bool brw_nir_should_vectorize_mem(unsigned align_mul, unsigned align_offset,
212 unsigned bit_size,
213 unsigned num_components,
214 nir_intrinsic_instr *low,
215 nir_intrinsic_instr *high,
216 void *data);
217
218 void brw_nir_analyze_ubo_ranges(const struct brw_compiler *compiler,
219 nir_shader *nir,
220 struct brw_ubo_range out_ranges[4]);
221
222 void brw_nir_optimize(nir_shader *nir,
223 const struct intel_device_info *devinfo);
224
225 nir_shader *brw_nir_create_passthrough_tcs(void *mem_ctx,
226 const struct brw_compiler *compiler,
227 const struct brw_tcs_prog_key *key);
228
229 #define BRW_NIR_FRAG_OUTPUT_INDEX_SHIFT 0
230 #define BRW_NIR_FRAG_OUTPUT_INDEX_MASK INTEL_MASK(0, 0)
231 #define BRW_NIR_FRAG_OUTPUT_LOCATION_SHIFT 1
232 #define BRW_NIR_FRAG_OUTPUT_LOCATION_MASK INTEL_MASK(31, 1)
233
234 bool brw_nir_move_interpolation_to_top(nir_shader *nir);
235 nir_def *brw_nir_load_global_const(nir_builder *b,
236 nir_intrinsic_instr *load_uniform,
237 nir_def *base_addr,
238 unsigned off);
239
240 const struct glsl_type *brw_nir_get_var_type(const struct nir_shader *nir,
241 nir_variable *var);
242
243 void brw_nir_adjust_payload(nir_shader *shader);
244
245 static inline nir_variable_mode
brw_nir_no_indirect_mask(const struct brw_compiler * compiler,gl_shader_stage stage)246 brw_nir_no_indirect_mask(const struct brw_compiler *compiler,
247 gl_shader_stage stage)
248 {
249 nir_variable_mode indirect_mask = (nir_variable_mode) 0;
250
251 switch (stage) {
252 case MESA_SHADER_VERTEX:
253 case MESA_SHADER_FRAGMENT:
254 indirect_mask |= nir_var_shader_in;
255 break;
256
257 default:
258 /* Everything else can handle indirect inputs */
259 break;
260 }
261
262 if (stage != MESA_SHADER_TESS_CTRL &&
263 stage != MESA_SHADER_TASK &&
264 stage != MESA_SHADER_MESH)
265 indirect_mask |= nir_var_shader_out;
266
267 return indirect_mask;
268 }
269
270 void
271 brw_nir_printf(nir_builder *b, const char *fmt, ...);
272
273 #ifdef __cplusplus
274 }
275 #endif
276
277 #endif /* BRW_NIR_H */
278