radv: handle exporting view index to fragment shader. (v1.1)
[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 if (nir->info.stage == MESA_SHADER_FRAGMENT)
94 info->ps.layer_input = true;
95 break;
96 case nir_intrinsic_load_invocation_id:
97 info->uses_invocation_id = true;
98 break;
99 case nir_intrinsic_load_primitive_id:
100 info->uses_prim_id = true;
101 break;
102 case nir_intrinsic_load_push_constant:
103 info->loads_push_constants = true;
104 break;
105 case nir_intrinsic_vulkan_resource_index:
106 info->desc_set_used_mask |= (1 << nir_intrinsic_desc_set(instr));
107 break;
108 case nir_intrinsic_image_load:
109 case nir_intrinsic_image_store:
110 case nir_intrinsic_image_atomic_add:
111 case nir_intrinsic_image_atomic_min:
112 case nir_intrinsic_image_atomic_max:
113 case nir_intrinsic_image_atomic_and:
114 case nir_intrinsic_image_atomic_or:
115 case nir_intrinsic_image_atomic_xor:
116 case nir_intrinsic_image_atomic_exchange:
117 case nir_intrinsic_image_atomic_comp_swap:
118 case nir_intrinsic_image_size: {
119 const struct glsl_type *type = instr->variables[0]->var->type;
120 if(instr->variables[0]->deref.child)
121 type = instr->variables[0]->deref.child->type;
122
123 enum glsl_sampler_dim dim = glsl_get_sampler_dim(type);
124 if (dim == GLSL_SAMPLER_DIM_SUBPASS ||
125 dim == GLSL_SAMPLER_DIM_SUBPASS_MS)
126 info->ps.uses_input_attachments = true;
127 mark_sampler_desc(instr->variables[0]->var, info);
128
129 if (nir_intrinsic_image_store ||
130 nir_intrinsic_image_atomic_add ||
131 nir_intrinsic_image_atomic_min ||
132 nir_intrinsic_image_atomic_max ||
133 nir_intrinsic_image_atomic_and ||
134 nir_intrinsic_image_atomic_or ||
135 nir_intrinsic_image_atomic_xor ||
136 nir_intrinsic_image_atomic_exchange ||
137 nir_intrinsic_image_atomic_comp_swap) {
138 if (nir->info.stage == MESA_SHADER_FRAGMENT)
139 info->ps.writes_memory = true;
140 }
141 break;
142 }
143 case nir_intrinsic_store_ssbo:
144 case nir_intrinsic_ssbo_atomic_add:
145 case nir_intrinsic_ssbo_atomic_imin:
146 case nir_intrinsic_ssbo_atomic_umin:
147 case nir_intrinsic_ssbo_atomic_imax:
148 case nir_intrinsic_ssbo_atomic_umax:
149 case nir_intrinsic_ssbo_atomic_and:
150 case nir_intrinsic_ssbo_atomic_or:
151 case nir_intrinsic_ssbo_atomic_xor:
152 case nir_intrinsic_ssbo_atomic_exchange:
153 case nir_intrinsic_ssbo_atomic_comp_swap:
154 if (nir->info.stage == MESA_SHADER_FRAGMENT)
155 info->ps.writes_memory = true;
156 break;
157 case nir_intrinsic_load_var:
158 if (nir->info.stage == MESA_SHADER_VERTEX) {
159 nir_deref_var *dvar = instr->variables[0];
160 nir_variable *var = dvar->var;
161
162 if (var->data.mode == nir_var_shader_in) {
163 unsigned idx = var->data.location;
164 uint8_t mask =
165 nir_ssa_def_components_read(&instr->dest.ssa) << var->data.location_frac;
166 info->vs.input_usage_mask[idx] |= mask;
167 }
168 }
169 break;
170 case nir_intrinsic_store_var: {
171 nir_deref_var *dvar = instr->variables[0];
172 nir_variable *var = dvar->var;
173
174 if (var->data.mode == nir_var_shader_out) {
175 unsigned idx = var->data.location;
176 unsigned comp = var->data.location_frac;
177
178 if (nir->info.stage == MESA_SHADER_VERTEX) {
179 info->vs.output_usage_mask[idx] |=
180 instr->const_index[0] << comp;
181 } else if (nir->info.stage == MESA_SHADER_TESS_EVAL) {
182 info->tes.output_usage_mask[idx] |=
183 instr->const_index[0] << comp;
184 } else if (nir->info.stage == MESA_SHADER_TESS_CTRL) {
185 unsigned param = shader_io_get_unique_index(idx);
186 const struct glsl_type *type = var->type;
187 if (!var->data.patch)
188 type = glsl_get_array_element(var->type);
189 unsigned slots =
190 var->data.compact ? DIV_ROUND_UP(glsl_get_length(type), 4)
191 : glsl_count_attribute_slots(type, false);
192 if (idx == VARYING_SLOT_CLIP_DIST0)
193 slots = (nir->info.clip_distance_array_size + nir->info.cull_distance_array_size > 4) ? 2 : 1;
194 mark_tess_output(info, var->data.patch, param, slots);
195 }
196 }
197 break;
198 }
199 default:
200 break;
201 }
202 }
203
204 static void
205 gather_tex_info(const nir_shader *nir, const nir_tex_instr *instr,
206 struct radv_shader_info *info)
207 {
208 if (instr->sampler)
209 mark_sampler_desc(instr->sampler->var, info);
210 if (instr->texture)
211 mark_sampler_desc(instr->texture->var, info);
212 }
213
214 static void
215 gather_info_block(const nir_shader *nir, const nir_block *block,
216 struct radv_shader_info *info)
217 {
218 nir_foreach_instr(instr, block) {
219 switch (instr->type) {
220 case nir_instr_type_intrinsic:
221 gather_intrinsic_info(nir, nir_instr_as_intrinsic(instr), info);
222 break;
223 case nir_instr_type_tex:
224 gather_tex_info(nir, nir_instr_as_tex(instr), info);
225 break;
226 default:
227 break;
228 }
229 }
230 }
231
232 static void
233 gather_info_input_decl_vs(const nir_shader *nir, const nir_variable *var,
234 struct radv_shader_info *info)
235 {
236 int idx = var->data.location;
237
238 if (idx >= VERT_ATTRIB_GENERIC0 && idx <= VERT_ATTRIB_GENERIC15)
239 info->vs.has_vertex_buffers = true;
240 }
241
242 static void
243 gather_info_input_decl_ps(const nir_shader *nir, const nir_variable *var,
244 struct radv_shader_info *info)
245 {
246 const struct glsl_type *type = glsl_without_array(var->type);
247 int idx = var->data.location;
248
249 switch (idx) {
250 case VARYING_SLOT_PNTC:
251 info->ps.has_pcoord = true;
252 break;
253 case VARYING_SLOT_PRIMITIVE_ID:
254 info->ps.prim_id_input = true;
255 break;
256 case VARYING_SLOT_LAYER:
257 info->ps.layer_input = true;
258 break;
259 default:
260 break;
261 }
262
263 if (glsl_get_base_type(type) == GLSL_TYPE_FLOAT) {
264 if (var->data.sample)
265 info->ps.force_persample = true;
266 }
267 }
268
269 static void
270 gather_info_input_decl(const nir_shader *nir, const nir_variable *var,
271 struct radv_shader_info *info)
272 {
273 switch (nir->info.stage) {
274 case MESA_SHADER_VERTEX:
275 gather_info_input_decl_vs(nir, var, info);
276 break;
277 case MESA_SHADER_FRAGMENT:
278 gather_info_input_decl_ps(nir, var, info);
279 break;
280 default:
281 break;
282 }
283 }
284
285 static void
286 gather_info_output_decl_ls(const nir_shader *nir, const nir_variable *var,
287 struct radv_shader_info *info)
288 {
289 int idx = var->data.location;
290 unsigned param = shader_io_get_unique_index(idx);
291 int num_slots = glsl_count_attribute_slots(var->type, false);
292 if (idx == VARYING_SLOT_CLIP_DIST0)
293 num_slots = (nir->info.clip_distance_array_size + nir->info.cull_distance_array_size > 4) ? 2 : 1;
294 mark_ls_output(info, param, num_slots);
295 }
296
297 static void
298 gather_info_output_decl_ps(const nir_shader *nir, const nir_variable *var,
299 struct radv_shader_info *info)
300 {
301 int idx = var->data.location;
302
303 switch (idx) {
304 case FRAG_RESULT_DEPTH:
305 info->ps.writes_z = true;
306 break;
307 case FRAG_RESULT_STENCIL:
308 info->ps.writes_stencil = true;
309 break;
310 case FRAG_RESULT_SAMPLE_MASK:
311 info->ps.writes_sample_mask = true;
312 break;
313 default:
314 break;
315 }
316 }
317
318 static void
319 gather_info_output_decl(const nir_shader *nir, const nir_variable *var,
320 struct radv_shader_info *info,
321 const struct radv_nir_compiler_options *options)
322 {
323 switch (nir->info.stage) {
324 case MESA_SHADER_FRAGMENT:
325 gather_info_output_decl_ps(nir, var, info);
326 break;
327 case MESA_SHADER_VERTEX:
328 if (options->key.vs.as_ls)
329 gather_info_output_decl_ls(nir, var, info);
330 break;
331 default:
332 break;
333 }
334 }
335
336 void
337 radv_nir_shader_info_pass(const struct nir_shader *nir,
338 const struct radv_nir_compiler_options *options,
339 struct radv_shader_info *info)
340 {
341 struct nir_function *func =
342 (struct nir_function *)exec_list_get_head_const(&nir->functions);
343
344 if (options->layout->dynamic_offset_count)
345 info->loads_push_constants = true;
346
347 nir_foreach_variable(variable, &nir->inputs)
348 gather_info_input_decl(nir, variable, info);
349
350 nir_foreach_block(block, func->impl) {
351 gather_info_block(nir, block, info);
352 }
353
354 nir_foreach_variable(variable, &nir->outputs)
355 gather_info_output_decl(nir, variable, info, options);
356 }