From b744405aa25ccdbe845a084e805e25a75eb14713 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Sat, 22 Jul 2023 22:34:54 +0800 Subject: [PATCH] radeonsi: extract si_llvm_build_shader_part MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prepare for aco code path. Reviewed-by: Marek Olšák Signed-off-by: Qiang Yu Part-of: --- src/gallium/drivers/radeonsi/si_shader.c | 78 ++--------------- .../drivers/radeonsi/si_shader_internal.h | 4 + src/gallium/drivers/radeonsi/si_shader_llvm.c | 85 +++++++++++++++++++ 3 files changed, 98 insertions(+), 69 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 18783f0cf4d..e495a284b40 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -2858,15 +2858,12 @@ out: * \param prolog whether the part being requested is a prolog * \param tm LLVM target machine * \param debug debug callback - * \param build the callback responsible for building the main function * \return non-NULL on success */ static struct si_shader_part * si_get_shader_part(struct si_screen *sscreen, struct si_shader_part **list, gl_shader_stage stage, bool prolog, union si_shader_part_key *key, struct ac_llvm_compiler *compiler, struct util_debug_callback *debug, - void (*build)(struct si_shader_context *, union si_shader_part_key *, - bool non_monolithic), const char *name) { struct si_shader_part *result; @@ -2885,73 +2882,16 @@ si_get_shader_part(struct si_screen *sscreen, struct si_shader_part **list, result = CALLOC_STRUCT(si_shader_part); result->key = *key; - struct si_shader_selector sel = {}; - sel.screen = sscreen; + bool ok = si_llvm_build_shader_part(sscreen, stage, prolog, compiler, debug, name, result); - struct si_shader shader = {}; - shader.selector = &sel; - bool wave32 = false; - bool exports_color_null = false; - bool exports_mrtz = false; - - switch (stage) { - case MESA_SHADER_VERTEX: - shader.key.ge.as_ls = key->vs_prolog.as_ls; - shader.key.ge.as_es = key->vs_prolog.as_es; - shader.key.ge.as_ngg = key->vs_prolog.as_ngg; - wave32 = key->vs_prolog.wave32; - break; - case MESA_SHADER_TESS_CTRL: - assert(!prolog); - shader.key.ge.part.tcs.epilog = key->tcs_epilog.states; - wave32 = key->tcs_epilog.wave32; - break; - case MESA_SHADER_FRAGMENT: - if (prolog) { - shader.key.ps.part.prolog = key->ps_prolog.states; - wave32 = key->ps_prolog.wave32; - exports_color_null = key->ps_prolog.states.poly_stipple; - } else { - shader.key.ps.part.epilog = key->ps_epilog.states; - wave32 = key->ps_epilog.wave32; - exports_color_null = key->ps_epilog.colors_written; - exports_mrtz = key->ps_epilog.writes_z || key->ps_epilog.writes_stencil || - key->ps_epilog.writes_samplemask; - if (!exports_mrtz && !exports_color_null) - exports_color_null = key->ps_epilog.uses_discard || sscreen->info.gfx_level < GFX10; - } - break; - default: - unreachable("bad shader part"); - } - - struct si_shader_context ctx; - si_llvm_context_init(&ctx, sscreen, compiler, wave32 ? 32 : 64, exports_color_null, exports_mrtz, - AC_FLOAT_MODE_DEFAULT_OPENGL); - - ctx.shader = &shader; - ctx.stage = stage; - - struct si_shader_args args; - ctx.args = &args; - - build(&ctx, key, true); - - /* Compile. */ - si_llvm_optimize_module(&ctx); - - if (!si_compile_llvm(sscreen, &result->binary, &result->config, compiler, &ctx.ac, debug, - ctx.stage, name, false)) { + if (ok) { + result->next = *list; + *list = result; + } else { FREE(result); result = NULL; - goto out; } - result->next = *list; - *list = result; - -out: - si_llvm_dispose(&ctx); simple_mtx_unlock(&sscreen->shader_parts_mutex); return result; } @@ -2972,7 +2912,7 @@ static bool si_get_vs_prolog(struct si_screen *sscreen, struct ac_llvm_compiler shader->prolog = si_get_shader_part(sscreen, &sscreen->vs_prologs, MESA_SHADER_VERTEX, true, &prolog_key, - compiler, debug, si_llvm_build_vs_prolog, "Vertex Shader Prolog"); + compiler, debug, "Vertex Shader Prolog"); return shader->prolog != NULL; } @@ -3017,7 +2957,7 @@ static bool si_shader_select_tcs_parts(struct si_screen *sscreen, struct ac_llvm si_get_tcs_epilog_key(shader, &epilog_key); shader->epilog = si_get_shader_part(sscreen, &sscreen->tcs_epilogs, MESA_SHADER_TESS_CTRL, false, - &epilog_key, compiler, debug, si_llvm_build_tcs_epilog, + &epilog_key, compiler, debug, "Tessellation Control Shader Epilog"); return shader->epilog != NULL; } @@ -3209,7 +3149,7 @@ static bool si_shader_select_ps_parts(struct si_screen *sscreen, struct ac_llvm_ if (si_need_ps_prolog(&prolog_key)) { shader->prolog = si_get_shader_part(sscreen, &sscreen->ps_prologs, MESA_SHADER_FRAGMENT, true, &prolog_key, - compiler, debug, si_llvm_build_ps_prolog, "Fragment Shader Prolog"); + compiler, debug, "Fragment Shader Prolog"); if (!shader->prolog) return false; } @@ -3219,7 +3159,7 @@ static bool si_shader_select_ps_parts(struct si_screen *sscreen, struct ac_llvm_ shader->epilog = si_get_shader_part(sscreen, &sscreen->ps_epilogs, MESA_SHADER_FRAGMENT, false, &epilog_key, - compiler, debug, si_llvm_build_ps_epilog, "Fragment Shader Epilog"); + compiler, debug, "Fragment Shader Epilog"); if (!shader->epilog) return false; diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h index 9d392d2e672..7c7228eb0f5 100644 --- a/src/gallium/drivers/radeonsi/si_shader_internal.h +++ b/src/gallium/drivers/radeonsi/si_shader_internal.h @@ -185,6 +185,10 @@ LLVMValueRef si_unpack_param(struct si_shader_context *ctx, struct ac_arg param, bool si_llvm_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compiler, struct si_shader *shader, struct si_shader_args *args, struct util_debug_callback *debug, struct nir_shader *nir); +bool si_llvm_build_shader_part(struct si_screen *sscreen, gl_shader_stage stage, + bool prolog, struct ac_llvm_compiler *compiler, + struct util_debug_callback *debug, const char *name, + struct si_shader_part *result); /* si_shader_llvm_gs.c */ LLVMValueRef si_is_es_thread(struct si_shader_context *ctx); diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm.c b/src/gallium/drivers/radeonsi/si_shader_llvm.c index 75b42923650..98506879f33 100644 --- a/src/gallium/drivers/radeonsi/si_shader_llvm.c +++ b/src/gallium/drivers/radeonsi/si_shader_llvm.c @@ -898,3 +898,88 @@ bool si_llvm_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler * si_llvm_dispose(&ctx); return true; } + +bool si_llvm_build_shader_part(struct si_screen *sscreen, gl_shader_stage stage, + bool prolog, struct ac_llvm_compiler *compiler, + struct util_debug_callback *debug, const char *name, + struct si_shader_part *result) +{ + union si_shader_part_key *key = &result->key; + + struct si_shader_selector sel = {}; + sel.screen = sscreen; + + struct si_shader shader = {}; + shader.selector = &sel; + bool wave32 = false; + bool exports_color_null = false; + bool exports_mrtz = false; + + switch (stage) { + case MESA_SHADER_VERTEX: + shader.key.ge.as_ls = key->vs_prolog.as_ls; + shader.key.ge.as_es = key->vs_prolog.as_es; + shader.key.ge.as_ngg = key->vs_prolog.as_ngg; + wave32 = key->vs_prolog.wave32; + break; + case MESA_SHADER_TESS_CTRL: + assert(!prolog); + shader.key.ge.part.tcs.epilog = key->tcs_epilog.states; + wave32 = key->tcs_epilog.wave32; + break; + case MESA_SHADER_FRAGMENT: + if (prolog) { + shader.key.ps.part.prolog = key->ps_prolog.states; + wave32 = key->ps_prolog.wave32; + exports_color_null = key->ps_prolog.states.poly_stipple; + } else { + shader.key.ps.part.epilog = key->ps_epilog.states; + wave32 = key->ps_epilog.wave32; + exports_color_null = key->ps_epilog.colors_written; + exports_mrtz = key->ps_epilog.writes_z || key->ps_epilog.writes_stencil || + key->ps_epilog.writes_samplemask; + if (!exports_mrtz && !exports_color_null) + exports_color_null = key->ps_epilog.uses_discard || sscreen->info.gfx_level < GFX10; + } + break; + default: + unreachable("bad shader part"); + } + + struct si_shader_context ctx; + si_llvm_context_init(&ctx, sscreen, compiler, wave32 ? 32 : 64, exports_color_null, exports_mrtz, + AC_FLOAT_MODE_DEFAULT_OPENGL); + + ctx.shader = &shader; + ctx.stage = stage; + + struct si_shader_args args; + ctx.args = &args; + + void (*build)(struct si_shader_context *, union si_shader_part_key *, bool); + + switch (stage) { + case MESA_SHADER_VERTEX: + build = si_llvm_build_vs_prolog; + break; + case MESA_SHADER_TESS_CTRL: + build = si_llvm_build_tcs_epilog; + break; + case MESA_SHADER_FRAGMENT: + build = prolog ? si_llvm_build_ps_prolog : si_llvm_build_ps_epilog; + break; + default: + unreachable("bad shader part"); + } + + build(&ctx, key, true); + + /* Compile. */ + si_llvm_optimize_module(&ctx); + + bool ret = si_compile_llvm(sscreen, &result->binary, &result->config, compiler, + &ctx.ac, debug, ctx.stage, name, false); + + si_llvm_dispose(&ctx); + return ret; +}