summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeonsi/si_state.c
diff options
context:
space:
mode:
authorChristian König <[email protected]>2012-07-17 23:43:00 +0200
committerChristian König <[email protected]>2012-07-24 12:29:29 +0200
commitf67fae0e43fa0909b57b8a07858d37caecd5cbb1 (patch)
tree8df28f5e35446724ed5f54301dcddd4ff7cd72d9 /src/gallium/drivers/radeonsi/si_state.c
parent835098a5290e59bb7b468eb987db67b0e1913c67 (diff)
radeonsi: move rasterizer state into new handling
Signed-off-by: Christian König <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeonsi/si_state.c')
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 3141f36a4e5..149182e5265 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -271,6 +271,155 @@ static void si_set_viewport_state(struct pipe_context *ctx,
}
/*
+ * Rasterizer
+ */
+
+static uint32_t si_translate_fill(uint32_t func)
+{
+ switch(func) {
+ case PIPE_POLYGON_MODE_FILL:
+ return V_028814_X_DRAW_TRIANGLES;
+ case PIPE_POLYGON_MODE_LINE:
+ return V_028814_X_DRAW_LINES;
+ case PIPE_POLYGON_MODE_POINT:
+ return V_028814_X_DRAW_POINTS;
+ default:
+ assert(0);
+ return V_028814_X_DRAW_POINTS;
+ }
+}
+
+static void *si_create_rs_state(struct pipe_context *ctx,
+ const struct pipe_rasterizer_state *state)
+{
+ struct si_state_rasterizer *rs = CALLOC_STRUCT(si_state_rasterizer);
+ struct si_pm4_state *pm4 = &rs->pm4;
+ unsigned tmp;
+ unsigned prov_vtx = 1, polygon_dual_mode;
+ unsigned clip_rule;
+ float psize_min, psize_max;
+
+ if (rs == NULL) {
+ return NULL;
+ }
+
+ polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL ||
+ state->fill_back != PIPE_POLYGON_MODE_FILL);
+
+ if (state->flatshade_first)
+ prov_vtx = 0;
+
+ rs->flatshade = state->flatshade;
+ rs->sprite_coord_enable = state->sprite_coord_enable;
+ rs->pa_sc_line_stipple = state->line_stipple_enable ?
+ S_028A0C_LINE_PATTERN(state->line_stipple_pattern) |
+ S_028A0C_REPEAT_COUNT(state->line_stipple_factor) : 0;
+ rs->pa_su_sc_mode_cntl =
+ S_028814_PROVOKING_VTX_LAST(prov_vtx) |
+ S_028814_CULL_FRONT(state->rasterizer_discard || (state->cull_face & PIPE_FACE_FRONT) ? 1 : 0) |
+ S_028814_CULL_BACK(state->rasterizer_discard || (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(polygon_dual_mode) |
+ S_028814_POLYMODE_FRONT_PTYPE(si_translate_fill(state->fill_front)) |
+ S_028814_POLYMODE_BACK_PTYPE(si_translate_fill(state->fill_back));
+ rs->pa_cl_clip_cntl =
+ S_028810_PS_UCP_MODE(3) |
+ S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) |
+ S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip) |
+ S_028810_DX_LINEAR_ATTR_CLIP_ENA(1);
+ rs->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);
+
+ clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
+
+ /* offset */
+ rs->offset_units = state->offset_units;
+ rs->offset_scale = state->offset_scale * 12.0f;
+
+ /* XXX: Flat shading hangs the GPU */
+ tmp = S_0286D4_FLAT_SHADE_ENA(0);
+ if (state->sprite_coord_enable) {
+ tmp |= S_0286D4_PNT_SPRITE_ENA(1) |
+ S_0286D4_PNT_SPRITE_OVRD_X(V_0286D4_SPI_PNT_SPRITE_SEL_S) |
+ S_0286D4_PNT_SPRITE_OVRD_Y(V_0286D4_SPI_PNT_SPRITE_SEL_T) |
+ S_0286D4_PNT_SPRITE_OVRD_Z(V_0286D4_SPI_PNT_SPRITE_SEL_0) |
+ S_0286D4_PNT_SPRITE_OVRD_W(V_0286D4_SPI_PNT_SPRITE_SEL_1);
+ if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) {
+ tmp |= S_0286D4_PNT_SPRITE_TOP_1(1);
+ }
+ }
+ si_pm4_set_reg(pm4, R_0286D4_SPI_INTERP_CONTROL_0, tmp);
+
+ si_pm4_set_reg(pm4, R_028820_PA_CL_NANINF_CNTL, 0x00000000);
+ /* point size 12.4 fixed point */
+ tmp = (unsigned)(state->point_size * 8.0);
+ si_pm4_set_reg(pm4, R_028A00_PA_SU_POINT_SIZE, S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp));
+
+ if (state->point_size_per_vertex) {
+ psize_min = util_get_min_point_size(state);
+ psize_max = 8192;
+ } else {
+ /* Force the point size to be as if the vertex output was disabled. */
+ psize_min = state->point_size;
+ psize_max = state->point_size;
+ }
+ /* Divide by two, because 0.5 = 1 pixel. */
+ si_pm4_set_reg(pm4, R_028A04_PA_SU_POINT_MINMAX,
+ S_028A04_MIN_SIZE(r600_pack_float_12p4(psize_min/2)) |
+ S_028A04_MAX_SIZE(r600_pack_float_12p4(psize_max/2)));
+
+ tmp = (unsigned)state->line_width * 8;
+ si_pm4_set_reg(pm4, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp));
+ si_pm4_set_reg(pm4, R_028A48_PA_SC_MODE_CNTL_0,
+ S_028A48_LINE_STIPPLE_ENABLE(state->line_stipple_enable));
+
+ si_pm4_set_reg(pm4, R_028BDC_PA_SC_LINE_CNTL, 0x00000400);
+ si_pm4_set_reg(pm4, R_028BE4_PA_SU_VTX_CNTL,
+ S_028BE4_PIX_CENTER(state->gl_rasterization_rules));
+ si_pm4_set_reg(pm4, R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, 0x3F800000);
+ si_pm4_set_reg(pm4, R_028BEC_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000);
+ si_pm4_set_reg(pm4, R_028BF0_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000);
+ si_pm4_set_reg(pm4, R_028BF4_PA_CL_GB_HORZ_DISC_ADJ, 0x3F800000);
+
+ si_pm4_set_reg(pm4, R_028B7C_PA_SU_POLY_OFFSET_CLAMP, fui(state->offset_clamp));
+ si_pm4_set_reg(pm4, R_02820C_PA_SC_CLIPRECT_RULE, clip_rule);
+
+ return rs;
+}
+
+static void si_bind_rs_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_state_rasterizer *rs = (struct si_state_rasterizer *)state;
+
+ if (state == NULL)
+ return;
+
+ // TODO
+ rctx->sprite_coord_enable = rs->sprite_coord_enable;
+ rctx->pa_sc_line_stipple = rs->pa_sc_line_stipple;
+ rctx->pa_su_sc_mode_cntl = rs->pa_su_sc_mode_cntl;
+ rctx->pa_cl_clip_cntl = rs->pa_cl_clip_cntl;
+ rctx->pa_cl_vs_out_cntl = rs->pa_cl_vs_out_cntl;
+
+ si_pm4_bind_state(rctx, rasterizer, rs);
+
+ if (rctx->chip_class >= CAYMAN) {
+ cayman_polygon_offset_update(rctx);
+ }
+}
+
+static void si_delete_rs_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = (struct r600_context *)ctx;
+ si_pm4_delete_state(rctx, rasterizer, (struct si_state_rasterizer *)state);
+}
+
+/*
* format translation
*/
static uint32_t si_translate_colorformat(enum pipe_format format)
@@ -933,6 +1082,10 @@ void si_init_state_functions(struct r600_context *rctx)
rctx->context.delete_blend_state = si_delete_blend_state;
rctx->context.set_blend_color = si_set_blend_color;
+ rctx->context.create_rasterizer_state = si_create_rs_state;
+ rctx->context.bind_rasterizer_state = si_bind_rs_state;
+ rctx->context.delete_rasterizer_state = si_delete_rs_state;
+
rctx->context.set_clip_state = si_set_clip_state;
rctx->context.set_scissor_state = si_set_scissor_state;
rctx->context.set_viewport_state = si_set_viewport_state;