---
 src/gallium/drivers/r600/evergreen_state.c   |   22 ++++++++++---
 src/gallium/drivers/r600/r600_pipe.h         |    3 ++
 src/gallium/drivers/r600/r600_shader.c       |   42 ++++++++++++++++++++++---
 src/gallium/drivers/r600/r600_shader.h       |    5 +++
 src/gallium/drivers/r600/r600_state.c        |   23 ++++++++++----
 src/gallium/drivers/r600/r600_state_common.c |   24 +++++++++++++++
 6 files changed, 103 insertions(+), 16 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c 
b/src/gallium/drivers/r600/evergreen_state.c
index f5efcbf..0e7c384 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -902,6 +902,7 @@ static void *evergreen_create_rs_state(struct pipe_context 
*ctx,
        rs->clamp_fragment_color = state->clamp_fragment_color;
        rs->flatshade = state->flatshade;
        rs->sprite_coord_enable = state->sprite_coord_enable;
+       rs->user_clip_plane_enable = state->user_clip_plane_enable;
 
        clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
 
@@ -939,8 +940,8 @@ static void *evergreen_create_rs_state(struct pipe_context 
*ctx,
                
S_028814_POLYMODE_FRONT_PTYPE(r600_translate_fill(state->fill_front)) |
                
S_028814_POLYMODE_BACK_PTYPE(r600_translate_fill(state->fill_back)), 
0xFFFFFFFF, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_02881C_PA_CL_VS_OUT_CNTL,
-                       
S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex) |
-                       
S_02881C_VS_OUT_MISC_VEC_ENA(state->point_size_per_vertex), 0xFFFFFFFF, NULL, 
0);
+                       
S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex),
+                       S_02881C_USE_VTX_POINT_SIZE(1), NULL, 0);
        r600_pipe_state_add_reg(rstate, R_028820_PA_CL_NANINF_CNTL, 0x00000000, 
0xFFFFFFFF, NULL, 0);
        /* point size 12.4 fixed point */
        tmp = (unsigned)(state->point_size * 8.0);
@@ -987,9 +988,10 @@ static void *evergreen_create_rs_state(struct pipe_context 
*ctx,
        r600_pipe_state_add_reg(rstate, R_028B7C_PA_SU_POLY_OFFSET_CLAMP, 
fui(state->offset_clamp), 0xFFFFFFFF, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_02820C_PA_SC_CLIPRECT_RULE, 
clip_rule, 0xFFFFFFFF, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_028810_PA_CL_CLIP_CNTL,
-                       S_028810_PS_UCP_MODE(3) | 
(state->user_clip_plane_enable & 63) |
-                       S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) |
-                       S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip), 
0xFFFFFFFF, NULL, 0);
+                       S_028810_PS_UCP_MODE(3) | 
S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) |
+                       S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip),
+                       S_028810_PS_UCP_MODE(3) | 
S_028810_ZCLIP_NEAR_DISABLE(1) |
+                       S_028810_ZCLIP_FAR_DISABLE(1), NULL, 0);
        return rstate;
 }
 
