radeonsi: implement vertex color clamping
authorMarek Olšák <marek.olsak@amd.com>
Wed, 7 Oct 2015 00:36:38 +0000 (02:36 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Sat, 17 Oct 2015 19:40:03 +0000 (21:40 +0200)
This is only supported in the compatibility profile (without GS and tess).

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
src/gallium/drivers/radeonsi/si_pipe.c
src/gallium/drivers/radeonsi/si_shader.c
src/gallium/drivers/radeonsi/si_shader.h
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state_shaders.c

index f03d02bd28747cd64bd9bbc04367a95166b2617e..53c80dba6028ab02af7bb613673b793f059c0801 100644 (file)
@@ -271,6 +271,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_START_INSTANCE:
        case PIPE_CAP_NPOT_TEXTURES:
        case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
+       case PIPE_CAP_VERTEX_COLOR_CLAMPED:
        case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
         case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
        case PIPE_CAP_TGSI_INSTANCEID:
@@ -331,7 +332,6 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        /* Unsupported features. */
        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
        case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
-       case PIPE_CAP_VERTEX_COLOR_CLAMPED:
        case PIPE_CAP_USER_VERTEX_BUFFERS:
        case PIPE_CAP_FAKE_SW_MSAA:
        case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
index c7ebb0f29bdcb0d2ab33f91b8fab5ec6727ec69f..a119cbdc16ca12b9e52faec41c1e8b895c66f713 100644 (file)
@@ -2076,6 +2076,45 @@ static void si_llvm_emit_vs_epilogue(struct lp_build_tgsi_context * bld_base)
 
        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 (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX &&
+           !si_shader_ctx->shader->is_gs_copy_shader) {
+               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;
+
+                       /* We've found a color. */
+                       if (!cond) {
+                               /* The state is in the first bit of the user SGPR. */
+                               cond = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
+                                                   SI_PARAM_VS_STATE_BITS);
+                               cond = LLVMBuildTrunc(gallivm->builder, cond,
+                                                     LLVMInt1TypeInContext(gallivm->context), "");
+                               lp_build_if(&if_ctx, gallivm, cond);
+                       }
+
+                       for (j = 0; j < 4; j++) {
+                               addr = si_shader_ctx->radeon_bld.soa.outputs[i][j];
+                               val = LLVMBuildLoad(gallivm->builder, addr, "");
+                               val = radeon_llvm_saturate(bld_base, val);
+                               LLVMBuildStore(gallivm->builder, val, addr);
+                       }
+               }
+
+               if (cond)
+                       lp_build_endif(&if_ctx);
+       }
+
        for (i = 0; i < info->num_outputs; i++) {
                outputs[i].name = info->output_semantic_name[i];
                outputs[i].sid = info->output_semantic_index[i];
@@ -3445,6 +3484,9 @@ static void create_function(struct si_shader_context *si_shader_ctx)
                        if (shader->is_gs_copy_shader) {
                                last_array_pointer = SI_PARAM_CONST;
                                num_params = SI_PARAM_CONST+1;
+                       } else {
+                               params[SI_PARAM_VS_STATE_BITS] = i32;
+                               num_params = SI_PARAM_VS_STATE_BITS+1;
                        }
 
                        /* The locations of the other parameters are assigned dynamically. */
index fa5930ad1d509d5201be30940b850d8297c17d45..54dad726d01e7635861e6526d4632d26434ffa02 100644 (file)
@@ -83,6 +83,7 @@ struct radeon_shader_reloc;
 #define SI_SGPR_VERTEX_BUFFER  8  /* VS only */
 #define SI_SGPR_BASE_VERTEX    10 /* VS only */
 #define SI_SGPR_START_INSTANCE 11 /* VS only */
+#define SI_SGPR_VS_STATE_BITS  12 /* VS(VS) only */
 #define SI_SGPR_LS_OUT_LAYOUT  12 /* VS(LS) only */
 #define SI_SGPR_TCS_OUT_OFFSETS        8  /* TCS & TES only */
 #define SI_SGPR_TCS_OUT_LAYOUT 9  /* TCS & TES only */
@@ -90,8 +91,9 @@ struct radeon_shader_reloc;
 #define SI_SGPR_ALPHA_REF      8  /* PS only */
 #define SI_SGPR_PS_STATE_BITS  9  /* PS only */
 
-#define SI_VS_NUM_USER_SGPR    12
-#define SI_LS_NUM_USER_SGPR    13
+#define SI_VS_NUM_USER_SGPR    13 /* API VS */
+#define SI_ES_NUM_USER_SGPR    12 /* API VS */
+#define SI_LS_NUM_USER_SGPR    13 /* API VS */
 #define SI_TCS_NUM_USER_SGPR   11
 #define SI_TES_NUM_USER_SGPR   10
 #define SI_GS_NUM_USER_SGPR    8
@@ -108,6 +110,8 @@ struct radeon_shader_reloc;
 #define SI_PARAM_VERTEX_BUFFER 4
 #define SI_PARAM_BASE_VERTEX   5
 #define SI_PARAM_START_INSTANCE        6
+/* [0] = clamp vertex color */
+#define SI_PARAM_VS_STATE_BITS 7
 /* the other VS parameters are assigned dynamically */
 
 /* Offsets where TCS outputs and TCS patch outputs live in LDS:
index 3aafe8a602f0fba502088d067ef73b23e9b986f0..e6475364f98af25842842a967ddfb01dc28fce8f 100644 (file)
@@ -760,6 +760,8 @@ static void *si_create_rs_state(struct pipe_context *ctx,
                                   state->fill_back != PIPE_POLYGON_MODE_FILL) |
                S_028814_POLYMODE_FRONT_PTYPE(si_translate_fill(state->fill_front)) |
                S_028814_POLYMODE_BACK_PTYPE(si_translate_fill(state->fill_back)));
+       si_pm4_set_reg(pm4, R_00B130_SPI_SHADER_USER_DATA_VS_0 +
+                      SI_SGPR_VS_STATE_BITS * 4, state->clamp_vertex_color);
 
        /* Precalculate polygon offset states for 16-bit, 24-bit, and 32-bit zbuffers. */
        for (i = 0; i < 3; i++) {
index c00f8f4101cc03a3906d54f4de38f6b96d86bbf5..c98509bb0b937b860918150a11c4244030429291 100644 (file)
@@ -179,7 +179,7 @@ static void si_shader_es(struct si_shader *shader)
 
        if (shader->selector->type == PIPE_SHADER_VERTEX) {
                vgpr_comp_cnt = shader->uses_instanceid ? 3 : 0;
-               num_user_sgprs = SI_VS_NUM_USER_SGPR;
+               num_user_sgprs = SI_ES_NUM_USER_SGPR;
        } else if (shader->selector->type == PIPE_SHADER_TESS_EVAL) {
                vgpr_comp_cnt = 3; /* all components are needed for TES */
                num_user_sgprs = SI_TES_NUM_USER_SGPR;