[Mesa-dev] [PATCH 10/14] r600g: atomize rasterizer state

Marek Olšák maraeo at gmail.com
Sun Oct 7 11:08:12 PDT 2012


---
 src/gallium/drivers/r600/evergreen_hw_context.c |   18 ----
 src/gallium/drivers/r600/evergreen_state.c      |  114 ++++++++++-----------
 src/gallium/drivers/r600/r600_blit.c            |    2 +-
 src/gallium/drivers/r600/r600_hw_context.c      |   12 +--
 src/gallium/drivers/r600/r600_pipe.h            |   10 +-
 src/gallium/drivers/r600/r600_state.c           |  123 ++++++++++-------------
 src/gallium/drivers/r600/r600_state_common.c    |   20 ++--
 7 files changed, 126 insertions(+), 173 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_hw_context.c b/src/gallium/drivers/r600/evergreen_hw_context.c
index f9b344d..93642db 100644
--- a/src/gallium/drivers/r600/evergreen_hw_context.c
+++ b/src/gallium/drivers/r600/evergreen_hw_context.c
@@ -38,7 +38,6 @@ static const struct r600_reg evergreen_context_reg_list[] = {
 	{R_028014_DB_HTILE_DATA_BASE, REG_FLAG_NEED_BO, 0},
 	{GROUP_FORCE_NEW_BLOCK, 0, 0},
 	{R_028234_PA_SU_HARDWARE_SCREEN_OFFSET, 0, 0},
-	{R_028350_SX_MISC, 0, 0},
 	{GROUP_FORCE_NEW_BLOCK, 0, 0},
 	{R_02861C_SPI_VS_OUT_ID_0, 0, 0},
 	{R_028620_SPI_VS_OUT_ID_1, 0, 0},
@@ -88,28 +87,20 @@ static const struct r600_reg evergreen_context_reg_list[] = {
 	{R_0286C8_SPI_THREAD_GROUPING, 0, 0},
 	{R_0286CC_SPI_PS_IN_CONTROL_0, 0, 0},
 	{R_0286D0_SPI_PS_IN_CONTROL_1, 0, 0},
-	{R_0286D4_SPI_INTERP_CONTROL_0, 0, 0},
 	{R_0286D8_SPI_INPUT_Z, 0, 0},
 	{R_0286E0_SPI_BARYC_CNTL, 0, 0},
 	{R_0286E4_SPI_PS_IN_CONTROL_2, 0, 0},
 	{R_0286E8_SPI_COMPUTE_INPUT_CNTL, 0, 0},
 	{R_028800_DB_DEPTH_CONTROL, 0, 0},
 	{R_02880C_DB_SHADER_CONTROL, 0, 0},
-	{R_028814_PA_SU_SC_MODE_CNTL, 0, 0},
 	{R_028840_SQ_PGM_START_PS, REG_FLAG_NEED_BO, 0},
 	{R_028844_SQ_PGM_RESOURCES_PS, 0, 0},
 	{R_02884C_SQ_PGM_EXPORTS_PS, 0, 0},
 	{R_02885C_SQ_PGM_START_VS, REG_FLAG_NEED_BO, 0},
 	{R_028860_SQ_PGM_RESOURCES_VS, 0, 0},
 	{R_0288EC_SQ_LDS_ALLOC_PS, 0, 0},
-	{R_028A00_PA_SU_POINT_SIZE, 0, 0},
-	{R_028A04_PA_SU_POINT_MINMAX, 0, 0},
-	{R_028A08_PA_SU_LINE_CNTL, 0, 0},
-	{R_028A48_PA_SC_MODE_CNTL_0, 0, 0},
 	{R_028ABC_DB_HTILE_SURFACE, 0, 0},
 	{R_028B54_VGT_SHADER_STAGES_EN, 0, 0},
-	{R_028B7C_PA_SU_POLY_OFFSET_CLAMP, 0, 0},
-	{R_028C08_PA_SU_VTX_CNTL, 0, 0},
 };
 
 static const struct r600_reg cayman_context_reg_list[] = {
@@ -118,7 +109,6 @@ static const struct r600_reg cayman_context_reg_list[] = {
 	{R_028014_DB_HTILE_DATA_BASE, REG_FLAG_NEED_BO, 0},
 	{GROUP_FORCE_NEW_BLOCK, 0, 0},
 	{R_028234_PA_SU_HARDWARE_SCREEN_OFFSET, 0, 0},
-	{R_028350_SX_MISC, 0, 0},
 	{GROUP_FORCE_NEW_BLOCK, 0, 0},
 	{R_02861C_SPI_VS_OUT_ID_0, 0, 0},
 	{R_028620_SPI_VS_OUT_ID_1, 0, 0},
@@ -166,14 +156,12 @@ static const struct r600_reg cayman_context_reg_list[] = {
 	{R_0286C8_SPI_THREAD_GROUPING, 0, 0},
 	{R_0286CC_SPI_PS_IN_CONTROL_0, 0, 0},
 	{R_0286D0_SPI_PS_IN_CONTROL_1, 0, 0},
-	{R_0286D4_SPI_INTERP_CONTROL_0, 0, 0},
 	{R_0286D8_SPI_INPUT_Z, 0, 0},
 	{R_0286E0_SPI_BARYC_CNTL, 0, 0},
 	{R_0286E4_SPI_PS_IN_CONTROL_2, 0, 0},
 	{R_0286E8_SPI_COMPUTE_INPUT_CNTL, 0, 0},
 	{R_028800_DB_DEPTH_CONTROL, 0, 0},
 	{R_02880C_DB_SHADER_CONTROL, 0, 0},
-	{R_028814_PA_SU_SC_MODE_CNTL, 0, 0},
 	{R_028838_SQ_DYN_GPR_RESOURCE_LIMIT_1, 0, 0},
 	{R_028840_SQ_PGM_START_PS, REG_FLAG_NEED_BO, 0},
 	{R_028844_SQ_PGM_RESOURCES_PS, 0, 0},
@@ -190,14 +178,8 @@ static const struct r600_reg cayman_context_reg_list[] = {
 	{R_028920_SQ_GS_VERT_ITEMSIZE_1, 0, 0},
 	{R_028924_SQ_GS_VERT_ITEMSIZE_2, 0, 0},
 	{R_028928_SQ_GS_VERT_ITEMSIZE_3, 0, 0},
-	{R_028A00_PA_SU_POINT_SIZE, 0, 0},
-	{R_028A04_PA_SU_POINT_MINMAX, 0, 0},
-	{R_028A08_PA_SU_LINE_CNTL, 0, 0},
-	{R_028A48_PA_SC_MODE_CNTL_0, 0, 0},
 	{R_028ABC_DB_HTILE_SURFACE, 0, 0},
 	{R_028B54_VGT_SHADER_STAGES_EN, 0, 0},
-	{R_028B7C_PA_SU_POLY_OFFSET_CLAMP, 0, 0},
-	{CM_R_028BE4_PA_SU_VTX_CNTL, 0, 0},
 };
 
 int evergreen_context_init(struct r600_context *ctx)
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index d6214fe..46b2fd7 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -837,23 +837,16 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
 					const struct pipe_rasterizer_state *state)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
-	struct r600_pipe_rasterizer *rs = CALLOC_STRUCT(r600_pipe_rasterizer);
-	struct r600_pipe_state *rstate;
-	unsigned tmp;
-	unsigned prov_vtx = 1, polygon_dual_mode;
+	unsigned tmp, spi_interp;
 	float psize_min, psize_max;
+	struct r600_rasterizer_state *rs = CALLOC_STRUCT(r600_rasterizer_state);
 
 	if (rs == NULL) {
 		return NULL;
 	}
 
-	polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL ||
-				state->fill_back != PIPE_POLYGON_MODE_FILL);
+	r600_init_command_buffer(&rs->buffer, 30);
 
-	if (state->flatshade_first)
-		prov_vtx = 0;
-
-	rstate = &rs->rstate;
 	rs->flatshade = state->flatshade;
 	rs->sprite_coord_enable = state->sprite_coord_enable;
 	rs->two_side = state->light_twoside;
@@ -873,24 +866,6 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
 	rs->offset_scale = state->offset_scale * 12.0f;
 	rs->offset_enable = state->offset_point || state->offset_line || state->offset_tri;
 
-	rstate->id = R600_PIPE_STATE_RASTERIZER;
-	tmp = S_0286D4_FLAT_SHADE_ENA(1);
-	if (state->sprite_coord_enable) {
-		tmp |= S_0286D4_PNT_SPRITE_ENA(1) |
-			S_0286D4_PNT_SPRITE_OVRD_X(2) |
-			S_0286D4_PNT_SPRITE_OVRD_Y(3) |
-			S_0286D4_PNT_SPRITE_OVRD_Z(0) |
-			S_0286D4_PNT_SPRITE_OVRD_W(1);
-		if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) {
-			tmp |= S_0286D4_PNT_SPRITE_TOP_1(1);
-		}
-	}
-	r600_pipe_state_add_reg(rstate, R_0286D4_SPI_INTERP_CONTROL_0, tmp);
-
-	/* point size 12.4 fixed point */
-	tmp = (unsigned)(state->point_size * 8.0);
-	r600_pipe_state_add_reg(rstate, 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;
@@ -899,41 +874,61 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
 		psize_min = state->point_size;
 		psize_max = state->point_size;
 	}
-	/* Divide by two, because 0.5 = 1 pixel. */
-	r600_pipe_state_add_reg(rstate, 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;
-	r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp));
-	r600_pipe_state_add_reg(rstate, R_028A48_PA_SC_MODE_CNTL_0,
-				S_028A48_MSAA_ENABLE(state->multisample) |
-				S_028A48_VPORT_SCISSOR_ENABLE(state->scissor) |
-				S_028A48_LINE_STIPPLE_ENABLE(state->line_stipple_enable));
+	spi_interp = S_0286D4_FLAT_SHADE_ENA(1);
+	if (state->sprite_coord_enable) {
+		spi_interp |= S_0286D4_PNT_SPRITE_ENA(1) |
+			      S_0286D4_PNT_SPRITE_OVRD_X(2) |
+			      S_0286D4_PNT_SPRITE_OVRD_Y(3) |
+			      S_0286D4_PNT_SPRITE_OVRD_Z(0) |
+			      S_0286D4_PNT_SPRITE_OVRD_W(1);
+		if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) {
+			spi_interp |= S_0286D4_PNT_SPRITE_TOP_1(1);
+		}
+	}
+
+	r600_store_context_reg_seq(&rs->buffer, R_028A00_PA_SU_POINT_SIZE, 3);
+	/* point size 12.4 fixed point (divide by two, because 0.5 = 1 pixel) */
+	tmp = r600_pack_float_12p4(state->point_size/2);
+	r600_store_value(&rs->buffer, /* R_028A00_PA_SU_POINT_SIZE */
+			 S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp));
+	r600_store_value(&rs->buffer, /* 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)));
+	r600_store_value(&rs->buffer, /* R_028A08_PA_SU_LINE_CNTL */
+			 S_028A08_WIDTH((unsigned)(state->line_width * 8)));
+
+	r600_store_context_reg(&rs->buffer, R_0286D4_SPI_INTERP_CONTROL_0, spi_interp);
+	r600_store_context_reg(&rs->buffer, R_028A48_PA_SC_MODE_CNTL_0,
+			       S_028A48_MSAA_ENABLE(state->multisample) |
+			       S_028A48_VPORT_SCISSOR_ENABLE(state->scissor) |
+			       S_028A48_LINE_STIPPLE_ENABLE(state->line_stipple_enable));
 
 	if (rctx->chip_class == CAYMAN) {
-		r600_pipe_state_add_reg(rstate, CM_R_028BE4_PA_SU_VTX_CNTL,
-					S_028C08_PIX_CENTER_HALF(state->gl_rasterization_rules) |
-					S_028C08_QUANT_MODE(V_028C08_X_1_256TH));
+		r600_store_context_reg(&rs->buffer, CM_R_028BE4_PA_SU_VTX_CNTL,
+				       S_028C08_PIX_CENTER_HALF(state->gl_rasterization_rules) |
+				       S_028C08_QUANT_MODE(V_028C08_X_1_256TH));
 	} else {
-		r600_pipe_state_add_reg(rstate, R_028C08_PA_SU_VTX_CNTL,
-					S_028C08_PIX_CENTER_HALF(state->gl_rasterization_rules) |
-					S_028C08_QUANT_MODE(V_028C08_X_1_256TH));
-	}
-	r600_pipe_state_add_reg(rstate, R_028B7C_PA_SU_POLY_OFFSET_CLAMP, fui(state->offset_clamp));
-	r600_pipe_state_add_reg(rstate, R_028814_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(r600_translate_fill(state->fill_front)) |
-				S_028814_POLYMODE_BACK_PTYPE(r600_translate_fill(state->fill_back)));
-	r600_pipe_state_add_reg(rstate, R_028350_SX_MISC, S_028350_MULTIPASS(state->rasterizer_discard));
-	return rstate;
+		r600_store_context_reg(&rs->buffer, R_028C08_PA_SU_VTX_CNTL,
+				       S_028C08_PIX_CENTER_HALF(state->gl_rasterization_rules) |
+				       S_028C08_QUANT_MODE(V_028C08_X_1_256TH));
+	}
+
+	r600_store_context_reg(&rs->buffer, R_028B7C_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)));
+	r600_store_context_reg(&rs->buffer, R_028350_SX_MISC, S_028350_MULTIPASS(state->rasterizer_discard));
+	return rs;
 }
 
 static void *evergreen_create_sampler_state(struct pipe_context *ctx,
@@ -2420,6 +2415,7 @@ void evergreen_init_state_functions(struct r600_context *rctx)
 	r600_init_atom(rctx, &rctx->clip_state.atom, id++, evergreen_emit_clip_state, 26);
 	r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, evergreen_emit_db_misc_state, 7);
 	r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, evergreen_emit_polygon_offset, 6);
