From 391e33ffbf01180d66d4c4e9a6c91fc17f9feaca Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 6 Nov 2011 12:49:21 +0000 Subject: [PATCH] r600g: add initial linestipple support. It seems line loop stipple in hardware needs something I don't know, it might need a proper geometry shader who knows. Signed-off-by: Dave Airlie --- .../drivers/r600/evergreen_hw_context.c | 2 ++ src/gallium/drivers/r600/evergreen_state.c | 13 +++++++++++-- src/gallium/drivers/r600/evergreend.h | 6 ++++++ src/gallium/drivers/r600/r600_state.c | 19 ++++++++++++++++--- src/gallium/drivers/r600/r600_state_common.c | 12 +++++++++++- src/gallium/drivers/r600/r600d.h | 5 +++++ 6 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_hw_context.c b/src/gallium/drivers/r600/evergreen_hw_context.c index 116fb4ecb5b..f7ed6ac290d 100644 --- a/src/gallium/drivers/r600/evergreen_hw_context.c +++ b/src/gallium/drivers/r600/evergreen_hw_context.c @@ -297,6 +297,7 @@ static const struct r600_reg evergreen_context_reg_list[] = { {R_028A00_PA_SU_POINT_SIZE, 0, 0, 0}, {R_028A04_PA_SU_POINT_MINMAX, 0, 0, 0}, {R_028A08_PA_SU_LINE_CNTL, 0, 0, 0}, + {R_028A0C_PA_SC_LINE_STIPPLE, 0 ,0, 0}, {R_028A10_VGT_OUTPUT_PATH_CNTL, 0, 0, 0}, {R_028A14_VGT_HOS_CNTL, 0, 0, 0}, {R_028A18_VGT_HOS_MAX_TESS_LEVEL, 0, 0, 0}, @@ -661,6 +662,7 @@ static const struct r600_reg cayman_context_reg_list[] = { {R_028A00_PA_SU_POINT_SIZE, 0, 0, 0}, {R_028A04_PA_SU_POINT_MINMAX, 0, 0, 0}, {R_028A08_PA_SU_LINE_CNTL, 0, 0, 0}, + {R_028A0C_PA_SC_LINE_STIPPLE, 0 ,0, 0}, {R_028A10_VGT_OUTPUT_PATH_CNTL, 0, 0, 0}, {R_028A14_VGT_HOS_CNTL, 0, 0, 0}, {R_028A18_VGT_HOS_MAX_TESS_LEVEL, 0, 0, 0}, diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index c0b057cc334..fa5e5db52d9 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -946,6 +946,17 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, tmp = (unsigned)state->line_width * 8; r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp), 0xFFFFFFFF, NULL, 0); + if (state->line_stipple_enable) { + r600_pipe_state_add_reg(rstate, R_028A0C_PA_SC_LINE_STIPPLE, + S_028A0C_LINE_PATTERN(state->line_stipple_pattern) | + S_028A0C_REPEAT_COUNT(state->line_stipple_factor), + 0x9FFFFFFF, NULL, 0); + } + + r600_pipe_state_add_reg(rstate, R_028A48_PA_SC_MODE_CNTL_0, + S_028A48_LINE_STIPPLE_ENABLE(state->line_stipple_enable), + 0xFFFFFFFF, NULL, 0); + if (rctx->chip_class == CAYMAN) { r600_pipe_state_add_reg(rstate, CM_R_028BDC_PA_SC_LINE_CNTL, 0x00000400, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, CM_R_028BE4_PA_SU_VTX_CNTL, @@ -1692,7 +1703,6 @@ static void cayman_init_config(struct r600_pipe_context *rctx) r600_pipe_state_add_reg(rstate, R_008C14_SQ_GLOBAL_GPR_RESOURCE_MGMT_2, 0, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, (1 << 8), 0xFFFFFFFF, NULL, 0); - r600_pipe_state_add_reg(rstate, R_028A48_PA_SC_MODE_CNTL_0, 0x0, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL_1, 0x0, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_028A10_VGT_OUTPUT_PATH_CNTL, 0x0, 0xFFFFFFFF, NULL, 0); @@ -2115,7 +2125,6 @@ void evergreen_init_config(struct r600_pipe_context *rctx) r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x0, 0xFFFFFFFF, NULL, 0); #endif - r600_pipe_state_add_reg(rstate, R_028A48_PA_SC_MODE_CNTL_0, 0x0, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL_1, 0x0, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_028900_SQ_ESGS_RING_ITEMSIZE, 0x0, 0xFFFFFFFF, NULL, 0); diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h index cd99e4939d9..6baa2a759e6 100644 --- a/src/gallium/drivers/r600/evergreend.h +++ b/src/gallium/drivers/r600/evergreend.h @@ -729,6 +729,11 @@ #define S_028A00_WIDTH(x) (((x) & 0xFFFF) << 16) #define G_028A00_WIDTH(x) (((x) >> 16) & 0xFFFF) #define C_028A00_WIDTH 0x0000FFFF +#define R_028A0C_PA_SC_LINE_STIPPLE 0x028A0C +#define S_028A0C_LINE_PATTERN(x) (((x) & 0xFFFF) << 0) +#define S_028A0C_REPEAT_COUNT(x) (((x) & 0xFF) << 16) +#define S_028A0C_PATTERN_BIT_ORDER(x) (((x) & 0x1) << 28) +#define S_028A0C_AUTO_RESET_CNTL(x) (((x) & 0x3) << 29) #define R_028A40_VGT_GS_MODE 0x028A40 #define S_028A40_MODE(x) (((x) & 0x3) << 0) #define G_028A40_MODE(x) (((x) >> 0) & 0x3) @@ -1706,6 +1711,7 @@ #define R_028A38_VGT_GROUP_VECT_0_FMT_CNTL 0x00028A38 #define R_028A3C_VGT_GROUP_VECT_1_FMT_CNTL 0x00028A3C #define R_028A48_PA_SC_MODE_CNTL_0 0x00028A48 +#define S_028A48_LINE_STIPPLE_ENABLE(x) (((x) & 0x1) << 2) #define R_028A4C_PA_SC_MODE_CNTL_1 0x00028A4C #define R_028A94_VGT_MULTI_PRIM_IB_RESET_EN 0x00028A94 #define S_028A94_RESET_EN(x) (((x) & 0x1) << 0) diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 9b5fb358ace..e38d1c9099f 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -939,6 +939,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx, unsigned tmp; unsigned prov_vtx = 1, polygon_dual_mode; unsigned clip_rule; + unsigned sc_mode_cntl; if (rs == NULL) { return NULL; @@ -996,7 +997,21 @@ static void *r600_create_rs_state(struct pipe_context *ctx, tmp = (unsigned)state->line_width * 8; r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp), 0xFFFFFFFF, NULL, 0); - r600_pipe_state_add_reg(rstate, R_028A0C_PA_SC_LINE_STIPPLE, 0x00000005, 0xFFFFFFFF, NULL, 0); + if (state->line_stipple_enable) { + r600_pipe_state_add_reg(rstate, R_028A0C_PA_SC_LINE_STIPPLE, + S_028A0C_LINE_PATTERN(state->line_stipple_pattern) | + S_028A0C_REPEAT_COUNT(state->line_stipple_factor), + 0x9FFFFFFF, NULL, 0); + } + + if (rctx->chip_class >= R700) + sc_mode_cntl = 0x514002; + else + sc_mode_cntl = 0x4102; + sc_mode_cntl |= S_028A4C_LINE_STIPPLE_ENABLE(state->line_stipple_enable); + + r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL, sc_mode_cntl, + 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_028A48_PA_SC_MPASS_PS_CNTL, 0x00000000, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_028C00_PA_SC_LINE_CNTL, 0x00000400, 0xFFFFFFFF, NULL, 0); @@ -1994,7 +2009,6 @@ void r600_init_config(struct r600_pipe_context *rctx) r600_pipe_state_add_reg(rstate, R_009830_DB_DEBUG, 0x00000000, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_009838_DB_WATERMARKS, 0x00420204, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_0286C8_SPI_THREAD_GROUPING, 0x00000000, 0xFFFFFFFF, NULL, 0); - r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL, 0x00514002, 0xFFFFFFFF, NULL, 0); } else { r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x00000000, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX, @@ -2005,7 +2019,6 @@ void r600_init_config(struct r600_pipe_context *rctx) r600_pipe_state_add_reg(rstate, R_009830_DB_DEBUG, 0x82000000, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_009838_DB_WATERMARKS, 0x01020204, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_0286C8_SPI_THREAD_GROUPING, 0x00000001, 0xFFFFFFFF, NULL, 0); - r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL, 0x00004012, 0xFFFFFFFF, NULL, 0); } r600_pipe_state_add_reg(rstate, R_0288A8_SQ_ESGS_RING_ITEMSIZE, 0x00000000, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_0288AC_SQ_GSVS_RING_ITEMSIZE, 0x00000000, 0xFFFFFFFF, NULL, 0); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index b81fba10467..14a2ab0a4db 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -534,7 +534,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) struct pipe_draw_info info = *dinfo; struct r600_draw rdraw = {}; struct pipe_index_buffer ib = {}; - unsigned prim, mask; + unsigned prim, mask, ls_mask = 0; if (!info.count || (info.indexed && !rctx->index_buffer.buffer) || @@ -599,6 +599,9 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) r600_pipe_state_add_reg(&rctx->vgt, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, info.primitive_restart, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(&rctx->vgt, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0, 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(&rctx->vgt, R_03CFF4_SQ_VTX_START_INST_LOC, info.start_instance, 0xFFFFFFFF, NULL, 0); + r600_pipe_state_add_reg(&rctx->vgt, R_028A0C_PA_SC_LINE_STIPPLE, + 0, + S_028A0C_AUTO_RESET_CNTL(3), NULL, 0); r600_pipe_state_add_reg(&rctx->vgt, R_028814_PA_SU_SC_MODE_CNTL, 0, S_028814_PROVOKING_VTX_LAST(1), NULL, 0); @@ -614,6 +617,13 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) r600_pipe_state_mod_reg(&rctx->vgt, info.primitive_restart); r600_pipe_state_mod_reg(&rctx->vgt, 0); r600_pipe_state_mod_reg(&rctx->vgt, info.start_instance); + + if (prim == V_008958_DI_PT_LINELIST) + ls_mask = 1; + else if (prim == V_008958_DI_PT_LINESTRIP) + ls_mask = 2; + r600_pipe_state_mod_reg(&rctx->vgt, S_028A0C_AUTO_RESET_CNTL(ls_mask)); + if (info.mode == PIPE_PRIM_QUADS || info.mode == PIPE_PRIM_QUAD_STRIP || info.mode == PIPE_PRIM_POLYGON) { r600_pipe_state_mod_reg(&rctx->vgt, S_028814_PROVOKING_VTX_LAST(1)); } diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index 441c9816762..079cd72c041 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -779,6 +779,11 @@ #define S_028A00_WIDTH(x) (((x) & 0xFFFF) << 16) #define G_028A00_WIDTH(x) (((x) >> 16) & 0xFFFF) #define C_028A00_WIDTH 0x0000FFFF +#define R_028A0C_PA_SC_LINE_STIPPLE 0x028A0C +#define S_028A0C_LINE_PATTERN(x) (((x) & 0xFFFF) << 0) +#define S_028A0C_REPEAT_COUNT(x) (((x) & 0xFF) << 16) +#define S_028A0C_PATTERN_BIT_ORDER(x) (((x) & 0x1) << 28) +#define S_028A0C_AUTO_RESET_CNTL(x) (((x) & 0x3) << 29) #define R_028A40_VGT_GS_MODE 0x028A40 #define S_028A40_MODE(x) (((x) & 0x3) << 0) #define G_028A40_MODE(x) (((x) >> 0) & 0x3) -- 2.30.2