[Mesa-dev] [PATCH 46/61] radeonsi/gfx9: add support for monolithic ES-GS
Marek Olšák
maraeo at gmail.com
Mon Apr 24 08:45:43 UTC 2017
From: Marek Olšák <marek.olsak at amd.com>
---
src/gallium/drivers/radeonsi/si_shader.c | 79 ++++++++++++++++++++++++++++----
src/gallium/drivers/radeonsi/si_shader.h | 2 +
2 files changed, 72 insertions(+), 9 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index aa19e16..edb50a3 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -7723,21 +7723,21 @@ static void si_build_gs_prolog_function(struct si_shader_context *ctx,
/* Create the function. */
si_create_function(ctx, "gs_prolog", returns, num_sgprs + num_vgprs,
params, num_sgprs + num_vgprs, num_sgprs - 1);
func = ctx->main_fn;
/* Set the full EXEC mask for the prolog, because we are only fiddling
* with registers here. The main shader part will set the correct EXEC
* mask.
*/
- if (ctx->screen->b.chip_class >= GFX9)
+ if (ctx->screen->b.chip_class >= GFX9 && !key->gs_prolog.is_monolithic)
si_init_exec_full_mask(ctx);
/* Copy inputs to outputs. This should be no-op, as the registers match,
* but it will prevent the compiler from overwriting them unintentionally.
*/
ret = ctx->return_value;
for (unsigned i = 0; i < num_sgprs; i++) {
LLVMValueRef p = LLVMGetParam(func, i);
ret = LLVMBuildInsertValue(builder, ret, p, i, "");
}
@@ -8187,31 +8187,92 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
union si_shader_part_key epilog_key;
parts[0] = ctx.main_fn;
si_get_vs_epilog_key(shader, &shader->key.part.tes.epilog, &epilog_key);
si_build_vs_epilog_function(&ctx, &epilog_key);
parts[1] = ctx.main_fn;
si_build_wrapper_function(&ctx, parts, 2, 0, 0);
} else if (is_monolithic && ctx.type == PIPE_SHADER_GEOMETRY) {
- LLVMValueRef parts[2];
- union si_shader_part_key prolog_key;
+ if (ctx.screen->b.chip_class >= GFX9) {
+ struct si_shader_selector *es = shader->key.part.gs.es;
+ LLVMValueRef es_prolog = NULL;
+ LLVMValueRef es_main = NULL;
+ LLVMValueRef gs_prolog = NULL;
+ LLVMValueRef gs_main = ctx.main_fn;
+
+ /* GS prolog */
+ union si_shader_part_key gs_prolog_key;
+ memset(&gs_prolog_key, 0, sizeof(gs_prolog_key));
+ gs_prolog_key.gs_prolog.states = shader->key.part.gs.prolog;
+ gs_prolog_key.gs_prolog.is_monolithic = true;
+ si_build_gs_prolog_function(&ctx, &gs_prolog_key);
+ gs_prolog = ctx.main_fn;
+
+ /* ES prolog */
+ if (es->vs_needs_prolog) {
+ union si_shader_part_key vs_prolog_key;
+ si_get_vs_prolog_key(&es->info,
+ shader->info.num_input_sgprs,
+ &shader->key.part.tcs.ls_prolog,
+ shader, &vs_prolog_key);
+ vs_prolog_key.vs_prolog.is_monolithic = true;
+ si_build_vs_prolog_function(&ctx, &vs_prolog_key);
+ es_prolog = ctx.main_fn;
+ }
- parts[1] = ctx.main_fn;
+ /* ES main part */
+ struct si_shader shader_es = {};
+ shader_es.selector = es;
+ shader_es.key.as_es = 1;
+ shader_es.key.mono = shader->key.mono;
+ shader_es.key.opt = shader->key.opt;
+ si_llvm_context_set_tgsi(&ctx, &shader_es);
- memset(&prolog_key, 0, sizeof(prolog_key));
- prolog_key.gs_prolog.states = shader->key.part.gs.prolog;
- si_build_gs_prolog_function(&ctx, &prolog_key);
- parts[0] = ctx.main_fn;
+ if (!si_compile_tgsi_main(&ctx, true)) {
+ si_llvm_dispose(&ctx);
+ return -1;
+ }
+ shader->info.uses_instanceid |= es->info.uses_instanceid;
+ es_main = ctx.main_fn;
- si_build_wrapper_function(&ctx, parts, 2, 1, 0);
+ /* Reset the shader context. */
+ ctx.shader = shader;
+ ctx.type = PIPE_SHADER_GEOMETRY;
+
+ /* Prepare the array of shader parts. */
+ LLVMValueRef parts[4];
+ unsigned num_parts = 0, main_part, next_first_part;
+
+ if (es_prolog)
+ parts[num_parts++] = es_prolog;
+
+ parts[main_part = num_parts++] = es_main;
+ parts[next_first_part = num_parts++] = gs_prolog;
+ parts[num_parts++] = gs_main;
+
+ si_build_wrapper_function(&ctx, parts, num_parts,
+ main_part, next_first_part);
+ } else {
+ LLVMValueRef parts[2];
+ union si_shader_part_key prolog_key;
+
+ parts[1] = ctx.main_fn;
+
+ memset(&prolog_key, 0, sizeof(prolog_key));
+ prolog_key.gs_prolog.states = shader->key.part.gs.prolog;
+ si_build_gs_prolog_function(&ctx, &prolog_key);
+ parts[0] = ctx.main_fn;
+
+ si_build_wrapper_function(&ctx, parts, 2, 1, 0);
+ }
} else if (is_monolithic && ctx.type == PIPE_SHADER_FRAGMENT) {
LLVMValueRef parts[3];
union si_shader_part_key prolog_key;
union si_shader_part_key epilog_key;
bool need_prolog;
si_get_ps_prolog_key(shader, &prolog_key, false);
need_prolog = si_need_ps_prolog(&prolog_key);
parts[need_prolog ? 1 : 0] = ctx.main_fn;
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index cc41174..e0227e4 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -374,20 +374,22 @@ union si_shader_part_key {
} vs_prolog;
struct {
struct si_vs_epilog_bits states;
unsigned prim_id_param_offset:5;
} vs_epilog;
struct {
struct si_tcs_epilog_bits states;
} tcs_epilog;
struct {
struct si_gs_prolog_bits states;
+ /* Prologs of monolithic shaders shouldn't set EXEC. */
+ unsigned is_monolithic:1;
} gs_prolog;
struct {
struct si_ps_prolog_bits states;
unsigned num_input_sgprs:6;
unsigned num_input_vgprs:5;
/* Color interpolation and two-side color selection. */
unsigned colors_read:8; /* color input components read */
unsigned num_interp_inputs:5; /* BCOLOR is at this location */
unsigned face_vgpr_index:5;
unsigned wqm:1;
--
2.7.4
More information about the mesa-dev
mailing list