1 /*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 *
5 * based in part on anv driver which is:
6 * Copyright © 2015 Intel Corporation
7 *
8 * SPDX-License-Identifier: MIT
9 */
10
11 #include "radv_shader.h"
12 #include "meta/radv_meta.h"
13 #include "nir/nir.h"
14 #include "nir/nir_builder.h"
15 #include "nir/nir_xfb_info.h"
16 #include "nir/radv_nir.h"
17 #include "spirv/nir_spirv.h"
18 #include "util/memstream.h"
19 #include "util/mesa-sha1.h"
20 #include "util/streaming-load-memcpy.h"
21 #include "util/u_atomic.h"
22 #include "radv_cs.h"
23 #include "radv_debug.h"
24 #include "radv_entrypoints.h"
25 #include "radv_nir_to_llvm.h"
26 #include "radv_printf.h"
27 #include "radv_sdma.h"
28 #include "radv_shader_args.h"
29
30 #include "util/u_debug.h"
31 #include "ac_binary.h"
32 #include "ac_nir.h"
33 #if defined(USE_LIBELF)
34 #include "ac_rtld.h"
35 #endif
36 #include "aco_interface.h"
37 #include "sid.h"
38 #include "vk_debug_report.h"
39 #include "vk_format.h"
40 #include "vk_nir.h"
41 #include "vk_semaphore.h"
42 #include "vk_sync.h"
43
44 #include "aco_shader_info.h"
45 #include "radv_aco_shader_info.h"
46 #if AMD_LLVM_AVAILABLE
47 #include "ac_llvm_util.h"
48 #endif
49
50 static void
get_nir_options_for_stage(struct radv_physical_device * pdev,gl_shader_stage stage)51 get_nir_options_for_stage(struct radv_physical_device *pdev, gl_shader_stage stage)
52 {
53 const struct radv_instance *instance = radv_physical_device_instance(pdev);
54 nir_shader_compiler_options *options = &pdev->nir_options[stage];
55 bool split_fma =
56 (stage <= MESA_SHADER_GEOMETRY || stage == MESA_SHADER_MESH) && instance->debug_flags & RADV_DEBUG_SPLIT_FMA;
57
58 ac_set_nir_options(&pdev->info, pdev->use_llvm, options);
59
60 options->lower_ffma16 = split_fma || pdev->info.gfx_level < GFX9;
61 options->lower_ffma32 = split_fma || pdev->info.gfx_level < GFX10_3;
62 options->lower_ffma64 = split_fma;
63 options->max_unroll_iterations = 32;
64 options->max_unroll_iterations_aggressive = 128;
65 options->lower_doubles_options = nir_lower_drcp | nir_lower_dsqrt | nir_lower_drsq | nir_lower_ddiv;
66 options->io_options |= nir_io_mediump_is_32bit;
67 options->varying_estimate_instr_cost = ac_nir_varying_estimate_instr_cost;
68 options->varying_expression_max_cost = ac_nir_varying_expression_max_cost;
69 }
70
71 void
radv_get_nir_options(struct radv_physical_device * pdev)72 radv_get_nir_options(struct radv_physical_device *pdev)
73 {
74 for (gl_shader_stage stage = MESA_SHADER_VERTEX; stage < MESA_VULKAN_SHADER_STAGES; stage++)
75 get_nir_options_for_stage(pdev, stage);
76 }
77
78 static uint8_t
vectorize_vec2_16bit(const nir_instr * instr,const void * _)79 vectorize_vec2_16bit(const nir_instr *instr, const void *_)
80 {
81 if (instr->type != nir_instr_type_alu)
82 return 0;
83
84 const nir_alu_instr *alu = nir_instr_as_alu(instr);
85 const unsigned bit_size = alu->def.bit_size;
86 if (bit_size == 16)
87 return 2;
88 else
89 return 1;
90 }
91
92 static bool
is_meta_shader(nir_shader * nir)93 is_meta_shader(nir_shader *nir)
94 {
95 return nir && nir->info.internal;
96 }
97
98 bool
radv_can_dump_shader(struct radv_device * device,nir_shader * nir,bool meta_shader)99 radv_can_dump_shader(struct radv_device *device, nir_shader *nir, bool meta_shader)
100 {
101 const struct radv_physical_device *pdev = radv_device_physical(device);
102 const struct radv_instance *instance = radv_physical_device_instance(pdev);
103
104 if (!(instance->debug_flags & RADV_DEBUG_DUMP_SHADERS))
105 return false;
106
107 if ((is_meta_shader(nir) || meta_shader) && !(instance->debug_flags & RADV_DEBUG_DUMP_META_SHADERS))
108 return false;
109
110 return true;
111 }
112
113 bool
radv_can_dump_shader_stats(struct radv_device * device,nir_shader * nir)114 radv_can_dump_shader_stats(struct radv_device *device, nir_shader *nir)
115 {
116 const struct radv_physical_device *pdev = radv_device_physical(device);
117 const struct radv_instance *instance = radv_physical_device_instance(pdev);
118
119 /* Only dump non-meta shader stats. */
120 return instance->debug_flags & RADV_DEBUG_DUMP_SHADER_STATS && !is_meta_shader(nir);
121 }
122
123 void
radv_optimize_nir(struct nir_shader * shader,bool optimize_conservatively)124 radv_optimize_nir(struct nir_shader *shader, bool optimize_conservatively)
125 {
126 bool progress;
127
128 struct set *skip = _mesa_pointer_set_create(NULL);
129 do {
130 progress = false;
131
132 NIR_LOOP_PASS(progress, skip, shader, nir_split_array_vars, nir_var_function_temp);
133 NIR_LOOP_PASS(progress, skip, shader, nir_shrink_vec_array_vars, nir_var_function_temp);
134
135 if (!shader->info.var_copies_lowered) {
136 /* Only run this pass if nir_lower_var_copies was not called
137 * yet. That would lower away any copy_deref instructions and we
138 * don't want to introduce any more.
139 */
140 NIR_LOOP_PASS(progress, skip, shader, nir_opt_find_array_copies);
141 }
142
143 NIR_LOOP_PASS(progress, skip, shader, nir_opt_copy_prop_vars);
144 NIR_LOOP_PASS(progress, skip, shader, nir_opt_dead_write_vars);
145 NIR_LOOP_PASS(_, skip, shader, nir_lower_vars_to_ssa);
146
147 NIR_LOOP_PASS(_, skip, shader, nir_lower_alu_width, vectorize_vec2_16bit, NULL);
148 NIR_LOOP_PASS(_, skip, shader, nir_lower_phis_to_scalar, true);
149
150 NIR_LOOP_PASS(progress, skip, shader, nir_copy_prop);
151 NIR_LOOP_PASS(progress, skip, shader, nir_opt_remove_phis);
152 NIR_LOOP_PASS(progress, skip, shader, nir_opt_dce);
153 NIR_LOOP_PASS(progress, skip, shader, nir_opt_dead_cf);
154 bool opt_loop_progress = false;
155 NIR_LOOP_PASS_NOT_IDEMPOTENT(opt_loop_progress, skip, shader, nir_opt_loop);
156 if (opt_loop_progress) {
157 progress = true;
158 NIR_LOOP_PASS(progress, skip, shader, nir_copy_prop);
159 NIR_LOOP_PASS(progress, skip, shader, nir_opt_remove_phis);
160 NIR_LOOP_PASS(progress, skip, shader, nir_opt_dce);
161 }
162 NIR_LOOP_PASS_NOT_IDEMPOTENT(progress, skip, shader, nir_opt_if, nir_opt_if_optimize_phi_true_false);
163 NIR_LOOP_PASS(progress, skip, shader, nir_opt_cse);
164 NIR_LOOP_PASS(progress, skip, shader, nir_opt_peephole_select, 8, true, true);
165 NIR_LOOP_PASS(progress, skip, shader, nir_opt_constant_folding);
166 NIR_LOOP_PASS(progress, skip, shader, nir_opt_intrinsics);
167 NIR_LOOP_PASS_NOT_IDEMPOTENT(progress, skip, shader, nir_opt_algebraic);
168
169 NIR_LOOP_PASS(progress, skip, shader, nir_opt_undef);
170
171 if (shader->options->max_unroll_iterations) {
172 NIR_LOOP_PASS_NOT_IDEMPOTENT(progress, skip, shader, nir_opt_loop_unroll);
173 }
174 } while (progress && !optimize_conservatively);
175 _mesa_set_destroy(skip, NULL);
176
177 NIR_PASS(progress, shader, nir_opt_shrink_vectors, true);
178 NIR_PASS(progress, shader, nir_remove_dead_variables,
179 nir_var_function_temp | nir_var_shader_in | nir_var_shader_out | nir_var_mem_shared, NULL);
180
181 if (shader->info.stage == MESA_SHADER_FRAGMENT && shader->info.fs.uses_discard) {
182 NIR_PASS(progress, shader, nir_opt_conditional_discard);
183 NIR_PASS(progress, shader, nir_opt_move_discards_to_top);
184 }
185
186 NIR_PASS(progress, shader, nir_opt_move, nir_move_load_ubo);
187 }
188
189 void
radv_optimize_nir_algebraic(nir_shader * nir,bool opt_offsets,bool opt_mqsad)190 radv_optimize_nir_algebraic(nir_shader *nir, bool opt_offsets, bool opt_mqsad)
191 {
192 bool more_algebraic = true;
193 while (more_algebraic) {
194 more_algebraic = false;
195 NIR_PASS(_, nir, nir_copy_prop);
196 NIR_PASS(_, nir, nir_opt_dce);
197 NIR_PASS(_, nir, nir_opt_constant_folding);
198 NIR_PASS(_, nir, nir_opt_cse);
199 NIR_PASS(more_algebraic, nir, nir_opt_algebraic);
200 NIR_PASS(_, nir, nir_opt_generate_bfi);
201 NIR_PASS(_, nir, nir_opt_dead_cf);
202 }
203
204 if (opt_offsets) {
205 static const nir_opt_offsets_options offset_options = {
206 .uniform_max = 0,
207 .buffer_max = ~0,
208 .shared_max = ~0,
209 };
210 NIR_PASS(_, nir, nir_opt_offsets, &offset_options);
211 }
212 if (opt_mqsad)
213 NIR_PASS(_, nir, nir_opt_mqsad);
214
215 /* Do late algebraic optimization to turn add(a,
216 * neg(b)) back into subs, then the mandatory cleanup
217 * after algebraic. Note that it may produce fnegs,
218 * and if so then we need to keep running to squash
219 * fneg(fneg(a)).
220 */
221 bool more_late_algebraic = true;
222 struct set *skip = _mesa_pointer_set_create(NULL);
223 while (more_late_algebraic) {
224 more_late_algebraic = false;
225 NIR_LOOP_PASS_NOT_IDEMPOTENT(more_late_algebraic, skip, nir, nir_opt_algebraic_late);
226 NIR_LOOP_PASS(_, skip, nir, nir_opt_constant_folding);
227 NIR_LOOP_PASS(_, skip, nir, nir_copy_prop);
228 NIR_LOOP_PASS(_, skip, nir, nir_opt_dce);
229 NIR_LOOP_PASS(_, skip, nir, nir_opt_cse);
230 }
231 _mesa_set_destroy(skip, NULL);
232 }
233
234 static void
shared_var_info(const struct glsl_type * type,unsigned * size,unsigned * align)235 shared_var_info(const struct glsl_type *type, unsigned *size, unsigned *align)
236 {
237 assert(glsl_type_is_vector_or_scalar(type));
238
239 uint32_t comp_size = glsl_type_is_boolean(type) ? 4 : glsl_get_bit_size(type) / 8;
240 unsigned length = glsl_get_vector_elements(type);
241 *size = comp_size * length, *align = comp_size;
242 }
243
244 struct radv_shader_debug_data {
245 struct radv_device *device;
246 const struct vk_object_base *object;
247 };
248
249 static void
radv_spirv_nir_debug(void * private_data,enum nir_spirv_debug_level level,size_t spirv_offset,const char * message)250 radv_spirv_nir_debug(void *private_data, enum nir_spirv_debug_level level, size_t spirv_offset, const char *message)
251 {
252 struct radv_shader_debug_data *debug_data = private_data;
253 const struct radv_physical_device *pdev = radv_device_physical(debug_data->device);
254 struct radv_instance *instance = radv_physical_device_instance(pdev);
255
256 static const VkDebugReportFlagsEXT vk_flags[] = {
257 [NIR_SPIRV_DEBUG_LEVEL_INFO] = VK_DEBUG_REPORT_INFORMATION_BIT_EXT,
258 [NIR_SPIRV_DEBUG_LEVEL_WARNING] = VK_DEBUG_REPORT_WARNING_BIT_EXT,
259 [NIR_SPIRV_DEBUG_LEVEL_ERROR] = VK_DEBUG_REPORT_ERROR_BIT_EXT,
260 };
261 char buffer[256];
262
263 snprintf(buffer, sizeof(buffer), "SPIR-V offset %lu: %s", (unsigned long)spirv_offset, message);
264
265 vk_debug_report(&instance->vk, vk_flags[level], debug_data->object, 0, 0, "radv", buffer);
266 }
267
268 static void
radv_compiler_debug(void * private_data,enum aco_compiler_debug_level level,const char * message)269 radv_compiler_debug(void *private_data, enum aco_compiler_debug_level level, const char *message)
270 {
271 struct radv_shader_debug_data *debug_data = private_data;
272 const struct radv_physical_device *pdev = radv_device_physical(debug_data->device);
273 struct radv_instance *instance = radv_physical_device_instance(pdev);
274
275 static const VkDebugReportFlagsEXT vk_flags[] = {
276 [ACO_COMPILER_DEBUG_LEVEL_ERROR] = VK_DEBUG_REPORT_ERROR_BIT_EXT,
277 };
278
279 /* VK_DEBUG_REPORT_DEBUG_BIT_EXT specifies diagnostic information
280 * from the implementation and layers.
281 */
282 vk_debug_report(&instance->vk, vk_flags[level] | VK_DEBUG_REPORT_DEBUG_BIT_EXT, NULL, 0, 0, "radv", message);
283 }
284
285 /* If the shader doesn't have an index=1 output, then assume that it meant for a location=1 to be used. This works on
286 * some older hardware because the MRT1 target is used for both location=1 and index=1, but GFX11 works differently.
287 */
288 static void
fix_dual_src_mrt1_export(nir_shader * nir)289 fix_dual_src_mrt1_export(nir_shader *nir)
290 {
291 nir_foreach_shader_out_variable (var, nir) {
292 if (var->data.location == FRAG_RESULT_DATA0 && var->data.index == 1)
293 return;
294 }
295
296 nir_variable *loc1_var = nir_find_variable_with_location(nir, nir_var_shader_out, FRAG_RESULT_DATA1);
297 if (loc1_var) {
298 loc1_var->data.location = FRAG_RESULT_DATA0;
299 loc1_var->data.index = 1;
300 }
301 }
302
303 nir_shader *
radv_shader_spirv_to_nir(struct radv_device * device,const struct radv_shader_stage * stage,const struct radv_spirv_to_nir_options * options,bool is_internal)304 radv_shader_spirv_to_nir(struct radv_device *device, const struct radv_shader_stage *stage,
305 const struct radv_spirv_to_nir_options *options, bool is_internal)
306 {
307 const struct radv_physical_device *pdev = radv_device_physical(device);
308 const struct radv_instance *instance = radv_physical_device_instance(pdev);
309 unsigned subgroup_size = 64, ballot_bit_size = 64;
310 const unsigned required_subgroup_size = stage->key.subgroup_required_size * 32;
311 if (required_subgroup_size) {
312 /* Only compute/mesh/task shaders currently support requiring a
313 * specific subgroup size.
314 */
315 assert(stage->stage >= MESA_SHADER_COMPUTE);
316 subgroup_size = required_subgroup_size;
317 ballot_bit_size = required_subgroup_size;
318 }
319
320 nir_shader *nir;
321
322 if (stage->internal_nir) {
323 /* Some things such as our meta clear/blit code will give us a NIR
324 * shader directly. In that case, we just ignore the SPIR-V entirely
325 * and just use the NIR shader. We don't want to alter meta and RT
326 * shaders IR directly, so clone it first. */
327 nir = nir_shader_clone(NULL, stage->internal_nir);
328 nir_validate_shader(nir, "in internal shader");
329
330 assert(exec_list_length(&nir->functions) == 1);
331 } else {
332 uint32_t *spirv = (uint32_t *)stage->spirv.data;
333 assert(stage->spirv.size % 4 == 0);
334
335 bool dump_meta = instance->debug_flags & RADV_DEBUG_DUMP_META_SHADERS;
336 if ((instance->debug_flags & RADV_DEBUG_DUMP_SPIRV) && (!is_internal || dump_meta))
337 spirv_print_asm(stderr, (const uint32_t *)stage->spirv.data, stage->spirv.size / 4);
338
339 uint32_t num_spec_entries = 0;
340 struct nir_spirv_specialization *spec_entries = vk_spec_info_to_nir_spirv(stage->spec_info, &num_spec_entries);
341 struct radv_shader_debug_data spirv_debug_data = {
342 .device = device,
343 .object = stage->spirv.object,
344 };
345 const struct spirv_capabilities spirv_caps =
346 vk_physical_device_get_spirv_capabilities(device->vk.physical);
347 const struct spirv_to_nir_options spirv_options = {
348 .amd_gcn_shader = true,
349 .amd_shader_ballot = true,
350 .amd_shader_explicit_vertex_parameter = true,
351 .amd_trinary_minmax = true,
352 .capabilities = &spirv_caps,
353 .ubo_addr_format = nir_address_format_vec2_index_32bit_offset,
354 .ssbo_addr_format = nir_address_format_vec2_index_32bit_offset,
355 .phys_ssbo_addr_format = nir_address_format_64bit_global,
356 .push_const_addr_format = nir_address_format_logical,
357 .shared_addr_format = nir_address_format_32bit_offset,
358 .constant_addr_format = nir_address_format_64bit_global,
359 .debug =
360 {
361 .func = radv_spirv_nir_debug,
362 .private_data = &spirv_debug_data,
363 },
364 .force_tex_non_uniform = pdev->cache_key.tex_non_uniform,
365 .force_ssbo_non_uniform = pdev->cache_key.ssbo_non_uniform,
366 };
367 nir = spirv_to_nir(spirv, stage->spirv.size / 4, spec_entries, num_spec_entries, stage->stage, stage->entrypoint,
368 &spirv_options, &pdev->nir_options[stage->stage]);
369 nir->info.internal |= is_internal;
370 assert(nir->info.stage == stage->stage);
371 nir_validate_shader(nir, "after spirv_to_nir");
372
373 free(spec_entries);
374
375 radv_device_associate_nir(device, nir);
376
377 /* TODO: This can be removed once GCM (which is more general) is used. */
378 NIR_PASS(_, nir, nir_opt_reuse_constants);
379
380 const struct nir_lower_sysvals_to_varyings_options sysvals_to_varyings = {
381 .point_coord = true,
382 };
383 NIR_PASS_V(nir, nir_lower_sysvals_to_varyings, &sysvals_to_varyings);
384
385 /* We have to lower away local constant initializers right before we
386 * inline functions. That way they get properly initialized at the top
387 * of the function and not at the top of its caller.
388 */
389 NIR_PASS(_, nir, nir_lower_variable_initializers, nir_var_function_temp);
390 NIR_PASS(_, nir, nir_lower_returns);
391 bool progress = false;
392 NIR_PASS(progress, nir, nir_inline_functions);
393 if (progress) {
394 NIR_PASS(_, nir, nir_opt_copy_prop_vars);
395 NIR_PASS(_, nir, nir_copy_prop);
396 }
397 NIR_PASS(_, nir, nir_opt_deref);
398
399 /* Pick off the single entrypoint that we want */
400 nir_remove_non_entrypoints(nir);
401
402 /* Make sure we lower constant initializers on output variables so that
403 * nir_remove_dead_variables below sees the corresponding stores
404 */
405 NIR_PASS(_, nir, nir_lower_variable_initializers, nir_var_shader_out);
406
407 /* Now that we've deleted all but the main function, we can go ahead and
408 * lower the rest of the constant initializers.
409 */
410 NIR_PASS(_, nir, nir_lower_variable_initializers, ~0);
411
412 NIR_PASS(_, nir, radv_nir_lower_cooperative_matrix, subgroup_size);
413
414 /* Split member structs. We do this before lower_io_to_temporaries so that
415 * it doesn't lower system values to temporaries by accident.
416 */
417 NIR_PASS(_, nir, nir_split_var_copies);
418 NIR_PASS(_, nir, nir_split_per_member_structs);
419
420 if (nir->info.stage == MESA_SHADER_FRAGMENT)
421 NIR_PASS(_, nir, nir_lower_io_to_vector, nir_var_shader_out);
422 if (nir->info.stage == MESA_SHADER_FRAGMENT)
423 NIR_PASS(_, nir, nir_lower_input_attachments,
424 &(nir_input_attachment_options){
425 .use_fragcoord_sysval = true,
426 .use_layer_id_sysval = false,
427 });
428
429 nir_remove_dead_variables_options dead_vars_opts = {
430 .can_remove_var = nir_vk_is_not_xfb_output,
431 };
432 NIR_PASS(_, nir, nir_remove_dead_variables,
433 nir_var_shader_in | nir_var_shader_out | nir_var_system_value | nir_var_mem_shared, &dead_vars_opts);
434
435 if (nir->info.stage == MESA_SHADER_FRAGMENT && options->fix_dual_src_mrt1_export)
436 fix_dual_src_mrt1_export(nir);
437
438 /* Variables can make nir_propagate_invariant more conservative
439 * than it needs to be.
440 */
441 NIR_PASS(_, nir, nir_lower_global_vars_to_local);
442
443 NIR_PASS(_, nir, nir_lower_vars_to_ssa);
444
445 NIR_PASS(_, nir, nir_propagate_invariant, pdev->cache_key.invariant_geom);
446
447 NIR_PASS(_, nir, nir_lower_clip_cull_distance_arrays);
448
449 if (nir->info.stage == MESA_SHADER_VERTEX || nir->info.stage == MESA_SHADER_TESS_EVAL ||
450 nir->info.stage == MESA_SHADER_GEOMETRY)
451 NIR_PASS_V(nir, nir_shader_gather_xfb_info);
452
453 nir_lower_doubles_options lower_doubles = nir->options->lower_doubles_options;
454
455 if (pdev->info.gfx_level == GFX6) {
456 /* GFX6 doesn't support v_floor_f64 and the precision
457 * of v_fract_f64 which is used to implement 64-bit
458 * floor is less than what Vulkan requires.
459 */
460 lower_doubles |= nir_lower_dfloor;
461 }
462
463 NIR_PASS(_, nir, nir_lower_doubles, NULL, lower_doubles);
464
465 NIR_PASS(_, nir, ac_nir_lower_sin_cos);
466 }
467
468 if (options && options->lower_view_index_to_device_index)
469 NIR_PASS(_, nir, nir_lower_view_index_to_device_index);
470
471 NIR_PASS(_, nir, nir_lower_system_values);
472 nir_lower_compute_system_values_options csv_options = {
473 /* Mesh shaders run as NGG which can implement local_invocation_index from
474 * the wave ID in merged_wave_info, but they don't have local_invocation_ids on GFX10.3.
475 */
476 .lower_cs_local_id_to_index = nir->info.stage == MESA_SHADER_MESH && !pdev->mesh_fast_launch_2,
477 .lower_local_invocation_index = nir->info.stage == MESA_SHADER_COMPUTE &&
478 ((nir->info.workgroup_size[0] == 1) + (nir->info.workgroup_size[1] == 1) +
479 (nir->info.workgroup_size[2] == 1)) == 2,
480 };
481 NIR_PASS(_, nir, nir_lower_compute_system_values, &csv_options);
482
483 /* Vulkan uses the separate-shader linking model */
484 nir->info.separate_shader = true;
485
486 nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
487
488 if (nir->info.ray_queries > 0) {
489 /* Lower shared variables early to prevent the over allocation of shared memory in
490 * radv_nir_lower_ray_queries. */
491 if (nir->info.stage == MESA_SHADER_COMPUTE) {
492 if (!nir->info.shared_memory_explicit_layout)
493 NIR_PASS(_, nir, nir_lower_vars_to_explicit_types, nir_var_mem_shared, shared_var_info);
494
495 NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_shared, nir_address_format_32bit_offset);
496 }
497
498 NIR_PASS(_, nir, nir_opt_ray_queries);
499 NIR_PASS(_, nir, nir_opt_ray_query_ranges);
500 NIR_PASS(_, nir, radv_nir_lower_ray_queries, device);
501 }
502
503 nir_lower_tex_options tex_options = {
504 .lower_txp = ~0,
505 .lower_txf_offset = true,
506 .lower_tg4_offsets = true,
507 .lower_txs_cube_array = true,
508 .lower_to_fragment_fetch_amd = pdev->use_fmask,
509 .lower_lod_zero_width = true,
510 .lower_invalid_implicit_lod = true,
511 .lower_1d = pdev->info.gfx_level == GFX9,
512 };
513
514 NIR_PASS(_, nir, nir_lower_tex, &tex_options);
515
516 static const nir_lower_image_options image_options = {
517 .lower_cube_size = true,
518 };
519
520 NIR_PASS(_, nir, nir_lower_image, &image_options);
521
522 NIR_PASS(_, nir, nir_lower_vars_to_ssa);
523
524 if (nir->info.stage == MESA_SHADER_VERTEX || nir->info.stage == MESA_SHADER_GEOMETRY ||
525 nir->info.stage == MESA_SHADER_FRAGMENT) {
526 NIR_PASS_V(nir, nir_lower_io_to_temporaries, nir_shader_get_entrypoint(nir), true, true);
527 } else if (nir->info.stage == MESA_SHADER_TESS_EVAL) {
528 NIR_PASS_V(nir, nir_lower_io_to_temporaries, nir_shader_get_entrypoint(nir), true, false);
529 }
530
531 NIR_PASS(_, nir, nir_split_var_copies);
532
533 NIR_PASS(_, nir, nir_lower_global_vars_to_local);
534 NIR_PASS(_, nir, nir_remove_dead_variables, nir_var_function_temp, NULL);
535
536 bool gfx7minus = pdev->info.gfx_level <= GFX7;
537 bool has_inverse_ballot = true;
538 bool use_llvm = radv_use_llvm_for_stage(pdev, nir->info.stage);
539 #if AMD_LLVM_AVAILABLE
540 has_inverse_ballot = !use_llvm || LLVM_VERSION_MAJOR >= 17;
541 #endif
542
543 NIR_PASS(_, nir, nir_lower_subgroups,
544 &(struct nir_lower_subgroups_options){
545 .subgroup_size = subgroup_size,
546 .ballot_bit_size = ballot_bit_size,
547 .ballot_components = 1,
548 .lower_to_scalar = 1,
549 .lower_subgroup_masks = 1,
550 .lower_relative_shuffle = 1,
551 .lower_rotate_to_shuffle = use_llvm,
552 .lower_shuffle_to_32bit = 1,
553 .lower_vote_eq = 1,
554 .lower_vote_bool_eq = 1,
555 .lower_quad_broadcast_dynamic = 1,
556 .lower_quad_broadcast_dynamic_to_const = gfx7minus,
557 .lower_shuffle_to_swizzle_amd = 1,
558 .lower_ballot_bit_count_to_mbcnt_amd = 1,
559 .lower_inverse_ballot = !has_inverse_ballot,
560 .lower_boolean_reduce = !use_llvm,
561 .lower_boolean_shuffle = true,
562 });
563
564 NIR_PASS(_, nir, nir_lower_load_const_to_scalar);
565 NIR_PASS(_, nir, nir_opt_shrink_stores, !instance->drirc.disable_shrink_image_store);
566
567 if (!stage->key.optimisations_disabled)
568 radv_optimize_nir(nir, false);
569
570 /* We call nir_lower_var_copies() after the first radv_optimize_nir()
571 * to remove any copies introduced by nir_opt_find_array_copies().
572 */
573 NIR_PASS(_, nir, nir_lower_var_copies);
574
575 unsigned lower_flrp = (nir->options->lower_flrp16 ? 16 : 0) | (nir->options->lower_flrp32 ? 32 : 0) |
576 (nir->options->lower_flrp64 ? 64 : 0);
577 if (lower_flrp != 0) {
578 bool progress = false;
579 NIR_PASS(progress, nir, nir_lower_flrp, lower_flrp, false /* always precise */);
580 if (progress)
581 NIR_PASS(_, nir, nir_opt_constant_folding);
582 }
583
584 const nir_opt_access_options opt_access_options = {
585 .is_vulkan = true,
586 };
587 NIR_PASS(_, nir, nir_opt_access, &opt_access_options);
588
589 NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_push_const, nir_address_format_32bit_offset);
590
591 NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_ubo | nir_var_mem_ssbo,
592 nir_address_format_vec2_index_32bit_offset);
593
594 NIR_PASS(_, nir, radv_nir_lower_intrinsics_early, options && options->lower_view_index_to_zero);
595
596 /* Lower deref operations for compute shared memory. */
597 if (nir->info.stage == MESA_SHADER_COMPUTE || nir->info.stage == MESA_SHADER_TASK ||
598 nir->info.stage == MESA_SHADER_MESH) {
599 nir_variable_mode var_modes = nir_var_mem_shared;
600
601 if (nir->info.stage == MESA_SHADER_TASK || nir->info.stage == MESA_SHADER_MESH)
602 var_modes |= nir_var_mem_task_payload;
603
604 if (!nir->info.shared_memory_explicit_layout)
605 NIR_PASS(_, nir, nir_lower_vars_to_explicit_types, var_modes, shared_var_info);
606 else if (var_modes & ~nir_var_mem_shared)
607 NIR_PASS(_, nir, nir_lower_vars_to_explicit_types, var_modes & ~nir_var_mem_shared, shared_var_info);
608 NIR_PASS(_, nir, nir_lower_explicit_io, var_modes, nir_address_format_32bit_offset);
609
610 if (nir->info.zero_initialize_shared_memory && nir->info.shared_size > 0) {
611 const unsigned chunk_size = 16; /* max single store size */
612 const unsigned shared_size = ALIGN(nir->info.shared_size, chunk_size);
613 NIR_PASS(_, nir, nir_zero_initialize_shared_memory, shared_size, chunk_size);
614 }
615 }
616
617 NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_global | nir_var_mem_constant, nir_address_format_64bit_global);
618
619 /* Lower large variables that are always constant with load_constant
620 * intrinsics, which get turned into PC-relative loads from a data
621 * section next to the shader.
622 */
623 NIR_PASS(_, nir, nir_opt_large_constants, glsl_get_natural_size_align_bytes, 16);
624
625 /* Lower primitive shading rate to match HW requirements. */
626 if ((nir->info.stage == MESA_SHADER_VERTEX || nir->info.stage == MESA_SHADER_GEOMETRY ||
627 nir->info.stage == MESA_SHADER_MESH) &&
628 nir->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_PRIMITIVE_SHADING_RATE)) {
629 /* Lower primitive shading rate to match HW requirements. */
630 NIR_PASS(_, nir, radv_nir_lower_primitive_shading_rate, pdev->info.gfx_level);
631 }
632
633 /* Indirect lowering must be called after the radv_optimize_nir() loop
634 * has been called at least once. Otherwise indirect lowering can
635 * bloat the instruction count of the loop and cause it to be
636 * considered too large for unrolling.
637 */
638 if (ac_nir_lower_indirect_derefs(nir, pdev->info.gfx_level) && !stage->key.optimisations_disabled &&
639 nir->info.stage != MESA_SHADER_COMPUTE) {
640 /* Optimize the lowered code before the linking optimizations. */
641 radv_optimize_nir(nir, false);
642 }
643
644 return nir;
645 }
646
647 bool
radv_consider_culling(const struct radv_physical_device * pdev,struct nir_shader * nir,uint64_t ps_inputs_read,unsigned num_vertices_per_primitive,const struct radv_shader_info * info)648 radv_consider_culling(const struct radv_physical_device *pdev, struct nir_shader *nir, uint64_t ps_inputs_read,
649 unsigned num_vertices_per_primitive, const struct radv_shader_info *info)
650 {
651 /* Culling doesn't make sense for meta shaders. */
652 if (is_meta_shader(nir))
653 return false;
654
655 /* We don't support culling with multiple viewports yet. */
656 if (nir->info.outputs_written & (VARYING_BIT_VIEWPORT | VARYING_BIT_VIEWPORT_MASK))
657 return false;
658
659 /* We don't support culling with vertex shader prologs. */
660 if (info->vs.has_prolog)
661 return false;
662
663 if (!pdev->use_ngg_culling)
664 return false;
665
666 /* Shader based culling efficiency can depend on PS throughput.
667 * Estimate an upper limit for PS input param count based on GPU info.
668 */
669 unsigned max_ps_params = 8;
670
671 if (pdev->info.gfx_level >= GFX10_3 && pdev->info.has_dedicated_vram)
672 max_ps_params = 12; /* GFX10.3 and newer discrete GPUs. */
673
674 /* TODO: consider other heuristics here, such as PS execution time */
675 if (util_bitcount64(ps_inputs_read & ~VARYING_BIT_POS) > max_ps_params)
676 return false;
677
678 /* Only triangle culling is supported. */
679 if (num_vertices_per_primitive != 3)
680 return false;
681
682 /* When the shader writes memory, it is difficult to guarantee correctness.
683 * Future work:
684 * - if only write-only SSBOs are used
685 * - if we can prove that non-position outputs don't rely on memory stores
686 * then may be okay to keep the memory stores in the 1st shader part, and delete them from the 2nd.
687 */
688 if (nir->info.writes_memory)
689 return false;
690
691 /* When the shader relies on the subgroup invocation ID, we'd break it, because the ID changes after the culling.
692 * Future work: try to save this to LDS and reload, but it can still be broken in subtle ways.
693 */
694 if (BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_SUBGROUP_INVOCATION))
695 return false;
696
697 /* When re-using values that depend on subgroup operations, we'd break convergence guarantees.
698 * Since we only re-use uniform values, the only subgroup operations we really care about are
699 * ballot, reductions and vote intrinsics.
700 */
701 if (nir->info.maximally_reconverges && nir->info.uses_wide_subgroup_intrinsics)
702 return false;
703
704 return true;
705 }
706
707 void
radv_lower_ngg(struct radv_device * device,struct radv_shader_stage * ngg_stage,const struct radv_graphics_state_key * gfx_state)708 radv_lower_ngg(struct radv_device *device, struct radv_shader_stage *ngg_stage,
709 const struct radv_graphics_state_key *gfx_state)
710 {
711 const struct radv_physical_device *pdev = radv_device_physical(device);
712 const struct radv_shader_info *info = &ngg_stage->info;
713 nir_shader *nir = ngg_stage->nir;
714
715 assert(nir->info.stage == MESA_SHADER_VERTEX || nir->info.stage == MESA_SHADER_TESS_EVAL ||
716 nir->info.stage == MESA_SHADER_GEOMETRY || nir->info.stage == MESA_SHADER_MESH);
717
718 unsigned num_vertices_per_prim = 3;
719
720 /* Get the number of vertices per input primitive */
721 if (nir->info.stage == MESA_SHADER_TESS_EVAL) {
722 if (nir->info.tess.point_mode)
723 num_vertices_per_prim = 1;
724 else if (nir->info.tess._primitive_mode == TESS_PRIMITIVE_ISOLINES)
725 num_vertices_per_prim = 2;
726
727 /* Manually mark the primitive ID used, so the shader can repack it. */
728 if (info->outinfo.export_prim_id)
729 BITSET_SET(nir->info.system_values_read, SYSTEM_VALUE_PRIMITIVE_ID);
730
731 } else if (nir->info.stage == MESA_SHADER_VERTEX) {
732 num_vertices_per_prim = radv_get_num_vertices_per_prim(gfx_state);
733
734 /* Manually mark the instance ID used, so the shader can repack it. */
735 if (gfx_state->vi.instance_rate_inputs)
736 BITSET_SET(nir->info.system_values_read, SYSTEM_VALUE_INSTANCE_ID);
737
738 } else if (nir->info.stage == MESA_SHADER_GEOMETRY) {
739 num_vertices_per_prim = nir->info.gs.vertices_in;
740 } else if (nir->info.stage == MESA_SHADER_MESH) {
741 if (nir->info.mesh.primitive_type == MESA_PRIM_POINTS)
742 num_vertices_per_prim = 1;
743 else if (nir->info.mesh.primitive_type == MESA_PRIM_LINES)
744 num_vertices_per_prim = 2;
745 else
746 assert(nir->info.mesh.primitive_type == MESA_PRIM_TRIANGLES);
747 } else {
748 unreachable("NGG needs to be VS, TES or GS.");
749 }
750
751 if (nir->info.stage != MESA_SHADER_MESH)
752 nir->info.shared_size = info->ngg_info.lds_size;
753
754 ac_nir_lower_ngg_options options = {0};
755 options.family = pdev->info.family;
756 options.gfx_level = pdev->info.gfx_level;
757 options.max_workgroup_size = info->workgroup_size;
758 options.wave_size = info->wave_size;
759 options.clip_cull_dist_mask = info->outinfo.clip_dist_mask | info->outinfo.cull_dist_mask;
760 options.vs_output_param_offset = info->outinfo.vs_output_param_offset;
761 options.has_param_exports = info->outinfo.param_exports || info->outinfo.prim_param_exports;
762 options.can_cull = nir->info.stage != MESA_SHADER_GEOMETRY && info->has_ngg_culling;
763 options.disable_streamout = !pdev->use_ngg_streamout;
764 options.has_gen_prim_query = info->has_prim_query;
765 options.has_xfb_prim_query = info->has_xfb_query;
766 options.has_gs_invocations_query = pdev->info.gfx_level < GFX11;
767 options.has_gs_primitives_query = pdev->info.gfx_level < GFX11;
768 options.force_vrs = info->force_vrs_per_vertex;
769
770 if (nir->info.stage == MESA_SHADER_VERTEX || nir->info.stage == MESA_SHADER_TESS_EVAL) {
771 assert(info->is_ngg);
772
773 if (info->has_ngg_culling)
774 radv_optimize_nir_algebraic(nir, false, false);
775
776 options.num_vertices_per_primitive = num_vertices_per_prim;
777 options.early_prim_export = info->has_ngg_early_prim_export;
778 options.passthrough = info->is_ngg_passthrough;
779 options.export_primitive_id = info->outinfo.export_prim_id;
780 options.instance_rate_inputs = gfx_state->vi.instance_rate_inputs << VERT_ATTRIB_GENERIC0;
781
782 NIR_PASS_V(nir, ac_nir_lower_ngg_nogs, &options);
783
784 /* Increase ESGS ring size so the LLVM binary contains the correct LDS size. */
785 ngg_stage->info.ngg_info.esgs_ring_size = nir->info.shared_size;
786 } else if (nir->info.stage == MESA_SHADER_GEOMETRY) {
787 assert(info->is_ngg);
788
789 options.gs_out_vtx_bytes = info->gs.gsvs_vertex_size;
790
791 NIR_PASS_V(nir, ac_nir_lower_ngg_gs, &options);
792 } else if (nir->info.stage == MESA_SHADER_MESH) {
793 /* ACO aligns the workgroup size to the wave size. */
794 unsigned hw_workgroup_size = ALIGN(info->workgroup_size, info->wave_size);
795
796 bool scratch_ring = false;
797 NIR_PASS_V(nir, ac_nir_lower_ngg_ms, options.gfx_level, options.clip_cull_dist_mask,
798 options.vs_output_param_offset, options.has_param_exports, &scratch_ring, info->wave_size,
799 hw_workgroup_size, gfx_state->has_multiview_view_index, info->ms.has_query, pdev->mesh_fast_launch_2);
800 ngg_stage->info.ms.needs_ms_scratch_ring = scratch_ring;
801 } else {
802 unreachable("invalid SW stage passed to radv_lower_ngg");
803 }
804 }
805
806 static unsigned
get_size_class(unsigned size,bool round_up)807 get_size_class(unsigned size, bool round_up)
808 {
809 size = round_up ? util_logbase2_ceil(size) : util_logbase2(size);
810 unsigned size_class = MAX2(size, RADV_SHADER_ALLOC_MIN_SIZE_CLASS) - RADV_SHADER_ALLOC_MIN_SIZE_CLASS;
811 return MIN2(size_class, RADV_SHADER_ALLOC_NUM_FREE_LISTS - 1);
812 }
813
814 static void
remove_hole(struct radv_shader_free_list * free_list,union radv_shader_arena_block * hole)815 remove_hole(struct radv_shader_free_list *free_list, union radv_shader_arena_block *hole)
816 {
817 unsigned size_class = get_size_class(hole->size, false);
818 list_del(&hole->freelist);
819 if (list_is_empty(&free_list->free_lists[size_class]))
820 free_list->size_mask &= ~(1u << size_class);
821 }
822
823 static void
add_hole(struct radv_shader_free_list * free_list,union radv_shader_arena_block * hole)824 add_hole(struct radv_shader_free_list *free_list, union radv_shader_arena_block *hole)
825 {
826 unsigned size_class = get_size_class(hole->size, false);
827 list_addtail(&hole->freelist, &free_list->free_lists[size_class]);
828 free_list->size_mask |= 1u << size_class;
829 }
830
831 static union radv_shader_arena_block *
alloc_block_obj(struct radv_device * device)832 alloc_block_obj(struct radv_device *device)
833 {
834 if (!list_is_empty(&device->shader_block_obj_pool)) {
835 union radv_shader_arena_block *block =
836 list_first_entry(&device->shader_block_obj_pool, union radv_shader_arena_block, pool);
837 list_del(&block->pool);
838 return block;
839 }
840
841 return malloc(sizeof(union radv_shader_arena_block));
842 }
843
844 static void
free_block_obj(struct radv_device * device,union radv_shader_arena_block * block)845 free_block_obj(struct radv_device *device, union radv_shader_arena_block *block)
846 {
847 list_del(&block->pool);
848 list_add(&block->pool, &device->shader_block_obj_pool);
849 }
850
851 VkResult
radv_shader_wait_for_upload(struct radv_device * device,uint64_t seq)852 radv_shader_wait_for_upload(struct radv_device *device, uint64_t seq)
853 {
854 if (!seq)
855 return VK_SUCCESS;
856
857 const VkSemaphoreWaitInfo wait_info = {
858 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
859 .pSemaphores = &device->shader_upload_sem,
860 .semaphoreCount = 1,
861 .pValues = &seq,
862 };
863 return device->vk.dispatch_table.WaitSemaphores(radv_device_to_handle(device), &wait_info, UINT64_MAX);
864 }
865
866 static struct radv_shader_arena *
radv_create_shader_arena(struct radv_device * device,struct radv_shader_free_list * free_list,unsigned min_size,unsigned arena_size,bool replayable,uint64_t replay_va)867 radv_create_shader_arena(struct radv_device *device, struct radv_shader_free_list *free_list, unsigned min_size,
868 unsigned arena_size, bool replayable, uint64_t replay_va)
869 {
870 const struct radv_physical_device *pdev = radv_device_physical(device);
871 union radv_shader_arena_block *alloc = NULL;
872 struct radv_shader_arena *arena = calloc(1, sizeof(struct radv_shader_arena));
873 if (!arena)
874 goto fail;
875
876 if (!arena_size)
877 arena_size = MAX2(
878 RADV_SHADER_ALLOC_MIN_ARENA_SIZE << MIN2(RADV_SHADER_ALLOC_MAX_ARENA_SIZE_SHIFT, device->shader_arena_shift),
879 min_size);
880 arena->size = arena_size;
881
882 enum radeon_bo_flag flags = RADEON_FLAG_NO_INTERPROCESS_SHARING | RADEON_FLAG_32BIT;
883 if (device->shader_use_invisible_vram)
884 flags |= RADEON_FLAG_NO_CPU_ACCESS;
885 else
886 flags |= (pdev->info.cpdma_prefetch_writes_memory ? 0 : RADEON_FLAG_READ_ONLY);
887
888 if (replayable)
889 flags |= RADEON_FLAG_REPLAYABLE;
890
891 /* vkCmdUpdatePipelineIndirectBufferNV() can be called on any queue supporting transfer
892 * operations and it's not required to call it on the same queue as DGC execute. To make sure the
893 * compute shader BO is part of the DGC execute submission, force all shaders to be local BOs.
894 */
895 if (device->vk.enabled_features.deviceGeneratedComputePipelines)
896 flags |= RADEON_FLAG_PREFER_LOCAL_BO;
897
898 VkResult result;
899 result = radv_bo_create(device, NULL, arena_size, RADV_SHADER_ALLOC_ALIGNMENT, RADEON_DOMAIN_VRAM, flags,
900 RADV_BO_PRIORITY_SHADER, replay_va, true, &arena->bo);
901 if (result != VK_SUCCESS)
902 goto fail;
903
904 list_inithead(&arena->entries);
905 alloc = alloc_block_obj(device);
906 if (!alloc)
907 goto fail;
908
909 list_inithead(&alloc->freelist);
910 alloc->arena = arena;
911 alloc->offset = 0;
912 alloc->size = arena_size;
913 list_addtail(&alloc->list, &arena->entries);
914 if (free_list)
915 add_hole(free_list, alloc);
916
917 if (!(flags & RADEON_FLAG_NO_CPU_ACCESS)) {
918 arena->ptr = (char *)radv_buffer_map(device->ws, arena->bo);
919 if (!arena->ptr)
920 goto fail;
921 }
922
923 if (replay_va)
924 arena->type = RADV_SHADER_ARENA_REPLAYED;
925 else if (replayable)
926 arena->type = RADV_SHADER_ARENA_REPLAYABLE;
927 else
928 arena->type = RADV_SHADER_ARENA_DEFAULT;
929
930 return arena;
931
932 fail:
933 if (alloc)
934 free_block_obj(device, alloc);
935 if (arena && arena->bo)
936 radv_bo_destroy(device, NULL, arena->bo);
937 free(arena);
938 return NULL;
939 }
940
941 /* Inserts a block at an arbitrary place into a hole, splitting the hole as needed */
942 static union radv_shader_arena_block *
insert_block(struct radv_device * device,union radv_shader_arena_block * hole,uint32_t offset_in_hole,uint32_t size,struct radv_shader_free_list * free_list)943 insert_block(struct radv_device *device, union radv_shader_arena_block *hole, uint32_t offset_in_hole, uint32_t size,
944 struct radv_shader_free_list *free_list)
945 {
946 uint32_t hole_begin = hole->offset;
947 uint32_t hole_end = hole->offset + hole->size;
948
949 /* The block might not lie exactly at the beginning or end
950 * of the hole. Resize the hole to fit the block exactly,
951 * and insert new holes before (left_hole) or after (right_hole) as needed.
952 * left_hole or right_hole are skipped if the allocation lies exactly at the
953 * beginning or end of the hole to avoid 0-sized holes. */
954 union radv_shader_arena_block *left_hole = NULL;
955 union radv_shader_arena_block *right_hole = NULL;
956
957 if (offset_in_hole) {
958 left_hole = alloc_block_obj(device);
959 if (!left_hole)
960 return NULL;
961 list_inithead(&left_hole->freelist);
962 left_hole->arena = hole->arena;
963 left_hole->offset = hole->offset;
964 left_hole->size = offset_in_hole;
965
966 if (free_list)
967 add_hole(free_list, left_hole);
968 }
969
970 if (hole->size > offset_in_hole + size) {
971 right_hole = alloc_block_obj(device);
972 if (!right_hole) {
973 free(left_hole);
974 return NULL;
975 }
976 list_inithead(&right_hole->freelist);
977 right_hole->arena = hole->arena;
978 right_hole->offset = hole_begin + offset_in_hole + size;
979 right_hole->size = hole_end - right_hole->offset;
980
981 if (free_list)
982 add_hole(free_list, right_hole);
983 }
984
985 if (left_hole) {
986 hole->offset += left_hole->size;
987 hole->size -= left_hole->size;
988
989 list_addtail(&left_hole->list, &hole->list);
990 }
991 if (right_hole) {
992 hole->size -= right_hole->size;
993
994 list_add(&right_hole->list, &hole->list);
995 }
996
997 if (free_list)
998 remove_hole(free_list, hole);
999 return hole;
1000 }
1001
1002 /* Segregated fit allocator, implementing a good-fit allocation policy.
1003 *
1004 * This is an variation of sequential fit allocation with several lists of free blocks ("holes")
1005 * instead of one. Each list of holes only contains holes of a certain range of sizes, so holes that
1006 * are too small can easily be ignored while allocating. Because this also ignores holes that are
1007 * larger than necessary (approximating best-fit allocation), this could be described as a
1008 * "good-fit" allocator.
1009 *
1010 * Typically, shaders are allocated and only free'd when the device is destroyed. For this pattern,
1011 * this should allocate blocks for shaders fast and with no fragmentation, while still allowing
1012 * free'd memory to be re-used.
1013 */
1014 union radv_shader_arena_block *
radv_alloc_shader_memory(struct radv_device * device,uint32_t size,bool replayable,void * ptr)1015 radv_alloc_shader_memory(struct radv_device *device, uint32_t size, bool replayable, void *ptr)
1016 {
1017 const struct radv_physical_device *pdev = radv_device_physical(device);
1018
1019 size = ac_align_shader_binary_for_prefetch(&pdev->info, size);
1020 size = align(size, RADV_SHADER_ALLOC_ALIGNMENT);
1021
1022 mtx_lock(&device->shader_arena_mutex);
1023
1024 struct radv_shader_free_list *free_list = replayable ? &device->capture_replay_free_list : &device->shader_free_list;
1025
1026 /* Try to use an existing hole. Unless the shader is very large, this should only have to look
1027 * at the first one available.
1028 */
1029 unsigned free_list_mask = BITFIELD_MASK(RADV_SHADER_ALLOC_NUM_FREE_LISTS);
1030 unsigned size_class = ffs(free_list->size_mask & (free_list_mask << get_size_class(size, true)));
1031 if (size_class) {
1032 size_class--;
1033
1034 list_for_each_entry (union radv_shader_arena_block, hole, &free_list->free_lists[size_class], freelist) {
1035 if (hole->size < size)
1036 continue;
1037
1038 assert(hole->offset % RADV_SHADER_ALLOC_ALIGNMENT == 0);
1039
1040 if (size == hole->size) {
1041 remove_hole(free_list, hole);
1042 hole->freelist.next = ptr;
1043 mtx_unlock(&device->shader_arena_mutex);
1044 return hole;
1045 } else {
1046 union radv_shader_arena_block *alloc = alloc_block_obj(device);
1047 if (!alloc) {
1048 mtx_unlock(&device->shader_arena_mutex);
1049 return NULL;
1050 }
1051 list_addtail(&alloc->list, &hole->list);
1052 alloc->freelist.prev = NULL;
1053 alloc->freelist.next = ptr;
1054 alloc->arena = hole->arena;
1055 alloc->offset = hole->offset;
1056 alloc->size = size;
1057
1058 remove_hole(free_list, hole);
1059 hole->offset += size;
1060 hole->size -= size;
1061 add_hole(free_list, hole);
1062
1063 mtx_unlock(&device->shader_arena_mutex);
1064 return alloc;
1065 }
1066 }
1067 }
1068
1069 struct radv_shader_arena *arena = radv_create_shader_arena(device, free_list, size, 0, replayable, 0);
1070 union radv_shader_arena_block *alloc = NULL;
1071 if (!arena)
1072 goto fail;
1073
1074 alloc =
1075 insert_block(device, list_entry(arena->entries.next, union radv_shader_arena_block, list), 0, size, free_list);
1076 alloc->freelist.prev = NULL;
1077 alloc->freelist.next = ptr;
1078
1079 ++device->shader_arena_shift;
1080 list_addtail(&arena->list, &device->shader_arenas);
1081
1082 mtx_unlock(&device->shader_arena_mutex);
1083 return alloc;
1084
1085 fail:
1086 mtx_unlock(&device->shader_arena_mutex);
1087 free(alloc);
1088 if (arena) {
1089 free(arena->list.next);
1090 radv_bo_destroy(device, NULL, arena->bo);
1091 }
1092 free(arena);
1093 return NULL;
1094 }
1095
1096 static union radv_shader_arena_block *
get_hole(struct radv_shader_arena * arena,struct list_head * head)1097 get_hole(struct radv_shader_arena *arena, struct list_head *head)
1098 {
1099 if (head == &arena->entries)
1100 return NULL;
1101
1102 union radv_shader_arena_block *hole = list_entry(head, union radv_shader_arena_block, list);
1103 return hole->freelist.prev ? hole : NULL;
1104 }
1105
1106 void
radv_free_shader_memory(struct radv_device * device,union radv_shader_arena_block * alloc)1107 radv_free_shader_memory(struct radv_device *device, union radv_shader_arena_block *alloc)
1108 {
1109 mtx_lock(&device->shader_arena_mutex);
1110
1111 union radv_shader_arena_block *hole_prev = get_hole(alloc->arena, alloc->list.prev);
1112 union radv_shader_arena_block *hole_next = get_hole(alloc->arena, alloc->list.next);
1113
1114 union radv_shader_arena_block *hole = alloc;
1115
1116 struct radv_shader_free_list *free_list;
1117
1118 switch (alloc->arena->type) {
1119 case RADV_SHADER_ARENA_DEFAULT:
1120 free_list = &device->shader_free_list;
1121 break;
1122 case RADV_SHADER_ARENA_REPLAYABLE:
1123 free_list = &device->capture_replay_free_list;
1124 break;
1125 case RADV_SHADER_ARENA_REPLAYED:
1126 free_list = NULL;
1127 break;
1128 default:
1129 unreachable("invalid shader arena type");
1130 }
1131
1132 /* merge with previous hole */
1133 if (hole_prev) {
1134 if (free_list)
1135 remove_hole(free_list, hole_prev);
1136
1137 hole_prev->size += hole->size;
1138 free_block_obj(device, hole);
1139
1140 hole = hole_prev;
1141 }
1142
1143 /* merge with next hole */
1144 if (hole_next) {
1145 if (free_list)
1146 remove_hole(free_list, hole_next);
1147
1148 hole_next->offset -= hole->size;
1149 hole_next->size += hole->size;
1150 free_block_obj(device, hole);
1151
1152 hole = hole_next;
1153 }
1154
1155 if (list_is_singular(&hole->list)) {
1156 struct radv_shader_arena *arena = hole->arena;
1157 free_block_obj(device, hole);
1158
1159 radv_bo_destroy(device, NULL, arena->bo);
1160 list_del(&arena->list);
1161
1162 if (device->capture_replay_arena_vas) {
1163 struct hash_entry *arena_entry = NULL;
1164 hash_table_foreach (device->capture_replay_arena_vas->table, entry) {
1165 if (entry->data == arena) {
1166 arena_entry = entry;
1167 break;
1168 }
1169 }
1170 _mesa_hash_table_remove(device->capture_replay_arena_vas->table, arena_entry);
1171 }
1172
1173 free(arena);
1174 } else if (free_list) {
1175 add_hole(free_list, hole);
1176 }
1177
1178 mtx_unlock(&device->shader_arena_mutex);
1179 }
1180
1181 union radv_shader_arena_block *
radv_replay_shader_arena_block(struct radv_device * device,const struct radv_serialized_shader_arena_block * src,void * ptr)1182 radv_replay_shader_arena_block(struct radv_device *device, const struct radv_serialized_shader_arena_block *src,
1183 void *ptr)
1184 {
1185 mtx_lock(&device->shader_arena_mutex);
1186
1187 union radv_shader_arena_block *ret_block = NULL;
1188
1189 uint64_t va = src->arena_va;
1190 void *data = _mesa_hash_table_u64_search(device->capture_replay_arena_vas, va);
1191
1192 if (!data) {
1193 struct radv_shader_arena *arena = radv_create_shader_arena(device, NULL, 0, src->arena_size, true, src->arena_va);
1194 if (!arena)
1195 goto out;
1196
1197 _mesa_hash_table_u64_insert(device->capture_replay_arena_vas, src->arena_va, arena);
1198 list_addtail(&arena->list, &device->shader_arenas);
1199 data = arena;
1200 }
1201
1202 uint32_t block_begin = src->offset;
1203 uint32_t block_end = src->offset + src->size;
1204
1205 struct radv_shader_arena *arena = data;
1206 list_for_each_entry (union radv_shader_arena_block, hole, &arena->entries, list) {
1207 /* Only consider holes, not allocated shaders */
1208 if (!hole->freelist.prev)
1209 continue;
1210
1211 uint32_t hole_begin = hole->offset;
1212 uint32_t hole_end = hole->offset + hole->size;
1213
1214 if (hole_end < block_end)
1215 continue;
1216
1217 /* If another allocated block overlaps the current replay block, allocation is impossible */
1218 if (hole_begin > block_begin)
1219 goto out;
1220
1221 union radv_shader_arena_block *block = insert_block(device, hole, block_begin - hole_begin, src->size, NULL);
1222 if (!block)
1223 goto out;
1224
1225 block->freelist.prev = NULL;
1226 block->freelist.next = ptr;
1227
1228 ret_block = hole;
1229 break;
1230 }
1231
1232 out:
1233 mtx_unlock(&device->shader_arena_mutex);
1234 return ret_block;
1235 }
1236
1237 void
radv_init_shader_arenas(struct radv_device * device)1238 radv_init_shader_arenas(struct radv_device *device)
1239 {
1240 mtx_init(&device->shader_arena_mutex, mtx_plain);
1241
1242 device->shader_free_list.size_mask = 0;
1243 device->capture_replay_free_list.size_mask = 0;
1244
1245 list_inithead(&device->shader_arenas);
1246 list_inithead(&device->shader_block_obj_pool);
1247 for (unsigned i = 0; i < RADV_SHADER_ALLOC_NUM_FREE_LISTS; i++) {
1248 list_inithead(&device->shader_free_list.free_lists[i]);
1249 list_inithead(&device->capture_replay_free_list.free_lists[i]);
1250 }
1251 }
1252
1253 void
radv_destroy_shader_arenas(struct radv_device * device)1254 radv_destroy_shader_arenas(struct radv_device *device)
1255 {
1256 list_for_each_entry_safe (union radv_shader_arena_block, block, &device->shader_block_obj_pool, pool)
1257 free(block);
1258
1259 list_for_each_entry_safe (struct radv_shader_arena, arena, &device->shader_arenas, list) {
1260 radv_bo_destroy(device, NULL, arena->bo);
1261 free(arena);
1262 }
1263 mtx_destroy(&device->shader_arena_mutex);
1264 }
1265
1266 VkResult
radv_init_shader_upload_queue(struct radv_device * device)1267 radv_init_shader_upload_queue(struct radv_device *device)
1268 {
1269 if (!device->shader_use_invisible_vram)
1270 return VK_SUCCESS;
1271
1272 VkDevice vk_device = radv_device_to_handle(device);
1273 struct radeon_winsys *ws = device->ws;
1274
1275 const struct vk_device_dispatch_table *disp = &device->vk.dispatch_table;
1276 VkResult result = VK_SUCCESS;
1277
1278 result = ws->ctx_create(ws, RADEON_CTX_PRIORITY_MEDIUM, &device->shader_upload_hw_ctx);
1279 if (result != VK_SUCCESS)
1280 return result;
1281 mtx_init(&device->shader_upload_hw_ctx_mutex, mtx_plain);
1282
1283 mtx_init(&device->shader_dma_submission_list_mutex, mtx_plain);
1284 cnd_init(&device->shader_dma_submission_list_cond);
1285 list_inithead(&device->shader_dma_submissions);
1286
1287 for (unsigned i = 0; i < RADV_SHADER_UPLOAD_CS_COUNT; i++) {
1288 struct radv_shader_dma_submission *submission = calloc(1, sizeof(struct radv_shader_dma_submission));
1289 submission->cs = ws->cs_create(ws, AMD_IP_SDMA, false);
1290 if (!submission->cs)
1291 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
1292 list_addtail(&submission->list, &device->shader_dma_submissions);
1293 }
1294
1295 const VkSemaphoreTypeCreateInfo sem_type = {
1296 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
1297 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
1298 .initialValue = 0,
1299 };
1300 const VkSemaphoreCreateInfo sem_create = {
1301 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
1302 .pNext = &sem_type,
1303 };
1304 result = disp->CreateSemaphore(vk_device, &sem_create, NULL, &device->shader_upload_sem);
1305 if (result != VK_SUCCESS)
1306 return result;
1307
1308 return VK_SUCCESS;
1309 }
1310
1311 void
radv_destroy_shader_upload_queue(struct radv_device * device)1312 radv_destroy_shader_upload_queue(struct radv_device *device)
1313 {
1314 if (!device->shader_use_invisible_vram)
1315 return;
1316
1317 struct vk_device_dispatch_table *disp = &device->vk.dispatch_table;
1318 struct radeon_winsys *ws = device->ws;
1319
1320 /* Upload queue should be idle assuming that pipelines are not leaked */
1321 if (device->shader_upload_sem)
1322 disp->DestroySemaphore(radv_device_to_handle(device), device->shader_upload_sem, NULL);
1323
1324 list_for_each_entry_safe (struct radv_shader_dma_submission, submission, &device->shader_dma_submissions, list) {
1325 if (submission->cs)
1326 ws->cs_destroy(submission->cs);
1327 if (submission->bo)
1328 radv_bo_destroy(device, NULL, submission->bo);
1329 list_del(&submission->list);
1330 free(submission);
1331 }
1332
1333 cnd_destroy(&device->shader_dma_submission_list_cond);
1334 mtx_destroy(&device->shader_dma_submission_list_mutex);
1335
1336 if (device->shader_upload_hw_ctx) {
1337 mtx_destroy(&device->shader_upload_hw_ctx_mutex);
1338 ws->ctx_destroy(device->shader_upload_hw_ctx);
1339 }
1340 }
1341
1342 static bool
radv_should_use_wgp_mode(const struct radv_device * device,gl_shader_stage stage,const struct radv_shader_info * info)1343 radv_should_use_wgp_mode(const struct radv_device *device, gl_shader_stage stage, const struct radv_shader_info *info)
1344 {
1345 const struct radv_physical_device *pdev = radv_device_physical(device);
1346 enum amd_gfx_level chip = pdev->info.gfx_level;
1347 switch (stage) {
1348 case MESA_SHADER_COMPUTE:
1349 case MESA_SHADER_TESS_CTRL:
1350 return chip >= GFX10;
1351 case MESA_SHADER_GEOMETRY:
1352 return chip == GFX10 || (chip >= GFX10_3 && !info->is_ngg);
1353 case MESA_SHADER_VERTEX:
1354 case MESA_SHADER_TESS_EVAL:
1355 return chip == GFX10 && info->is_ngg;
1356 default:
1357 return false;
1358 }
1359 }
1360
1361 #if defined(USE_LIBELF)
1362 static bool
radv_open_rtld_binary(struct radv_device * device,const struct radv_shader_binary * binary,struct ac_rtld_binary * rtld_binary)1363 radv_open_rtld_binary(struct radv_device *device, const struct radv_shader_binary *binary,
1364 struct ac_rtld_binary *rtld_binary)
1365 {
1366 const struct radv_physical_device *pdev = radv_device_physical(device);
1367 const char *elf_data = (const char *)((struct radv_shader_binary_rtld *)binary)->data;
1368 size_t elf_size = ((struct radv_shader_binary_rtld *)binary)->elf_size;
1369 struct ac_rtld_symbol lds_symbols[3];
1370 unsigned num_lds_symbols = 0;
1371
1372 if (pdev->info.gfx_level >= GFX9 && (binary->info.stage == MESA_SHADER_GEOMETRY || binary->info.is_ngg)) {
1373 struct ac_rtld_symbol *sym = &lds_symbols[num_lds_symbols++];
1374 sym->name = "esgs_ring";
1375 sym->size = binary->info.ngg_info.esgs_ring_size;
1376 sym->align = 64 * 1024;
1377 }
1378
1379 if (binary->info.is_ngg && binary->info.stage == MESA_SHADER_GEOMETRY) {
1380 struct ac_rtld_symbol *sym = &lds_symbols[num_lds_symbols++];
1381 sym->name = "ngg_emit";
1382 sym->size = binary->info.ngg_info.ngg_emit_size * 4;
1383 sym->align = 4;
1384
1385 sym = &lds_symbols[num_lds_symbols++];
1386 sym->name = "ngg_scratch";
1387 sym->size = 8;
1388 sym->align = 4;
1389 }
1390
1391 struct ac_rtld_open_info open_info = {
1392 .info = &pdev->info,
1393 .shader_type = binary->info.stage,
1394 .wave_size = binary->info.wave_size,
1395 .num_parts = 1,
1396 .elf_ptrs = &elf_data,
1397 .elf_sizes = &elf_size,
1398 .num_shared_lds_symbols = num_lds_symbols,
1399 .shared_lds_symbols = lds_symbols,
1400 };
1401
1402 return ac_rtld_open(rtld_binary, open_info);
1403 }
1404 #endif
1405
1406 static void
radv_precompute_registers_hw_vs(struct radv_device * device,struct radv_shader_binary * binary)1407 radv_precompute_registers_hw_vs(struct radv_device *device, struct radv_shader_binary *binary)
1408 {
1409 const struct radv_physical_device *pdev = radv_device_physical(device);
1410 struct radv_shader_info *info = &binary->info;
1411
1412 /* VS is required to export at least one param. */
1413 const uint32_t nparams = MAX2(info->outinfo.param_exports, 1);
1414 info->regs.spi_vs_out_config = S_0286C4_VS_EXPORT_COUNT(nparams - 1);
1415 if (pdev->info.gfx_level >= GFX10) {
1416 info->regs.spi_vs_out_config |= S_0286C4_NO_PC_EXPORT(info->outinfo.param_exports == 0);
1417 }
1418
1419 info->regs.spi_shader_pos_format =
1420 S_02870C_POS0_EXPORT_FORMAT(V_02870C_SPI_SHADER_4COMP) |
1421 S_02870C_POS1_EXPORT_FORMAT(info->outinfo.pos_exports > 1 ? V_02870C_SPI_SHADER_4COMP
1422 : V_02870C_SPI_SHADER_NONE) |
1423 S_02870C_POS2_EXPORT_FORMAT(info->outinfo.pos_exports > 2 ? V_02870C_SPI_SHADER_4COMP
1424 : V_02870C_SPI_SHADER_NONE) |
1425 S_02870C_POS3_EXPORT_FORMAT(info->outinfo.pos_exports > 3 ? V_02870C_SPI_SHADER_4COMP : V_02870C_SPI_SHADER_NONE);
1426
1427 const bool misc_vec_ena = info->outinfo.writes_pointsize || info->outinfo.writes_layer ||
1428 info->outinfo.writes_viewport_index || info->outinfo.writes_primitive_shading_rate;
1429 const unsigned clip_dist_mask = info->outinfo.clip_dist_mask;
1430 const unsigned cull_dist_mask = info->outinfo.cull_dist_mask;
1431 const unsigned total_mask = clip_dist_mask | cull_dist_mask;
1432
1433 info->regs.pa_cl_vs_out_cntl =
1434 S_02881C_USE_VTX_POINT_SIZE(info->outinfo.writes_pointsize) |
1435 S_02881C_USE_VTX_RENDER_TARGET_INDX(info->outinfo.writes_layer) |
1436 S_02881C_USE_VTX_VIEWPORT_INDX(info->outinfo.writes_viewport_index) |
1437 S_02881C_USE_VTX_VRS_RATE(info->outinfo.writes_primitive_shading_rate) |
1438 S_02881C_VS_OUT_MISC_VEC_ENA(misc_vec_ena) |
1439 S_02881C_VS_OUT_MISC_SIDE_BUS_ENA(misc_vec_ena ||
1440 (pdev->info.gfx_level >= GFX10_3 && info->outinfo.pos_exports > 1)) |
1441 S_02881C_VS_OUT_CCDIST0_VEC_ENA((total_mask & 0x0f) != 0) |
1442 S_02881C_VS_OUT_CCDIST1_VEC_ENA((total_mask & 0xf0) != 0) | total_mask << 8 | clip_dist_mask;
1443
1444 if (pdev->info.gfx_level <= GFX8)
1445 info->regs.vs.vgt_reuse_off = info->outinfo.writes_viewport_index;
1446
1447 unsigned late_alloc_wave64, cu_mask;
1448 ac_compute_late_alloc(&pdev->info, false, false, binary->config.scratch_bytes_per_wave > 0, &late_alloc_wave64,
1449 &cu_mask);
1450
1451 if (pdev->info.gfx_level >= GFX7) {
1452 info->regs.vs.spi_shader_pgm_rsrc3_vs =
1453 ac_apply_cu_en(S_00B118_CU_EN(cu_mask) | S_00B118_WAVE_LIMIT(0x3F), C_00B118_CU_EN, 0, &pdev->info);
1454 info->regs.vs.spi_shader_late_alloc_vs = S_00B11C_LIMIT(late_alloc_wave64);
1455
1456 if (pdev->info.gfx_level >= GFX10) {
1457 const uint32_t oversub_pc_lines = late_alloc_wave64 ? pdev->info.pc_lines / 4 : 0;
1458
1459 info->regs.ge_pc_alloc =
1460 S_030980_OVERSUB_EN(oversub_pc_lines > 0) | S_030980_NUM_PC_LINES(oversub_pc_lines - 1);
1461
1462 /* Required programming for tessellation (legacy pipeline only). */
1463 if (binary->info.stage == MESA_SHADER_TESS_EVAL) {
1464 info->regs.vgt_gs_onchip_cntl = S_028A44_ES_VERTS_PER_SUBGRP(250) | S_028A44_GS_PRIMS_PER_SUBGRP(126) |
1465 S_028A44_GS_INST_PRIMS_IN_SUBGRP(126);
1466 }
1467 }
1468 }
1469 }
1470
1471 static void
radv_precompute_registers_hw_gs(struct radv_device * device,struct radv_shader_binary * binary)1472 radv_precompute_registers_hw_gs(struct radv_device *device, struct radv_shader_binary *binary)
1473 {
1474 const struct radv_physical_device *pdev = radv_device_physical(device);
1475 struct radv_shader_info *info = &binary->info;
1476
1477 info->regs.gs.vgt_esgs_ring_itemsize = info->gs_ring_info.esgs_itemsize;
1478
1479 info->regs.gs.vgt_gs_max_prims_per_subgroup =
1480 S_028A94_MAX_PRIMS_PER_SUBGROUP(info->gs_ring_info.gs_inst_prims_in_subgroup);
1481
1482 info->regs.vgt_gs_onchip_cntl = S_028A44_ES_VERTS_PER_SUBGRP(info->gs_ring_info.es_verts_per_subgroup) |
1483 S_028A44_GS_PRIMS_PER_SUBGRP(info->gs_ring_info.gs_prims_per_subgroup) |
1484 S_028A44_GS_INST_PRIMS_IN_SUBGRP(info->gs_ring_info.gs_inst_prims_in_subgroup);
1485
1486 const uint32_t gs_max_out_vertices = info->gs.vertices_out;
1487 const uint8_t max_stream = info->gs.max_stream;
1488 const uint8_t *num_components = info->gs.num_stream_output_components;
1489
1490 uint32_t offset = num_components[0] * gs_max_out_vertices;
1491 info->regs.gs.vgt_gsvs_ring_offset[0] = offset;
1492
1493 if (max_stream >= 1)
1494 offset += num_components[1] * gs_max_out_vertices;
1495 info->regs.gs.vgt_gsvs_ring_offset[1] = offset;
1496
1497 if (max_stream >= 2)
1498 offset += num_components[2] * gs_max_out_vertices;
1499 info->regs.gs.vgt_gsvs_ring_offset[2] = offset;
1500
1501 if (max_stream >= 3)
1502 offset += num_components[3] * gs_max_out_vertices;
1503 info->regs.gs.vgt_gsvs_ring_itemsize = offset;
1504
1505 for (uint32_t i = 0; i < 4; i++)
1506 info->regs.gs.vgt_gs_vert_itemsize[i] = (max_stream >= i) ? num_components[i] : 0;
1507
1508 const uint32_t gs_num_invocations = info->gs.invocations;
1509 info->regs.gs.vgt_gs_instance_cnt =
1510 S_028B90_CNT(MIN2(gs_num_invocations, 127)) | S_028B90_ENABLE(gs_num_invocations > 0);
1511
1512 info->regs.spi_shader_pgm_rsrc3_gs =
1513 ac_apply_cu_en(S_00B21C_CU_EN(0xffff) | S_00B21C_WAVE_LIMIT(0x3F), C_00B21C_CU_EN, 0, &pdev->info);
1514
1515 if (pdev->info.gfx_level >= GFX10) {
1516 info->regs.spi_shader_pgm_rsrc4_gs =
1517 ac_apply_cu_en(S_00B204_CU_EN_GFX10(0xffff) | S_00B204_SPI_SHADER_LATE_ALLOC_GS_GFX10(0), C_00B204_CU_EN_GFX10,
1518 16, &pdev->info);
1519 }
1520
1521 info->regs.vgt_gs_max_vert_out = info->gs.vertices_out;
1522 }
1523
1524 void
radv_precompute_registers_hw_ngg(struct radv_device * device,const struct ac_shader_config * config,struct radv_shader_info * info)1525 radv_precompute_registers_hw_ngg(struct radv_device *device, const struct ac_shader_config *config,
1526 struct radv_shader_info *info)
1527 {
1528 const struct radv_physical_device *pdev = radv_device_physical(device);
1529
1530 const bool no_pc_export = info->outinfo.param_exports == 0 && info->outinfo.prim_param_exports == 0;
1531 const unsigned num_prim_params = info->outinfo.prim_param_exports;
1532
1533 if (pdev->info.gfx_level >= GFX12) {
1534 unsigned num_params = info->outinfo.param_exports;
1535
1536 /* Since there is no alloc/dealloc mechanism for the 12-bit ordered IDs, they can wrap
1537 * around if there are more than 2^12 workgroups, causing 2 workgroups to get the same
1538 * ordered ID, which would break the streamout algorithm.
1539 * The recommended solution is to use the alloc/dealloc mechanism of the attribute ring,
1540 * which is enough to limit the range of ordered IDs that can be in flight.
1541 */
1542 if (info->so.num_outputs) {
1543 num_params = MAX2(num_params, 8);
1544 } else {
1545 num_params = MAX2(num_params, 1);
1546 }
1547
1548 info->regs.spi_vs_out_config = S_00B0C4_VS_EXPORT_COUNT(num_params - 1) |
1549 S_00B0C4_PRIM_EXPORT_COUNT(num_prim_params) | S_00B0C4_NO_PC_EXPORT(no_pc_export);
1550
1551 info->regs.spi_shader_pgm_rsrc4_gs =
1552 S_00B220_SPI_SHADER_LATE_ALLOC_GS(127) | S_00B220_GLG_FORCE_DISABLE(1) | S_00B220_WAVE_LIMIT(0x3ff);
1553 } else {
1554 const unsigned num_params = MAX2(info->outinfo.param_exports, 1);
1555
1556 info->regs.spi_vs_out_config = S_0286C4_VS_EXPORT_COUNT(num_params - 1) |
1557 S_0286C4_PRIM_EXPORT_COUNT(num_prim_params) | S_0286C4_NO_PC_EXPORT(no_pc_export);
1558
1559 unsigned late_alloc_wave64, cu_mask;
1560 ac_compute_late_alloc(&pdev->info, true, info->has_ngg_culling, config->scratch_bytes_per_wave > 0,
1561 &late_alloc_wave64, &cu_mask);
1562
1563 info->regs.spi_shader_pgm_rsrc3_gs =
1564 ac_apply_cu_en(S_00B21C_CU_EN(cu_mask) | S_00B21C_WAVE_LIMIT(0x3F), C_00B21C_CU_EN, 0, &pdev->info);
1565
1566 if (pdev->info.gfx_level >= GFX11) {
1567 info->regs.spi_shader_pgm_rsrc4_gs =
1568 ac_apply_cu_en(S_00B204_CU_EN_GFX11(0x1) | S_00B204_SPI_SHADER_LATE_ALLOC_GS_GFX10(late_alloc_wave64),
1569 C_00B204_CU_EN_GFX11, 16, &pdev->info);
1570 } else {
1571 info->regs.spi_shader_pgm_rsrc4_gs =
1572 ac_apply_cu_en(S_00B204_CU_EN_GFX10(0xffff) | S_00B204_SPI_SHADER_LATE_ALLOC_GS_GFX10(late_alloc_wave64),
1573 C_00B204_CU_EN_GFX10, 16, &pdev->info);
1574 }
1575
1576 uint32_t oversub_pc_lines = late_alloc_wave64 ? pdev->info.pc_lines / 4 : 0;
1577 if (info->has_ngg_culling) {
1578 unsigned oversub_factor = 2;
1579
1580 if (info->outinfo.param_exports > 4)
1581 oversub_factor = 4;
1582 else if (info->outinfo.param_exports > 2)
1583 oversub_factor = 3;
1584
1585 oversub_pc_lines *= oversub_factor;
1586 }
1587
1588 info->regs.ge_pc_alloc = S_030980_OVERSUB_EN(oversub_pc_lines > 0) | S_030980_NUM_PC_LINES(oversub_pc_lines - 1);
1589 }
1590
1591 unsigned idx_format = V_028708_SPI_SHADER_1COMP;
1592 if (info->outinfo.writes_layer_per_primitive || info->outinfo.writes_viewport_index_per_primitive ||
1593 info->outinfo.writes_primitive_shading_rate_per_primitive)
1594 idx_format = V_028708_SPI_SHADER_2COMP;
1595
1596 info->regs.ngg.spi_shader_idx_format = S_028708_IDX0_EXPORT_FORMAT(idx_format);
1597
1598 info->regs.spi_shader_pos_format =
1599 S_02870C_POS0_EXPORT_FORMAT(V_02870C_SPI_SHADER_4COMP) |
1600 S_02870C_POS1_EXPORT_FORMAT(info->outinfo.pos_exports > 1 ? V_02870C_SPI_SHADER_4COMP
1601 : V_02870C_SPI_SHADER_NONE) |
1602 S_02870C_POS2_EXPORT_FORMAT(info->outinfo.pos_exports > 2 ? V_02870C_SPI_SHADER_4COMP
1603 : V_02870C_SPI_SHADER_NONE) |
1604 S_02870C_POS3_EXPORT_FORMAT(info->outinfo.pos_exports > 3 ? V_02870C_SPI_SHADER_4COMP : V_02870C_SPI_SHADER_NONE);
1605
1606 const bool misc_vec_ena = info->outinfo.writes_pointsize || info->outinfo.writes_layer ||
1607 info->outinfo.writes_viewport_index || info->outinfo.writes_primitive_shading_rate;
1608 const unsigned clip_dist_mask = info->outinfo.clip_dist_mask;
1609 const unsigned cull_dist_mask = info->outinfo.cull_dist_mask;
1610 const unsigned total_mask = clip_dist_mask | cull_dist_mask;
1611
1612 info->regs.pa_cl_vs_out_cntl =
1613 S_02881C_USE_VTX_POINT_SIZE(info->outinfo.writes_pointsize) |
1614 S_02881C_USE_VTX_RENDER_TARGET_INDX(info->outinfo.writes_layer) |
1615 S_02881C_USE_VTX_VIEWPORT_INDX(info->outinfo.writes_viewport_index) |
1616 S_02881C_USE_VTX_VRS_RATE(info->outinfo.writes_primitive_shading_rate) |
1617 S_02881C_VS_OUT_MISC_VEC_ENA(misc_vec_ena) |
1618 S_02881C_VS_OUT_MISC_SIDE_BUS_ENA(misc_vec_ena ||
1619 (pdev->info.gfx_level >= GFX10_3 && info->outinfo.pos_exports > 1)) |
1620 S_02881C_VS_OUT_CCDIST0_VEC_ENA((total_mask & 0x0f) != 0) |
1621 S_02881C_VS_OUT_CCDIST1_VEC_ENA((total_mask & 0xf0) != 0) | total_mask << 8 | clip_dist_mask;
1622
1623 info->regs.ngg.vgt_primitiveid_en = S_028A84_NGG_DISABLE_PROVOK_REUSE(info->outinfo.export_prim_id);
1624
1625 const uint32_t gs_num_invocations = info->stage == MESA_SHADER_GEOMETRY ? info->gs.invocations : 1;
1626
1627 info->regs.ngg.ge_max_output_per_subgroup = S_0287FC_MAX_VERTS_PER_SUBGROUP(info->ngg_info.max_out_verts);
1628
1629 info->regs.ngg.ge_ngg_subgrp_cntl =
1630 S_028B4C_PRIM_AMP_FACTOR(info->ngg_info.prim_amp_factor) | S_028B4C_THDS_PER_SUBGRP(0); /* for fast launch */
1631
1632 info->regs.vgt_gs_instance_cnt =
1633 S_028B90_CNT(gs_num_invocations) | S_028B90_ENABLE(gs_num_invocations > 1) |
1634 S_028B90_EN_MAX_VERT_OUT_PER_GS_INSTANCE(info->ngg_info.max_vert_out_per_gs_instance);
1635
1636 if (pdev->info.gfx_level >= GFX11) {
1637 /* This should be <= 252 for performance on Gfx11. 256 works too but is slower. */
1638 const uint32_t max_prim_grp_size = pdev->info.gfx_level >= GFX12 ? 256 : 252;
1639
1640 info->regs.ngg.ge_cntl = S_03096C_PRIMS_PER_SUBGRP(info->ngg_info.max_gsprims) |
1641 S_03096C_VERTS_PER_SUBGRP(info->ngg_info.hw_max_esverts) |
1642 S_03096C_PRIM_GRP_SIZE_GFX11(max_prim_grp_size) |
1643 S_03096C_DIS_PG_SIZE_ADJUST_FOR_STRIP(pdev->info.gfx_level >= GFX12);
1644 } else {
1645 info->regs.ngg.ge_cntl = S_03096C_PRIM_GRP_SIZE_GFX10(info->ngg_info.max_gsprims) |
1646 S_03096C_VERT_GRP_SIZE(info->ngg_info.hw_max_esverts);
1647
1648 info->regs.vgt_gs_onchip_cntl = S_028A44_ES_VERTS_PER_SUBGRP(info->ngg_info.hw_max_esverts) |
1649 S_028A44_GS_PRIMS_PER_SUBGRP(info->ngg_info.max_gsprims) |
1650 S_028A44_GS_INST_PRIMS_IN_SUBGRP(info->ngg_info.max_gsprims * gs_num_invocations);
1651 }
1652
1653
1654 info->regs.vgt_gs_max_vert_out = info->gs.vertices_out;
1655 }
1656
1657 static void
radv_precompute_registers_hw_ms(struct radv_device * device,struct radv_shader_binary * binary)1658 radv_precompute_registers_hw_ms(struct radv_device *device, struct radv_shader_binary *binary)
1659 {
1660 const struct radv_physical_device *pdev = radv_device_physical(device);
1661 struct radv_shader_info *info = &binary->info;
1662
1663 radv_precompute_registers_hw_ngg(device, &binary->config, &binary->info);
1664
1665 info->regs.vgt_gs_max_vert_out = pdev->mesh_fast_launch_2 ? info->ngg_info.max_out_verts : info->workgroup_size;
1666
1667 info->regs.ms.spi_shader_gs_meshlet_dim = S_00B2B0_MESHLET_NUM_THREAD_X(info->cs.block_size[0] - 1) |
1668 S_00B2B0_MESHLET_NUM_THREAD_Y(info->cs.block_size[1] - 1) |
1669 S_00B2B0_MESHLET_NUM_THREAD_Z(info->cs.block_size[2] - 1) |
1670 S_00B2B0_MESHLET_THREADGROUP_SIZE(info->workgroup_size - 1);
1671
1672 info->regs.ms.spi_shader_gs_meshlet_exp_alloc =
1673 S_00B2B4_MAX_EXP_VERTS(info->ngg_info.max_out_verts) | S_00B2B4_MAX_EXP_PRIMS(info->ngg_info.prim_amp_factor);
1674 }
1675
1676 static void
radv_precompute_registers_hw_fs(struct radv_device * device,struct radv_shader_binary * binary)1677 radv_precompute_registers_hw_fs(struct radv_device *device, struct radv_shader_binary *binary)
1678 {
1679 const struct radv_physical_device *pdev = radv_device_physical(device);
1680 struct radv_shader_info *info = &binary->info;
1681
1682 unsigned conservative_z_export = V_02880C_EXPORT_ANY_Z;
1683 if (info->ps.depth_layout == FRAG_DEPTH_LAYOUT_GREATER)
1684 conservative_z_export = V_02880C_EXPORT_GREATER_THAN_Z;
1685 else if (info->ps.depth_layout == FRAG_DEPTH_LAYOUT_LESS)
1686 conservative_z_export = V_02880C_EXPORT_LESS_THAN_Z;
1687
1688 const unsigned z_order =
1689 info->ps.early_fragment_test || !info->ps.writes_memory ? V_02880C_EARLY_Z_THEN_LATE_Z : V_02880C_LATE_Z;
1690
1691 /* It shouldn't be needed to export gl_SampleMask when MSAA is disabled, but this appears to break Project Cars
1692 * (DXVK). See https://bugs.freedesktop.org/show_bug.cgi?id=109401
1693 */
1694 const bool mask_export_enable = info->ps.writes_sample_mask;
1695 const bool disable_rbplus = pdev->info.has_rbplus && !pdev->info.rbplus_allowed;
1696
1697 info->regs.ps.db_shader_control =
1698 S_02880C_Z_EXPORT_ENABLE(info->ps.writes_z) | S_02880C_STENCIL_TEST_VAL_EXPORT_ENABLE(info->ps.writes_stencil) |
1699 S_02880C_KILL_ENABLE(info->ps.can_discard) | S_02880C_MASK_EXPORT_ENABLE(mask_export_enable) |
1700 S_02880C_CONSERVATIVE_Z_EXPORT(conservative_z_export) | S_02880C_Z_ORDER(z_order) |
1701 S_02880C_DEPTH_BEFORE_SHADER(info->ps.early_fragment_test) |
1702 S_02880C_PRE_SHADER_DEPTH_COVERAGE_ENABLE(info->ps.post_depth_coverage) |
1703 S_02880C_EXEC_ON_HIER_FAIL(info->ps.writes_memory) | S_02880C_EXEC_ON_NOOP(info->ps.writes_memory) |
1704 S_02880C_DUAL_QUAD_DISABLE(disable_rbplus) | S_02880C_PRIMITIVE_ORDERED_PIXEL_SHADER(info->ps.pops);
1705
1706 if (pdev->info.gfx_level >= GFX12) {
1707 info->regs.ps.spi_ps_in_control = S_028640_PS_W32_EN(info->wave_size == 32);
1708 info->regs.ps.spi_gs_out_config_ps = S_00B0C4_NUM_INTERP(info->ps.num_interp);
1709
1710 info->regs.ps.pa_sc_hisz_control = S_028BBC_ROUND(2); /* required minimum value */
1711 if (info->ps.depth_layout == FRAG_DEPTH_LAYOUT_GREATER)
1712 info->regs.ps.pa_sc_hisz_control |= S_028BBC_CONSERVATIVE_Z_EXPORT(V_028BBC_EXPORT_GREATER_THAN_Z);
1713 else if (info->ps.depth_layout == FRAG_DEPTH_LAYOUT_LESS)
1714 info->regs.ps.pa_sc_hisz_control |= S_028BBC_CONSERVATIVE_Z_EXPORT(V_028BBC_EXPORT_LESS_THAN_Z);
1715 } else {
1716 /* GFX11 workaround when there are no PS inputs but LDS is used. */
1717 const bool param_gen = pdev->info.gfx_level == GFX11 && !info->ps.num_interp && binary->config.lds_size;
1718
1719 info->regs.ps.spi_ps_in_control = S_0286D8_NUM_INTERP(info->ps.num_interp) |
1720 S_0286D8_NUM_PRIM_INTERP(info->ps.num_prim_interp) |
1721 S_0286D8_PS_W32_EN(info->wave_size == 32) | S_0286D8_PARAM_GEN(param_gen);
1722
1723 if (pdev->info.gfx_level >= GFX9 && pdev->info.gfx_level < GFX11)
1724 info->regs.ps.pa_sc_shader_control = S_028C40_LOAD_COLLISION_WAVEID(info->ps.pops);
1725 }
1726
1727 info->regs.ps.spi_shader_z_format = ac_get_spi_shader_z_format(
1728 info->ps.writes_z, info->ps.writes_stencil, info->ps.writes_sample_mask, info->ps.writes_mrt0_alpha);
1729 }
1730
1731 static void
radv_precompute_registers_hw_cs(struct radv_device * device,struct radv_shader_binary * binary)1732 radv_precompute_registers_hw_cs(struct radv_device *device, struct radv_shader_binary *binary)
1733 {
1734 const struct radv_physical_device *pdev = radv_device_physical(device);
1735 struct radv_shader_info *info = &binary->info;
1736
1737 info->regs.cs.compute_resource_limits = radv_get_compute_resource_limits(pdev, info);
1738 if (pdev->info.gfx_level >= GFX12) {
1739 info->regs.cs.compute_num_thread_x = S_00B81C_NUM_THREAD_FULL_GFX12(info->cs.block_size[0]);
1740 info->regs.cs.compute_num_thread_y = S_00B820_NUM_THREAD_FULL_GFX12(info->cs.block_size[1]);
1741 } else {
1742 info->regs.cs.compute_num_thread_x = S_00B81C_NUM_THREAD_FULL_GFX6(info->cs.block_size[0]);
1743 info->regs.cs.compute_num_thread_y = S_00B820_NUM_THREAD_FULL_GFX6(info->cs.block_size[1]);
1744 }
1745 info->regs.cs.compute_num_thread_z = S_00B824_NUM_THREAD_FULL(info->cs.block_size[2]);
1746 }
1747
1748 static void
radv_precompute_registers_pgm(const struct radv_device * device,struct radv_shader_info * info)1749 radv_precompute_registers_pgm(const struct radv_device *device, struct radv_shader_info *info)
1750 {
1751 const struct radv_physical_device *pdev = radv_device_physical(device);
1752 const enum amd_gfx_level gfx_level = pdev->info.gfx_level;
1753 enum ac_hw_stage hw_stage = radv_select_hw_stage(info, gfx_level);
1754
1755 /* Special case for merged shaders compiled separately with ESO on GFX9+. */
1756 if (info->merged_shader_compiled_separately) {
1757 if (info->stage == MESA_SHADER_VERTEX && info->next_stage == MESA_SHADER_TESS_CTRL) {
1758 hw_stage = AC_HW_HULL_SHADER;
1759 } else if ((info->stage == MESA_SHADER_VERTEX || info->stage == MESA_SHADER_TESS_EVAL) &&
1760 info->next_stage == MESA_SHADER_GEOMETRY) {
1761 hw_stage = info->is_ngg ? AC_HW_NEXT_GEN_GEOMETRY_SHADER : AC_HW_LEGACY_GEOMETRY_SHADER;
1762 }
1763 }
1764
1765 switch (hw_stage) {
1766 case AC_HW_NEXT_GEN_GEOMETRY_SHADER:
1767 assert(gfx_level >= GFX10);
1768 if (gfx_level >= GFX12) {
1769 info->regs.pgm_lo = R_00B224_SPI_SHADER_PGM_LO_ES;
1770 } else {
1771 info->regs.pgm_lo = R_00B320_SPI_SHADER_PGM_LO_ES;
1772 }
1773
1774 info->regs.pgm_rsrc1 = R_00B228_SPI_SHADER_PGM_RSRC1_GS;
1775 info->regs.pgm_rsrc2 = R_00B22C_SPI_SHADER_PGM_RSRC2_GS;
1776 break;
1777 case AC_HW_LEGACY_GEOMETRY_SHADER:
1778 assert(gfx_level < GFX11);
1779 if (gfx_level >= GFX10) {
1780 info->regs.pgm_lo = R_00B320_SPI_SHADER_PGM_LO_ES;
1781 } else if (gfx_level >= GFX9) {
1782 info->regs.pgm_lo = R_00B210_SPI_SHADER_PGM_LO_ES;
1783 } else {
1784 info->regs.pgm_lo = R_00B220_SPI_SHADER_PGM_LO_GS;
1785 }
1786
1787 info->regs.pgm_rsrc1 = R_00B228_SPI_SHADER_PGM_RSRC1_GS;
1788 info->regs.pgm_rsrc2 = R_00B22C_SPI_SHADER_PGM_RSRC2_GS;
1789 break;
1790 case AC_HW_EXPORT_SHADER:
1791 assert(gfx_level < GFX9);
1792 info->regs.pgm_lo = R_00B320_SPI_SHADER_PGM_LO_ES;
1793 info->regs.pgm_rsrc1 = R_00B328_SPI_SHADER_PGM_RSRC1_ES;
1794 info->regs.pgm_rsrc2 = R_00B32C_SPI_SHADER_PGM_RSRC2_ES;
1795 break;
1796 case AC_HW_LOCAL_SHADER:
1797 assert(gfx_level < GFX9);
1798 info->regs.pgm_lo = R_00B520_SPI_SHADER_PGM_LO_LS;
1799 info->regs.pgm_rsrc1 = R_00B528_SPI_SHADER_PGM_RSRC1_LS;
1800 info->regs.pgm_rsrc2 = R_00B52C_SPI_SHADER_PGM_RSRC2_LS;
1801 break;
1802 case AC_HW_HULL_SHADER:
1803 if (gfx_level >= GFX12) {
1804 info->regs.pgm_lo = R_00B424_SPI_SHADER_PGM_LO_LS;
1805 } else if (gfx_level >= GFX10) {
1806 info->regs.pgm_lo = R_00B520_SPI_SHADER_PGM_LO_LS;
1807 } else if (gfx_level >= GFX9) {
1808 info->regs.pgm_lo = R_00B410_SPI_SHADER_PGM_LO_LS;
1809 } else {
1810 info->regs.pgm_lo = R_00B420_SPI_SHADER_PGM_LO_HS;
1811 }
1812
1813 info->regs.pgm_rsrc1 = R_00B428_SPI_SHADER_PGM_RSRC1_HS;
1814 info->regs.pgm_rsrc2 = R_00B42C_SPI_SHADER_PGM_RSRC2_HS;
1815 break;
1816 case AC_HW_VERTEX_SHADER:
1817 assert(gfx_level < GFX11);
1818 info->regs.pgm_lo = R_00B120_SPI_SHADER_PGM_LO_VS;
1819 info->regs.pgm_rsrc1 = R_00B128_SPI_SHADER_PGM_RSRC1_VS;
1820 info->regs.pgm_rsrc2 = R_00B12C_SPI_SHADER_PGM_RSRC2_VS;
1821 break;
1822 case AC_HW_PIXEL_SHADER:
1823 info->regs.pgm_lo = R_00B020_SPI_SHADER_PGM_LO_PS;
1824 info->regs.pgm_rsrc1 = R_00B028_SPI_SHADER_PGM_RSRC1_PS;
1825 info->regs.pgm_rsrc2 = R_00B02C_SPI_SHADER_PGM_RSRC2_PS;
1826 break;
1827 case AC_HW_COMPUTE_SHADER:
1828 info->regs.pgm_lo = R_00B830_COMPUTE_PGM_LO;
1829 info->regs.pgm_rsrc1 = R_00B848_COMPUTE_PGM_RSRC1;
1830 info->regs.pgm_rsrc2 = R_00B84C_COMPUTE_PGM_RSRC2;
1831 info->regs.pgm_rsrc3 = R_00B8A0_COMPUTE_PGM_RSRC3;
1832 break;
1833 default:
1834 unreachable("invalid hw stage");
1835 break;
1836 }
1837 }
1838
1839 static void
radv_precompute_registers(struct radv_device * device,struct radv_shader_binary * binary)1840 radv_precompute_registers(struct radv_device *device, struct radv_shader_binary *binary)
1841 {
1842 struct radv_shader_info *info = &binary->info;
1843
1844 radv_precompute_registers_pgm(device, info);
1845
1846 switch (info->stage) {
1847 case MESA_SHADER_VERTEX:
1848 if (!info->vs.as_ls && !info->vs.as_es) {
1849 if (info->is_ngg) {
1850 radv_precompute_registers_hw_ngg(device, &binary->config, &binary->info);
1851 } else {
1852 radv_precompute_registers_hw_vs(device, binary);
1853 }
1854 }
1855 break;
1856 case MESA_SHADER_TESS_EVAL:
1857 if (!info->tes.as_es) {
1858 if (info->is_ngg) {
1859 radv_precompute_registers_hw_ngg(device, &binary->config, &binary->info);
1860 } else {
1861 radv_precompute_registers_hw_vs(device, binary);
1862 }
1863 }
1864 break;
1865 case MESA_SHADER_GEOMETRY:
1866 if (info->is_ngg) {
1867 radv_precompute_registers_hw_ngg(device, &binary->config, &binary->info);
1868 } else {
1869 radv_precompute_registers_hw_gs(device, binary);
1870 }
1871 break;
1872 case MESA_SHADER_MESH:
1873 radv_precompute_registers_hw_ms(device, binary);
1874 break;
1875 case MESA_SHADER_FRAGMENT:
1876 radv_precompute_registers_hw_fs(device, binary);
1877 break;
1878 case MESA_SHADER_COMPUTE:
1879 case MESA_SHADER_TASK:
1880 radv_precompute_registers_hw_cs(device, binary);
1881 break;
1882 default:
1883 break;
1884 }
1885 }
1886
1887 static bool
radv_mem_ordered(const struct radv_physical_device * pdev)1888 radv_mem_ordered(const struct radv_physical_device *pdev)
1889 {
1890 return pdev->info.gfx_level >= GFX10 && pdev->info.gfx_level < GFX12;
1891 }
1892
1893 static bool
radv_postprocess_binary_config(struct radv_device * device,struct radv_shader_binary * binary,const struct radv_shader_args * args)1894 radv_postprocess_binary_config(struct radv_device *device, struct radv_shader_binary *binary,
1895 const struct radv_shader_args *args)
1896 {
1897 const struct radv_physical_device *pdev = radv_device_physical(device);
1898 struct ac_shader_config *config = &binary->config;
1899
1900 if (binary->type == RADV_BINARY_TYPE_RTLD) {
1901 #if !defined(USE_LIBELF)
1902 return false;
1903 #else
1904 struct ac_rtld_binary rtld_binary = {0};
1905
1906 if (!radv_open_rtld_binary(device, binary, &rtld_binary)) {
1907 return false;
1908 }
1909
1910 if (!ac_rtld_read_config(&pdev->info, &rtld_binary, config)) {
1911 ac_rtld_close(&rtld_binary);
1912 return false;
1913 }
1914
1915 if (rtld_binary.lds_size > 0) {
1916 unsigned encode_granularity = pdev->info.lds_encode_granularity;
1917 config->lds_size = DIV_ROUND_UP(rtld_binary.lds_size, encode_granularity);
1918 }
1919 if (!config->lds_size && binary->info.stage == MESA_SHADER_TESS_CTRL) {
1920 /* This is used for reporting LDS statistics */
1921 config->lds_size = binary->info.tcs.num_lds_blocks;
1922 }
1923
1924 assert(!binary->info.has_ngg_culling || config->lds_size);
1925 ac_rtld_close(&rtld_binary);
1926 #endif
1927 }
1928
1929 const struct radv_shader_info *info = &binary->info;
1930 gl_shader_stage stage = binary->info.stage;
1931 bool scratch_enabled = config->scratch_bytes_per_wave > 0;
1932 bool trap_enabled = !!device->trap_handler_shader;
1933 unsigned vgpr_comp_cnt = 0;
1934 unsigned num_input_vgprs = args->ac.num_vgprs_used;
1935
1936 if (stage == MESA_SHADER_FRAGMENT) {
1937 num_input_vgprs = ac_get_fs_input_vgpr_cnt(config, NULL);
1938 }
1939
1940 unsigned num_vgprs = MAX2(config->num_vgprs, num_input_vgprs);
1941 /* +2 for the ring offsets, +3 for scratch wave offset and VCC */
1942 unsigned num_sgprs = MAX2(config->num_sgprs, args->ac.num_sgprs_used + 2 + 3);
1943 unsigned num_shared_vgprs = config->num_shared_vgprs;
1944 /* shared VGPRs are introduced in Navi and are allocated in blocks of 8 (RDNA ref 3.6.5) */
1945 assert((pdev->info.gfx_level >= GFX10 && num_shared_vgprs % 8 == 0) ||
1946 (pdev->info.gfx_level < GFX10 && num_shared_vgprs == 0));
1947 unsigned num_shared_vgpr_blocks = num_shared_vgprs / 8;
1948 unsigned excp_en = 0;
1949
1950 config->num_vgprs = num_vgprs;
1951 config->num_sgprs = num_sgprs;
1952 config->num_shared_vgprs = num_shared_vgprs;
1953
1954 config->rsrc2 = S_00B12C_USER_SGPR(args->num_user_sgprs) | S_00B12C_SCRATCH_EN(scratch_enabled) |
1955 S_00B12C_TRAP_PRESENT(trap_enabled);
1956
1957 if (trap_enabled) {
1958 /* Configure the shader exceptions like memory violation, etc.
1959 * TODO: Enable (and validate) more exceptions.
1960 */
1961 excp_en = 1 << 8; /* mem_viol */
1962 }
1963
1964 if (!pdev->use_ngg_streamout) {
1965 config->rsrc2 |= S_00B12C_SO_BASE0_EN(!!info->so.strides[0]) | S_00B12C_SO_BASE1_EN(!!info->so.strides[1]) |
1966 S_00B12C_SO_BASE2_EN(!!info->so.strides[2]) | S_00B12C_SO_BASE3_EN(!!info->so.strides[3]) |
1967 S_00B12C_SO_EN(!!info->so.num_outputs);
1968 }
1969
1970 config->rsrc1 = S_00B848_VGPRS((num_vgprs - 1) / (info->wave_size == 32 ? 8 : 4)) |
1971 S_00B848_DX10_CLAMP(pdev->info.gfx_level < GFX12) | S_00B848_FLOAT_MODE(config->float_mode);
1972
1973 if (pdev->info.gfx_level >= GFX10) {
1974 config->rsrc2 |= S_00B22C_USER_SGPR_MSB_GFX10(args->num_user_sgprs >> 5);
1975 } else {
1976 config->rsrc1 |= S_00B228_SGPRS((num_sgprs - 1) / 8);
1977 config->rsrc2 |= S_00B22C_USER_SGPR_MSB_GFX9(args->num_user_sgprs >> 5);
1978 }
1979
1980 gl_shader_stage es_stage = MESA_SHADER_NONE;
1981 if (pdev->info.gfx_level >= GFX9) {
1982 es_stage = stage == MESA_SHADER_GEOMETRY ? info->gs.es_type : stage;
1983 }
1984
1985 if (info->merged_shader_compiled_separately) {
1986 /* Update the stage for merged shaders compiled separately with ESO on GFX9+. */
1987 if (stage == MESA_SHADER_VERTEX && info->vs.as_ls) {
1988 stage = MESA_SHADER_TESS_CTRL;
1989 } else if (stage == MESA_SHADER_VERTEX && info->vs.as_es) {
1990 es_stage = MESA_SHADER_VERTEX;
1991 stage = MESA_SHADER_GEOMETRY;
1992 } else if (stage == MESA_SHADER_TESS_EVAL && info->tes.as_es) {
1993 es_stage = MESA_SHADER_TESS_EVAL;
1994 stage = MESA_SHADER_GEOMETRY;
1995 }
1996 }
1997
1998 bool wgp_mode = radv_should_use_wgp_mode(device, stage, info);
1999
2000 switch (stage) {
2001 case MESA_SHADER_TESS_EVAL:
2002 if (info->is_ngg) {
2003 config->rsrc1 |= S_00B228_MEM_ORDERED(radv_mem_ordered(pdev));
2004 config->rsrc2 |= S_00B22C_OC_LDS_EN(1) | S_00B22C_EXCP_EN(excp_en);
2005 } else if (info->tes.as_es) {
2006 assert(pdev->info.gfx_level <= GFX8);
2007 vgpr_comp_cnt = info->uses_prim_id ? 3 : 2;
2008
2009 config->rsrc2 |= S_00B12C_OC_LDS_EN(1) | S_00B12C_EXCP_EN(excp_en);
2010 } else {
2011 bool enable_prim_id = info->outinfo.export_prim_id || info->uses_prim_id;
2012 vgpr_comp_cnt = enable_prim_id ? 3 : 2;
2013
2014 config->rsrc1 |= S_00B128_MEM_ORDERED(radv_mem_ordered(pdev));
2015 config->rsrc2 |= S_00B12C_OC_LDS_EN(1) | S_00B12C_EXCP_EN(excp_en);
2016 }
2017 config->rsrc2 |= S_00B22C_SHARED_VGPR_CNT(num_shared_vgpr_blocks);
2018 break;
2019 case MESA_SHADER_TESS_CTRL:
2020 if (pdev->info.gfx_level >= GFX9) {
2021 /* We need at least 2 components for LS.
2022 * VGPR0-3: (VertexID, RelAutoindex, InstanceID / StepRate0, InstanceID).
2023 * StepRate0 is set to 1. so that VGPR3 doesn't have to be loaded.
2024 */
2025 if (pdev->info.gfx_level >= GFX10) {
2026 if (info->vs.needs_instance_id) {
2027 vgpr_comp_cnt = pdev->info.gfx_level >= GFX12 ? 1 : 3;
2028 } else if (pdev->info.gfx_level <= GFX10_3) {
2029 vgpr_comp_cnt = 1;
2030 }
2031 config->rsrc2 |= S_00B42C_EXCP_EN_GFX6(excp_en);
2032 } else {
2033 vgpr_comp_cnt = info->vs.needs_instance_id ? 2 : 1;
2034 config->rsrc2 |= S_00B42C_EXCP_EN_GFX9(excp_en);
2035 }
2036 } else {
2037 config->rsrc2 |= S_00B12C_OC_LDS_EN(1) | S_00B12C_EXCP_EN(excp_en);
2038 }
2039 config->rsrc1 |= S_00B428_MEM_ORDERED(radv_mem_ordered(pdev)) | S_00B428_WGP_MODE(wgp_mode);
2040 config->rsrc2 |= S_00B42C_SHARED_VGPR_CNT(num_shared_vgpr_blocks);
2041 break;
2042 case MESA_SHADER_VERTEX:
2043 if (info->is_ngg) {
2044 config->rsrc1 |= S_00B228_MEM_ORDERED(radv_mem_ordered(pdev));
2045 } else if (info->vs.as_ls) {
2046 assert(pdev->info.gfx_level <= GFX8);
2047 /* We need at least 2 components for LS.
2048 * VGPR0-3: (VertexID, RelAutoindex, InstanceID / StepRate0, InstanceID).
2049 * StepRate0 is set to 1. so that VGPR3 doesn't have to be loaded.
2050 *
2051 * On GFX12, InstanceID is in VGPR1.
2052 */
2053 vgpr_comp_cnt = info->vs.needs_instance_id ? 2 : 1;
2054 } else if (info->vs.as_es) {
2055 assert(pdev->info.gfx_level <= GFX8);
2056 /* VGPR0-3: (VertexID, InstanceID / StepRate0, ...) */
2057 vgpr_comp_cnt = info->vs.needs_instance_id ? 1 : 0;
2058 } else {
2059 /* VGPR0-3: (VertexID, InstanceID / StepRate0, PrimID, InstanceID)
2060 * If PrimID is disabled. InstanceID / StepRate1 is loaded instead.
2061 * StepRate0 is set to 1. so that VGPR3 doesn't have to be loaded.
2062 */
2063 if (info->vs.needs_instance_id && pdev->info.gfx_level >= GFX10) {
2064 vgpr_comp_cnt = 3;
2065 } else if (info->outinfo.export_prim_id) {
2066 vgpr_comp_cnt = 2;
2067 } else if (info->vs.needs_instance_id) {
2068 vgpr_comp_cnt = 1;
2069 } else {
2070 vgpr_comp_cnt = 0;
2071 }
2072
2073 config->rsrc1 |= S_00B128_MEM_ORDERED(radv_mem_ordered(pdev));
2074 }
2075 config->rsrc2 |= S_00B12C_SHARED_VGPR_CNT(num_shared_vgpr_blocks) | S_00B12C_EXCP_EN(excp_en);
2076 break;
2077 case MESA_SHADER_MESH:
2078 config->rsrc1 |= S_00B228_MEM_ORDERED(radv_mem_ordered(pdev));
2079 config->rsrc2 |= S_00B12C_SHARED_VGPR_CNT(num_shared_vgpr_blocks) | S_00B12C_EXCP_EN(excp_en);
2080 break;
2081 case MESA_SHADER_FRAGMENT:
2082 config->rsrc1 |=
2083 S_00B028_MEM_ORDERED(radv_mem_ordered(pdev)) | S_00B028_LOAD_PROVOKING_VTX(info->ps.load_provoking_vtx);
2084 config->rsrc2 |= S_00B02C_SHARED_VGPR_CNT(num_shared_vgpr_blocks) | S_00B02C_EXCP_EN(excp_en) |
2085 S_00B02C_LOAD_COLLISION_WAVEID(info->ps.pops && pdev->info.gfx_level < GFX11);
2086 break;
2087 case MESA_SHADER_GEOMETRY:
2088 config->rsrc1 |= S_00B228_MEM_ORDERED(radv_mem_ordered(pdev));
2089 config->rsrc2 |= S_00B22C_SHARED_VGPR_CNT(num_shared_vgpr_blocks) | S_00B22C_EXCP_EN(excp_en);
2090 break;
2091 case MESA_SHADER_RAYGEN:
2092 case MESA_SHADER_CLOSEST_HIT:
2093 case MESA_SHADER_MISS:
2094 case MESA_SHADER_CALLABLE:
2095 case MESA_SHADER_INTERSECTION:
2096 case MESA_SHADER_ANY_HIT:
2097 case MESA_SHADER_COMPUTE:
2098 case MESA_SHADER_TASK:
2099 config->rsrc1 |= S_00B848_MEM_ORDERED(radv_mem_ordered(pdev)) | S_00B848_WGP_MODE(wgp_mode);
2100 config->rsrc2 |= S_00B84C_TGID_X_EN(info->cs.uses_block_id[0]) | S_00B84C_TGID_Y_EN(info->cs.uses_block_id[1]) |
2101 S_00B84C_TGID_Z_EN(info->cs.uses_block_id[2]) |
2102 S_00B84C_TIDIG_COMP_CNT(info->cs.uses_thread_id[2] ? 2
2103 : info->cs.uses_thread_id[1] ? 1
2104 : 0) |
2105 S_00B84C_TG_SIZE_EN(info->cs.uses_local_invocation_idx) | S_00B84C_LDS_SIZE(config->lds_size) |
2106 S_00B84C_EXCP_EN(excp_en);
2107 config->rsrc3 |= S_00B8A0_SHARED_VGPR_CNT(num_shared_vgpr_blocks);
2108
2109 break;
2110 default:
2111 unreachable("unsupported shader type");
2112 break;
2113 }
2114
2115 if (pdev->info.gfx_level >= GFX10 && info->is_ngg &&
2116 (stage == MESA_SHADER_VERTEX || stage == MESA_SHADER_TESS_EVAL || stage == MESA_SHADER_GEOMETRY ||
2117 stage == MESA_SHADER_MESH)) {
2118 unsigned gs_vgpr_comp_cnt, es_vgpr_comp_cnt;
2119
2120 /* VGPR5-8: (VertexID, UserVGPR0, UserVGPR1, UserVGPR2 / InstanceID)
2121 *
2122 * On GFX12, InstanceID is in VGPR1.
2123 */
2124 if (es_stage == MESA_SHADER_VERTEX) {
2125 if (info->vs.needs_instance_id) {
2126 es_vgpr_comp_cnt = pdev->info.gfx_level >= GFX12 ? 1 : 3;
2127 } else {
2128 es_vgpr_comp_cnt = 0;
2129 }
2130 } else if (es_stage == MESA_SHADER_TESS_EVAL) {
2131 bool enable_prim_id = info->outinfo.export_prim_id || info->uses_prim_id;
2132 es_vgpr_comp_cnt = enable_prim_id ? 3 : 2;
2133 } else if (es_stage == MESA_SHADER_MESH) {
2134 es_vgpr_comp_cnt = 0;
2135 } else {
2136 unreachable("Unexpected ES shader stage");
2137 }
2138
2139 if (pdev->info.gfx_level >= GFX12) {
2140 if (info->gs.vertices_in >= 4) {
2141 gs_vgpr_comp_cnt = 2; /* VGPR2 contains offsets 3-5 */
2142 } else if (info->uses_prim_id || (es_stage == MESA_SHADER_VERTEX && info->outinfo.export_prim_id)) {
2143 gs_vgpr_comp_cnt = 1; /* VGPR1 contains PrimitiveID. */
2144 } else {
2145 gs_vgpr_comp_cnt = 0; /* VGPR0 contains offsets 0-2, GS invocation ID. */
2146 }
2147 } else {
2148 /* GS vertex offsets in NGG:
2149 * - in passthrough mode, they are all packed into VGPR0
2150 * - in the default mode: VGPR0: offsets 0, 1; VGPR1: offsets 2, 3
2151 *
2152 * The vertex offset 2 is always needed when NGG isn't in passthrough mode
2153 * and uses triangle input primitives, including with NGG culling.
2154 */
2155 bool need_gs_vtx_offset2 = !info->is_ngg_passthrough || info->gs.vertices_in >= 3;
2156
2157 /* TES only needs vertex offset 2 for triangles or quads. */
2158 if (stage == MESA_SHADER_TESS_EVAL)
2159 need_gs_vtx_offset2 &= info->tes._primitive_mode == TESS_PRIMITIVE_TRIANGLES ||
2160 info->tes._primitive_mode == TESS_PRIMITIVE_QUADS;
2161
2162 if (info->uses_invocation_id) {
2163 gs_vgpr_comp_cnt = 3; /* VGPR3 contains InvocationID. */
2164 } else if (info->uses_prim_id || (es_stage == MESA_SHADER_VERTEX && info->outinfo.export_prim_id)) {
2165 gs_vgpr_comp_cnt = 2; /* VGPR2 contains PrimitiveID. */
2166 } else if (need_gs_vtx_offset2) {
2167 gs_vgpr_comp_cnt = 1; /* VGPR1 contains offsets 2, 3 */
2168 } else {
2169 gs_vgpr_comp_cnt = 0; /* VGPR0 contains offsets 0, 1 (or passthrough prim) */
2170 }
2171 }
2172
2173 /* Disable the WGP mode on gfx10.3 because it can hang. (it
2174 * happened on VanGogh) Let's disable it on all chips that
2175 * disable exactly 1 CU per SA for GS.
2176 */
2177 config->rsrc1 |= S_00B228_GS_VGPR_COMP_CNT(gs_vgpr_comp_cnt) | S_00B228_WGP_MODE(wgp_mode);
2178 config->rsrc2 |= S_00B22C_ES_VGPR_COMP_CNT(es_vgpr_comp_cnt) | S_00B22C_LDS_SIZE(config->lds_size) |
2179 S_00B22C_OC_LDS_EN(es_stage == MESA_SHADER_TESS_EVAL);
2180 } else if (pdev->info.gfx_level >= GFX9 && stage == MESA_SHADER_GEOMETRY) {
2181 unsigned gs_vgpr_comp_cnt, es_vgpr_comp_cnt;
2182
2183 if (es_stage == MESA_SHADER_VERTEX) {
2184 /* VGPR0-3: (VertexID, InstanceID / StepRate0, ...) */
2185 if (info->vs.needs_instance_id) {
2186 es_vgpr_comp_cnt = pdev->info.gfx_level >= GFX10 ? 3 : 1;
2187 } else {
2188 es_vgpr_comp_cnt = 0;
2189 }
2190 } else if (es_stage == MESA_SHADER_TESS_EVAL) {
2191 es_vgpr_comp_cnt = info->uses_prim_id ? 3 : 2;
2192 } else {
2193 unreachable("invalid shader ES type");
2194 }
2195
2196 /* If offsets 4, 5 are used, GS_VGPR_COMP_CNT is ignored and
2197 * VGPR[0:4] are always loaded.
2198 */
2199 if (info->uses_invocation_id) {
2200 gs_vgpr_comp_cnt = 3; /* VGPR3 contains InvocationID. */
2201 } else if (info->uses_prim_id) {
2202 gs_vgpr_comp_cnt = 2; /* VGPR2 contains PrimitiveID. */
2203 } else if (info->gs.vertices_in >= 3) {
2204 gs_vgpr_comp_cnt = 1; /* VGPR1 contains offsets 2, 3 */
2205 } else {
2206 gs_vgpr_comp_cnt = 0; /* VGPR0 contains offsets 0, 1 */
2207 }
2208
2209 config->rsrc1 |= S_00B228_GS_VGPR_COMP_CNT(gs_vgpr_comp_cnt) | S_00B228_WGP_MODE(wgp_mode);
2210 config->rsrc2 |=
2211 S_00B22C_ES_VGPR_COMP_CNT(es_vgpr_comp_cnt) | S_00B22C_OC_LDS_EN(es_stage == MESA_SHADER_TESS_EVAL);
2212 } else if (pdev->info.gfx_level >= GFX9 && stage == MESA_SHADER_TESS_CTRL) {
2213 config->rsrc1 |= S_00B428_LS_VGPR_COMP_CNT(vgpr_comp_cnt);
2214 } else {
2215 config->rsrc1 |= S_00B128_VGPR_COMP_CNT(vgpr_comp_cnt);
2216 }
2217
2218 /* Precompute register values for faster emission. */
2219 radv_precompute_registers(device, binary);
2220
2221 return true;
2222 }
2223
2224 void
radv_shader_combine_cfg_vs_tcs(const struct radv_shader * vs,const struct radv_shader * tcs,uint32_t * rsrc1_out,uint32_t * rsrc2_out)2225 radv_shader_combine_cfg_vs_tcs(const struct radv_shader *vs, const struct radv_shader *tcs, uint32_t *rsrc1_out,
2226 uint32_t *rsrc2_out)
2227 {
2228 if (rsrc1_out) {
2229 uint32_t rsrc1 = vs->config.rsrc1;
2230
2231 if (G_00B848_VGPRS(tcs->config.rsrc1) > G_00B848_VGPRS(rsrc1))
2232 rsrc1 = (rsrc1 & C_00B848_VGPRS) | (tcs->config.rsrc1 & ~C_00B848_VGPRS);
2233 if (G_00B228_SGPRS(tcs->config.rsrc1) > G_00B228_SGPRS(rsrc1))
2234 rsrc1 = (rsrc1 & C_00B228_SGPRS) | (tcs->config.rsrc1 & ~C_00B228_SGPRS);
2235 if (G_00B428_LS_VGPR_COMP_CNT(tcs->config.rsrc1) > G_00B428_LS_VGPR_COMP_CNT(rsrc1))
2236 rsrc1 = (rsrc1 & C_00B428_LS_VGPR_COMP_CNT) | (tcs->config.rsrc1 & ~C_00B428_LS_VGPR_COMP_CNT);
2237
2238 *rsrc1_out = rsrc1;
2239 }
2240
2241 if (rsrc2_out) {
2242 uint32_t rsrc2 = vs->config.rsrc2;
2243
2244 rsrc2 |= tcs->config.rsrc2 & ~C_00B12C_SCRATCH_EN;
2245
2246 *rsrc2_out = rsrc2;
2247 }
2248 }
2249
2250 void
radv_shader_combine_cfg_vs_gs(const struct radv_shader * vs,const struct radv_shader * gs,uint32_t * rsrc1_out,uint32_t * rsrc2_out)2251 radv_shader_combine_cfg_vs_gs(const struct radv_shader *vs, const struct radv_shader *gs, uint32_t *rsrc1_out,
2252 uint32_t *rsrc2_out)
2253 {
2254 assert(G_00B12C_USER_SGPR(vs->config.rsrc2) == G_00B12C_USER_SGPR(gs->config.rsrc2));
2255
2256 if (rsrc1_out) {
2257 uint32_t rsrc1 = vs->config.rsrc1;
2258
2259 if (G_00B848_VGPRS(gs->config.rsrc1) > G_00B848_VGPRS(rsrc1))
2260 rsrc1 = (rsrc1 & C_00B848_VGPRS) | (gs->config.rsrc1 & ~C_00B848_VGPRS);
2261 if (G_00B228_SGPRS(gs->config.rsrc1) > G_00B228_SGPRS(rsrc1))
2262 rsrc1 = (rsrc1 & C_00B228_SGPRS) | (gs->config.rsrc1 & ~C_00B228_SGPRS);
2263 if (G_00B228_GS_VGPR_COMP_CNT(gs->config.rsrc1) > G_00B228_GS_VGPR_COMP_CNT(rsrc1))
2264 rsrc1 = (rsrc1 & C_00B228_GS_VGPR_COMP_CNT) | (gs->config.rsrc1 & ~C_00B228_GS_VGPR_COMP_CNT);
2265
2266 *rsrc1_out = rsrc1;
2267 }
2268
2269 if (rsrc2_out) {
2270 uint32_t rsrc2 = vs->config.rsrc2;
2271
2272 if (G_00B22C_ES_VGPR_COMP_CNT(gs->config.rsrc2) > G_00B22C_ES_VGPR_COMP_CNT(rsrc2))
2273 rsrc2 = (rsrc2 & C_00B22C_ES_VGPR_COMP_CNT) | (gs->config.rsrc2 & ~C_00B22C_ES_VGPR_COMP_CNT);
2274
2275 rsrc2 |= gs->config.rsrc2 & ~(C_00B12C_SCRATCH_EN & C_00B12C_SO_EN & C_00B12C_SO_BASE0_EN & C_00B12C_SO_BASE1_EN &
2276 C_00B12C_SO_BASE2_EN & C_00B12C_SO_BASE3_EN);
2277
2278 *rsrc2_out = rsrc2;
2279 }
2280 }
2281
2282 void
radv_shader_combine_cfg_tes_gs(const struct radv_shader * tes,const struct radv_shader * gs,uint32_t * rsrc1_out,uint32_t * rsrc2_out)2283 radv_shader_combine_cfg_tes_gs(const struct radv_shader *tes, const struct radv_shader *gs, uint32_t *rsrc1_out,
2284 uint32_t *rsrc2_out)
2285 {
2286 radv_shader_combine_cfg_vs_gs(tes, gs, rsrc1_out, rsrc2_out);
2287
2288 if (rsrc2_out) {
2289 *rsrc2_out |= S_00B22C_OC_LDS_EN(1);
2290 }
2291 }
2292
2293 static bool
radv_shader_binary_upload(struct radv_device * device,const struct radv_shader_binary * binary,struct radv_shader * shader,void * dest_ptr)2294 radv_shader_binary_upload(struct radv_device *device, const struct radv_shader_binary *binary,
2295 struct radv_shader *shader, void *dest_ptr)
2296 {
2297 shader->code = calloc(shader->code_size, 1);
2298 if (!shader->code) {
2299 radv_shader_unref(device, shader);
2300 return false;
2301 }
2302
2303 if (binary->type == RADV_BINARY_TYPE_RTLD) {
2304 #if !defined(USE_LIBELF)
2305 return false;
2306 #else
2307 struct ac_rtld_binary rtld_binary = {0};
2308
2309 if (!radv_open_rtld_binary(device, binary, &rtld_binary)) {
2310 free(shader);
2311 return false;
2312 }
2313
2314 struct ac_rtld_upload_info info = {
2315 .binary = &rtld_binary,
2316 .rx_va = radv_shader_get_va(shader),
2317 .rx_ptr = dest_ptr,
2318 };
2319
2320 if (!ac_rtld_upload(&info)) {
2321 radv_shader_unref(device, shader);
2322 ac_rtld_close(&rtld_binary);
2323 return false;
2324 }
2325
2326 ac_rtld_close(&rtld_binary);
2327
2328 if (shader->code) {
2329 /* Instead of running RTLD twice, just copy the relocated binary back from VRAM.
2330 * Use streaming memcpy to reduce penalty of copying from uncachable memory.
2331 */
2332 util_streaming_load_memcpy(shader->code, dest_ptr, shader->code_size);
2333 }
2334 #endif
2335 } else {
2336 struct radv_shader_binary_legacy *bin = (struct radv_shader_binary_legacy *)binary;
2337 memcpy(dest_ptr, bin->data + bin->stats_size, bin->code_size);
2338
2339 if (shader->code) {
2340 memcpy(shader->code, bin->data + bin->stats_size, bin->code_size);
2341 }
2342 }
2343
2344 return true;
2345 }
2346
2347 static VkResult
radv_shader_dma_resize_upload_buf(struct radv_device * device,struct radv_shader_dma_submission * submission,uint64_t size)2348 radv_shader_dma_resize_upload_buf(struct radv_device *device, struct radv_shader_dma_submission *submission,
2349 uint64_t size)
2350 {
2351 if (submission->bo)
2352 radv_bo_destroy(device, NULL, submission->bo);
2353
2354 VkResult result = radv_bo_create(
2355 device, NULL, size, RADV_SHADER_ALLOC_ALIGNMENT, RADEON_DOMAIN_GTT,
2356 RADEON_FLAG_CPU_ACCESS | RADEON_FLAG_NO_INTERPROCESS_SHARING | RADEON_FLAG_32BIT | RADEON_FLAG_GTT_WC,
2357 RADV_BO_PRIORITY_UPLOAD_BUFFER, 0, true, &submission->bo);
2358 if (result != VK_SUCCESS)
2359 return result;
2360
2361 submission->ptr = radv_buffer_map(device->ws, submission->bo);
2362 submission->bo_size = size;
2363
2364 return VK_SUCCESS;
2365 }
2366
2367 struct radv_shader_dma_submission *
radv_shader_dma_pop_submission(struct radv_device * device)2368 radv_shader_dma_pop_submission(struct radv_device *device)
2369 {
2370 struct radv_shader_dma_submission *submission;
2371
2372 mtx_lock(&device->shader_dma_submission_list_mutex);
2373
2374 while (list_is_empty(&device->shader_dma_submissions))
2375 cnd_wait(&device->shader_dma_submission_list_cond, &device->shader_dma_submission_list_mutex);
2376
2377 submission = list_first_entry(&device->shader_dma_submissions, struct radv_shader_dma_submission, list);
2378 list_del(&submission->list);
2379
2380 mtx_unlock(&device->shader_dma_submission_list_mutex);
2381
2382 return submission;
2383 }
2384
2385 void
radv_shader_dma_push_submission(struct radv_device * device,struct radv_shader_dma_submission * submission,uint64_t seq)2386 radv_shader_dma_push_submission(struct radv_device *device, struct radv_shader_dma_submission *submission, uint64_t seq)
2387 {
2388 submission->seq = seq;
2389
2390 mtx_lock(&device->shader_dma_submission_list_mutex);
2391
2392 list_addtail(&submission->list, &device->shader_dma_submissions);
2393 cnd_signal(&device->shader_dma_submission_list_cond);
2394
2395 mtx_unlock(&device->shader_dma_submission_list_mutex);
2396 }
2397
2398 struct radv_shader_dma_submission *
radv_shader_dma_get_submission(struct radv_device * device,struct radeon_winsys_bo * bo,uint64_t va,uint64_t size)2399 radv_shader_dma_get_submission(struct radv_device *device, struct radeon_winsys_bo *bo, uint64_t va, uint64_t size)
2400 {
2401 struct radv_shader_dma_submission *submission = radv_shader_dma_pop_submission(device);
2402 struct radeon_cmdbuf *cs = submission->cs;
2403 struct radeon_winsys *ws = device->ws;
2404 VkResult result;
2405
2406 /* Wait for potentially in-flight submission to settle */
2407 result = radv_shader_wait_for_upload(device, submission->seq);
2408 if (result != VK_SUCCESS)
2409 goto fail;
2410
2411 ws->cs_reset(cs);
2412
2413 if (submission->bo_size < size) {
2414 result = radv_shader_dma_resize_upload_buf(device, submission, size);
2415 if (result != VK_SUCCESS)
2416 goto fail;
2417 }
2418
2419 radv_sdma_copy_buffer(device, cs, radv_buffer_get_va(submission->bo), va, size);
2420 radv_cs_add_buffer(ws, cs, submission->bo);
2421 radv_cs_add_buffer(ws, cs, bo);
2422
2423 result = ws->cs_finalize(cs);
2424 if (result != VK_SUCCESS)
2425 goto fail;
2426
2427 return submission;
2428
2429 fail:
2430 radv_shader_dma_push_submission(device, submission, 0);
2431
2432 return NULL;
2433 }
2434
2435 /*
2436 * If upload_seq_out is NULL, this function blocks until the DMA is complete. Otherwise, the
2437 * semaphore value to wait on device->shader_upload_sem is stored in *upload_seq_out.
2438 */
2439 bool
radv_shader_dma_submit(struct radv_device * device,struct radv_shader_dma_submission * submission,uint64_t * upload_seq_out)2440 radv_shader_dma_submit(struct radv_device *device, struct radv_shader_dma_submission *submission,
2441 uint64_t *upload_seq_out)
2442 {
2443 struct radeon_cmdbuf *cs = submission->cs;
2444 struct radeon_winsys *ws = device->ws;
2445 VkResult result;
2446
2447 mtx_lock(&device->shader_upload_hw_ctx_mutex);
2448
2449 uint64_t upload_seq = device->shader_upload_seq + 1;
2450
2451 struct vk_semaphore *semaphore = vk_semaphore_from_handle(device->shader_upload_sem);
2452 struct vk_sync *sync = vk_semaphore_get_active_sync(semaphore);
2453 const struct vk_sync_signal signal_info = {
2454 .sync = sync,
2455 .signal_value = upload_seq,
2456 .stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
2457 };
2458
2459 struct radv_winsys_submit_info submit = {
2460 .ip_type = AMD_IP_SDMA,
2461 .queue_index = 0,
2462 .cs_array = &cs,
2463 .cs_count = 1,
2464 };
2465
2466 result = ws->cs_submit(device->shader_upload_hw_ctx, &submit, 0, NULL, 1, &signal_info);
2467 if (result != VK_SUCCESS) {
2468 mtx_unlock(&device->shader_upload_hw_ctx_mutex);
2469 radv_shader_dma_push_submission(device, submission, 0);
2470 return false;
2471 }
2472 device->shader_upload_seq = upload_seq;
2473 mtx_unlock(&device->shader_upload_hw_ctx_mutex);
2474
2475 radv_shader_dma_push_submission(device, submission, upload_seq);
2476
2477 if (upload_seq_out) {
2478 *upload_seq_out = upload_seq;
2479 } else {
2480 result = radv_shader_wait_for_upload(device, upload_seq);
2481 if (result != VK_SUCCESS)
2482 return false;
2483 }
2484
2485 return true;
2486 }
2487
2488 static bool
radv_shader_upload(struct radv_device * device,struct radv_shader * shader,const struct radv_shader_binary * binary)2489 radv_shader_upload(struct radv_device *device, struct radv_shader *shader, const struct radv_shader_binary *binary)
2490 {
2491 if (device->shader_use_invisible_vram) {
2492 struct radv_shader_dma_submission *submission =
2493 radv_shader_dma_get_submission(device, shader->bo, shader->va, shader->code_size);
2494 if (!submission)
2495 return false;
2496
2497 if (!radv_shader_binary_upload(device, binary, shader, submission->ptr)) {
2498 radv_shader_dma_push_submission(device, submission, 0);
2499 return false;
2500 }
2501
2502 if (!radv_shader_dma_submit(device, submission, &shader->upload_seq))
2503 return false;
2504 } else {
2505 void *dest_ptr = shader->alloc->arena->ptr + shader->alloc->offset;
2506
2507 if (!radv_shader_binary_upload(device, binary, shader, dest_ptr))
2508 return false;
2509 }
2510 return true;
2511 }
2512
2513 unsigned
radv_get_max_waves(const struct radv_device * device,const struct ac_shader_config * conf,const struct radv_shader_info * info)2514 radv_get_max_waves(const struct radv_device *device, const struct ac_shader_config *conf,
2515 const struct radv_shader_info *info)
2516 {
2517 const struct radv_physical_device *pdev = radv_device_physical(device);
2518 const struct radeon_info *gpu_info = &pdev->info;
2519 const enum amd_gfx_level gfx_level = gpu_info->gfx_level;
2520 const uint8_t wave_size = info->wave_size;
2521 gl_shader_stage stage = info->stage;
2522 unsigned max_simd_waves = gpu_info->max_waves_per_simd;
2523 unsigned lds_per_wave = 0;
2524
2525 if (stage == MESA_SHADER_FRAGMENT) {
2526 lds_per_wave = conf->lds_size * gpu_info->lds_encode_granularity + info->ps.num_interp * 48;
2527 lds_per_wave = align(lds_per_wave, gpu_info->lds_alloc_granularity);
2528 } else if (stage == MESA_SHADER_COMPUTE || stage == MESA_SHADER_TASK) {
2529 unsigned max_workgroup_size = info->workgroup_size;
2530 lds_per_wave = align(conf->lds_size * gpu_info->lds_encode_granularity, gpu_info->lds_alloc_granularity);
2531 lds_per_wave /= DIV_ROUND_UP(max_workgroup_size, wave_size);
2532 }
2533
2534 if (conf->num_sgprs && gfx_level < GFX10) {
2535 unsigned sgprs = align(conf->num_sgprs, gfx_level >= GFX8 ? 16 : 8);
2536 max_simd_waves = MIN2(max_simd_waves, gpu_info->num_physical_sgprs_per_simd / sgprs);
2537 }
2538
2539 if (conf->num_vgprs) {
2540 unsigned physical_vgprs = gpu_info->num_physical_wave64_vgprs_per_simd * (64 / wave_size);
2541 unsigned vgprs = align(conf->num_vgprs, wave_size == 32 ? 8 : 4);
2542 if (gfx_level >= GFX10_3) {
2543 unsigned real_vgpr_gran = gpu_info->num_physical_wave64_vgprs_per_simd / 64;
2544 vgprs = util_align_npot(vgprs, real_vgpr_gran * (wave_size == 32 ? 2 : 1));
2545 }
2546 max_simd_waves = MIN2(max_simd_waves, physical_vgprs / vgprs);
2547 }
2548
2549 unsigned simd_per_workgroup = gpu_info->num_simd_per_compute_unit;
2550 if (gfx_level >= GFX10)
2551 simd_per_workgroup *= 2; /* like lds_size_per_workgroup, assume WGP on GFX10+ */
2552
2553 unsigned max_lds_per_simd = gpu_info->lds_size_per_workgroup / simd_per_workgroup;
2554 if (lds_per_wave)
2555 max_simd_waves = MIN2(max_simd_waves, DIV_ROUND_UP(max_lds_per_simd, lds_per_wave));
2556
2557 return gfx_level >= GFX10 ? max_simd_waves * (wave_size / 32) : max_simd_waves;
2558 }
2559
2560 unsigned
radv_get_max_scratch_waves(const struct radv_device * device,struct radv_shader * shader)2561 radv_get_max_scratch_waves(const struct radv_device *device, struct radv_shader *shader)
2562 {
2563 const struct radv_physical_device *pdev = radv_device_physical(device);
2564 const unsigned num_cu = pdev->info.num_cu;
2565
2566 return MIN2(device->scratch_waves, 4 * num_cu * shader->max_waves);
2567 }
2568
2569 VkResult
radv_shader_create_uncached(struct radv_device * device,const struct radv_shader_binary * binary,bool replayable,struct radv_serialized_shader_arena_block * replay_block,struct radv_shader ** out_shader)2570 radv_shader_create_uncached(struct radv_device *device, const struct radv_shader_binary *binary, bool replayable,
2571 struct radv_serialized_shader_arena_block *replay_block, struct radv_shader **out_shader)
2572 {
2573 VkResult result = VK_SUCCESS;
2574 struct radv_shader *shader = calloc(1, sizeof(struct radv_shader));
2575 if (!shader) {
2576 result = VK_ERROR_OUT_OF_HOST_MEMORY;
2577 goto out;
2578 }
2579 simple_mtx_init(&shader->replay_mtx, mtx_plain);
2580
2581 _mesa_blake3_compute(binary, binary->total_size, shader->hash);
2582
2583 vk_pipeline_cache_object_init(&device->vk, &shader->base, &radv_shader_ops, shader->hash, sizeof(shader->hash));
2584
2585 shader->info = binary->info;
2586 shader->config = binary->config;
2587 shader->max_waves = radv_get_max_waves(device, &shader->config, &shader->info);
2588
2589 if (binary->type == RADV_BINARY_TYPE_RTLD) {
2590 #if !defined(USE_LIBELF)
2591 goto out;
2592 #else
2593 struct ac_rtld_binary rtld_binary = {0};
2594
2595 if (!radv_open_rtld_binary(device, binary, &rtld_binary)) {
2596 result = VK_ERROR_OUT_OF_HOST_MEMORY;
2597 goto out;
2598 }
2599
2600 shader->code_size = rtld_binary.rx_size;
2601 shader->exec_size = rtld_binary.exec_size;
2602 ac_rtld_close(&rtld_binary);
2603 #endif
2604 } else {
2605 struct radv_shader_binary_legacy *bin = (struct radv_shader_binary_legacy *)binary;
2606
2607 shader->code_size = bin->code_size;
2608 shader->exec_size = bin->exec_size;
2609
2610 if (bin->stats_size) {
2611 shader->statistics = calloc(bin->stats_size, 1);
2612 memcpy(shader->statistics, bin->data, bin->stats_size);
2613 }
2614 }
2615
2616 if (replay_block) {
2617 shader->alloc = radv_replay_shader_arena_block(device, replay_block, shader);
2618 if (!shader->alloc) {
2619 result = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS;
2620 goto out;
2621 }
2622
2623 shader->has_replay_alloc = true;
2624 } else {
2625 shader->alloc = radv_alloc_shader_memory(device, shader->code_size, replayable, shader);
2626 if (!shader->alloc) {
2627 result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
2628 goto out;
2629 }
2630 }
2631
2632 shader->bo = shader->alloc->arena->bo;
2633 shader->va = radv_buffer_get_va(shader->bo) + shader->alloc->offset;
2634
2635 if (!radv_shader_upload(device, shader, binary)) {
2636 result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
2637 goto out;
2638 }
2639
2640 *out_shader = shader;
2641
2642 out:
2643 if (result != VK_SUCCESS) {
2644 free(shader);
2645 *out_shader = NULL;
2646 }
2647
2648 return result;
2649 }
2650
2651 bool
radv_shader_reupload(struct radv_device * device,struct radv_shader * shader)2652 radv_shader_reupload(struct radv_device *device, struct radv_shader *shader)
2653 {
2654 if (device->shader_use_invisible_vram) {
2655 struct radv_shader_dma_submission *submission =
2656 radv_shader_dma_get_submission(device, shader->bo, shader->va, shader->code_size);
2657 if (!submission)
2658 return false;
2659
2660 memcpy(submission->ptr, shader->code, shader->code_size);
2661
2662 if (!radv_shader_dma_submit(device, submission, &shader->upload_seq))
2663 return false;
2664 } else {
2665 void *dest_ptr = shader->alloc->arena->ptr + shader->alloc->offset;
2666 memcpy(dest_ptr, shader->code, shader->code_size);
2667 }
2668 return true;
2669 }
2670
2671 static bool
radv_shader_part_binary_upload(struct radv_device * device,const struct radv_shader_part_binary * bin,struct radv_shader_part * shader_part)2672 radv_shader_part_binary_upload(struct radv_device *device, const struct radv_shader_part_binary *bin,
2673 struct radv_shader_part *shader_part)
2674 {
2675 struct radv_shader_dma_submission *submission = NULL;
2676 void *dest_ptr;
2677
2678 if (device->shader_use_invisible_vram) {
2679 uint64_t va = radv_buffer_get_va(shader_part->alloc->arena->bo) + shader_part->alloc->offset;
2680 submission = radv_shader_dma_get_submission(device, shader_part->alloc->arena->bo, va, bin->code_size);
2681 if (!submission)
2682 return false;
2683
2684 dest_ptr = submission->ptr;
2685 } else {
2686 dest_ptr = shader_part->alloc->arena->ptr + shader_part->alloc->offset;
2687 }
2688
2689 memcpy(dest_ptr, bin->data, bin->code_size);
2690
2691 if (device->shader_use_invisible_vram) {
2692 if (!radv_shader_dma_submit(device, submission, &shader_part->upload_seq))
2693 return false;
2694 }
2695
2696 return true;
2697 }
2698
2699 struct radv_shader_part *
radv_shader_part_create(struct radv_device * device,struct radv_shader_part_binary * binary,unsigned wave_size)2700 radv_shader_part_create(struct radv_device *device, struct radv_shader_part_binary *binary, unsigned wave_size)
2701 {
2702 struct radv_shader_part *shader_part;
2703
2704 shader_part = calloc(1, sizeof(struct radv_shader_part));
2705 if (!shader_part)
2706 return NULL;
2707
2708 shader_part->ref_count = 1;
2709 shader_part->code_size = binary->code_size;
2710 shader_part->rsrc1 =
2711 S_00B848_VGPRS((binary->num_vgprs - 1) / (wave_size == 32 ? 8 : 4)) | S_00B228_SGPRS((binary->num_sgprs - 1) / 8);
2712 shader_part->disasm_string = binary->disasm_size ? strdup((const char *)(binary->data + binary->code_size)) : NULL;
2713
2714 shader_part->spi_shader_col_format = binary->info.spi_shader_col_format;
2715 shader_part->cb_shader_mask = binary->info.cb_shader_mask;
2716 shader_part->spi_shader_z_format = binary->info.spi_shader_z_format;
2717
2718 /* Allocate memory and upload. */
2719 shader_part->alloc = radv_alloc_shader_memory(device, shader_part->code_size, false, NULL);
2720 if (!shader_part->alloc)
2721 goto fail;
2722
2723 shader_part->bo = shader_part->alloc->arena->bo;
2724 shader_part->va = radv_buffer_get_va(shader_part->bo) + shader_part->alloc->offset;
2725
2726 if (!radv_shader_part_binary_upload(device, binary, shader_part))
2727 goto fail;
2728
2729 return shader_part;
2730
2731 fail:
2732 radv_shader_part_destroy(device, shader_part);
2733 return NULL;
2734 }
2735
2736 bool
radv_shader_part_cache_init(struct radv_shader_part_cache * cache,struct radv_shader_part_cache_ops * ops)2737 radv_shader_part_cache_init(struct radv_shader_part_cache *cache, struct radv_shader_part_cache_ops *ops)
2738 {
2739 cache->ops = ops;
2740 if (!_mesa_set_init(&cache->entries, NULL, cache->ops->hash, cache->ops->equals))
2741 return false;
2742 simple_mtx_init(&cache->lock, mtx_plain);
2743 return true;
2744 }
2745
2746 void
radv_shader_part_cache_finish(struct radv_device * device,struct radv_shader_part_cache * cache)2747 radv_shader_part_cache_finish(struct radv_device *device, struct radv_shader_part_cache *cache)
2748 {
2749 set_foreach (&cache->entries, entry)
2750 radv_shader_part_unref(device, radv_shader_part_from_cache_entry(entry->key));
2751 simple_mtx_destroy(&cache->lock);
2752 ralloc_free(cache->entries.table);
2753 }
2754
2755 /*
2756 * A cache with atomics-free fast path for prolog / epilog lookups.
2757 *
2758 * VS prologs and PS/TCS epilogs are used to support dynamic states. In
2759 * particular dynamic blend state is heavily used by Zink. These are called
2760 * every frame as a part of command buffer building, so these functions are
2761 * on the hot path.
2762 *
2763 * Originally this was implemented with a rwlock, but this lead to high
2764 * overhead. To avoid locking altogether in the hot path, the cache is done
2765 * at two levels: one at device level, and another at each CS. Access to the
2766 * CS cache is externally synchronized and do not require a lock.
2767 */
2768 struct radv_shader_part *
radv_shader_part_cache_get(struct radv_device * device,struct radv_shader_part_cache * cache,struct set * local_entries,const void * key)2769 radv_shader_part_cache_get(struct radv_device *device, struct radv_shader_part_cache *cache, struct set *local_entries,
2770 const void *key)
2771 {
2772 struct set_entry *local, *global;
2773 bool local_found, global_found;
2774 uint32_t hash = cache->ops->hash(key);
2775
2776 local = _mesa_set_search_or_add_pre_hashed(local_entries, hash, key, &local_found);
2777 if (local_found)
2778 return radv_shader_part_from_cache_entry(local->key);
2779
2780 simple_mtx_lock(&cache->lock);
2781 global = _mesa_set_search_or_add_pre_hashed(&cache->entries, hash, key, &global_found);
2782 if (global_found) {
2783 simple_mtx_unlock(&cache->lock);
2784 local->key = global->key;
2785 return radv_shader_part_from_cache_entry(global->key);
2786 }
2787
2788 struct radv_shader_part *shader_part = cache->ops->create(device, key);
2789 if (!shader_part) {
2790 _mesa_set_remove(&cache->entries, global);
2791 simple_mtx_unlock(&cache->lock);
2792 _mesa_set_remove(local_entries, local);
2793 return NULL;
2794 }
2795
2796 /* Make the set entry a pointer to the key, so that the hash and equals
2797 * functions from radv_shader_part_cache_ops can be directly used.
2798 */
2799 global->key = &shader_part->key;
2800 simple_mtx_unlock(&cache->lock);
2801 local->key = &shader_part->key;
2802 return shader_part;
2803 }
2804
2805 static char *
radv_dump_nir_shaders(struct nir_shader * const * shaders,int shader_count)2806 radv_dump_nir_shaders(struct nir_shader *const *shaders, int shader_count)
2807 {
2808 char *data = NULL;
2809 char *ret = NULL;
2810 size_t size = 0;
2811 struct u_memstream mem;
2812 if (u_memstream_open(&mem, &data, &size)) {
2813 FILE *const memf = u_memstream_get(&mem);
2814 for (int i = 0; i < shader_count; ++i)
2815 nir_print_shader(shaders[i], memf);
2816 u_memstream_close(&mem);
2817 }
2818
2819 ret = malloc(size + 1);
2820 if (ret) {
2821 memcpy(ret, data, size);
2822 ret[size] = 0;
2823 }
2824 free(data);
2825 return ret;
2826 }
2827
2828 static void
radv_aco_build_shader_binary(void ** bin,const struct ac_shader_config * config,const char * llvm_ir_str,unsigned llvm_ir_size,const char * disasm_str,unsigned disasm_size,uint32_t * statistics,uint32_t stats_size,uint32_t exec_size,const uint32_t * code,uint32_t code_dw,const struct aco_symbol * symbols,unsigned num_symbols)2829 radv_aco_build_shader_binary(void **bin, const struct ac_shader_config *config, const char *llvm_ir_str,
2830 unsigned llvm_ir_size, const char *disasm_str, unsigned disasm_size, uint32_t *statistics,
2831 uint32_t stats_size, uint32_t exec_size, const uint32_t *code, uint32_t code_dw,
2832 const struct aco_symbol *symbols, unsigned num_symbols)
2833 {
2834 struct radv_shader_binary **binary = (struct radv_shader_binary **)bin;
2835 size_t size = llvm_ir_size;
2836
2837 size += disasm_size;
2838 size += stats_size;
2839
2840 size += code_dw * sizeof(uint32_t) + sizeof(struct radv_shader_binary_legacy);
2841
2842 /* We need to calloc to prevent uninitialized data because this will be used
2843 * directly for the disk cache. Uninitialized data can appear because of
2844 * padding in the struct or because legacy_binary->data can be at an offset
2845 * from the start less than sizeof(radv_shader_binary_legacy). */
2846 struct radv_shader_binary_legacy *legacy_binary = (struct radv_shader_binary_legacy *)calloc(size, 1);
2847 legacy_binary->base.type = RADV_BINARY_TYPE_LEGACY;
2848 legacy_binary->base.total_size = size;
2849 legacy_binary->base.config = *config;
2850
2851 if (stats_size)
2852 memcpy(legacy_binary->data, statistics, stats_size);
2853 legacy_binary->stats_size = stats_size;
2854
2855 memcpy(legacy_binary->data + legacy_binary->stats_size, code, code_dw * sizeof(uint32_t));
2856 legacy_binary->exec_size = exec_size;
2857 legacy_binary->code_size = code_dw * sizeof(uint32_t);
2858
2859 legacy_binary->disasm_size = 0;
2860 legacy_binary->ir_size = llvm_ir_size;
2861
2862 if (llvm_ir_size) {
2863 memcpy((char *)legacy_binary->data + legacy_binary->stats_size + legacy_binary->code_size, llvm_ir_str,
2864 llvm_ir_size);
2865 }
2866
2867 legacy_binary->disasm_size = disasm_size;
2868 if (disasm_size) {
2869 memcpy((char *)legacy_binary->data + legacy_binary->stats_size + legacy_binary->code_size + llvm_ir_size,
2870 disasm_str, disasm_size);
2871 }
2872 *binary = (struct radv_shader_binary *)legacy_binary;
2873 }
2874
2875 static void
radv_fill_nir_compiler_options(struct radv_nir_compiler_options * options,struct radv_device * device,const struct radv_graphics_state_key * gfx_state,bool should_use_wgp,bool can_dump_shader,bool is_meta_shader,bool keep_shader_info,bool keep_statistic_info)2876 radv_fill_nir_compiler_options(struct radv_nir_compiler_options *options, struct radv_device *device,
2877 const struct radv_graphics_state_key *gfx_state, bool should_use_wgp,
2878 bool can_dump_shader, bool is_meta_shader, bool keep_shader_info,
2879 bool keep_statistic_info)
2880 {
2881 const struct radv_physical_device *pdev = radv_device_physical(device);
2882 const struct radv_instance *instance = radv_physical_device_instance(pdev);
2883
2884 /* robust_buffer_access_llvm here used by LLVM only, pipeline robustness is not exposed there. */
2885 options->robust_buffer_access_llvm =
2886 (device->vk.enabled_features.robustBufferAccess2 || device->vk.enabled_features.robustBufferAccess);
2887 options->wgp_mode = should_use_wgp;
2888 options->info = &pdev->info;
2889 options->dump_shader = can_dump_shader;
2890 options->dump_preoptir = options->dump_shader && instance->debug_flags & RADV_DEBUG_PREOPTIR;
2891 options->record_ir = keep_shader_info;
2892 options->record_stats = keep_statistic_info;
2893 options->check_ir = instance->debug_flags & RADV_DEBUG_CHECKIR;
2894 options->enable_mrt_output_nan_fixup = gfx_state ? gfx_state->ps.epilog.enable_mrt_output_nan_fixup : false;
2895 }
2896
2897 void
radv_set_stage_key_robustness(const struct vk_pipeline_robustness_state * rs,gl_shader_stage stage,struct radv_shader_stage_key * key)2898 radv_set_stage_key_robustness(const struct vk_pipeline_robustness_state *rs, gl_shader_stage stage,
2899 struct radv_shader_stage_key *key)
2900 {
2901 if (rs->storage_buffers == VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT)
2902 key->storage_robustness2 = 1;
2903 if (rs->uniform_buffers == VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT)
2904 key->uniform_robustness2 = 1;
2905 if (stage == MESA_SHADER_VERTEX &&
2906 (rs->vertex_inputs == VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT ||
2907 rs->vertex_inputs == VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT))
2908 key->vertex_robustness1 = 1u;
2909 }
2910
2911 static void
radv_capture_shader_executable_info(struct radv_device * device,struct radv_shader * shader,struct nir_shader * const * shaders,int shader_count,const struct radv_shader_binary * binary)2912 radv_capture_shader_executable_info(struct radv_device *device, struct radv_shader *shader,
2913 struct nir_shader *const *shaders, int shader_count,
2914 const struct radv_shader_binary *binary)
2915 {
2916 shader->nir_string = radv_dump_nir_shaders(shaders, shader_count);
2917
2918 if (binary->type == RADV_BINARY_TYPE_RTLD) {
2919 #if !defined(USE_LIBELF)
2920 return;
2921 #else
2922 struct radv_shader_binary_rtld *bin = (struct radv_shader_binary_rtld *)binary;
2923 struct ac_rtld_binary rtld_binary = {0};
2924
2925 if (!radv_open_rtld_binary(device, binary, &rtld_binary)) {
2926 return;
2927 }
2928
2929 const char *disasm_data;
2930 size_t disasm_size;
2931 if (!ac_rtld_get_section_by_name(&rtld_binary, ".AMDGPU.disasm", &disasm_data, &disasm_size)) {
2932 return;
2933 }
2934
2935 shader->ir_string = bin->llvm_ir_size ? strdup((const char *)(bin->data + bin->elf_size)) : NULL;
2936 shader->disasm_string = malloc(disasm_size + 1);
2937 memcpy(shader->disasm_string, disasm_data, disasm_size);
2938 shader->disasm_string[disasm_size] = 0;
2939
2940 ac_rtld_close(&rtld_binary);
2941 #endif
2942 } else {
2943 struct radv_shader_binary_legacy *bin = (struct radv_shader_binary_legacy *)binary;
2944
2945 shader->ir_string = bin->ir_size ? strdup((const char *)(bin->data + bin->stats_size + bin->code_size)) : NULL;
2946 shader->disasm_string =
2947 bin->disasm_size ? strdup((const char *)(bin->data + bin->stats_size + bin->code_size + bin->ir_size)) : NULL;
2948 }
2949 }
2950
2951 static struct radv_shader_binary *
shader_compile(struct radv_device * device,struct nir_shader * const * shaders,int shader_count,gl_shader_stage stage,const struct radv_shader_info * info,const struct radv_shader_args * args,const struct radv_shader_stage_key * stage_key,struct radv_nir_compiler_options * options)2952 shader_compile(struct radv_device *device, struct nir_shader *const *shaders, int shader_count, gl_shader_stage stage,
2953 const struct radv_shader_info *info, const struct radv_shader_args *args,
2954 const struct radv_shader_stage_key *stage_key, struct radv_nir_compiler_options *options)
2955 {
2956 struct radv_shader_debug_data debug_data = {
2957 .device = device,
2958 .object = NULL,
2959 };
2960 options->debug.func = radv_compiler_debug;
2961 options->debug.private_data = &debug_data;
2962
2963 struct radv_shader_binary *binary = NULL;
2964
2965 #if AMD_LLVM_AVAILABLE
2966 const struct radv_physical_device *pdev = radv_device_physical(device);
2967
2968 if (radv_use_llvm_for_stage(pdev, stage) || options->dump_shader || options->record_ir)
2969 ac_init_llvm_once();
2970
2971 if (radv_use_llvm_for_stage(pdev, stage)) {
2972 llvm_compile_shader(options, info, shader_count, shaders, &binary, args);
2973 #else
2974 if (false) {
2975 #endif
2976 } else {
2977 struct aco_shader_info ac_info;
2978 struct aco_compiler_options ac_opts;
2979 radv_aco_convert_opts(&ac_opts, options, args, stage_key);
2980 radv_aco_convert_shader_info(&ac_info, info, args, &device->cache_key, options->info->gfx_level);
2981 aco_compile_shader(&ac_opts, &ac_info, shader_count, shaders, &args->ac, &radv_aco_build_shader_binary,
2982 (void **)&binary);
2983 }
2984
2985 binary->info = *info;
2986
2987 if (!radv_postprocess_binary_config(device, binary, args)) {
2988 free(binary);
2989 return NULL;
2990 }
2991
2992 return binary;
2993 }
2994
2995 struct radv_shader_binary *
2996 radv_shader_nir_to_asm(struct radv_device *device, struct radv_shader_stage *pl_stage,
2997 struct nir_shader *const *shaders, int shader_count,
2998 const struct radv_graphics_state_key *gfx_state, bool keep_shader_info, bool keep_statistic_info)
2999 {
3000 gl_shader_stage stage = shaders[shader_count - 1]->info.stage;
3001 struct radv_shader_info *info = &pl_stage->info;
3002
3003 struct radv_nir_compiler_options options = {0};
3004 radv_fill_nir_compiler_options(&options, device, gfx_state, radv_should_use_wgp_mode(device, stage, info),
3005 radv_can_dump_shader(device, shaders[0], false), is_meta_shader(shaders[0]),
3006 keep_shader_info, keep_statistic_info);
3007
3008 struct radv_shader_binary *binary =
3009 shader_compile(device, shaders, shader_count, stage, info, &pl_stage->args, &pl_stage->key, &options);
3010
3011 return binary;
3012 }
3013
3014 void
3015 radv_shader_generate_debug_info(struct radv_device *device, bool dump_shader, bool keep_shader_info,
3016 struct radv_shader_binary *binary, struct radv_shader *shader,
3017 struct nir_shader *const *shaders, int shader_count, struct radv_shader_info *info)
3018 {
3019 if (dump_shader || keep_shader_info)
3020 radv_capture_shader_executable_info(device, shader, shaders, shader_count, binary);
3021
3022 if (dump_shader) {
3023 fprintf(stderr, "%s", radv_get_shader_name(info, shaders[0]->info.stage));
3024 for (int i = 1; i < shader_count; ++i)
3025 fprintf(stderr, " + %s", radv_get_shader_name(info, shaders[i]->info.stage));
3026
3027 fprintf(stderr, "\ndisasm:\n%s\n", shader->disasm_string);
3028 }
3029 }
3030
3031 struct radv_shader *
3032 radv_create_trap_handler_shader(struct radv_device *device)
3033 {
3034 gl_shader_stage stage = MESA_SHADER_COMPUTE;
3035 struct radv_shader_stage_key stage_key = {0};
3036 struct radv_shader_info info = {0};
3037 struct radv_nir_compiler_options options = {0};
3038 radv_fill_nir_compiler_options(&options, device, NULL, radv_should_use_wgp_mode(device, stage, &info), false, false,
3039 false, false);
3040
3041 nir_builder b = radv_meta_init_shader(device, stage, "meta_trap_handler");
3042
3043 info.wave_size = 64;
3044 info.type = RADV_SHADER_TYPE_TRAP_HANDLER;
3045
3046 struct radv_shader_args args;
3047 radv_declare_shader_args(device, NULL, &info, stage, MESA_SHADER_NONE, &args);
3048
3049 struct radv_shader_binary *binary = shader_compile(device, &b.shader, 1, stage, &info, &args, &stage_key, &options);
3050 struct radv_shader *shader;
3051 radv_shader_create_uncached(device, binary, false, NULL, &shader);
3052
3053 ralloc_free(b.shader);
3054 free(binary);
3055
3056 return shader;
3057 }
3058
3059 static void
3060 radv_aco_build_shader_part(void **bin, uint32_t num_sgprs, uint32_t num_vgprs, const uint32_t *code, uint32_t code_size,
3061 const char *disasm_str, uint32_t disasm_size)
3062 {
3063 struct radv_shader_part_binary **binary = (struct radv_shader_part_binary **)bin;
3064 size_t size = code_size * sizeof(uint32_t) + sizeof(struct radv_shader_part_binary);
3065
3066 size += disasm_size;
3067 struct radv_shader_part_binary *part_binary = (struct radv_shader_part_binary *)calloc(size, 1);
3068
3069 part_binary->num_sgprs = num_sgprs;
3070 part_binary->num_vgprs = num_vgprs;
3071 part_binary->total_size = size;
3072 part_binary->code_size = code_size * sizeof(uint32_t);
3073 memcpy(part_binary->data, code, part_binary->code_size);
3074 if (disasm_size) {
3075 memcpy((char *)part_binary->data + part_binary->code_size, disasm_str, disasm_size);
3076 part_binary->disasm_size = disasm_size;
3077 }
3078
3079 *binary = part_binary;
3080 }
3081
3082 struct radv_shader *
3083 radv_create_rt_prolog(struct radv_device *device)
3084 {
3085 const struct radv_physical_device *pdev = radv_device_physical(device);
3086 const struct radv_instance *instance = radv_physical_device_instance(pdev);
3087 struct radv_shader *prolog;
3088 struct radv_shader_args in_args = {0};
3089 struct radv_shader_args out_args = {0};
3090 struct radv_nir_compiler_options options = {0};
3091 radv_fill_nir_compiler_options(&options, device, NULL, false, instance->debug_flags & RADV_DEBUG_DUMP_PROLOGS, false,
3092 radv_device_fault_detection_enabled(device), false);
3093 struct radv_shader_info info = {0};
3094 info.stage = MESA_SHADER_COMPUTE;
3095 info.loads_push_constants = true;
3096 info.desc_set_used_mask = -1; /* just to force indirection */
3097 info.wave_size = pdev->rt_wave_size;
3098 info.workgroup_size = info.wave_size;
3099 info.user_data_0 = R_00B900_COMPUTE_USER_DATA_0;
3100 info.type = RADV_SHADER_TYPE_RT_PROLOG;
3101 info.cs.block_size[0] = 8;
3102 info.cs.block_size[1] = pdev->rt_wave_size == 64 ? 8 : 4;
3103 info.cs.block_size[2] = 1;
3104 info.cs.uses_thread_id[0] = true;
3105 info.cs.uses_thread_id[1] = true;
3106 for (unsigned i = 0; i < 3; i++)
3107 info.cs.uses_block_id[i] = true;
3108
3109 radv_declare_shader_args(device, NULL, &info, MESA_SHADER_COMPUTE, MESA_SHADER_NONE, &in_args);
3110 radv_declare_rt_shader_args(options.info->gfx_level, &out_args);
3111 info.user_sgprs_locs = in_args.user_sgprs_locs;
3112
3113 #if AMD_LLVM_AVAILABLE
3114 if (options.dump_shader || options.record_ir)
3115 ac_init_llvm_once();
3116 #endif
3117
3118 struct radv_shader_binary *binary = NULL;
3119 struct radv_shader_stage_key stage_key = {0};
3120 struct aco_shader_info ac_info;
3121 struct aco_compiler_options ac_opts;
3122 radv_aco_convert_shader_info(&ac_info, &info, &in_args, &device->cache_key, options.info->gfx_level);
3123 radv_aco_convert_opts(&ac_opts, &options, &in_args, &stage_key);
3124 aco_compile_rt_prolog(&ac_opts, &ac_info, &in_args.ac, &out_args.ac, &radv_aco_build_shader_binary,
3125 (void **)&binary);
3126 binary->info = info;
3127
3128 radv_postprocess_binary_config(device, binary, &in_args);
3129 radv_shader_create_uncached(device, binary, false, NULL, &prolog);
3130 if (!prolog)
3131 goto done;
3132
3133 if (device->keep_shader_info || options.dump_shader) {
3134 radv_capture_shader_executable_info(device, prolog, NULL, 0, binary);
3135 }
3136
3137 if (options.dump_shader) {
3138 fprintf(stderr, "Raytracing prolog");
3139 fprintf(stderr, "\ndisasm:\n%s\n", prolog->disasm_string);
3140 }
3141
3142 done:
3143 free(binary);
3144 return prolog;
3145 }
3146
3147 struct radv_shader_part *
3148 radv_create_vs_prolog(struct radv_device *device, const struct radv_vs_prolog_key *key)
3149 {
3150 const struct radv_physical_device *pdev = radv_device_physical(device);
3151 const struct radv_instance *instance = radv_physical_device_instance(pdev);
3152 struct radv_shader_part *prolog;
3153 struct radv_shader_args args = {0};
3154 struct radv_nir_compiler_options options = {0};
3155 radv_fill_nir_compiler_options(&options, device, NULL, false, instance->debug_flags & RADV_DEBUG_DUMP_PROLOGS, false,
3156 radv_device_fault_detection_enabled(device), false);
3157
3158 struct radv_shader_info info = {0};
3159 info.stage = MESA_SHADER_VERTEX;
3160 info.wave_size = key->wave32 ? 32 : 64;
3161 info.vs.needs_instance_id = true;
3162 info.vs.needs_base_instance = true;
3163 info.vs.needs_draw_id = true;
3164 info.vs.use_per_attribute_vb_descs = true;
3165 info.vs.vb_desc_usage_mask = BITFIELD_MASK(key->num_attributes);
3166 info.vs.has_prolog = true;
3167 info.vs.as_ls = key->as_ls;
3168 info.is_ngg = key->is_ngg;
3169
3170 struct radv_graphics_state_key gfx_state = {0};
3171
3172 radv_declare_shader_args(device, &gfx_state, &info, key->next_stage,
3173 key->next_stage != MESA_SHADER_VERTEX ? MESA_SHADER_VERTEX : MESA_SHADER_NONE, &args);
3174
3175 info.user_sgprs_locs = args.user_sgprs_locs;
3176 info.inline_push_constant_mask = args.ac.inline_push_const_mask;
3177
3178 #if AMD_LLVM_AVAILABLE
3179 if (options.dump_shader || options.record_ir)
3180 ac_init_llvm_once();
3181 #endif
3182
3183 struct radv_shader_part_binary *binary = NULL;
3184 struct radv_shader_stage_key stage_key = {0};
3185 struct aco_shader_info ac_info;
3186 struct aco_vs_prolog_info ac_prolog_info;
3187 struct aco_compiler_options ac_opts;
3188 radv_aco_convert_shader_info(&ac_info, &info, &args, &device->cache_key, options.info->gfx_level);
3189 radv_aco_convert_opts(&ac_opts, &options, &args, &stage_key);
3190 radv_aco_convert_vs_prolog_key(&ac_prolog_info, key, &args);
3191 aco_compile_vs_prolog(&ac_opts, &ac_info, &ac_prolog_info, &args.ac, &radv_aco_build_shader_part, (void **)&binary);
3192
3193 prolog = radv_shader_part_create(device, binary, info.wave_size);
3194 if (!prolog)
3195 goto fail;
3196
3197 prolog->key.vs = *key;
3198 prolog->nontrivial_divisors = key->nontrivial_divisors;
3199
3200 if (options.dump_shader) {
3201 fprintf(stderr, "Vertex prolog");
3202 fprintf(stderr, "\ndisasm:\n%s\n", prolog->disasm_string);
3203 }
3204
3205 free(binary);
3206
3207 return prolog;
3208
3209 fail:
3210 free(binary);
3211 return NULL;
3212 }
3213
3214 struct radv_shader_part *
3215 radv_create_ps_epilog(struct radv_device *device, const struct radv_ps_epilog_key *key,
3216 struct radv_shader_part_binary **binary_out)
3217 {
3218 const struct radv_physical_device *pdev = radv_device_physical(device);
3219 const struct radv_instance *instance = radv_physical_device_instance(pdev);
3220 struct radv_shader_part *epilog;
3221 struct radv_shader_args args = {0};
3222 struct radv_nir_compiler_options options = {0};
3223 radv_fill_nir_compiler_options(&options, device, NULL, false, instance->debug_flags & RADV_DEBUG_DUMP_EPILOGS, false,
3224 radv_device_fault_detection_enabled(device), false);
3225
3226 struct radv_shader_info info = {0};
3227 info.stage = MESA_SHADER_FRAGMENT;
3228 info.wave_size = pdev->ps_wave_size;
3229 info.workgroup_size = 64;
3230
3231 radv_declare_ps_epilog_args(device, key, &args);
3232
3233 #if AMD_LLVM_AVAILABLE
3234 if (options.dump_shader || options.record_ir)
3235 ac_init_llvm_once();
3236 #endif
3237
3238 struct radv_shader_part_binary *binary = NULL;
3239 struct radv_shader_stage_key stage_key = {0};
3240 struct aco_shader_info ac_info;
3241 struct aco_ps_epilog_info ac_epilog_info = {0};
3242 struct aco_compiler_options ac_opts;
3243 radv_aco_convert_shader_info(&ac_info, &info, &args, &device->cache_key, options.info->gfx_level);
3244 radv_aco_convert_opts(&ac_opts, &options, &args, &stage_key);
3245 radv_aco_convert_ps_epilog_key(&ac_epilog_info, key, &args);
3246 aco_compile_ps_epilog(&ac_opts, &ac_info, &ac_epilog_info, &args.ac, &radv_aco_build_shader_part, (void **)&binary);
3247
3248 binary->info.spi_shader_col_format = key->spi_shader_col_format;
3249 binary->info.cb_shader_mask = ac_get_cb_shader_mask(key->spi_shader_col_format);
3250 binary->info.spi_shader_z_format = key->spi_shader_z_format;
3251
3252 epilog = radv_shader_part_create(device, binary, info.wave_size);
3253 if (!epilog)
3254 goto fail;
3255
3256 epilog->key.ps = *key;
3257
3258 if (options.dump_shader) {
3259 fprintf(stderr, "Fragment epilog");
3260 fprintf(stderr, "\ndisasm:\n%s\n", epilog->disasm_string);
3261 }
3262
3263 if (binary_out) {
3264 *binary_out = binary;
3265 } else {
3266 free(binary);
3267 }
3268
3269 return epilog;
3270
3271 fail:
3272 free(binary);
3273 return NULL;
3274 }
3275
3276 void
3277 radv_shader_part_destroy(struct radv_device *device, struct radv_shader_part *shader_part)
3278 {
3279 assert(shader_part->ref_count == 0);
3280
3281 if (device->shader_use_invisible_vram) {
3282 /* Wait for any pending upload to complete, or we'll be writing into freed shader memory. */
3283 radv_shader_wait_for_upload(device, shader_part->upload_seq);
3284 }
3285
3286 if (shader_part->alloc)
3287 radv_free_shader_memory(device, shader_part->alloc);
3288 free(shader_part->disasm_string);
3289 free(shader_part);
3290 }
3291
3292 uint64_t
3293 radv_shader_get_va(const struct radv_shader *shader)
3294 {
3295 return shader->va;
3296 }
3297
3298 struct radv_shader *
3299 radv_find_shader(struct radv_device *device, uint64_t pc)
3300 {
3301 mtx_lock(&device->shader_arena_mutex);
3302 list_for_each_entry (struct radv_shader_arena, arena, &device->shader_arenas, list) {
3303 #ifdef __GNUC__
3304 #pragma GCC diagnostic push
3305 #pragma GCC diagnostic ignored "-Wshadow"
3306 #endif
3307 list_for_each_entry (union radv_shader_arena_block, block, &arena->entries, list) {
3308 #ifdef __GNUC__
3309 #pragma GCC diagnostic pop
3310 #endif
3311 uint64_t start = radv_buffer_get_va(block->arena->bo) + block->offset;
3312 start &= ((1ull << 48) - 1);
3313 if (!block->freelist.prev && pc >= start && pc < start + block->size) {
3314 mtx_unlock(&device->shader_arena_mutex);
3315 return (struct radv_shader *)block->freelist.next;
3316 }
3317 }
3318 }
3319
3320 mtx_unlock(&device->shader_arena_mutex);
3321 return NULL;
3322 }
3323
3324 const char *
3325 radv_get_shader_name(const struct radv_shader_info *info, gl_shader_stage stage)
3326 {
3327 switch (stage) {
3328 case MESA_SHADER_VERTEX:
3329 if (info->vs.as_ls)
3330 return "Vertex Shader as LS";
3331 else if (info->vs.as_es)
3332 return "Vertex Shader as ES";
3333 else if (info->is_ngg)
3334 return "Vertex Shader as ESGS";
3335 else
3336 return "Vertex Shader as VS";
3337 case MESA_SHADER_TESS_CTRL:
3338 return "Tessellation Control Shader";
3339 case MESA_SHADER_TESS_EVAL:
3340 if (info->tes.as_es)
3341 return "Tessellation Evaluation Shader as ES";
3342 else if (info->is_ngg)
3343 return "Tessellation Evaluation Shader as ESGS";
3344 else
3345 return "Tessellation Evaluation Shader as VS";
3346 case MESA_SHADER_GEOMETRY:
3347 return "Geometry Shader";
3348 case MESA_SHADER_FRAGMENT:
3349 return "Pixel Shader";
3350 case MESA_SHADER_COMPUTE:
3351 return "Compute Shader";
3352 case MESA_SHADER_MESH:
3353 return "Mesh Shader as NGG";
3354 case MESA_SHADER_TASK:
3355 return "Task Shader as CS";
3356 case MESA_SHADER_RAYGEN:
3357 return "Ray Generation Shader as CS Function";
3358 case MESA_SHADER_CLOSEST_HIT:
3359 return "Closest Hit Shader as CS Function";
3360 case MESA_SHADER_INTERSECTION:
3361 return "Intersection Shader as CS Function";
3362 case MESA_SHADER_ANY_HIT:
3363 return "Any Hit Shader as CS Function";
3364 case MESA_SHADER_MISS:
3365 return "Miss Shader as CS Function";
3366 case MESA_SHADER_CALLABLE:
3367 return "Callable Shader as CS Function";
3368 default:
3369 return "Unknown shader";
3370 };
3371 }
3372
3373 unsigned
3374 radv_compute_spi_ps_input(const struct radv_physical_device *pdev, const struct radv_graphics_state_key *gfx_state,
3375 const struct radv_shader_info *info)
3376 {
3377 unsigned spi_ps_input;
3378
3379 spi_ps_input = S_0286CC_PERSP_CENTER_ENA(info->ps.reads_persp_center) |
3380 S_0286CC_PERSP_CENTROID_ENA(info->ps.reads_persp_centroid) |
3381 S_0286CC_PERSP_SAMPLE_ENA(info->ps.reads_persp_sample) |
3382 S_0286CC_LINEAR_CENTER_ENA(info->ps.reads_linear_center) |
3383 S_0286CC_LINEAR_CENTROID_ENA(info->ps.reads_linear_centroid) |
3384 S_0286CC_LINEAR_SAMPLE_ENA(info->ps.reads_linear_sample) |
3385 S_0286CC_PERSP_PULL_MODEL_ENA(info->ps.reads_barycentric_model) |
3386 S_0286CC_FRONT_FACE_ENA(info->ps.reads_front_face);
3387
3388 if (info->ps.reads_frag_coord_mask || info->ps.reads_sample_pos_mask) {
3389 uint8_t mask = info->ps.reads_frag_coord_mask | info->ps.reads_sample_pos_mask;
3390
3391 for (unsigned i = 0; i < 4; i++) {
3392 if (mask & (1 << i))
3393 spi_ps_input |= S_0286CC_POS_X_FLOAT_ENA(1) << i;
3394 }
3395
3396 if (gfx_state->adjust_frag_coord_z && info->ps.reads_frag_coord_mask & (1 << 2)) {
3397 spi_ps_input |= S_0286CC_ANCILLARY_ENA(1);
3398 }
3399 }
3400
3401 if (info->ps.reads_sample_id || info->ps.reads_frag_shading_rate || info->ps.reads_sample_mask_in) {
3402 spi_ps_input |= S_0286CC_ANCILLARY_ENA(1);
3403 }
3404
3405 if (info->ps.reads_sample_mask_in || info->ps.reads_fully_covered) {
3406 spi_ps_input |= S_0286CC_SAMPLE_COVERAGE_ENA(1) |
3407 S_02865C_COVERAGE_TO_SHADER_SELECT(pdev->info.gfx_level >= GFX12 && info->ps.reads_fully_covered);
3408 }
3409
3410 if (G_0286CC_POS_W_FLOAT_ENA(spi_ps_input)) {
3411 /* If POS_W_FLOAT (11) is enabled, at least one of PERSP_* must be enabled too */
3412 spi_ps_input |= S_0286CC_PERSP_CENTER_ENA(1);
3413 }
3414
3415 if (!(spi_ps_input & 0x7F)) {
3416 /* At least one of PERSP_* (0xF) or LINEAR_* (0x70) must be enabled */
3417 spi_ps_input |= S_0286CC_PERSP_CENTER_ENA(1);
3418 }
3419
3420 return spi_ps_input;
3421 }
3422
3423 const struct radv_userdata_info *
3424 radv_get_user_sgpr_info(const struct radv_shader *shader, int idx)
3425 {
3426 return &shader->info.user_sgprs_locs.shader_data[idx];
3427 }
3428
3429 uint32_t
3430 radv_get_user_sgpr_loc(const struct radv_shader *shader, int idx)
3431 {
3432 const struct radv_userdata_info *loc = radv_get_user_sgpr_info(shader, idx);
3433
3434 if (loc->sgpr_idx == -1)
3435 return 0;
3436
3437 return shader->info.user_data_0 + loc->sgpr_idx * 4;
3438 }
3439
3440 uint32_t
3441 radv_get_user_sgpr(const struct radv_shader *shader, int idx)
3442 {
3443 const uint32_t offset = radv_get_user_sgpr_loc(shader, idx);
3444
3445 return offset ? ((offset - SI_SH_REG_OFFSET) >> 2) : 0;
3446 }
3447
3448 static uint32_t
3449 radv_get_tess_patch_size(uint32_t tcs_num_input_vertices, uint32_t tcs_num_output_vertices, uint32_t tcs_num_inputs,
3450 uint32_t tcs_num_lds_outputs, uint32_t tcs_num_lds_patch_outputs)
3451 {
3452 const uint32_t input_vertex_size = get_tcs_input_vertex_stride(tcs_num_inputs);
3453 const uint32_t input_patch_size = tcs_num_input_vertices * input_vertex_size;
3454 const uint32_t lds_output_vertex_size = tcs_num_lds_outputs * 16;
3455 const uint32_t lds_pervertex_output_patch_size = tcs_num_output_vertices * lds_output_vertex_size;
3456 const uint32_t lds_output_patch_size = lds_pervertex_output_patch_size + tcs_num_lds_patch_outputs * 16;
3457
3458 return input_patch_size + lds_output_patch_size;
3459 }
3460
3461 uint32_t
3462 radv_get_tcs_num_patches(const struct radv_physical_device *pdev, unsigned tcs_num_input_vertices,
3463 unsigned tcs_num_output_vertices, unsigned tcs_num_inputs, unsigned tcs_num_lds_outputs,
3464 unsigned tcs_num_lds_patch_outputs, unsigned tcs_num_vram_outputs,
3465 unsigned tcs_num_vram_patch_outputs)
3466 {
3467 const uint32_t lds_per_patch = radv_get_tess_patch_size(
3468 tcs_num_input_vertices, tcs_num_output_vertices, tcs_num_inputs, tcs_num_lds_outputs, tcs_num_lds_patch_outputs);
3469 const uint32_t vram_per_patch = radv_get_tess_patch_size(tcs_num_input_vertices, tcs_num_output_vertices, 0,
3470 tcs_num_vram_outputs, tcs_num_vram_patch_outputs);
3471
3472 return ac_compute_num_tess_patches(&pdev->info, tcs_num_input_vertices, tcs_num_output_vertices, vram_per_patch,
3473 lds_per_patch, pdev->ge_wave_size, false);
3474 }
3475
3476 uint32_t
3477 radv_get_tess_lds_size(const struct radv_physical_device *pdev, uint32_t tcs_num_input_vertices,
3478 uint32_t tcs_num_output_vertices, uint32_t tcs_num_inputs, uint32_t tcs_num_patches,
3479 uint32_t tcs_num_lds_outputs, uint32_t tcs_num_lds_patch_outputs)
3480 {
3481 const uint32_t lds_per_patch = radv_get_tess_patch_size(
3482 tcs_num_input_vertices, tcs_num_output_vertices, tcs_num_inputs, tcs_num_lds_outputs, tcs_num_lds_patch_outputs);
3483
3484 return ac_compute_tess_lds_size(&pdev->info, lds_per_patch, tcs_num_patches);
3485 }
3486
3487 VkResult
3488 radv_dump_shader_stats(struct radv_device *device, struct radv_pipeline *pipeline, struct radv_shader *shader,
3489 gl_shader_stage stage, FILE *output)
3490 {
3491 VkPipelineExecutablePropertiesKHR *props = NULL;
3492 uint32_t prop_count = 0;
3493 VkResult result;
3494
3495 VkPipelineInfoKHR pipeline_info = {0};
3496 pipeline_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR;
3497 pipeline_info.pipeline = radv_pipeline_to_handle(pipeline);
3498
3499 result = radv_GetPipelineExecutablePropertiesKHR(radv_device_to_handle(device), &pipeline_info, &prop_count, NULL);
3500 if (result != VK_SUCCESS)
3501 return result;
3502
3503 props = calloc(prop_count, sizeof(*props));
3504 if (!props)
3505 return VK_ERROR_OUT_OF_HOST_MEMORY;
3506
3507 result = radv_GetPipelineExecutablePropertiesKHR(radv_device_to_handle(device), &pipeline_info, &prop_count, props);
3508 if (result != VK_SUCCESS)
3509 goto fail;
3510
3511 for (unsigned exec_idx = 0; exec_idx < prop_count; exec_idx++) {
3512 if (!(props[exec_idx].stages & mesa_to_vk_shader_stage(stage)))
3513 continue;
3514
3515 VkPipelineExecutableStatisticKHR *stats = NULL;
3516 uint32_t stat_count = 0;
3517
3518 VkPipelineExecutableInfoKHR exec_info = {0};
3519 exec_info.pipeline = radv_pipeline_to_handle(pipeline);
3520 exec_info.executableIndex = exec_idx;
3521
3522 result = radv_GetPipelineExecutableStatisticsKHR(radv_device_to_handle(device), &exec_info, &stat_count, NULL);
3523 if (result != VK_SUCCESS)
3524 goto fail;
3525
3526 stats = calloc(stat_count, sizeof(*stats));
3527 if (!stats) {
3528 result = VK_ERROR_OUT_OF_HOST_MEMORY;
3529 goto fail;
3530 }
3531
3532 result = radv_GetPipelineExecutableStatisticsKHR(radv_device_to_handle(device), &exec_info, &stat_count, stats);
3533 if (result != VK_SUCCESS) {
3534 free(stats);
3535 goto fail;
3536 }
3537
3538 fprintf(output, "\n%s:\n", radv_get_shader_name(&shader->info, stage));
3539 fprintf(output, "*** SHADER STATS ***\n");
3540
3541 for (unsigned i = 0; i < stat_count; i++) {
3542 fprintf(output, "%s: ", stats[i].name);
3543 switch (stats[i].format) {
3544 case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR:
3545 fprintf(output, "%s", stats[i].value.b32 == VK_TRUE ? "true" : "false");
3546 break;
3547 case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR:
3548 fprintf(output, "%" PRIi64, stats[i].value.i64);
3549 break;
3550 case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR:
3551 fprintf(output, "%" PRIu64, stats[i].value.u64);
3552 break;
3553 case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR:
3554 fprintf(output, "%f", stats[i].value.f64);
3555 break;
3556 default:
3557 unreachable("Invalid pipeline statistic format");
3558 }
3559 fprintf(output, "\n");
3560 }
3561
3562 fprintf(output, "********************\n\n\n");
3563
3564 free(stats);
3565 }
3566
3567 fail:
3568 free(props);
3569 return result;
3570 }
3571