From: Marek Olšák <[email protected]>

---
 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

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to