r600g: fix for broken CULL_FRONT behavior on R6xx
authorMarek Olšák <marek.olsak@amd.com>
Sun, 20 Apr 2014 13:19:43 +0000 (15:19 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 24 Apr 2014 23:33:12 +0000 (01:33 +0200)
Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_common.c

index 50d959e318c34e9d76cc07acf7f85a418aad4da6..fc54ae7606ad9086b50bee8067713afb72d31078 100644 (file)
@@ -2987,30 +2987,6 @@ void evergreen_update_es_state(struct pipe_context *ctx, struct r600_pipe_shader
        /* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */
 }
 
-static unsigned r600_conv_prim_to_gs_out(unsigned mode)
-{
-       static const int prim_conv[] = {
-               V_028A6C_OUTPRIM_TYPE_POINTLIST,
-               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
-               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
-               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
-               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP
-       };
-       assert(mode < Elements(prim_conv));
-
-       return prim_conv[mode];
-}
-
 void evergreen_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *shader)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
index f31fa45acb01e9259e38b3e5e9a016fd3ecb1e2a..952b6bded8d560e251e9ed0c7e2fcf1ca9968551 100644 (file)
@@ -41,7 +41,7 @@
 
 /* the number of CS dwords for flushing and drawing */
 #define R600_MAX_FLUSH_CS_DWORDS       16
-#define R600_MAX_DRAW_CS_DWORDS                34
+#define R600_MAX_DRAW_CS_DWORDS                37
 #define R600_TRACE_CS_DWORDS           7
 
 #define R600_MAX_USER_CONST_BUFFERS 13
@@ -234,6 +234,7 @@ struct r600_rasterizer_state {
        unsigned                        clip_plane_enable;
        unsigned                        pa_sc_line_stipple;
        unsigned                        pa_cl_clip_cntl;
+       unsigned                        pa_su_sc_mode_cntl;
        float                           offset_units;
        float                           offset_scale;
        bool                            offset_enable;
@@ -852,4 +853,32 @@ static INLINE bool r600_can_read_depth(struct r600_texture *rtex)
                rtex->resource.b.b.format == PIPE_FORMAT_Z32_FLOAT);
 }
 
+#define     V_028A6C_OUTPRIM_TYPE_POINTLIST            0
+#define     V_028A6C_OUTPRIM_TYPE_LINESTRIP            1
+#define     V_028A6C_OUTPRIM_TYPE_TRISTRIP             2
+
+static INLINE unsigned r600_conv_prim_to_gs_out(unsigned mode)
+{
+       static const int prim_conv[] = {
+               V_028A6C_OUTPRIM_TYPE_POINTLIST,
+               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
+               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
+               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
+               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
+               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
+               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
+               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
+               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
+               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
+               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
+               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
+               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
+               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
+               V_028A6C_OUTPRIM_TYPE_TRISTRIP
+       };
+       assert(mode < Elements(prim_conv));
+
+       return prim_conv[mode];
+}
+
 #endif
index 99206cf4c0e01e92978d1c36a317ef0bf9652be3..99cfe6f8e66262202c7ce0c91eb0691100e3766f 100644 (file)
@@ -517,18 +517,21 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
                               S_028C08_PIX_CENTER_HALF(state->half_pixel_center) |
                               S_028C08_QUANT_MODE(V_028C08_X_1_256TH));
        r600_store_context_reg(&rs->buffer, R_028DFC_PA_SU_POLY_OFFSET_CLAMP, fui(state->offset_clamp));
