[Mesa-dev] [PATCH 11/13] r600g: fix for broken CULL_FRONT behavior on R6xx

Alex Deucher alexdeucher at gmail.com
Mon Apr 21 08:28:33 PDT 2014


On Sun, Apr 20, 2014 at 9:59 PM, Marek Olšák <maraeo at gmail.com> wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> Cc: mesa-stable at lists.freedesktop.org

Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  src/gallium/drivers/r600/evergreen_state.c   | 24 -------------
>  src/gallium/drivers/r600/r600_pipe.h         | 31 ++++++++++++++++-
>  src/gallium/drivers/r600/r600_state.c        | 51 ++++++++--------------------
>  src/gallium/drivers/r600/r600_state_common.c | 19 +++++++++++
>  4 files changed, 64 insertions(+), 61 deletions(-)
>
> diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
> index 50d959e..fc54ae7 100644
> --- a/src/gallium/drivers/r600/evergreen_state.c
> +++ b/src/gallium/drivers/r600/evergreen_state.c
> @@ -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;
> diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
> index f31fa45a..952b6bd 100644
> --- a/src/gallium/drivers/r600/r600_pipe.h
> +++ b/src/gallium/drivers/r600/r600_pipe.h
> @@ -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
> diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
> index 99206cf..99cfe6f 100644
> --- a/src/gallium/drivers/r600/r600_state.c
> +++ b/src/gallium/drivers/r600/r600_state.c
> @@ -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;
> diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
> index 4245b14..fabc52c 100644
> --- a/src/gallium/drivers/r600/r600_state_common.c
> +++ b/src/gallium/drivers/r600/r600_state_common.c
> @@ -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);
> --
> 1.8.3.2
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list