radeonsi: scan NIR shaders to obtain required info
[mesa.git] / src / gallium / drivers / radeonsi / si_shader_nir.c
1 /*
2 * Copyright 2017 Advanced Micro Devices, Inc.
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "si_shader.h"
25
26 #include "tgsi/tgsi_from_mesa.h"
27
28 #include "compiler/nir/nir.h"
29 #include "compiler/nir_types.h"
30
31
32 static void scan_instruction(struct tgsi_shader_info *info,
33 nir_instr *instr)
34 {
35 if (instr->type == nir_instr_type_alu) {
36 nir_alu_instr *alu = nir_instr_as_alu(instr);
37
38 switch (alu->op) {
39 case nir_op_fddx:
40 case nir_op_fddy:
41 case nir_op_fddx_fine:
42 case nir_op_fddy_fine:
43 case nir_op_fddx_coarse:
44 case nir_op_fddy_coarse:
45 info->uses_derivatives = true;
46 break;
47 default:
48 break;
49 }
50 } else if (instr->type == nir_instr_type_tex) {
51 nir_tex_instr *tex = nir_instr_as_tex(instr);
52
53 switch (tex->op) {
54 case nir_texop_tex:
55 case nir_texop_txb:
56 case nir_texop_lod:
57 info->uses_derivatives = true;
58 break;
59 default:
60 break;
61 }
62 } else if (instr->type == nir_instr_type_intrinsic) {
63 nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
64
65 switch (intr->intrinsic) {
66 case nir_intrinsic_load_front_face:
67 info->uses_frontface = 1;
68 break;
69 case nir_intrinsic_load_instance_id:
70 info->uses_instanceid = 1;
71 break;
72 case nir_intrinsic_load_vertex_id:
73 info->uses_vertexid = 1;
74 break;
75 case nir_intrinsic_load_vertex_id_zero_base:
76 info->uses_vertexid_nobase = 1;
77 break;
78 case nir_intrinsic_load_base_vertex:
79 info->uses_basevertex = 1;
80 break;
81 case nir_intrinsic_load_primitive_id:
82 info->uses_primid = 1;
83 break;
84 case nir_intrinsic_image_store:
85 case nir_intrinsic_image_atomic_add:
86 case nir_intrinsic_image_atomic_min:
87 case nir_intrinsic_image_atomic_max:
88 case nir_intrinsic_image_atomic_and:
89 case nir_intrinsic_image_atomic_or:
90 case nir_intrinsic_image_atomic_xor:
91 case nir_intrinsic_image_atomic_exchange:
92 case nir_intrinsic_image_atomic_comp_swap:
93 case nir_intrinsic_store_ssbo:
94 case nir_intrinsic_ssbo_atomic_add:
95 case nir_intrinsic_ssbo_atomic_imin:
96 case nir_intrinsic_ssbo_atomic_umin:
97 case nir_intrinsic_ssbo_atomic_imax:
98 case nir_intrinsic_ssbo_atomic_umax:
99 case nir_intrinsic_ssbo_atomic_and:
100 case nir_intrinsic_ssbo_atomic_or:
101 case nir_intrinsic_ssbo_atomic_xor:
102 case nir_intrinsic_ssbo_atomic_exchange:
103 case nir_intrinsic_ssbo_atomic_comp_swap:
104 info->writes_memory = true;
105 break;
106 default:
107 break;
108 }
109 }
110 }
111
112 void si_nir_scan_shader(const struct nir_shader *nir,
113 struct tgsi_shader_info *info)
114 {
115 nir_function *func;
116 unsigned i;
117
118 assert(nir->stage == MESA_SHADER_VERTEX ||
119 nir->stage == MESA_SHADER_FRAGMENT);
120
121 info->processor = pipe_shader_type_from_mesa(nir->stage);
122 info->num_tokens = 2; /* indicate that the shader is non-empty */
123 info->num_instructions = 2;
124
125 info->num_inputs = nir->num_inputs;
126 info->num_outputs = nir->num_outputs;
127
128 i = 0;
129 nir_foreach_variable(variable, &nir->inputs) {
130 unsigned semantic_name, semantic_index;
131 unsigned attrib_count = glsl_count_attribute_slots(variable->type,
132 nir->stage == MESA_SHADER_VERTEX);
133
134 assert(attrib_count == 1 && "not implemented");
135
136 /* Vertex shader inputs don't have semantics. The state
137 * tracker has already mapped them to attributes via
138 * variable->data.driver_location.
139 */
140 if (nir->stage == MESA_SHADER_VERTEX)
141 continue;
142
143 /* Fragment shader position is a system value. */
144 if (nir->stage == MESA_SHADER_FRAGMENT &&
145 variable->data.location == VARYING_SLOT_POS) {
146 if (variable->data.pixel_center_integer)
147 info->properties[TGSI_PROPERTY_FS_COORD_PIXEL_CENTER] =
148 TGSI_FS_COORD_PIXEL_CENTER_INTEGER;
149 continue;
150 }
151
152 tgsi_get_gl_varying_semantic(variable->data.location, true,
153 &semantic_name, &semantic_index);
154
155 info->input_semantic_name[i] = semantic_name;
156 info->input_semantic_index[i] = semantic_index;
157
158 if (variable->data.sample)
159 info->input_interpolate_loc[i] = TGSI_INTERPOLATE_LOC_SAMPLE;
160 else if (variable->data.centroid)
161 info->input_interpolate_loc[i] = TGSI_INTERPOLATE_LOC_CENTROID;
162 else
163 info->input_interpolate_loc[i] = TGSI_INTERPOLATE_LOC_CENTER;
164
165 enum glsl_base_type base_type =
166 glsl_get_base_type(glsl_without_array(variable->type));
167
168 switch (variable->data.interpolation) {
169 case INTERP_MODE_NONE:
170 if (glsl_base_type_is_integer(base_type)) {
171 info->input_interpolate[i] = TGSI_INTERPOLATE_CONSTANT;
172 break;
173 }
174
175 if (semantic_name == TGSI_SEMANTIC_COLOR) {
176 info->input_interpolate[i] = TGSI_INTERPOLATE_COLOR;
177 goto persp_locations;
178 }
179 /* fall-through */
180 case INTERP_MODE_SMOOTH:
181 assert(!glsl_base_type_is_integer(base_type));
182
183 info->input_interpolate[i] = TGSI_INTERPOLATE_PERSPECTIVE;
184
185 persp_locations:
186 if (variable->data.sample)
187 info->uses_persp_sample = true;
188 else if (variable->data.centroid)
189 info->uses_persp_centroid = true;
190 else
191 info->uses_persp_center = true;
192 break;
193
194 case INTERP_MODE_NOPERSPECTIVE:
195 assert(!glsl_base_type_is_integer(base_type));
196
197 info->input_interpolate[i] = TGSI_INTERPOLATE_LINEAR;
198
199 if (variable->data.sample)
200 info->uses_linear_sample = true;
201 else if (variable->data.centroid)
202 info->uses_linear_centroid = true;
203 else
204 info->uses_linear_center = true;
205 break;
206
207 case INTERP_MODE_FLAT:
208 info->input_interpolate[i] = TGSI_INTERPOLATE_CONSTANT;
209 break;
210 }
211
212 /* TODO make this more precise */
213 if (variable->data.location == VARYING_SLOT_COL0)
214 info->colors_read |= 0x0f;
215 else if (variable->data.location == VARYING_SLOT_COL1)
216 info->colors_read |= 0xf0;
217
218 i++;
219 }
220
221 i = 0;
222 nir_foreach_variable(variable, &nir->outputs) {
223 unsigned semantic_name, semantic_index;
224
225 if (nir->stage == MESA_SHADER_FRAGMENT) {
226 tgsi_get_gl_frag_result_semantic(variable->data.location,
227 &semantic_name, &semantic_index);
228 } else {
229 tgsi_get_gl_varying_semantic(variable->data.location, true,
230 &semantic_name, &semantic_index);
231 }
232
233 info->output_semantic_name[i] = semantic_name;
234 info->output_semantic_index[i] = semantic_index;
235 info->output_usagemask[i] = TGSI_WRITEMASK_XYZW;
236
237 switch (semantic_name) {
238 case TGSI_SEMANTIC_PRIMID:
239 info->writes_primid = true;
240 break;
241 case TGSI_SEMANTIC_VIEWPORT_INDEX:
242 info->writes_viewport_index = true;
243 break;
244 case TGSI_SEMANTIC_LAYER:
245 info->writes_layer = true;
246 break;
247 case TGSI_SEMANTIC_PSIZE:
248 info->writes_psize = true;
249 break;
250 case TGSI_SEMANTIC_CLIPVERTEX:
251 info->writes_clipvertex = true;
252 break;
253 case TGSI_SEMANTIC_COLOR:
254 info->colors_written |= 1 << semantic_index;
255 break;
256 case TGSI_SEMANTIC_STENCIL:
257 info->writes_stencil = true;
258 break;
259 case TGSI_SEMANTIC_SAMPLEMASK:
260 info->writes_samplemask = true;
261 break;
262 case TGSI_SEMANTIC_EDGEFLAG:
263 info->writes_edgeflag = true;
264 break;
265 case TGSI_SEMANTIC_POSITION:
266 if (info->processor == PIPE_SHADER_FRAGMENT)
267 info->writes_z = true;
268 else
269 info->writes_position = true;
270 break;
271 }
272
273 i++;
274 }
275
276 nir_foreach_variable(variable, &nir->uniforms) {
277 const struct glsl_type *type = variable->type;
278 enum glsl_base_type base_type =
279 glsl_get_base_type(glsl_without_array(type));
280 unsigned aoa_size = MAX2(1, glsl_get_aoa_size(type));
281
282 /* We rely on the fact that nir_lower_samplers_as_deref has
283 * eliminated struct dereferences.
284 */
285 if (base_type == GLSL_TYPE_SAMPLER)
286 info->samplers_declared |=
287 u_bit_consecutive(variable->data.binding, aoa_size);
288 else if (base_type == GLSL_TYPE_IMAGE)
289 info->images_declared |=
290 u_bit_consecutive(variable->data.binding, aoa_size);
291 }
292
293 info->num_written_clipdistance = nir->info.clip_distance_array_size;
294 info->num_written_culldistance = nir->info.cull_distance_array_size;
295 info->clipdist_writemask = u_bit_consecutive(0, info->num_written_clipdistance);
296 info->culldist_writemask = u_bit_consecutive(info->num_written_clipdistance,
297 info->num_written_culldistance);
298
299 if (info->processor == PIPE_SHADER_FRAGMENT)
300 info->uses_kill = nir->info.fs.uses_discard;
301
302 /* TODO make this more accurate */
303 info->const_buffers_declared = u_bit_consecutive(0, SI_NUM_CONST_BUFFERS);
304 info->shader_buffers_declared = u_bit_consecutive(0, SI_NUM_SHADER_BUFFERS);
305
306 func = (struct nir_function *)exec_list_get_head_const(&nir->functions);
307 nir_foreach_block(block, func->impl) {
308 nir_foreach_instr(instr, block)
309 scan_instruction(info, instr);
310 }
311 }
312