@@ -2463,6 +2465,16 @@ void evergreen_pipe_shader_vs(struct pipe_context *ctx, 
struct r600_pipe_shader
        r600_pipe_state_add_reg(rstate,
                                R_03A200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF,
                                0xFFFFFFFF, NULL, 0);
+
+       r600_pipe_state_add_reg(rstate,
+                               R_02881C_PA_CL_VS_OUT_CNTL,
+                               
S_02881C_VS_OUT_CCDIST0_VEC_ENA((rshader->clip_dist_write & 0x0F) != 0) |
+                               
S_02881C_VS_OUT_CCDIST1_VEC_ENA((rshader->clip_dist_write & 0xF0) != 0) |
+                               
S_02881C_VS_OUT_MISC_VEC_ENA(rshader->vs_out_misc_write),
+                               S_02881C_VS_OUT_CCDIST0_VEC_ENA(1) |
+                               S_02881C_VS_OUT_CCDIST1_VEC_ENA(1) |
+                               S_02881C_VS_OUT_MISC_VEC_ENA(1),
+                               NULL, 0);
 }
 
 void evergreen_fetch_shader(struct pipe_context *ctx,
diff --git a/src/gallium/drivers/r600/r600_pipe.h 
b/src/gallium/drivers/r600/r600_pipe.h
index 447b9dc..0967018 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -109,6 +109,7 @@ struct r600_pipe_rasterizer {
        boolean                         clamp_fragment_color;
        boolean                         flatshade;
        unsigned                        sprite_coord_enable;
+       unsigned                        user_clip_plane_enable;
        float                           offset_units;
        float                           offset_scale;
 };
@@ -218,6 +219,8 @@ struct r600_pipe_context {
        /* shader information */
        boolean                         clamp_vertex_color;
        boolean                         clamp_fragment_color;
+       unsigned                        user_clip_plane_enable;
+       unsigned                        clip_dist_enable;
        unsigned                        sprite_coord_enable;
        boolean                         export_16bpc;
        unsigned                        alpha_ref;
diff --git a/src/gallium/drivers/r600/r600_shader.c 
b/src/gallium/drivers/r600/r600_shader.c
index ad4aded..1ce19aa 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -427,6 +427,17 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
                ctx->shader->output[i].spi_sid = 
r600_spi_sid(&ctx->shader->output[i]);
                ctx->shader->output[i].gpr = ctx->file_offset[TGSI_FILE_OUTPUT] 
+ d->Range.First;
                ctx->shader->output[i].interpolate = d->Declaration.Interpolate;
+               ctx->shader->output[i].write_mask = d->Declaration.UsageMask;
+               if (ctx->type == TGSI_PROCESSOR_VERTEX) {
+                       switch (d->Semantic.Name) {
+                       case TGSI_SEMANTIC_CLIPDIST:
+                               ctx->shader->clip_dist_write |= 
d->Declaration.UsageMask << (d->Semantic.Index << 2);
+                               break;
+                       case TGSI_SEMANTIC_PSIZE:
+                               ctx->shader->vs_out_misc_write = 1;
+                               break;
+                       }
+               }
                break;
        case TGSI_FILE_CONSTANT:
        case TGSI_FILE_TEMPORARY:
@@ -950,8 +961,9 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * 
rctx, struct r600_pi
 
        /* export output */
        j = 0;
+
        for (i = 0, pos0 = 0; i < noutput; i++) {
-               memset(&output[i], 0, sizeof(struct r600_bytecode_output));
+               memset(&output[i+j], 0, sizeof(struct r600_bytecode_output));
                output[i + j].gpr = shader->output[i].gpr;
                output[i + j].elem_size = 3;
                output[i + j].swizzle_x = 0;
@@ -961,21 +973,41 @@ static int r600_shader_from_tgsi(struct r600_pipe_context 
* rctx, struct r600_pi
                output[i + j].burst_count = 1;
                output[i + j].barrier = 1;
                output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
-               output[i + j].array_base = i - pos0;
+               output[i + j].array_base = i+j - pos0;
                output[i + j].inst = BC_INST(ctx.bc, 
V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT);
                switch (ctx.type) {
                case TGSI_PROCESSOR_VERTEX:
-                       if (shader->output[i].name == TGSI_SEMANTIC_POSITION) {
+                       switch (shader->output[i].name) {
+                       case TGSI_SEMANTIC_POSITION:
                                output[i + j].array_base = 60;
                                output[i + j].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
                                /* position doesn't count in array_base */
                                pos0++;
-                       }
-                       if (shader->output[i].name == TGSI_SEMANTIC_PSIZE) {
+                               break;
+
+                       case TGSI_SEMANTIC_PSIZE:
                                output[i + j].array_base = 61;
                                output[i + j].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
                                /* position doesn't count in array_base */
                                pos0++;
+                               break;
+
+                       case TGSI_SEMANTIC_CLIPDIST:
+                               /* array base for enabled OUT_MISC_VEC & 
CCDIST[0|1]_VEC
+                                * vectors is allocated sequentially, starting 
from 61 */
+                               output[i + j].array_base = 61 + 
shader->output[i].sid
+                                       /* +1 if OUT_MISC_VEC is enabled */
+                                       + shader->vs_out_misc_write
+                                       /* -1 if OUT_CCDIST0_VEC is disabled */
+                                       - (((shader->clip_dist_write & 0xF) == 
0)? 1 : 0);
+                               output[i + j].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
+                               j++;
+                               pos0++;
+                               /* duplicate it as PARAM to pass to the pixel 
shader */
+                               memcpy(&output[i+j], &output[i+j-1], 
sizeof(struct r600_bytecode_output));
+                               output[i + j].array_base = i+j-pos0;
+                               output[i + j].type = 
V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
+                               break;
                        }
                        break;
                case TGSI_PROCESSOR_FRAGMENT:
diff --git a/src/gallium/drivers/r600/r600_shader.h 
b/src/gallium/drivers/r600/r600_shader.h
index 9990ba6..fa56c80 100644
--- a/src/gallium/drivers/r600/r600_shader.h
+++ b/src/gallium/drivers/r600/r600_shader.h
@@ -34,6 +34,7 @@ struct r600_shader_io {
        unsigned                interpolate;
        boolean                 centroid;
        unsigned                lds_pos; /* for evergreen */
+       unsigned                write_mask;
 };
 
 struct r600_shader {
@@ -48,6 +49,10 @@ struct r600_shader {
        boolean                 fs_write_all;
        boolean                 clamp_color;
        unsigned                nr_cbufs;
+       /* bit n is set if the shader writes gl_ClipDistance[n] */
+       unsigned                clip_dist_write;
+       /* flag is set if the shader writes VS_OUT_MISC_VEC (e.g. for PSIZE) */
+       boolean                 vs_out_misc_write;
 };
 
 #endif
diff --git a/src/gallium/drivers/r600/r600_state.c 
b/src/gallium/drivers/r600/r600_state.c
index 384035d..32e2076 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -954,6 +954,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
        rs->clamp_fragment_color = state->clamp_fragment_color;
        rs->flatshade = state->flatshade;
        rs->sprite_coord_enable = state->sprite_coord_enable;
+       rs->user_clip_plane_enable = state->user_clip_plane_enable;
 
        clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
        /* offset */
@@ -990,8 +991,8 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
                
S_028814_POLYMODE_FRONT_PTYPE(r600_translate_fill(state->fill_front)) |
                
S_028814_POLYMODE_BACK_PTYPE(r600_translate_fill(state->fill_back)), 
0xFFFFFFFF, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_02881C_PA_CL_VS_OUT_CNTL,
-                       
S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex) |
-                       
S_02881C_VS_OUT_MISC_VEC_ENA(state->point_size_per_vertex), 0xFFFFFFFF, NULL, 
0);
+                       
S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex),
+                       S_02881C_USE_VTX_POINT_SIZE(1), NULL, 0);
        r600_pipe_state_add_reg(rstate, R_028820_PA_CL_NANINF_CNTL, 0x00000000, 
0xFFFFFFFF, NULL, 0);
        /* point size 12.4 fixed point */
        tmp = (unsigned)(state->point_size * 8.0);
@@ -1030,10 +1031,10 @@ static void *r600_create_rs_state(struct pipe_context 
*ctx,
        r600_pipe_state_add_reg(rstate, R_028DFC_PA_SU_POLY_OFFSET_CLAMP, 
fui(state->offset_clamp), 0xFFFFFFFF, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_02820C_PA_SC_CLIPRECT_RULE, 
clip_rule, 0xFFFFFFFF, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_028810_PA_CL_CLIP_CNTL,
-                       S_028810_PS_UCP_MODE(3) | 
(state->user_clip_plane_enable & 63) |
-                       S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) |
-                       S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip), 
0xFFFFFFFF, NULL, 0);
-
+                       S_028810_PS_UCP_MODE(3) | 
S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) |
+                       S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip),
+                       S_028810_PS_UCP_MODE(3) | 
S_028810_ZCLIP_NEAR_DISABLE(1) |
+                       S_028810_ZCLIP_FAR_DISABLE(1), NULL, 0);
        return rstate;
 }
 
