diff options
author | Marek Olšák <[email protected]> | 2014-04-20 15:19:43 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2014-04-25 01:33:12 +0200 |
commit | ecc8a37ec5be7fca79205f08666fb76474ab5c0d (patch) | |
tree | 1f30e44764ba76d917743c0844d616b2560c8bb6 | |
parent | ef162cf13df96b2c8ab36001b8dab5640cabf05f (diff) |
r600g: fix for broken CULL_FRONT behavior on R6xx
Cc: [email protected]
Reviewed-by: Alex Deucher <[email protected]>
-rw-r--r-- | src/gallium/drivers/r600/evergreen_state.c | 24 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.h | 31 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state.c | 51 | ||||
-rw-r--r-- | 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 50d959e318c..fc54ae7606a 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 f31fa45acb0..952b6bded8d 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 99206cf4c0e..99cfe6f8e66 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 4245b145a93..fabc52cf116 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); |