+	r600_init_atom(rctx, &rctx->rasterizer_state.atom, id++, r600_emit_cso_state, 0);
 	r600_init_atom(rctx, &rctx->scissor.atom, id++, evergreen_emit_scissor_state, 4);
 	r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, r600_emit_stencil_ref, 4);
 	r600_init_atom(rctx, &rctx->viewport.atom, id++, r600_emit_viewport_state, 8);
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index 6386798..4918c3c 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -62,7 +62,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
 	util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader);
 	util_blitter_save_so_targets(rctx->blitter, rctx->num_so_targets,
 				     (struct pipe_stream_output_target**)rctx->so_targets);
-	util_blitter_save_rasterizer(rctx->blitter, rctx->states[R600_PIPE_STATE_RASTERIZER]);
+	util_blitter_save_rasterizer(rctx->blitter, rctx->rasterizer_state.cso);
 
 	if (op & R600_SAVE_FRAGMENT_STATE) {
 		util_blitter_save_viewport(rctx->blitter, &rctx->viewport.state);
diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
index 247f804..4334f0d 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -219,20 +219,10 @@ static const struct r600_reg r600_config_reg_list[] = {
 };
 
 static const struct r600_reg r600_context_reg_list[] = {
-	{R_028A4C_PA_SC_MODE_CNTL, 0, 0},
-	{GROUP_FORCE_NEW_BLOCK, 0, 0},
 	{R_028800_DB_DEPTH_CONTROL, 0, 0},
 	{R_02880C_DB_SHADER_CONTROL, 0, 0},
 	{GROUP_FORCE_NEW_BLOCK, 0, 0},
 	{R_028D24_DB_HTILE_SURFACE, 0, 0},
-	{R_0286D4_SPI_INTERP_CONTROL_0, 0, 0},
-	{R_028814_PA_SU_SC_MODE_CNTL, 0, 0},
-	{R_028A00_PA_SU_POINT_SIZE, 0, 0},
-	{R_028A04_PA_SU_POINT_MINMAX, 0, 0},
-	{R_028A08_PA_SU_LINE_CNTL, 0, 0},
-	{R_028C08_PA_SU_VTX_CNTL, 0, 0},
-	{R_028DFC_PA_SU_POLY_OFFSET_CLAMP, 0, 0},
-	{R_028350_SX_MISC, 0, 0},
 	{R_028614_SPI_VS_OUT_ID_0, 0, 0},
 	{R_028618_SPI_VS_OUT_ID_1, 0, 0},
 	{R_02861C_SPI_VS_OUT_ID_2, 0, 0},
@@ -839,6 +829,8 @@ void r600_begin_new_cs(struct r600_context *ctx)
 
 	if (ctx->blend_state.cso)
 		ctx->blend_state.atom.dirty = true;
+	if (ctx->rasterizer_state.cso)
+		ctx->rasterizer_state.atom.dirty = true;
 
 	if (ctx->chip_class <= R700) {
 		ctx->seamless_cube_map.atom.dirty = true;
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 68e2f3b..cde12f4 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -35,7 +35,7 @@
 #include "r600_resource.h"
 #include "evergreen_compute.h"
 
-#define R600_NUM_ATOMS 33
+#define R600_NUM_ATOMS 34
 
 #define R600_MAX_CONST_BUFFERS 2
 #define R600_MAX_CONST_BUFFER_SIZE 4096
@@ -161,7 +161,6 @@ struct r600_viewport_state {
 };
 
 enum r600_pipe_state_id {
-	R600_PIPE_STATE_RASTERIZER,
 	R600_PIPE_STATE_DSA,
 	R600_PIPE_NSTATES
 };
@@ -205,8 +204,8 @@ struct r600_pipe_sampler_view {
 	uint32_t			tex_resource_words[8];
 };
 
-struct r600_pipe_rasterizer {
-	struct r600_pipe_state		rstate;
+struct r600_rasterizer_state {
+	struct r600_command_buffer	buffer;
 	boolean				flatshade;
 	boolean				two_side;
 	unsigned			sprite_coord_enable;
@@ -418,6 +417,7 @@ struct r600_context {
 	struct r600_db_misc_state	db_misc_state;
 	struct r600_framebuffer		framebuffer;
 	struct r600_poly_offset_state	poly_offset_state;
+	struct r600_cso_state		rasterizer_state;
 	struct r600_sample_mask		sample_mask;
 	struct r600_scissor_state	scissor;
 	struct r600_seamless_cube_map	seamless_cube_map;
@@ -441,7 +441,7 @@ struct r600_context {
 	unsigned			db_shader_control;
 	struct r600_pipe_shader_selector 	*ps_shader;
 	struct r600_pipe_shader_selector 	*vs_shader;
-	struct r600_pipe_rasterizer	*rasterizer;
+	struct r600_rasterizer_state	*rasterizer;
 	bool				alpha_to_one;
 	bool				force_blend_disable;
 	boolean				dual_src_blend;
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index d7e0430..06f76fe 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -844,24 +844,16 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
 				  const struct pipe_rasterizer_state *state)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
-	struct r600_pipe_rasterizer *rs = CALLOC_STRUCT(r600_pipe_rasterizer);
-	struct r600_pipe_state *rstate;
-	unsigned tmp;
-	unsigned prov_vtx = 1, polygon_dual_mode;
-	unsigned sc_mode_cntl;
+	unsigned tmp, sc_mode_cntl, spi_interp;
 	float psize_min, psize_max;
+	struct r600_rasterizer_state *rs = CALLOC_STRUCT(r600_rasterizer_state);
 
 	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;
+	r600_init_command_buffer(&rs->buffer, 30);
 
-	rstate = &rs->rstate;
 	rs->flatshade = state->flatshade;
 	rs->sprite_coord_enable = state->sprite_coord_enable;
 	rs->two_side = state->light_twoside;
@@ -881,24 +873,6 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
 	rs->offset_scale = state->offset_scale * 12.0f;
 	rs->offset_enable = state->offset_point || state->offset_line || state->offset_tri;
 
-	rstate->id = R600_PIPE_STATE_RASTERIZER;
-	tmp = S_0286D4_FLAT_SHADE_ENA(1);
-	if (state->sprite_coord_enable) {
-		tmp |= S_0286D4_PNT_SPRITE_ENA(1) |
-			S_0286D4_PNT_SPRITE_OVRD_X(2) |
-			S_0286D4_PNT_SPRITE_OVRD_Y(3) |
-			S_0286D4_PNT_SPRITE_OVRD_Z(0) |
-			S_0286D4_PNT_SPRITE_OVRD_W(1);
-		if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) {
-			tmp |= S_0286D4_PNT_SPRITE_TOP_1(1);
-		}
-	}
-	r600_pipe_state_add_reg(rstate, R_0286D4_SPI_INTERP_CONTROL_0, tmp);
-
-	/* point size 12.4 fixed point */
-	tmp = r600_pack_float_12p4(state->point_size/2);
-	r600_pipe_state_add_reg(rstate, 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;
@@ -907,50 +881,62 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
 		psize_min = state->point_size;
 		psize_max = state->point_size;
 	}
-	/* Divide by two, because 0.5 = 1 pixel. */
-	r600_pipe_state_add_reg(rstate, 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 = r600_pack_float_12p4(state->line_width/2);
-	r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp));
 
+	sc_mode_cntl = S_028A4C_MSAA_ENABLE(state->multisample) |
+		       S_028A4C_LINE_STIPPLE_ENABLE(state->line_stipple_enable) |
+		       S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1);
 	if (rctx->chip_class >= R700) {
-		sc_mode_cntl =
-			S_028A4C_MSAA_ENABLE(state->multisample) |
-			S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1) |
-			S_028A4C_FORCE_EOV_REZ_ENABLE(1) |
-			S_028A4C_R700_ZMM_LINE_OFFSET(1) |
-			S_028A4C_R700_VPORT_SCISSOR_ENABLE(state->scissor);
+		sc_mode_cntl |= S_028A4C_FORCE_EOV_REZ_ENABLE(1) |
+				S_028A4C_R700_ZMM_LINE_OFFSET(1) |
+				S_028A4C_R700_VPORT_SCISSOR_ENABLE(state->scissor);
 	} else {
-		sc_mode_cntl =
-			S_028A4C_MSAA_ENABLE(state->multisample) |
-			S_028A4C_WALK_ALIGN8_PRIM_FITS_ST(1) |
-			S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1);
+		sc_mode_cntl |= S_028A4C_WALK_ALIGN8_PRIM_FITS_ST(1);
 		rs->scissor_enable = state->scissor;
 	}
-	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);
-
-	r600_pipe_state_add_reg(rstate, R_028C08_PA_SU_VTX_CNTL,
-				S_028C08_PIX_CENTER_HALF(state->gl_rasterization_rules) |
-				S_028C08_QUANT_MODE(V_028C08_X_1_256TH));
-
-	r600_pipe_state_add_reg(rstate, R_028DFC_PA_SU_POLY_OFFSET_CLAMP, fui(state->offset_clamp));
-	r600_pipe_state_add_reg(rstate, R_028814_PA_SU_SC_MODE_CNTL,
-				S_028814_PROVOKING_VTX_LAST(prov_vtx) |
-				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(polygon_dual_mode) |
-				S_028814_POLYMODE_FRONT_PTYPE(r600_translate_fill(state->fill_front)) |
-				S_028814_POLYMODE_BACK_PTYPE(r600_translate_fill(state->fill_back)));
-	r600_pipe_state_add_reg(rstate, R_028350_SX_MISC, S_028350_MULTIPASS(state->rasterizer_discard));
-	return rstate;
+
+	spi_interp = S_0286D4_FLAT_SHADE_ENA(1);
+	if (state->sprite_coord_enable) {
+		spi_interp |= S_0286D4_PNT_SPRITE_ENA(1) |
+			      S_0286D4_PNT_SPRITE_OVRD_X(2) |
+			      S_0286D4_PNT_SPRITE_OVRD_Y(3) |
+			      S_0286D4_PNT_SPRITE_OVRD_Z(0) |
+			      S_0286D4_PNT_SPRITE_OVRD_W(1);
+		if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) {
+			spi_interp |= S_0286D4_PNT_SPRITE_TOP_1(1);
+		}
+	}
+
+	r600_store_context_reg_seq(&rs->buffer, R_028A00_PA_SU_POINT_SIZE, 3);
+	/* point size 12.4 fixed point (divide by two, because 0.5 = 1 pixel. */
+	tmp = r600_pack_float_12p4(state->point_size/2);
+	r600_store_value(&rs->buffer, /* R_028A00_PA_SU_POINT_SIZE */
+			 S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp));
+	r600_store_value(&rs->buffer, /* 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)));
+	r600_store_value(&rs->buffer, /* R_028A08_PA_SU_LINE_CNTL */
+			 S_028A08_WIDTH(r600_pack_float_12p4(state->line_width/2)));
+
+	r600_store_context_reg(&rs->buffer, R_0286D4_SPI_INTERP_CONTROL_0, spi_interp);
+	r600_store_context_reg(&rs->buffer, R_028A4C_PA_SC_MODE_CNTL, sc_mode_cntl);
+	r600_store_context_reg(&rs->buffer, R_028C08_PA_SU_VTX_CNTL,
+			       S_028C08_PIX_CENTER_HALF(state->gl_rasterization_rules) |
+			       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)));
+	r600_store_context_reg(&rs->buffer, R_028350_SX_MISC, S_028350_MULTIPASS(state->rasterizer_discard));
+	return rs;
 }
 
 static void *r600_create_sampler_state(struct pipe_context *ctx,
@@ -2179,6 +2165,7 @@ void r600_init_state_functions(struct r600_context *rctx)
 	r600_init_atom(rctx, &rctx->clip_state.atom, id++, r600_emit_clip_state, 26);
 	r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, r600_emit_db_misc_state, 4);
 	r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, r600_emit_polygon_offset, 6);
