From: Marek Olšák <marek.ol...@amd.com>

---
 src/gallium/drivers/radeonsi/si_descriptors.c | 10 +-
 src/gallium/drivers/radeonsi/si_shader.c      | 97 +++++++++++++------
 src/gallium/drivers/radeonsi/si_shader.h      |  2 +-
 src/gallium/drivers/radeonsi/si_state_draw.c  | 11 +++
 4 files changed, 87 insertions(+), 33 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c 
b/src/gallium/drivers/radeonsi/si_descriptors.c
index e8c028061d1..323cdbbf7af 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -1995,26 +1995,28 @@ static void si_shader_pointers_begin_new_cs(struct 
si_context *sctx)
  * This assigns a mapping from PIPE_SHADER_* to SPI_SHADER_USER_DATA_*.
  */
 static void si_set_user_data_base(struct si_context *sctx,
                                  unsigned shader, uint32_t new_base)
 {
        uint32_t *base = &sctx->shader_pointers.sh_base[shader];
 
        if (*base != new_base) {
                *base = new_base;
 
-               if (new_base) {
+               if (new_base)
                        si_mark_shader_pointers_dirty(sctx, shader);
 
-                       if (shader == PIPE_SHADER_VERTEX)
-                               sctx->last_vs_state = ~0;
-               }
+               /* Any change in enabled shader stages requires re-emitting
+                * the VS state SGPR, because it contains the clamp_vertex_color
+                * state, which can be done VS, TES, and GS.
+                */
+               sctx->last_vs_state = ~0;
        }
 }
 
 /* This must be called when these shaders are changed from non-NULL to NULL
  * and vice versa:
  * - geometry shader
  * - tessellation control shader
  * - tessellation evaluation shader
  */
 void si_shader_change_notify(struct si_context *sctx)
