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