@@ -2234,6 +2235,16 @@ void r600_pipe_shader_vs(struct pipe_context *ctx, 
struct r600_pipe_shader *shad
        r600_pipe_state_add_reg(rstate,
                                R_03E200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF,
                                0xFFFFFFFF, NULL, 0);
+
+       r600_pipe_state_add_reg(rstate,
+                               R_02881C_PA_CL_VS_OUT_CNTL,
+                               
S_02881C_VS_OUT_CCDIST0_VEC_ENA((rshader->clip_dist_write & 0x0F) != 0) |
+                               
S_02881C_VS_OUT_CCDIST1_VEC_ENA((rshader->clip_dist_write & 0xF0) != 0) |
+                               
S_02881C_VS_OUT_MISC_VEC_ENA(rshader->vs_out_misc_write),
+                               S_02881C_VS_OUT_CCDIST0_VEC_ENA(1) |
+                               S_02881C_VS_OUT_CCDIST1_VEC_ENA(1) |
+                               S_02881C_VS_OUT_MISC_VEC_ENA(1),
+                               NULL, 0);
 }
 
 void r600_fetch_shader(struct pipe_context *ctx,
diff --git a/src/gallium/drivers/r600/r600_state_common.c 
b/src/gallium/drivers/r600/r600_state_common.c
index 9f6f514..29acc6e 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -549,6 +549,30 @@ static int r600_shader_rebuild(struct pipe_context * ctx, 
struct r600_pipe_shade
 static void r600_update_derived_state(struct r600_pipe_context *rctx)
 {
        struct pipe_context * ctx = (struct pipe_context*)rctx;
+       struct r600_pipe_state rstate;
+       unsigned user_clip_plane_enable;
+       unsigned clip_dist_enable;
+
+       if (rctx->vs_shader->shader.clip_dist_write)
+               user_clip_plane_enable = 0;
+       else
+               user_clip_plane_enable = 
rctx->rasterizer->user_clip_plane_enable & 0x3F;
+
+       clip_dist_enable = rctx->rasterizer->user_clip_plane_enable & 
rctx->vs_shader->shader.clip_dist_write & 0xFF;
+       rstate.nregs = 0;
+
+       if (user_clip_plane_enable != rctx->user_clip_plane_enable) {
+               r600_pipe_state_add_reg(&rstate, R_028810_PA_CL_CLIP_CNTL, 
user_clip_plane_enable , 0x3F, NULL, 0);
+               rctx->user_clip_plane_enable = user_clip_plane_enable;
+       }
+
+       if (clip_dist_enable != rctx->clip_dist_enable) {
+               r600_pipe_state_add_reg(&rstate, R_02881C_PA_CL_VS_OUT_CNTL, 
clip_dist_enable, 0xFF, NULL, 0);
+               rctx->clip_dist_enable = clip_dist_enable;
+       }
+
+       if (rstate.nregs)
+               r600_context_pipe_state_set(&rctx->ctx, &rstate);
 
        if (!rctx->blitter->running) {
                if (rctx->have_depth_fb || rctx->have_depth_texture)
-- 
1.7.7.5

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

Reply via email to