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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user