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