diff --git a/src/gallium/drivers/radeonsi/si_shader.c 
b/src/gallium/drivers/radeonsi/si_shader.c
index 9bee8440027..32db089ed2c 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -3669,52 +3669,50 @@ static void si_llvm_emit_vs_epilogue(struct 
ac_shader_abi *abi,
        assert(info->num_outputs <= max_outputs);
 
        outputs = MALLOC((info->num_outputs + 1) * sizeof(outputs[0]));
 
        /* Vertex color clamping.
         *
         * This uses a state constant loaded in a user data SGPR and
         * an IF statement is added that clamps all colors if the constant
         * is true.
         */
-       if (ctx->type == PIPE_SHADER_VERTEX) {
-               struct lp_build_if_state if_ctx;
-               LLVMValueRef cond = NULL;
-               LLVMValueRef addr, val;
-
-               for (i = 0; i < info->num_outputs; i++) {
-                       if (info->output_semantic_name[i] != 
TGSI_SEMANTIC_COLOR &&
-                           info->output_semantic_name[i] != 
TGSI_SEMANTIC_BCOLOR)
-                               continue;
+       struct lp_build_if_state if_ctx;
+       LLVMValueRef cond = NULL;
+       LLVMValueRef addr, val;
 
-                       /* We've found a color. */
-                       if (!cond) {
-                               /* The state is in the first bit of the user 
SGPR. */
-                               cond = LLVMGetParam(ctx->main_fn,
-                                                   ctx->param_vs_state_bits);
-                               cond = LLVMBuildTrunc(ctx->ac.builder, cond,
-                                                     ctx->i1, "");
-                               lp_build_if(&if_ctx, &ctx->gallivm, cond);
-                       }
+       for (i = 0; i < info->num_outputs; i++) {
+               if (info->output_semantic_name[i] != TGSI_SEMANTIC_COLOR &&
+                   info->output_semantic_name[i] != TGSI_SEMANTIC_BCOLOR)
+                       continue;
 
-                       for (j = 0; j < 4; j++) {
-                               addr = addrs[4 * i + j];
-                               val = LLVMBuildLoad(ctx->ac.builder, addr, "");
-                               val = ac_build_clamp(&ctx->ac, val);
-                               LLVMBuildStore(ctx->ac.builder, val, addr);
-                       }
+               /* We've found a color. */
+               if (!cond) {
+                       /* The state is in the first bit of the user SGPR. */
+                       cond = LLVMGetParam(ctx->main_fn,
+                                           ctx->param_vs_state_bits);
+                       cond = LLVMBuildTrunc(ctx->ac.builder, cond,
+                                             ctx->i1, "");
+                       lp_build_if(&if_ctx, &ctx->gallivm, cond);
                }
 
-               if (cond)
-                       lp_build_endif(&if_ctx);
+               for (j = 0; j < 4; j++) {
+                       addr = addrs[4 * i + j];
+                       val = LLVMBuildLoad(ctx->ac.builder, addr, "");
+                       val = ac_build_clamp(&ctx->ac, val);
+                       LLVMBuildStore(ctx->ac.builder, val, addr);
+               }
        }
 
+       if (cond)
+               lp_build_endif(&if_ctx);
+
        for (i = 0; i < info->num_outputs; i++) {
                outputs[i].semantic_name = info->output_semantic_name[i];
                outputs[i].semantic_index = info->output_semantic_index[i];
 
                for (j = 0; j < 4; j++) {
                        outputs[i].values[j] =
                                LLVMBuildLoad(ctx->ac.builder,
                                              addrs[4 * i + j],
                                              "");
                        outputs[i].vertex_stream[j] =
@@ -4738,21 +4736,21 @@ static void create_function(struct si_shader_context 
*ctx)
                declare_vs_specific_input_sgprs(ctx, &fninfo);
                ctx->param_vertex_buffers = add_arg(&fninfo, ARG_SGPR,
                        ac_array_in_const32_addr_space(ctx->v4i32));
 
                if (shader->key.as_es) {
                        ctx->param_es2gs_offset = add_arg(&fninfo, ARG_SGPR, 
ctx->i32);
                } else if (shader->key.as_ls) {
                        /* no extra parameters */
                } else {
                        if (shader->is_gs_copy_shader) {
-                               fninfo.num_params = ctx->param_rw_buffers + 1;
+                               fninfo.num_params = ctx->param_vs_state_bits + 
1;
                                fninfo.num_sgpr_params = fninfo.num_params;
                        }
 
                        /* The locations of the other parameters are assigned 
dynamically. */
                        declare_streamout_params(ctx, &shader->selector->so,
                                                 &fninfo);
                }
 
                /* VGPRs */
                declare_vs_input_vgprs(ctx, &fninfo, &num_prolog_vgprs);
@@ -5819,22 +5817,65 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
                        }
                }
 
                /* Streamout and exports. */
                if (gs_selector->so.num_outputs) {
                        si_llvm_emit_streamout(&ctx, outputs,
                                               gsinfo->num_outputs,
                                               stream);
                }
 
-               if (stream == 0)
+               if (stream == 0) {
+                       /* Vertex color clamping.
+                        *
+                        * This uses a state constant loaded in a user data 
SGPR and
+                        * an IF statement is added that clamps all colors if 
the constant
+                        * is true.
+                        */
+                       struct lp_build_if_state if_ctx;
+                       LLVMValueRef v[2], cond = NULL;
+                       LLVMBasicBlockRef blocks[2];
+
+                       for (unsigned i = 0; i < gsinfo->num_outputs; i++) {
+                               if (gsinfo->output_semantic_name[i] != 
TGSI_SEMANTIC_COLOR &&
+                                   gsinfo->output_semantic_name[i] != 
TGSI_SEMANTIC_BCOLOR)
+                                       continue;
+
+                               /* We've found a color. */
+                               if (!cond) {
+                                       /* The state is in the first bit of the 
user SGPR. */
+                                       cond = LLVMGetParam(ctx.main_fn,
+                                                           
ctx.param_vs_state_bits);
+                                       cond = LLVMBuildTrunc(ctx.ac.builder, 
cond,
+                                                             ctx.i1, "");
+                                       lp_build_if(&if_ctx, &ctx.gallivm, 
cond);
+                                       /* Remember blocks for Phi. */
+                                       blocks[0] = if_ctx.true_block;
+                                       blocks[1] = if_ctx.entry_block;
+                               }
+
+                               for (unsigned j = 0; j < 4; j++) {
+                                       /* Insert clamp into the true block. */
+                                       v[0] = ac_build_clamp(&ctx.ac, 
outputs[i].values[j]);
+                                       v[1] = outputs[i].values[j];
+
+                                       /* Insert Phi into the endif block. */
+                                       
LLVMPositionBuilderAtEnd(ctx.ac.builder, if_ctx.merge_block);
+                                       outputs[i].values[j] = 
ac_build_phi(&ctx.ac, ctx.f32, 2, v, blocks);
+                                       
LLVMPositionBuilderAtEnd(ctx.ac.builder, if_ctx.true_block);
+                               }
+                       }
+                       if (cond)
+                               lp_build_endif(&if_ctx);
+
                        si_llvm_export_vs(&ctx, outputs, gsinfo->num_outputs);
+               }
 
                LLVMBuildBr(builder, end_bb);
        }
 
        LLVMPositionBuilderAtEnd(builder, end_bb);
 
        LLVMBuildRetVoid(ctx.ac.builder);
 
        ctx.type = PIPE_SHADER_GEOMETRY; /* override for shader dumping */
        si_llvm_optimize_module(&ctx);
diff --git a/src/gallium/drivers/radeonsi/si_shader.h 
b/src/gallium/drivers/radeonsi/si_shader.h
index bba4d4f9018..0dc27f29afd 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -221,21 +221,21 @@ enum {
 
        /* GS limits */
        GFX6_GS_NUM_USER_SGPR = SI_NUM_RESOURCE_SGPRS,
 #if HAVE_32BIT_POINTERS
        GFX9_VSGS_NUM_USER_SGPR = SI_VS_NUM_USER_SGPR,
        GFX9_TESGS_NUM_USER_SGPR = SI_TES_NUM_USER_SGPR,
 #else
        GFX9_VSGS_NUM_USER_SGPR = GFX9_MERGED_NUM_USER_SGPR,
        GFX9_TESGS_NUM_USER_SGPR = GFX9_MERGED_NUM_USER_SGPR,
 #endif
-       SI_GSCOPY_NUM_USER_SGPR = SI_SGPR_RW_BUFFERS + (HAVE_32BIT_POINTERS ? 1 
: 2),
+       SI_GSCOPY_NUM_USER_SGPR = SI_NUM_VS_STATE_RESOURCE_SGPRS,
 
        /* PS only */
        SI_SGPR_ALPHA_REF       = SI_NUM_RESOURCE_SGPRS,
        SI_PS_NUM_USER_SGPR,
 };
 
 /* LLVM function parameter indices */
 enum {
        SI_NUM_RESOURCE_PARAMS = 4,
 
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c 
b/src/gallium/drivers/radeonsi/si_state_draw.c
index 2291b4a00ad..f35f73a37ce 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -564,25 +564,36 @@ static void si_emit_vs_state(struct si_context *sctx,
 
        if (sctx->num_vs_blit_sgprs) {
                /* Re-emit the state after we leave u_blitter. */
                sctx->last_vs_state = ~0;
                return;
        }
 
        if (sctx->current_vs_state != sctx->last_vs_state) {
                struct radeon_cmdbuf *cs = sctx->gfx_cs;
 
+               /* For the API vertex shader (VS_STATE_INDEXED). */
                radeon_set_sh_reg(cs,
                        sctx->shader_pointers.sh_base[PIPE_SHADER_VERTEX] +
                        SI_SGPR_VS_STATE_BITS * 4,
                        sctx->current_vs_state);
 
+               /* For vertex color clamping, which is done in the last stage
+                * before the rasterizer. */
+               if (sctx->gs_shader.cso || sctx->tes_shader.cso) {
+                       /* GS copy shader or TES if GS is missing. */
+                       radeon_set_sh_reg(cs,
+                               R_00B130_SPI_SHADER_USER_DATA_VS_0 +
+                               SI_SGPR_VS_STATE_BITS * 4,
+                               sctx->current_vs_state);
+               }
+
                sctx->last_vs_state = sctx->current_vs_state;
        }
 }
 
 static inline bool si_prim_restart_index_changed(struct si_context *sctx,
                                                 const struct pipe_draw_info 
*info)
 {
        return info->primitive_restart &&
               (info->restart_index != sctx->last_restart_index ||
                sctx->last_restart_index == SI_RESTART_INDEX_UNKNOWN);
-- 
2.17.1

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

Reply via email to