+	r600_init_atom(rctx, &rctx->rasterizer_state.atom, id++, r600_emit_cso_state, 0);
 	r600_init_atom(rctx, &rctx->scissor.atom, id++, r600_emit_scissor_state, 4);
 	r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, r600_emit_stencil_ref, 4);
 	r600_init_atom(rctx, &rctx->viewport.atom, id++, r600_emit_viewport_state, 8);
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 2be3bf4..18e8fc5 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -300,7 +300,7 @@ static void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
 
 static void r600_bind_rs_state(struct pipe_context *ctx, void *state)
 {
-	struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state;
+	struct r600_rasterizer_state *rs = (struct r600_rasterizer_state *)state;
 	struct r600_context *rctx = (struct r600_context *)ctx;
 
 	if (state == NULL)
@@ -308,8 +308,7 @@ static void r600_bind_rs_state(struct pipe_context *ctx, void *state)
 
 	rctx->rasterizer = rs;
 
-	rctx->states[rs->rstate.id] = &rs->rstate;
-	r600_context_pipe_state_set(rctx, &rs->rstate);
+	r600_set_cso_state_with_cb(&rctx->rasterizer_state, rs, &rs->buffer);
 
 	if (rs->offset_enable &&
 	    (rs->offset_units != rctx->poly_offset_state.offset_units ||
@@ -333,20 +332,17 @@ static void r600_bind_rs_state(struct pipe_context *ctx, void *state)
 		rctx->scissor.enable = rs->scissor_enable;
 		rctx->scissor.atom.dirty = true;
 	}
+
+	/* Re-emit PA_SC_LINE_STIPPLE. */
+	rctx->last_primitive_type = -1;
 }
 
 static void r600_delete_rs_state(struct pipe_context *ctx, void *state)
 {
-	struct r600_context *rctx = (struct r600_context *)ctx;
-	struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state;
+	struct r600_rasterizer_state *rs = (struct r600_rasterizer_state *)state;
 
-	if (rctx->rasterizer == rs) {
-		rctx->rasterizer = NULL;
-	}
-	if (rctx->states[rs->rstate.id] == &rs->rstate) {
-		rctx->states[rs->rstate.id] = NULL;
-	}
-	free(rs);
+	r600_release_command_buffer(&rs->buffer);
+	FREE(rs);
 }
 
 static void r600_sampler_view_destroy(struct pipe_context *ctx,
-- 
1.7.9.5



More information about the mesa-dev mailing list