radv/shader_info: start gathering tess output info (v2)
[mesa.git] / src / amd / vulkan / radv_shader_info.c
1 /*
2 * Copyright © 2017 Red Hat
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 #include "radv_private.h"
24 #include "radv_shader.h"
25 #include "nir/nir.h"
26
27 static void mark_sampler_desc(const nir_variable *var,
28 struct radv_shader_info *info)
29 {
30 info->desc_set_used_mask |= (1 << var->data.descriptor_set);
31 }
32
33 static void mark_ls_output(struct radv_shader_info *info,
34 uint32_t param, int num_slots)
35 {
36 uint64_t mask = (1ull << num_slots) - 1ull;
37 info->vs.ls_outputs_written |= (mask << param);
38 }
39
40 static void mark_tess_output(struct radv_shader_info *info,
41 bool is_patch, uint32_t param, int num_slots)
42 {
43 uint64_t mask = (1ull << num_slots) - 1ull;
44 if (is_patch)
45 info->tcs.patch_outputs_written |= (mask << param);
46 else
47 info->tcs.outputs_written |= (mask << param);
48 }
49
50 static void
51 gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr,
52 struct radv_shader_info *info)
53 {
54 switch (instr->intrinsic) {
55 case nir_intrinsic_interp_var_at_sample:
56 info->ps.needs_sample_positions = true;
57 break;
58 case nir_intrinsic_load_draw_id:
59 info->vs.needs_draw_id = true;
60 break;
61 case nir_intrinsic_load_instance_id:
62 info->vs.needs_instance_id = true;
63 break;
64 case nir_intrinsic_load_num_work_groups:
65 info->cs.uses_grid_size = true;
66 break;
67 case nir_intrinsic_load_local_invocation_id:
68 case nir_intrinsic_load_work_group_id: {
69 unsigned mask = nir_ssa_def_components_read(&instr->dest.ssa);
70 while (mask) {
71 unsigned i = u_bit_scan(&mask);
72
73 if (instr->intrinsic == nir_intrinsic_load_work_group_id)
74 info->cs.uses_block_id[i] = true;
75 else
76 info->cs.uses_thread_id[i] = true;
77 }
78 break;
79 }
80 case nir_intrinsic_load_local_invocation_index:
81 case nir_intrinsic_load_subgroup_id:
82 case nir_intrinsic_load_num_subgroups:
83 info->cs.uses_local_invocation_idx = true;
84 break;
85 case nir_intrinsic_load_sample_id:
86 info->ps.force_persample = true;
87 break;
88 case nir_intrinsic_load_sample_pos:
89 info->ps.force_persample = true;
90 break;
91 case nir_intrinsic_load_view_index:
92 info->needs_multiview_view_index = true;
93 break;
94 case nir_intrinsic_load_invocation_id:
95 info->uses_invocation_id = true;
96 break;
97 case nir_intrinsic_load_primitive_id:
98 info->uses_prim_id = true;
99 break;
100 case nir_intrinsic_load_push_constant:
101 info->loads_push_constants = true;
102 break;
103 case nir_intrinsic_vulkan_resource_index:
104 info->desc_set_used_mask |= (1 << nir_intrinsic_desc_set(instr));
105 break;
106 case nir_intrinsic_image_load:
107 case nir_intrinsic_image_store:
108 case nir_intrinsic_image_atomic_add:
109 case nir_intrinsic_image_atomic_min:
110 case nir_intrinsic_image_atomic_max:
111 case nir_intrinsic_image_atomic_and:
112 case nir_intrinsic_image_atomic_or:
113 case nir_intrinsic_image_atomic_xor:
114 case nir_intrinsic_image_atomic_exchange:
115 case nir_intrinsic_image_atomic_comp_swap:
116 case nir_intrinsic_image_size: {
117 const struct glsl_type *type = instr->variables[0]->var->type;
118 if(instr->variables[0]->deref.child)
119 type = instr->variables[0]->deref.child->type;
120
121 enum glsl_sampler_dim dim = glsl_get_sampler_dim(type);
122 if (dim == GLSL_SAMPLER_DIM_SUBPASS ||
123 dim == GLSL_SAMPLER_DIM_SUBPASS_MS)
124 info->ps.uses_input_attachments = true;
125 mark_sampler_desc(instr->variables[0]->var, info);
126
127 if (nir_intrinsic_image_store ||
128 nir_intrinsic_image_atomic_add ||
129 nir_intrinsic_image_atomic_min ||
130 nir_intrinsic_image_atomic_max ||
131 nir_intrinsic_image_atomic_and ||
132 nir_intrinsic_image_atomic_or ||
133 nir_intrinsic_image_atomic_xor ||
134 nir_intrinsic_image_atomic_exchange ||
135 nir_intrinsic_image_atomic_comp_swap) {
136 if (nir->info.stage == MESA_SHADER_FRAGMENT)
137 info->ps.writes_memory = true;
138 }
139 break;
140 }
141 case nir_intrinsic_store_ssbo:
142 case nir_intrinsic_ssbo_atomic_add:
143 case nir_intrinsic_ssbo_atomic_imin:
144 case nir_intrinsic_ssbo_atomic_umin:
145 case nir_intrinsic_ssbo_atomic_imax:
146 case nir_intrinsic_ssbo_atomic_umax:
147 case nir_intrinsic_ssbo_atomic_and:
148 case nir_intrinsic_ssbo_atomic_or:
149 case nir_intrinsic_ssbo_atomic_xor:
150 case nir_intrinsic_ssbo_atomic_exchange:
151 case nir_intrinsic_ssbo_atomic_comp_swap:
152 if (nir->info.stage == MESA_SHADER_FRAGMENT)
153 info->ps.writes_memory = true;
154 break;
155 case nir_intrinsic_load_var:
156 if (nir->info.stage == MESA_SHADER_VERTEX) {
157 nir_deref_var *dvar = instr->variables[0];
158 nir_variable *var = dvar->var;
159
160 if (var->data.mode == nir_var_shader_in) {
161 unsigned idx = var->data.location;
162 uint8_t mask =
163 nir_ssa_def_components_read(&instr->dest.ssa) << var->data.location_frac;
164 info->vs.input_usage_mask[idx] |= mask;
165 }
166 }
167 break;
168 case nir_intrinsic_store_var: {
169 nir_deref_var *dvar = instr->variables[0];
170 nir_variable *var = dvar->var;
171
172 if (var->data.mode == nir_var_shader_out) {
173 unsigned idx = var->data.location;
174 unsigned comp = var->data.location_frac;
175
176 if (nir->info.stage == MESA_SHADER_VERTEX) {
177 info->vs.output_usage_mask[idx] |=
178 instr->const_index[0] << comp;
179 } else if (nir->info.stage == MESA_SHADER_TESS_EVAL) {
180 info->tes.output_usage_mask[idx] |=
181 instr->const_index[0] << comp;
182 } else if (nir->info.stage == MESA_SHADER_TESS_CTRL) {
183 unsigned param = shader_io_get_unique_index(idx);
184 const struct glsl_type *type = var->type;
185 if (!var->data.patch)
186 type = glsl_get_array_element(var->type);
187 unsigned slots =
188 var->data.compact ? DIV_ROUND_UP(glsl_get_length(type), 4)
189 : glsl_count_attribute_slots(type, false);
190 if (idx == VARYING_SLOT_CLIP_DIST0)
191 slots = (nir->info.clip_distance_array_size + nir->info.cull_distance_array_size > 4) ? 2 : 1;
192 mark_tess_output(info, var->data.patch, param, slots);
193 }
194 }
195 break;
196 }
197 default:
198 break;
199 }
200 }
201
202 static void
203 gather_tex_info(const nir_shader *nir, const nir_tex_instr *instr,
204 struct radv_shader_info *info)
205 {
206 if (instr->sampler)
207 mark_sampler_desc(instr->sampler->var, info);
208 if (instr->texture)
209 mark_sampler_desc(instr->texture->var, info);
210 }
211
212 static void
213 gather_info_block(const nir_shader *nir, const nir_block *block,
214 struct radv_shader_info *info)
215 {
216 nir_foreach_instr(instr, block) {
217 switch (instr->type) {
218 case nir_instr_type_intrinsic:
219 gather_intrinsic_info(nir, nir_instr_as_intrinsic(instr), info);
220 break;
221 case nir_instr_type_tex:
222 gather_tex_info(nir, nir_instr_as_tex(instr), info);
223 break;
224 default:
225 break;
226 }
227 }
228 }
229
230 static void
231 gather_info_input_decl_vs(const nir_shader *nir, const nir_variable *var,
232 struct radv_shader_info *info)
233 {
234 int idx = var->data.location;
235
236 if (idx >= VERT_ATTRIB_GENERIC0 && idx <= VERT_ATTRIB_GENERIC15)
237 info->vs.has_vertex_buffers = true;
238 }
239
240 static void
241 gather_info_input_decl_ps(const nir_shader *nir, const nir_variable *var,
242 struct radv_shader_info *info)
243 {
244 const struct glsl_type *type = glsl_without_array(var->type);
245 int idx = var->data.location;
246
247 switch (idx) {
248 case VARYING_SLOT_PNTC:
249 info->ps.has_pcoord = true;
250 break;
251 case VARYING_SLOT_PRIMITIVE_ID:
252 info->ps.prim_id_input = true;
253 break;
254 case VARYING_SLOT_LAYER:
255 info->ps.layer_input = true;
256 break;
257 default:
258 break;
259 }
260
261 if (glsl_get_base_type(type) == GLSL_TYPE_FLOAT) {
262 if (var->data.sample)
263 info->ps.force_persample = true;
264 }
265 }
266
267 static void
268 gather_info_input_decl(const nir_shader *nir, const nir_variable *var,
269 struct radv_shader_info *info)
270 {
271 switch (nir->info.stage) {
272 case MESA_SHADER_VERTEX:
273 gather_info_input_decl_vs(nir, var, info);
274 break;
275 case MESA_SHADER_FRAGMENT:
276 gather_info_input_decl_ps(nir, var, info);
277 break;
278 default:
279 break;
280 }
281 }
282
283 static void
284 gather_info_output_decl_ls(const nir_shader *nir, const nir_variable *var,
285 struct radv_shader_info *info)
286 {
287 int idx = var->data.location;
288 unsigned param = shader_io_get_unique_index(idx);
289 int num_slots = glsl_count_attribute_slots(var->type, false);
290 if (idx == VARYING_SLOT_CLIP_DIST0)
291 num_slots = (nir->info.clip_distance_array_size + nir->info.cull_distance_array_size > 4) ? 2 : 1;
292 mark_ls_output(info, param, num_slots);
293 }
294
295 static void
296 gather_info_output_decl_ps(const nir_shader *nir, const nir_variable *var,
297 struct radv_shader_info *info)
298 {
299 int idx = var->data.location;
300
301 switch (idx) {
302 case FRAG_RESULT_DEPTH:
303 info->ps.writes_z = true;
304 break;
305 case FRAG_RESULT_STENCIL:
306 info->ps.writes_stencil = true;
307 break;
308 case FRAG_RESULT_SAMPLE_MASK:
309 info->ps.writes_sample_mask = true;
310 break;
311 default:
312 break;
313 }
314 }
315
316 static void
317 gather_info_output_decl(const nir_shader *nir, const nir_variable *var,
318 struct radv_shader_info *info,
319 const struct radv_nir_compiler_options *options)
320 {
321 switch (nir->info.stage) {
322 case MESA_SHADER_FRAGMENT:
323 gather_info_output_decl_ps(nir, var, info);
324 break;
325 case MESA_SHADER_VERTEX:
326 if (options->key.vs.as_ls)
327 gather_info_output_decl_ls(nir, var, info);
328 break;
329 default:
330 break;
331 }
332 }
333
334 void
335 radv_nir_shader_info_pass(const struct nir_shader *nir,
336 const struct radv_nir_compiler_options *options,
337 struct radv_shader_info *info)
338 {
339 struct nir_function *func =
340 (struct nir_function *)exec_list_get_head_const(&nir->functions);
341
342 if (options->layout->dynamic_offset_count)
343 info->loads_push_constants = true;
344
345 nir_foreach_variable(variable, &nir->inputs)
346 gather_info_input_decl(nir, variable, info);
347
348 nir_foreach_block(block, func->impl) {
349 gather_info_block(nir, block, info);
350 }
351
352 nir_foreach_variable(variable, &nir->outputs)
353 gather_info_output_decl(nir, variable, info, options);
354 }