From: Nicolai Hähnle <nicolai.haeh...@amd.com>

For fixed function TCS, we keep the copying of VS outputs to TES inputs inside
the main function; the call to si_copy_tcs_inputs is moved accordingly.
---
 src/gallium/drivers/radeonsi/si_shader.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c 
b/src/gallium/drivers/radeonsi/si_shader.c
index b33f54a..b7678e1 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -68,20 +68,22 @@ static void si_llvm_emit_barrier(const struct 
lp_build_tgsi_action *action,
                                 struct lp_build_tgsi_context *bld_base,
                                 struct lp_build_emit_data *emit_data);
 
 static void si_dump_shader_key(unsigned shader, union si_shader_key *key,
                               FILE *f);
 
 static void si_build_vs_prolog_function(struct si_shader_context *ctx,
                                        union si_shader_part_key *key);
 static void si_build_vs_epilog_function(struct si_shader_context *ctx,
                                        union si_shader_part_key *key);
+static void si_build_tcs_epilog_function(struct si_shader_context *ctx,
+                                        union si_shader_part_key *key);
 static void si_build_ps_prolog_function(struct si_shader_context *ctx,
                                        union si_shader_part_key *key);
 static void si_build_ps_epilog_function(struct si_shader_context *ctx,
                                        union si_shader_part_key *key);
 
 /* Ideally pass the sample mask input to the PS epilog as v13, which
  * is its usual location, so that the shader doesn't have to add v_mov.
  */
 #define PS_EPILOG_SAMPLEMASK_MIN_LOC 13
 
@@ -2476,20 +2478,24 @@ handle_semantic:
 
                if (pos_idx == shader->info.nr_pos_exports)
                        /* Specify that this is the last export */
                        pos_args[i][2] = uint->one;
 
                lp_build_intrinsic(base->gallivm->builder, "llvm.SI.export",
                                   ctx->voidt, pos_args[i], 9, 0);
        }
 }
 
+/**
+ * Forward all outputs from the vertex shader to the TES. This is only used
+ * for the fixed function TCS.
+ */
 static void si_copy_tcs_inputs(struct lp_build_tgsi_context *bld_base)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct gallivm_state *gallivm = bld_base->base.gallivm;
        LLVMValueRef invocation_id, rw_buffers, buffer, buffer_offset;
        LLVMValueRef lds_vertex_stride, lds_vertex_offset, lds_base;
        uint64_t inputs;
 
        invocation_id = unpack_param(ctx, SI_PARAM_REL_IDS, 8, 5);
 
@@ -2630,20 +2636,22 @@ static void si_write_tess_factors(struct 
lp_build_tgsi_context *bld_base,
                                           stride - 4, byteoffset, tf_base, 20);
        lp_build_endif(&if_ctx);
 }
 
 /* This only writes the tessellation factor levels. */
 static void si_llvm_emit_tcs_epilogue(struct lp_build_tgsi_context *bld_base)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        LLVMValueRef rel_patch_id, invocation_id, tf_lds_offset;
 
+       si_copy_tcs_inputs(bld_base);
+
        rel_patch_id = get_rel_patch_id(ctx);
        invocation_id = unpack_param(ctx, SI_PARAM_REL_IDS, 8, 5);
        tf_lds_offset = get_tcs_out_current_patch_data_offset(ctx);
 
        if (!ctx->no_epilog) {
                /* Return epilog parameters from this function. */
                LLVMBuilderRef builder = bld_base->base.gallivm->builder;
                LLVMValueRef ret = ctx->return_value;
                LLVMValueRef rw_buffers, rw0, rw1, tf_soffset;
                unsigned vgpr;
@@ -2672,21 +2680,20 @@ static void si_llvm_emit_tcs_epilogue(struct 
lp_build_tgsi_context *bld_base)
                tf_lds_offset = bitcast(bld_base, TGSI_TYPE_FLOAT, 
tf_lds_offset);
 
                vgpr = SI_TCS_NUM_USER_SGPR + 2;
                ret = LLVMBuildInsertValue(builder, ret, rel_patch_id, vgpr++, 
"");
                ret = LLVMBuildInsertValue(builder, ret, invocation_id, vgpr++, 
"");
                ret = LLVMBuildInsertValue(builder, ret, tf_lds_offset, vgpr++, 
"");
                ctx->return_value = ret;
                return;
        }
 
-       si_copy_tcs_inputs(bld_base);
        si_write_tess_factors(bld_base, rel_patch_id, invocation_id, 
tf_lds_offset);
 }
 
 static void si_llvm_emit_ls_epilogue(struct lp_build_tgsi_context *bld_base)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct si_shader *shader = ctx->shader;
        struct tgsi_shader_info *info = &shader->selector->info;
        struct gallivm_state *gallivm = bld_base->base.gallivm;
        unsigned i, chan;
@@ -7172,20 +7179,21 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
                tgsi_dump(sel->tokens, 0);
                si_dump_streamout(&sel->so);
        }
 
        si_init_shader_ctx(&ctx, sscreen, shader, tm);
        ctx.no_prolog = is_monolithic;
        ctx.no_epilog = is_monolithic;
        ctx.separate_prolog = !is_monolithic;
 
        if (ctx.type == PIPE_SHADER_VERTEX ||
+           ctx.type == PIPE_SHADER_TESS_CTRL ||
            ctx.type == PIPE_SHADER_TESS_EVAL ||
            ctx.type == PIPE_SHADER_FRAGMENT) {
                ctx.no_prolog = false;
                ctx.no_epilog = false;
        }
 
        memset(shader->info.vs_output_param_offset, 0xff,
               sizeof(shader->info.vs_output_param_offset));
 
        shader->info.uses_instanceid = sel->info.uses_instanceid;
@@ -7217,20 +7225,32 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
 
                if (need_epilog) {
                        union si_shader_part_key epilog_key;
                        si_get_vs_epilog_key(shader, &shader->key.vs.epilog, 
&epilog_key);
                        si_build_vs_epilog_function(&ctx, &epilog_key);
                        parts[need_prolog ? 2 : 1] = ctx.main_fn;
                }
 
                si_build_wrapper_function(&ctx, parts, 1 + need_prolog + 
need_epilog,
                                          need_prolog ? 1 : 0);
+       } else if (is_monolithic && ctx.type == PIPE_SHADER_TESS_CTRL) {
+               LLVMValueRef parts[2];
+               union si_shader_part_key epilog_key;
+
+               parts[0] = ctx.main_fn;
+
+               memset(&epilog_key, 0, sizeof(epilog_key));
+               epilog_key.tcs_epilog.states = shader->key.tcs.epilog;
+               si_build_tcs_epilog_function(&ctx, &epilog_key);
+               parts[1] = ctx.main_fn;
+
+               si_build_wrapper_function(&ctx, parts, 2, 0);
        } else if (is_monolithic && ctx.type == PIPE_SHADER_TESS_EVAL &&
                   !shader->key.tes.as_es) {
                LLVMValueRef parts[2];
                union si_shader_part_key epilog_key;
 
                parts[0] = ctx.main_fn;
 
                si_get_vs_epilog_key(shader, &shader->key.tes.epilog, 
&epilog_key);
                si_build_vs_epilog_function(&ctx, &epilog_key);
                parts[1] = ctx.main_fn;
-- 
2.7.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to