From a9af11f1facd5d79e1284296870ca200ccf17da6 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Tue, 3 Sep 2019 10:29:19 +0200 Subject: [PATCH] radv: fill shader info for all stages in the pipeline This shouldn't be in NIR->LLVM because ACO also needs the shader info. This will also help for computing some NGG values that are necessary for declaring LDS symbols. Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen --- src/amd/vulkan/radv_nir_to_llvm.c | 9 --- src/amd/vulkan/radv_pipeline.c | 125 ++++++++++++++++++++++++++++-- src/amd/vulkan/radv_shader.c | 14 ++-- src/amd/vulkan/radv_shader.h | 2 + 4 files changed, 130 insertions(+), 20 deletions(-) diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c index 916f43924c5..178b0960db1 100644 --- a/src/amd/vulkan/radv_nir_to_llvm.c +++ b/src/amd/vulkan/radv_nir_to_llvm.c @@ -4145,12 +4145,6 @@ LLVMModuleRef ac_translate_nir_to_llvm(struct ac_llvm_compiler *ac_llvm, options->family, float_mode, options->wave_size, 64); ctx.context = ctx.ac.context; - radv_nir_shader_info_init(shader_info); - - for(int i = 0; i < shader_count; ++i) - radv_nir_shader_info_pass(shaders[i], options->layout, - &options->key, shader_info); - for (i = 0; i < MAX_SETS; i++) shader_info->user_sgprs_locs.descriptor_sets[i].sgpr_idx = -1; for (i = 0; i < AC_UD_MAX_UD; i++) @@ -4592,9 +4586,6 @@ radv_compile_gs_copy_shader(struct ac_llvm_compiler *ac_llvm, ctx.stage = MESA_SHADER_VERTEX; ctx.shader = geom_shader; - radv_nir_shader_info_pass(geom_shader, options->layout, &options->key, - shader_info); - create_function(&ctx, MESA_SHADER_VERTEX, false, MESA_SHADER_VERTEX); ac_setup_rings(&ctx); diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 83ba4cacbf7..d5b752aa84e 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -2396,6 +2396,107 @@ radv_fill_shader_keys(struct radv_device *device, keys[MESA_SHADER_FRAGMENT].fs.num_samples = key->num_samples; } +static void +radv_fill_shader_info(struct radv_pipeline *pipeline, + struct radv_shader_variant_key *keys, + struct radv_shader_info *infos, + nir_shader **nir) +{ + unsigned active_stages = 0; + unsigned filled_stages = 0; + + for (int i = 0; i < MESA_SHADER_STAGES; i++) { + if (nir[i]) + active_stages |= (1 << i); + } + + if (nir[MESA_SHADER_FRAGMENT]) { + radv_nir_shader_info_init(&infos[MESA_SHADER_FRAGMENT]); + radv_nir_shader_info_pass(nir[MESA_SHADER_FRAGMENT], + pipeline->layout, + &keys[MESA_SHADER_FRAGMENT], + &infos[MESA_SHADER_FRAGMENT]); + + /* TODO: These are no longer used as keys we should refactor this */ + keys[MESA_SHADER_VERTEX].vs_common_out.export_prim_id = + infos[MESA_SHADER_FRAGMENT].ps.prim_id_input; + keys[MESA_SHADER_VERTEX].vs_common_out.export_layer_id = + infos[MESA_SHADER_FRAGMENT].ps.layer_input; + keys[MESA_SHADER_VERTEX].vs_common_out.export_clip_dists = + !!infos[MESA_SHADER_FRAGMENT].ps.num_input_clips_culls; + keys[MESA_SHADER_TESS_EVAL].vs_common_out.export_prim_id = + infos[MESA_SHADER_FRAGMENT].ps.prim_id_input; + keys[MESA_SHADER_TESS_EVAL].vs_common_out.export_layer_id = + infos[MESA_SHADER_FRAGMENT].ps.layer_input; + keys[MESA_SHADER_TESS_EVAL].vs_common_out.export_clip_dists = + !!infos[MESA_SHADER_FRAGMENT].ps.num_input_clips_culls; + + filled_stages |= (1 << MESA_SHADER_FRAGMENT); + } + + if (pipeline->device->physical_device->rad_info.chip_class >= GFX9 && + nir[MESA_SHADER_TESS_CTRL]) { + struct nir_shader *combined_nir[] = {nir[MESA_SHADER_VERTEX], nir[MESA_SHADER_TESS_CTRL]}; + struct radv_shader_variant_key key = keys[MESA_SHADER_TESS_CTRL]; + key.tcs.vs_key = keys[MESA_SHADER_VERTEX].vs; + + radv_nir_shader_info_init(&infos[MESA_SHADER_TESS_CTRL]); + + for (int i = 0; i < 2; i++) { + radv_nir_shader_info_pass(combined_nir[i], + pipeline->layout, &key, + &infos[MESA_SHADER_TESS_CTRL]); + } + + keys[MESA_SHADER_TESS_EVAL].tes.num_patches = + infos[MESA_SHADER_TESS_CTRL].tcs.num_patches; + keys[MESA_SHADER_TESS_EVAL].tes.tcs_num_outputs = + util_last_bit64(infos[MESA_SHADER_TESS_CTRL].tcs.outputs_written); + + filled_stages |= (1 << MESA_SHADER_VERTEX); + filled_stages |= (1 << MESA_SHADER_TESS_CTRL); + } + + if (pipeline->device->physical_device->rad_info.chip_class >= GFX9 && + nir[MESA_SHADER_GEOMETRY]) { + gl_shader_stage pre_stage = nir[MESA_SHADER_TESS_EVAL] ? MESA_SHADER_TESS_EVAL : MESA_SHADER_VERTEX; + struct nir_shader *combined_nir[] = {nir[pre_stage], nir[MESA_SHADER_GEOMETRY]}; + + radv_nir_shader_info_init(&infos[MESA_SHADER_GEOMETRY]); + + for (int i = 0; i < 2; i++) { + radv_nir_shader_info_pass(combined_nir[i], + pipeline->layout, + &keys[pre_stage], + &infos[MESA_SHADER_GEOMETRY]); + } + + filled_stages |= (1 << pre_stage); + filled_stages |= (1 << MESA_SHADER_GEOMETRY); + } + + active_stages ^= filled_stages; + while (active_stages) { + int i = u_bit_scan(&active_stages); + + if (i == MESA_SHADER_TESS_CTRL) { + keys[MESA_SHADER_TESS_CTRL].tcs.num_inputs = + util_last_bit64(infos[MESA_SHADER_VERTEX].vs.ls_outputs_written); + } + + if (i == MESA_SHADER_TESS_EVAL) { + keys[MESA_SHADER_TESS_EVAL].tes.num_patches = + infos[MESA_SHADER_TESS_CTRL].tcs.num_patches; + keys[MESA_SHADER_TESS_EVAL].tes.tcs_num_outputs = + util_last_bit64(infos[MESA_SHADER_TESS_CTRL].tcs.outputs_written); + } + + radv_nir_shader_info_init(&infos[i]); + radv_nir_shader_info_pass(nir[i], pipeline->layout, + &keys[i], &infos[i]); + } +} + static void merge_tess_info(struct shader_info *tes_info, const struct shader_info *tcs_info) @@ -2488,6 +2589,7 @@ void radv_create_shaders(struct radv_pipeline *pipeline, nir_shader *nir[MESA_SHADER_STAGES] = {0}; struct radv_shader_binary *binaries[MESA_SHADER_STAGES] = {NULL}; struct radv_shader_variant_key keys[MESA_SHADER_STAGES] = {{{{{0}}}}}; + struct radv_shader_info infos[MESA_SHADER_STAGES] = {0}; unsigned char hash[20], gs_copy_hash[20]; bool keep_executable_info = (flags & VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR) || device->keep_shader_info; @@ -2583,6 +2685,8 @@ void radv_create_shaders(struct radv_pipeline *pipeline, radv_fill_shader_keys(device, keys, key, nir); + radv_fill_shader_info(pipeline, keys, infos, nir); + if (nir[MESA_SHADER_FRAGMENT]) { if (!pipeline->shaders[MESA_SHADER_FRAGMENT]) { radv_start_feedback(stage_feedbacks[MESA_SHADER_FRAGMENT]); @@ -2590,6 +2694,7 @@ void radv_create_shaders(struct radv_pipeline *pipeline, pipeline->shaders[MESA_SHADER_FRAGMENT] = radv_shader_variant_compile(device, modules[MESA_SHADER_FRAGMENT], &nir[MESA_SHADER_FRAGMENT], 1, pipeline->layout, keys + MESA_SHADER_FRAGMENT, + infos + MESA_SHADER_FRAGMENT, keep_executable_info, &binaries[MESA_SHADER_FRAGMENT]); radv_stop_feedback(stage_feedbacks[MESA_SHADER_FRAGMENT], false); @@ -2620,7 +2725,7 @@ void radv_create_shaders(struct radv_pipeline *pipeline, pipeline->shaders[MESA_SHADER_TESS_CTRL] = radv_shader_variant_compile(device, modules[MESA_SHADER_TESS_CTRL], combined_nir, 2, pipeline->layout, - &key, keep_executable_info, + &key, &infos[MESA_SHADER_TESS_CTRL], keep_executable_info, &binaries[MESA_SHADER_TESS_CTRL]); radv_stop_feedback(stage_feedbacks[MESA_SHADER_TESS_CTRL], false); @@ -2639,7 +2744,7 @@ void radv_create_shaders(struct radv_pipeline *pipeline, pipeline->shaders[MESA_SHADER_GEOMETRY] = radv_shader_variant_compile(device, modules[MESA_SHADER_GEOMETRY], combined_nir, 2, pipeline->layout, - &keys[pre_stage], keep_executable_info, + &keys[pre_stage], &infos[MESA_SHADER_GEOMETRY], keep_executable_info, &binaries[MESA_SHADER_GEOMETRY]); radv_stop_feedback(stage_feedbacks[MESA_SHADER_GEOMETRY], false); @@ -2661,7 +2766,7 @@ void radv_create_shaders(struct radv_pipeline *pipeline, pipeline->shaders[i] = radv_shader_variant_compile(device, modules[i], &nir[i], 1, pipeline->layout, - keys + i, keep_executable_info, + keys + i, infos + i,keep_executable_info, &binaries[i]); radv_stop_feedback(stage_feedbacks[i], false); @@ -2672,9 +2777,19 @@ void radv_create_shaders(struct radv_pipeline *pipeline, struct radv_shader_binary *gs_copy_binary = NULL; if (!pipeline->gs_copy_shader && !radv_pipeline_has_ngg(pipeline)) { + struct radv_shader_info info = {}; + struct radv_shader_variant_key key = {}; + + key.has_multiview_view_index = + keys[MESA_SHADER_GEOMETRY].has_multiview_view_index; + + radv_nir_shader_info_pass(nir[MESA_SHADER_GEOMETRY], + pipeline->layout, &key, + &info); + pipeline->gs_copy_shader = radv_create_gs_copy_shader( - device, nir[MESA_SHADER_GEOMETRY], &gs_copy_binary, - keep_executable_info, + device, nir[MESA_SHADER_GEOMETRY], &info, + &gs_copy_binary, keep_executable_info, keys[MESA_SHADER_GEOMETRY].has_multiview_view_index); } diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c index 082bdde04ab..146d85ade5a 100644 --- a/src/amd/vulkan/radv_shader.c +++ b/src/amd/vulkan/radv_shader.c @@ -1039,6 +1039,7 @@ shader_variant_compile(struct radv_device *device, struct nir_shader * const *shaders, int shader_count, gl_shader_stage stage, + struct radv_shader_info *info, struct radv_nir_compiler_options *options, bool gs_copy_shader, bool keep_shader_info, @@ -1048,7 +1049,6 @@ shader_variant_compile(struct radv_device *device, enum ac_target_machine_options tm_options = 0; struct ac_llvm_compiler ac_llvm; struct radv_shader_binary *binary = NULL; - struct radv_shader_info info = {0}; bool thread_compiler; options->family = chip_family; @@ -1090,12 +1090,12 @@ shader_variant_compile(struct radv_device *device, if (gs_copy_shader) { assert(shader_count == 1); radv_compile_gs_copy_shader(&ac_llvm, *shaders, &binary, - &info, options); + info, options); } else { - radv_compile_nir_shader(&ac_llvm, &binary, &info, + radv_compile_nir_shader(&ac_llvm, &binary, info, shaders, shader_count, options); } - binary->info = info; + binary->info = *info; radv_destroy_llvm_compiler(&ac_llvm, thread_compiler); @@ -1134,6 +1134,7 @@ radv_shader_variant_compile(struct radv_device *device, int shader_count, struct radv_pipeline_layout *layout, const struct radv_shader_variant_key *key, + struct radv_shader_info *info, bool keep_shader_info, struct radv_shader_binary **binary_out) { @@ -1147,13 +1148,14 @@ radv_shader_variant_compile(struct radv_device *device, options.supports_spill = true; options.robust_buffer_access = device->robust_buffer_access; - return shader_variant_compile(device, module, shaders, shader_count, shaders[shader_count - 1]->info.stage, + return shader_variant_compile(device, module, shaders, shader_count, shaders[shader_count - 1]->info.stage, info, &options, false, keep_shader_info, binary_out); } struct radv_shader_variant * radv_create_gs_copy_shader(struct radv_device *device, struct nir_shader *shader, + struct radv_shader_info *info, struct radv_shader_binary **binary_out, bool keep_shader_info, bool multiview) @@ -1163,7 +1165,7 @@ radv_create_gs_copy_shader(struct radv_device *device, options.key.has_multiview_view_index = multiview; return shader_variant_compile(device, NULL, &shader, 1, MESA_SHADER_VERTEX, - &options, true, keep_shader_info, binary_out); + info, &options, true, keep_shader_info, binary_out); } void diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h index 0deb786f70e..f43b268fa58 100644 --- a/src/amd/vulkan/radv_shader.h +++ b/src/amd/vulkan/radv_shader.h @@ -387,11 +387,13 @@ radv_shader_variant_compile(struct radv_device *device, int shader_count, struct radv_pipeline_layout *layout, const struct radv_shader_variant_key *key, + struct radv_shader_info *info, bool keep_shader_info, struct radv_shader_binary **binary_out); struct radv_shader_variant * radv_create_gs_copy_shader(struct radv_device *device, struct nir_shader *nir, + struct radv_shader_info *info, struct radv_shader_binary **binary_out, bool multiview, bool keep_shader_info); -- 2.30.2