From 58c91fb8cf816d14283f626c3fcaab739fdd1937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 25 Dec 2024 07:38:22 -0500 Subject: [PATCH] radeonsi: add si_nir_shader_ctx holding parameters from si_get_nir_shader we'll need to pass this structure around Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/gallium/drivers/radeonsi/si_shader.c | 64 ++++++++----------- src/gallium/drivers/radeonsi/si_shader_aco.c | 13 ++-- .../drivers/radeonsi/si_shader_internal.h | 13 ++-- src/gallium/drivers/radeonsi/si_shader_llvm.c | 7 +- 4 files changed, 46 insertions(+), 51 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index fdcd4560996..e2243f9d06e 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -2229,28 +2229,26 @@ si_init_gs_output_info(struct si_shader_info *info, struct si_gs_output_info *ou ac_info->types_16bit_lo = ac_info->types_16bit_hi = NULL; } -static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_shader_args *args, - bool *free_nir, - struct si_gs_output_info *legacy_gs_output_info) +static void get_nir_shader(struct si_shader *shader, struct si_nir_shader_ctx *ctx) { struct si_shader_selector *sel = shader->selector; const union si_shader_key *key = &shader->key; + memset(ctx, 0, sizeof(*ctx)); nir_shader *nir; - *free_nir = false; if (sel->nir) { - nir = sel->nir; + ctx->nir = nir = sel->nir; } else if (sel->nir_binary) { - nir = si_deserialize_shader(sel); - *free_nir = true; + ctx->nir = nir = si_deserialize_shader(sel); + ctx->free_nir = true; } else { - return NULL; + return; } if (sel->stage == MESA_SHADER_GEOMETRY && !shader->key.ge.as_ngg) { - memset(legacy_gs_output_info, 0, sizeof(*legacy_gs_output_info)); - si_init_gs_output_info(&sel->info, legacy_gs_output_info); + memset(&ctx->legacy_gs_output_info, 0, sizeof(ctx->legacy_gs_output_info)); + si_init_gs_output_info(&sel->info, &ctx->legacy_gs_output_info); } bool progress = false; @@ -2267,7 +2265,7 @@ static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_ nir_print_shader(nir, stdout); } - si_init_shader_args(shader, args, &nir->info); + si_init_shader_args(shader, &ctx->args, &nir->info); /* Kill outputs according to the shader key. */ if (nir->info.stage <= MESA_SHADER_GEOMETRY) @@ -2288,7 +2286,7 @@ static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_ &inline_uniforms, &inlined_uniform_values); if (inline_uniforms) { - assert(*free_nir); + assert(ctx->free_nir); /* Most places use shader information from the default variant, not * the optimized variant. These are the things that the driver looks at @@ -2427,7 +2425,7 @@ static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_ progress |= ac_nir_lower_indirect_derefs(nir, sel->screen->info.gfx_level); if (nir->info.stage == MESA_SHADER_VERTEX) - NIR_PASS(progress, nir, si_nir_lower_vs_inputs, shader, args); + NIR_PASS(progress, nir, si_nir_lower_vs_inputs, shader, &ctx->args); progress |= si_lower_io_to_mem(shader, nir); @@ -2461,7 +2459,8 @@ static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_ } progress = true; } else if (nir->info.stage == MESA_SHADER_GEOMETRY && !key->ge.as_ngg) { - NIR_PASS_V(nir, ac_nir_lower_legacy_gs, false, sel->screen->use_ngg, &legacy_gs_output_info->info); + NIR_PASS_V(nir, ac_nir_lower_legacy_gs, false, sel->screen->use_ngg, + &ctx->legacy_gs_output_info.info); progress = true; } else if (nir->info.stage == MESA_SHADER_FRAGMENT && shader->is_monolithic) { /* Uniform inlining can eliminate PS inputs, and colormask can remove PS outputs, @@ -2549,7 +2548,7 @@ static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_ NIR_PASS(progress, nir, nir_lower_io_to_scalar, nir_var_mem_ubo | nir_var_mem_ssbo | nir_var_mem_shared | nir_var_mem_global, ac_nir_scalarize_overfetching_loads_callback, &sel->screen->info.gfx_level); - NIR_PASS(progress, nir, si_nir_lower_resource, shader, args); + NIR_PASS(progress, nir, si_nir_lower_resource, shader, &ctx->args); if (progress) { si_nir_opts(sel->screen, nir, false); @@ -2595,11 +2594,11 @@ static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_ progress |= ac_nir_optimize_uniform_atomics(nir); NIR_PASS(progress, nir, nir_lower_int64); - NIR_PASS(progress, nir, si_nir_lower_abi, shader, args); + NIR_PASS(progress, nir, si_nir_lower_abi, shader, &ctx->args); NIR_PASS(progress, nir, ac_nir_lower_intrinsics_to_args, sel->screen->info.gfx_level, sel->screen->info.has_ls_vgpr_init_bug, si_select_hw_stage(nir->info.stage, key, sel->screen->info.gfx_level), - shader->wave_size, si_get_max_workgroup_size(shader), &args->ac); + shader->wave_size, si_get_max_workgroup_size(shader), &ctx->args.ac); /* LLVM keep non-uniform sampler as index, so can't do this in NIR. * Must be done after si_nir_lower_resource(). @@ -2648,8 +2647,6 @@ static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_ ralloc_free((void*)nir->info.name); nir->info.name = original_name; } - - return nir; } void si_update_shader_binary_info(struct si_shader *shader, nir_shader *nir) @@ -2943,12 +2940,9 @@ bool si_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compi if (sel->stage == MESA_SHADER_FRAGMENT && sel->info.base.use_aco_amd) si_set_spi_ps_input_config(shader); - /* We need this info only when legacy GS. */ - struct si_gs_output_info legacy_gs_output_info; - struct si_shader_args args; - bool free_nir; - struct nir_shader *nir = - si_get_nir_shader(shader, &args, &free_nir, &legacy_gs_output_info); + struct si_nir_shader_ctx ctx; + get_nir_shader(shader, &ctx); + nir_shader *nir = ctx.nir; /* Dump NIR before doing NIR->LLVM conversion in case the * conversion fails. */ @@ -2999,10 +2993,10 @@ bool si_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compi ret = #if AMD_LLVM_AVAILABLE - !nir->info.use_aco_amd ? si_llvm_compile_shader(sscreen, compiler, shader, &args, + !nir->info.use_aco_amd ? si_llvm_compile_shader(sscreen, compiler, shader, &ctx.args, debug, nir) : #endif - si_aco_compile_shader(shader, &args, nir, debug); + si_aco_compile_shader(shader, &ctx.args, nir, debug); if (!ret) goto out; @@ -3013,7 +3007,7 @@ bool si_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compi if (nir->info.stage == MESA_SHADER_GEOMETRY && !shader->key.ge.as_ngg) { shader->gs_copy_shader = si_nir_generate_gs_copy_shader(sscreen, compiler, shader, nir, debug, - &legacy_gs_output_info.info); + &ctx.legacy_gs_output_info.info); if (!shader->gs_copy_shader) { fprintf(stderr, "radeonsi: can't create GS copy shader\n"); ret = false; @@ -3121,7 +3115,7 @@ bool si_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compi } out: - if (free_nir) + if (ctx.free_nir) ralloc_free(nir); return ret; @@ -3652,10 +3646,8 @@ void si_shader_destroy(struct si_shader *shader) free(shader->shader_log); } -nir_shader *si_get_prev_stage_nir_shader(struct si_shader *shader, - struct si_shader *prev_shader, - struct si_shader_args *args, - bool *free_nir) +void si_get_prev_stage_nir_shader(struct si_shader *shader, struct si_shader *prev_shader, + struct si_nir_shader_ctx *ctx) { const struct si_shader_selector *sel = shader->selector; const union si_shader_key *key = &shader->key; @@ -3684,13 +3676,11 @@ nir_shader *si_get_prev_stage_nir_shader(struct si_shader *shader, prev_shader->is_monolithic = true; prev_shader->wave_size = shader->wave_size; - nir_shader *nir = si_get_nir_shader(prev_shader, args, free_nir, NULL); - si_update_shader_binary_info(shader, nir); + get_nir_shader(prev_shader, ctx); + si_update_shader_binary_info(shader, ctx->nir); shader->info.uses_instanceid |= prev_shader->selector->info.uses_instanceid || prev_shader->info.uses_instanceid; - - return nir; } void si_get_ps_prolog_args(struct si_shader_args *args, diff --git a/src/gallium/drivers/radeonsi/si_shader_aco.c b/src/gallium/drivers/radeonsi/si_shader_aco.c index 14706551366..9fd241f6b8a 100644 --- a/src/gallium/drivers/radeonsi/si_shader_aco.c +++ b/src/gallium/drivers/radeonsi/si_shader_aco.c @@ -159,17 +159,16 @@ si_aco_compile_shader(struct si_shader *shader, nir_shader *shaders[2]; unsigned num_shaders = 0; - bool free_nir = false; struct si_shader prev_shader = {}; - struct si_shader_args prev_args; + struct si_nir_shader_ctx prev_ctx; + prev_ctx.free_nir = false; /* For merged shader stage. */ if (shader->is_monolithic && sel->screen->info.gfx_level >= GFX9 && (nir->info.stage == MESA_SHADER_TESS_CTRL || nir->info.stage == MESA_SHADER_GEOMETRY)) { - shaders[num_shaders++] = - si_get_prev_stage_nir_shader(shader, &prev_shader, &prev_args, &free_nir); - - args = &prev_args; + si_get_prev_stage_nir_shader(shader, &prev_shader, &prev_ctx); + shaders[num_shaders++] = prev_ctx.nir; + args = &prev_ctx.args; } shaders[num_shaders++] = nir; @@ -177,7 +176,7 @@ si_aco_compile_shader(struct si_shader *shader, aco_compile_shader(&options, &info, num_shaders, shaders, &args->ac, si_aco_build_shader_binary, (void **)shader); - if (free_nir) + if (prev_ctx.free_nir) ralloc_free(shaders[0]); return true; diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h index 442dcf2f5c1..b20cc7b5f4d 100644 --- a/src/gallium/drivers/radeonsi/si_shader_internal.h +++ b/src/gallium/drivers/radeonsi/si_shader_internal.h @@ -91,6 +91,13 @@ struct si_gs_output_info { ac_nir_gs_output_info info; }; +struct si_nir_shader_ctx { + struct si_shader_args args; + struct si_gs_output_info legacy_gs_output_info; + nir_shader *nir; + bool free_nir; +}; + struct nir_builder; typedef struct nir_builder nir_builder; @@ -103,10 +110,8 @@ bool si_is_merged_shader(struct si_shader *shader); unsigned si_get_max_workgroup_size(const struct si_shader *shader); enum ac_hw_stage si_select_hw_stage(const gl_shader_stage stage, const union si_shader_key *const key, const enum amd_gfx_level gfx_level); -nir_shader *si_get_prev_stage_nir_shader(struct si_shader *shader, - struct si_shader *prev_shader, - struct si_shader_args *args, - bool *free_nir); +void si_get_prev_stage_nir_shader(struct si_shader *shader, struct si_shader *prev_shader, + struct si_nir_shader_ctx *ctx); void si_get_ps_prolog_args(struct si_shader_args *args, const union si_shader_part_key *key); void si_get_ps_epilog_args(struct si_shader_args *args, diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm.c b/src/gallium/drivers/radeonsi/si_shader_llvm.c index 9655a453a0e..e133ff01994 100644 --- a/src/gallium/drivers/radeonsi/si_shader_llvm.c +++ b/src/gallium/drivers/radeonsi/si_shader_llvm.c @@ -804,14 +804,15 @@ bool si_llvm_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler * (nir->info.stage == MESA_SHADER_TESS_CTRL || nir->info.stage == MESA_SHADER_GEOMETRY)) { /* LS or ES shader. */ struct si_shader prev_shader = {}; + struct si_nir_shader_ctx prev_nir_ctx; - bool free_nir; - nir_shader *prev_nir = si_get_prev_stage_nir_shader(shader, &prev_shader, ctx.args, &free_nir); + si_get_prev_stage_nir_shader(shader, &prev_shader, &prev_nir_ctx); + ctx.args = &prev_nir_ctx.args; struct ac_llvm_pointer parts[2]; parts[1] = ctx.main_fn; - if (!si_llvm_translate_nir(&ctx, &prev_shader, prev_nir, free_nir)) { + if (!si_llvm_translate_nir(&ctx, &prev_shader, prev_nir_ctx.nir, prev_nir_ctx.free_nir)) { si_llvm_dispose(&ctx); return false; }