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