-       r600_store_context_reg(&rs->buffer, R_028814_PA_SU_SC_MODE_CNTL,
-                              S_028814_PROVOKING_VTX_LAST(!state->flatshade_first) |
-                              S_028814_CULL_FRONT(state->cull_face & PIPE_FACE_FRONT ? 1 : 0) |
-                              S_028814_CULL_BACK(state->cull_face & PIPE_FACE_BACK ? 1 : 0) |
-                              S_028814_FACE(!state->front_ccw) |
-                              S_028814_POLY_OFFSET_FRONT_ENABLE(state->offset_tri) |
-                              S_028814_POLY_OFFSET_BACK_ENABLE(state->offset_tri) |
-                              S_028814_POLY_OFFSET_PARA_ENABLE(state->offset_tri) |
-                              S_028814_POLY_MODE(state->fill_front != PIPE_POLYGON_MODE_FILL ||
-                                                 state->fill_back != PIPE_POLYGON_MODE_FILL) |
-                              S_028814_POLYMODE_FRONT_PTYPE(r600_translate_fill(state->fill_front)) |
-                              S_028814_POLYMODE_BACK_PTYPE(r600_translate_fill(state->fill_back)));
+
+       rs->pa_su_sc_mode_cntl = S_028814_PROVOKING_VTX_LAST(!state->flatshade_first) |
+                                S_028814_CULL_FRONT(state->cull_face & PIPE_FACE_FRONT ? 1 : 0) |
+                                S_028814_CULL_BACK(state->cull_face & PIPE_FACE_BACK ? 1 : 0) |
+                                S_028814_FACE(!state->front_ccw) |
+                                S_028814_POLY_OFFSET_FRONT_ENABLE(state->offset_tri) |
+                                S_028814_POLY_OFFSET_BACK_ENABLE(state->offset_tri) |
+                                S_028814_POLY_OFFSET_PARA_ENABLE(state->offset_tri) |
+                                S_028814_POLY_MODE(state->fill_front != PIPE_POLYGON_MODE_FILL ||
+                                                                        state->fill_back != PIPE_POLYGON_MODE_FILL) |
+                                S_028814_POLYMODE_FRONT_PTYPE(r600_translate_fill(state->fill_front)) |
+                                S_028814_POLYMODE_BACK_PTYPE(r600_translate_fill(state->fill_back));
+       if (rctx->b.chip_class == R700) {
+               r600_store_context_reg(&rs->buffer, R_028814_PA_SU_SC_MODE_CNTL, rs->pa_su_sc_mode_cntl);
+       }
        r600_store_context_reg(&rs->buffer, R_028350_SX_MISC, S_028350_MULTIPASS(state->rasterizer_discard));
        return rs;
 }
@@ -2574,30 +2577,6 @@ void r600_update_vs_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
                S_02881C_USE_VTX_VIEWPORT_INDX(rshader->vs_out_viewport);
 }
 
-static unsigned r600_conv_prim_to_gs_out(unsigned mode)
-{
-       static const int prim_conv[] = {
-               V_028A6C_OUTPRIM_TYPE_POINTLIST,
-               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
-               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
-               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
-               V_028A6C_OUTPRIM_TYPE_LINESTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP,
-               V_028A6C_OUTPRIM_TYPE_TRISTRIP
-       };
-       assert(mode < Elements(prim_conv));
-
-       return prim_conv[mode];
-}
-
 void r600_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *shader)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
index 4245b145a93a71b6d825b05c1064f56be1ce381c..fabc52cf116c90498a63d867aefaddecda62ece6 100644 (file)
@@ -1413,6 +1413,25 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
                r600_emit_atom(rctx, rctx->atoms[i]);
        }
 
+       /* On R6xx, CULL_FRONT=1 culls all points, lines, and rectangles,
+        * even though it should have no effect on those. */
+       if (rctx->b.chip_class == R600 && rctx->rasterizer) {
+               unsigned su_sc_mode_cntl = rctx->rasterizer->pa_su_sc_mode_cntl;
+               unsigned prim = info.mode;
+
+               if (rctx->gs_shader) {
+                       prim = rctx->gs_shader->current->shader.gs_output_prim;
+               }
+               prim = r600_conv_prim_to_gs_out(prim); /* decrease the number of types to 3 */
+
+               if (prim == V_028A6C_OUTPRIM_TYPE_POINTLIST ||
+                   prim == V_028A6C_OUTPRIM_TYPE_LINESTRIP ||
+                   info.mode == R600_PRIM_RECTANGLE_LIST) {
+                       su_sc_mode_cntl &= C_028814_CULL_FRONT;
+               }
+               r600_write_context_reg(cs, R_028814_PA_SU_SC_MODE_CNTL, su_sc_mode_cntl);
+       }
+
        /* Update start instance. */
        if (rctx->last_start_instance != info.start_instance) {
                r600_write_ctl_const(cs, R_03CFF4_SQ_VTX_START_INST_LOC, info.start_instance);