radv: Add logic for multisample format descriptions.
[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 #include "nir/nir_deref.h"
27 #include "nir/nir_xfb_info.h"
28
29 static void mark_sampler_desc(const nir_variable *var,
30 struct radv_shader_info *info)
31 {
32 info->desc_set_used_mask |= (1 << var->data.descriptor_set);
33 }
34
35 static void mark_ls_output(struct radv_shader_info *info,
36 uint32_t param, int num_slots)
37 {
38 uint64_t mask = (1ull << num_slots) - 1ull;
39 info->vs.ls_outputs_written |= (mask << param);
40 }
41
42 static void mark_tess_output(struct radv_shader_info *info,
43 bool is_patch, uint32_t param, int num_slots)
44 {
45 uint64_t mask = (1ull << num_slots) - 1ull;
46 if (is_patch)
47 info->tcs.patch_outputs_written |= (mask << param);
48 else
49 info->tcs.outputs_written |= (mask << param);
50 }
51
52 static void
53 get_deref_offset(nir_deref_instr *instr,
54 unsigned *const_out)
55 {
56 nir_variable *var = nir_deref_instr_get_variable(instr);
57 nir_deref_path path;
58 unsigned idx_lvl = 1;
59
60 if (var->data.compact) {
61 assert(instr->deref_type == nir_deref_type_array);
62 *const_out = nir_src_as_uint(instr->arr.index);
63 return;
64 }
65
66 nir_deref_path_init(&path, instr, NULL);
67
68 uint32_t const_offset = 0;
69
70 for (; path.path[idx_lvl]; ++idx_lvl) {
71 const struct glsl_type *parent_type = path.path[idx_lvl - 1]->type;
72 if (path.path[idx_lvl]->deref_type == nir_deref_type_struct) {
73 unsigned index = path.path[idx_lvl]->strct.index;
74
75 for (unsigned i = 0; i < index; i++) {
76 const struct glsl_type *ft = glsl_get_struct_field(parent_type, i);
77 const_offset += glsl_count_attribute_slots(ft, false);
78 }
79 } else if(path.path[idx_lvl]->deref_type == nir_deref_type_array) {
80 unsigned size = glsl_count_attribute_slots(path.path[idx_lvl]->type, false);
81 if (nir_src_is_const(path.path[idx_lvl]->arr.index))
82 const_offset += nir_src_as_uint(path.path[idx_lvl]->arr.index) * size;
83 } else
84 unreachable("Uhandled deref type in get_deref_instr_offset");
85 }
86
87 *const_out = const_offset;
88
89 nir_deref_path_finish(&path);
90 }
91
92 static void
93 gather_intrinsic_load_deref_info(const nir_shader *nir,
94 const nir_intrinsic_instr *instr,
95 struct radv_shader_info *info)
96 {
97 switch (nir->info.stage) {
98 case MESA_SHADER_VERTEX: {
99 nir_variable *var = nir_deref_instr_get_variable(nir_instr_as_deref(instr->src[0].ssa->parent_instr));
100
101 if (var && var->data.mode == nir_var_shader_in) {
102 unsigned idx = var->data.location;
103 uint8_t mask = nir_ssa_def_components_read(&instr->dest.ssa);
104
105 info->vs.input_usage_mask[idx] |=
106 mask << var->data.location_frac;
107 }
108 break;
109 }
110 default:
111 break;
112 }
113 }
114
115 static void
116 set_output_usage_mask(const nir_shader *nir, const nir_intrinsic_instr *instr,
117 uint8_t *output_usage_mask)
118 {
119 nir_deref_instr *deref_instr =
120 nir_instr_as_deref(instr->src[0].ssa->parent_instr);
121 nir_variable *var = nir_deref_instr_get_variable(deref_instr);
122 unsigned attrib_count = glsl_count_attribute_slots(var->type, false);
123 unsigned idx = var->data.location;
124 unsigned comp = var->data.location_frac;
125 unsigned const_offset = 0;
126
127 get_deref_offset(deref_instr, &const_offset);
128
129 if (var->data.compact) {
130 const_offset += comp;
131 output_usage_mask[idx + const_offset / 4] |= 1 << (const_offset % 4);
132 return;
133 }
134
135 for (unsigned i = 0; i < attrib_count; i++) {
136 output_usage_mask[idx + i + const_offset] |=
137 instr->const_index[0] << comp;
138 }
139 }
140
141 static void
142 gather_intrinsic_store_deref_info(const nir_shader *nir,
143 const nir_intrinsic_instr *instr,
144 struct radv_shader_info *info)
145 {
146 nir_variable *var = nir_deref_instr_get_variable(nir_instr_as_deref(instr->src[0].ssa->parent_instr));
147
148 if (var && var->data.mode == nir_var_shader_out) {
149 unsigned idx = var->data.location;
150
151 switch (nir->info.stage) {
152 case MESA_SHADER_VERTEX:
153 set_output_usage_mask(nir, instr,
154 info->vs.output_usage_mask);
155 break;
156 case MESA_SHADER_GEOMETRY:
157 set_output_usage_mask(nir, instr,
158 info->gs.output_usage_mask);
159 break;
160 case MESA_SHADER_TESS_EVAL:
161 set_output_usage_mask(nir, instr,
162 info->tes.output_usage_mask);
163 break;
164 case MESA_SHADER_TESS_CTRL: {
165 unsigned param = shader_io_get_unique_index(idx);
166 const struct glsl_type *type = var->type;
167
168 if (!var->data.patch)
169 type = glsl_get_array_element(var->type);
170
171 unsigned slots =
172 var->data.compact ? DIV_ROUND_UP(var->data.location_frac + glsl_get_length(type), 4)
173 : glsl_count_attribute_slots(type, false);
174
175 mark_tess_output(info, var->data.patch, param, slots);
176 break;
177 }
178 default:
179 break;
180 }
181 }
182 }
183
184 static void
185 gather_push_constant_info(const nir_shader *nir,
186 const nir_intrinsic_instr *instr,
187 struct radv_shader_info *info)
188 {
189 int base = nir_intrinsic_base(instr);
190
191 if (!nir_src_is_const(instr->src[0])) {
192 info->has_indirect_push_constants = true;
193 } else {
194 uint32_t min = base + nir_src_as_uint(instr->src[0]);
195 uint32_t max = min + instr->num_components * 4;
196
197 info->max_push_constant_used =
198 MAX2(max, info->max_push_constant_used);
199 info->min_push_constant_used =
200 MIN2(min, info->min_push_constant_used);
201 }
202
203 if (instr->dest.ssa.bit_size != 32)
204 info->has_only_32bit_push_constants = false;
205
206 info->loads_push_constants = true;
207 }
208
209 static void
210 gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr,
211 struct radv_shader_info *info)
212 {
213 switch (instr->intrinsic) {
214 case nir_intrinsic_interp_deref_at_sample:
215 info->ps.needs_sample_positions = true;
216 break;
217 case nir_intrinsic_load_draw_id:
218 info->vs.needs_draw_id = true;
219 break;
220 case nir_intrinsic_load_instance_id:
221 info->vs.needs_instance_id = true;
222 break;
223 case nir_intrinsic_load_num_work_groups:
224 info->cs.uses_grid_size = true;
225 break;
226 case nir_intrinsic_load_local_invocation_id:
227 case nir_intrinsic_load_work_group_id: {
228 unsigned mask = nir_ssa_def_components_read(&instr->dest.ssa);
229 while (mask) {
230 unsigned i = u_bit_scan(&mask);
231
232 if (instr->intrinsic == nir_intrinsic_load_work_group_id)
233 info->cs.uses_block_id[i] = true;
234 else
235 info->cs.uses_thread_id[i] = true;
236 }
237 break;
238 }
239 case nir_intrinsic_load_local_invocation_index:
240 case nir_intrinsic_load_subgroup_id:
241 case nir_intrinsic_load_num_subgroups:
242 info->cs.uses_local_invocation_idx = true;
243 break;
244 case nir_intrinsic_load_sample_id:
245 info->ps.force_persample = true;
246 break;
247 case nir_intrinsic_load_sample_pos:
248 info->ps.force_persample = true;
249 break;
250 case nir_intrinsic_load_view_index:
251 info->needs_multiview_view_index = true;
252 if (nir->info.stage == MESA_SHADER_FRAGMENT)
253 info->ps.layer_input = true;
254 break;
255 case nir_intrinsic_load_invocation_id:
256 info->uses_invocation_id = true;
257 break;
258 case nir_intrinsic_load_primitive_id:
259 info->uses_prim_id = true;
260 break;
261 case nir_intrinsic_load_push_constant:
262 gather_push_constant_info(nir, instr, info);
263 break;
264 case nir_intrinsic_vulkan_resource_index:
265 info->desc_set_used_mask |= (1 << nir_intrinsic_desc_set(instr));
266 break;
267 case nir_intrinsic_image_deref_load:
268 case nir_intrinsic_image_deref_store:
269 case nir_intrinsic_image_deref_atomic_add:
270 case nir_intrinsic_image_deref_atomic_min:
271 case nir_intrinsic_image_deref_atomic_max:
272 case nir_intrinsic_image_deref_atomic_and:
273 case nir_intrinsic_image_deref_atomic_or:
274 case nir_intrinsic_image_deref_atomic_xor:
275 case nir_intrinsic_image_deref_atomic_exchange:
276 case nir_intrinsic_image_deref_atomic_comp_swap:
277 case nir_intrinsic_image_deref_size: {
278 nir_variable *var = nir_deref_instr_get_variable(nir_instr_as_deref(instr->src[0].ssa->parent_instr));
279 const struct glsl_type *type = glsl_without_array(var->type);
280
281 enum glsl_sampler_dim dim = glsl_get_sampler_dim(type);
282 if (dim == GLSL_SAMPLER_DIM_SUBPASS ||
283 dim == GLSL_SAMPLER_DIM_SUBPASS_MS) {
284 info->ps.layer_input = true;
285 info->ps.uses_input_attachments = true;
286 }
287 mark_sampler_desc(var, info);
288
289 if (instr->intrinsic == nir_intrinsic_image_deref_store ||
290 instr->intrinsic == nir_intrinsic_image_deref_atomic_add ||
291 instr->intrinsic == nir_intrinsic_image_deref_atomic_min ||
292 instr->intrinsic == nir_intrinsic_image_deref_atomic_max ||
293 instr->intrinsic == nir_intrinsic_image_deref_atomic_and ||
294 instr->intrinsic == nir_intrinsic_image_deref_atomic_or ||
295 instr->intrinsic == nir_intrinsic_image_deref_atomic_xor ||
296 instr->intrinsic == nir_intrinsic_image_deref_atomic_exchange ||
297 instr->intrinsic == nir_intrinsic_image_deref_atomic_comp_swap) {
298 if (nir->info.stage == MESA_SHADER_FRAGMENT)
299 info->ps.writes_memory = true;
300 }
301 break;
302 }
303 case nir_intrinsic_store_ssbo:
304 case nir_intrinsic_ssbo_atomic_add:
305 case nir_intrinsic_ssbo_atomic_imin:
306 case nir_intrinsic_ssbo_atomic_umin:
307 case nir_intrinsic_ssbo_atomic_imax:
308 case nir_intrinsic_ssbo_atomic_umax:
309 case nir_intrinsic_ssbo_atomic_and:
310 case nir_intrinsic_ssbo_atomic_or:
311 case nir_intrinsic_ssbo_atomic_xor:
312 case nir_intrinsic_ssbo_atomic_exchange:
313 case nir_intrinsic_ssbo_atomic_comp_swap:
314 if (nir->info.stage == MESA_SHADER_FRAGMENT)
315 info->ps.writes_memory = true;
316 break;
317 case nir_intrinsic_load_deref:
318 gather_intrinsic_load_deref_info(nir, instr, info);
319 break;
320 case nir_intrinsic_store_deref:
321 gather_intrinsic_store_deref_info(nir, instr, info);
322 break;
323 default:
324 break;
325 }
326 }
327
328 static void
329 gather_tex_info(const nir_shader *nir, const nir_tex_instr *instr,
330 struct radv_shader_info *info)
331 {
332 for (unsigned i = 0; i < instr->num_srcs; i++) {
333 switch (instr->src[i].src_type) {
334 case nir_tex_src_texture_deref:
335 mark_sampler_desc(nir_deref_instr_get_variable(nir_src_as_deref(instr->src[i].src)), info);
336 break;
337 case nir_tex_src_sampler_deref:
338 mark_sampler_desc(nir_deref_instr_get_variable(nir_src_as_deref(instr->src[i].src)), info);
339 break;
340 default:
341 break;
342 }
343 }
344 }
345
346 static void
347 gather_info_block(const nir_shader *nir, const nir_block *block,
348 struct radv_shader_info *info)
349 {
350 nir_foreach_instr(instr, block) {
351 switch (instr->type) {
352 case nir_instr_type_intrinsic:
353 gather_intrinsic_info(nir, nir_instr_as_intrinsic(instr), info);
354 break;
355 case nir_instr_type_tex:
356 gather_tex_info(nir, nir_instr_as_tex(instr), info);
357 break;
358 default:
359 break;
360 }
361 }
362 }
363
364 static void
365 gather_info_input_decl_vs(const nir_shader *nir, const nir_variable *var,
366 struct radv_shader_info *info)
367 {
368 int idx = var->data.location;
369
370 if (idx >= VERT_ATTRIB_GENERIC0 && idx <= VERT_ATTRIB_GENERIC15)
371 info->vs.has_vertex_buffers = true;
372 }
373
374 static void
375 gather_info_input_decl_ps(const nir_shader *nir, const nir_variable *var,
376 struct radv_shader_info *info)
377 {
378 unsigned attrib_count = glsl_count_attribute_slots(var->type, false);
379 const struct glsl_type *type = glsl_without_array(var->type);
380 int idx = var->data.location;
381
382 switch (idx) {
383 case VARYING_SLOT_PNTC:
384 info->ps.has_pcoord = true;
385 break;
386 case VARYING_SLOT_PRIMITIVE_ID:
387 info->ps.prim_id_input = true;
388 break;
389 case VARYING_SLOT_LAYER:
390 info->ps.layer_input = true;
391 break;
392 case VARYING_SLOT_CLIP_DIST0:
393 case VARYING_SLOT_CLIP_DIST1:
394 info->ps.num_input_clips_culls += attrib_count;
395 break;
396 default:
397 break;
398 }
399
400 if (glsl_get_base_type(type) == GLSL_TYPE_FLOAT) {
401 if (var->data.sample)
402 info->ps.force_persample = true;
403 }
404 }
405
406 static void
407 gather_info_input_decl(const nir_shader *nir, const nir_variable *var,
408 struct radv_shader_info *info)
409 {
410 switch (nir->info.stage) {
411 case MESA_SHADER_VERTEX:
412 gather_info_input_decl_vs(nir, var, info);
413 break;
414 case MESA_SHADER_FRAGMENT:
415 gather_info_input_decl_ps(nir, var, info);
416 break;
417 default:
418 break;
419 }
420 }
421
422 static void
423 gather_info_output_decl_ls(const nir_shader *nir, const nir_variable *var,
424 struct radv_shader_info *info)
425 {
426 int idx = var->data.location;
427 unsigned param = shader_io_get_unique_index(idx);
428 int num_slots = glsl_count_attribute_slots(var->type, false);
429 if (var->data.compact)
430 num_slots = DIV_ROUND_UP(var->data.location_frac + glsl_get_length(var->type), 4);
431 mark_ls_output(info, param, num_slots);
432 }
433
434 static void
435 gather_info_output_decl_ps(const nir_shader *nir, const nir_variable *var,
436 struct radv_shader_info *info)
437 {
438 int idx = var->data.location;
439
440 switch (idx) {
441 case FRAG_RESULT_DEPTH:
442 info->ps.writes_z = true;
443 break;
444 case FRAG_RESULT_STENCIL:
445 info->ps.writes_stencil = true;
446 break;
447 case FRAG_RESULT_SAMPLE_MASK:
448 info->ps.writes_sample_mask = true;
449 break;
450 default:
451 break;
452 }
453 }
454
455 static void
456 gather_info_output_decl_gs(const nir_shader *nir, const nir_variable *var,
457 struct radv_shader_info *info)
458 {
459 unsigned num_components = glsl_get_component_slots(var->type);
460 unsigned stream = var->data.stream;
461 unsigned idx = var->data.location;
462
463 assert(stream < 4);
464
465 info->gs.max_stream = MAX2(info->gs.max_stream, stream);
466 info->gs.num_stream_output_components[stream] += num_components;
467 info->gs.output_streams[idx] = stream;
468 }
469
470 static void
471 gather_info_output_decl(const nir_shader *nir, const nir_variable *var,
472 struct radv_shader_info *info,
473 const struct radv_nir_compiler_options *options)
474 {
475 switch (nir->info.stage) {
476 case MESA_SHADER_FRAGMENT:
477 gather_info_output_decl_ps(nir, var, info);
478 break;
479 case MESA_SHADER_VERTEX:
480 if (options->key.vs.as_ls)
481 gather_info_output_decl_ls(nir, var, info);
482 break;
483 case MESA_SHADER_GEOMETRY:
484 gather_info_output_decl_gs(nir, var, info);
485 break;
486 default:
487 break;
488 }
489 }
490
491 static void
492 gather_xfb_info(const nir_shader *nir, struct radv_shader_info *info)
493 {
494 nir_xfb_info *xfb = nir_gather_xfb_info(nir, NULL);
495 struct radv_streamout_info *so = &info->so;
496
497 if (!xfb)
498 return;
499
500 assert(xfb->output_count < MAX_SO_OUTPUTS);
501 so->num_outputs = xfb->output_count;
502
503 for (unsigned i = 0; i < xfb->output_count; i++) {
504 struct radv_stream_output *output = &so->outputs[i];
505
506 output->buffer = xfb->outputs[i].buffer;
507 output->stream = xfb->buffer_to_stream[xfb->outputs[i].buffer];
508 output->offset = xfb->outputs[i].offset;
509 output->location = xfb->outputs[i].location;
510 output->component_mask = xfb->outputs[i].component_mask;
511
512 so->enabled_stream_buffers_mask |=
513 (1 << output->buffer) << (output->stream * 4);
514
515 }
516
517 for (unsigned i = 0; i < NIR_MAX_XFB_BUFFERS; i++) {
518 so->strides[i] = xfb->buffers[i].stride / 4;
519 }
520
521 ralloc_free(xfb);
522 }
523
524 void
525 radv_nir_shader_info_init(struct radv_shader_info *info)
526 {
527 /* Assume that shaders only have 32-bit push constants by default. */
528 info->min_push_constant_used = UINT8_MAX;
529 info->has_only_32bit_push_constants = true;
530 }
531
532 void
533 radv_nir_shader_info_pass(const struct nir_shader *nir,
534 const struct radv_nir_compiler_options *options,
535 struct radv_shader_info *info)
536 {
537 struct nir_function *func =
538 (struct nir_function *)exec_list_get_head_const(&nir->functions);
539
540 if (options->layout && options->layout->dynamic_offset_count &&
541 (options->layout->dynamic_shader_stages & mesa_to_vk_shader_stage(nir->info.stage))) {
542 info->loads_push_constants = true;
543 info->loads_dynamic_offsets = true;
544 }
545
546 nir_foreach_variable(variable, &nir->inputs)
547 gather_info_input_decl(nir, variable, info);
548
549 nir_foreach_block(block, func->impl) {
550 gather_info_block(nir, block, info);
551 }
552
553 nir_foreach_variable(variable, &nir->outputs)
554 gather_info_output_decl(nir, variable, info, options);
555
556 if (nir->info.stage == MESA_SHADER_VERTEX ||
557 nir->info.stage == MESA_SHADER_TESS_EVAL ||
558 nir->info.stage == MESA_SHADER_GEOMETRY)
559 gather_xfb_info(nir, info);
560 }