radeonsi: extract si_llvm_build_shader_part

Prepare for aco code path.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24443>
This commit is contained in:
Qiang Yu
2023-07-22 22:34:54 +08:00
parent e797bd78c9
commit b744405aa2
3 changed files with 98 additions and 69 deletions
+9 -69
View File
@@ -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;
@@ -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);
@@ -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;
}