[Mesa-dev] [PATCH 10/23] radeonsi: move dsa state to new handling

Christian König deathsimple at vodafone.de
Fri Jul 20 03:21:57 PDT 2012


Signed-off-by: Christian König <deathsimple at vodafone.de>
---
 .../drivers/radeonsi/evergreen_hw_context.c        |   12 --
 src/gallium/drivers/radeonsi/evergreen_state.c     |  101 ---------------
 src/gallium/drivers/radeonsi/r600_blit.c           |    2 +-
 src/gallium/drivers/radeonsi/r600_state_common.c   |   33 +----
 src/gallium/drivers/radeonsi/radeonsi_pipe.c       |    1 -
 src/gallium/drivers/radeonsi/radeonsi_pipe.h       |   13 +-
 src/gallium/drivers/radeonsi/si_state.c            |  132 ++++++++++++++++++++
 src/gallium/drivers/radeonsi/si_state.h            |   10 ++
 8 files changed, 149 insertions(+), 155 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/evergreen_hw_context.c b/src/gallium/drivers/radeonsi/evergreen_hw_context.c
index 07fa74f..8cab629 100644
--- a/src/gallium/drivers/radeonsi/evergreen_hw_context.c
+++ b/src/gallium/drivers/radeonsi/evergreen_hw_context.c
@@ -43,18 +43,11 @@ static const struct r600_reg si_config_reg_list[] = {
 };
 
 static const struct r600_reg si_context_reg_list[] = {
-	{R_028000_DB_RENDER_CONTROL, 0},
 	{R_028004_DB_COUNT_CONTROL, 0},
-	{R_02800C_DB_RENDER_OVERRIDE, 0},
 	{R_028010_DB_RENDER_OVERRIDE2, 0},
 	{GROUP_FORCE_NEW_BLOCK, 0},
 	{R_028014_DB_HTILE_DATA_BASE, REG_FLAG_NEED_BO},
 	{GROUP_FORCE_NEW_BLOCK, 0},
-	{R_028020_DB_DEPTH_BOUNDS_MIN, 0},
-	{R_028024_DB_DEPTH_BOUNDS_MAX, 0},
-	{R_028028_DB_STENCIL_CLEAR, 0},
-	{R_02802C_DB_DEPTH_CLEAR, 0},
-	{GROUP_FORCE_NEW_BLOCK, 0},
 	{R_028080_TA_BC_BASE_ADDR, REG_FLAG_NEED_BO},
 	{GROUP_FORCE_NEW_BLOCK, 0},
 	{R_028234_PA_SU_HARDWARE_SCREEN_OFFSET, 0},
@@ -112,7 +105,6 @@ static const struct r600_reg si_context_reg_list[] = {
 	{R_0287D8_PA_CL_POINT_Y_RAD, 0},
 	{R_0287DC_PA_CL_POINT_SIZE, 0},
 	{R_0287E0_PA_CL_POINT_CULL_RAD, 0},
-	{R_028800_DB_DEPTH_CONTROL, 0},
 	{R_028804_DB_EQAA, 0},
 	{R_02880C_DB_SHADER_CONTROL, 0},
 	{R_028810_PA_CL_CLIP_CNTL, 0},
@@ -155,11 +147,7 @@ static const struct r600_reg si_context_reg_list[] = {
 	{R_028AB4_VGT_REUSE_OFF, 0},
 	{R_028AB8_VGT_VTX_CNT_EN, 0},
 	{R_028ABC_DB_HTILE_SURFACE, 0},
-	{R_028AC0_DB_SRESULTS_COMPARE_STATE0, 0},
-	{R_028AC4_DB_SRESULTS_COMPARE_STATE1, 0},
-	{R_028AC8_DB_PRELOAD_CONTROL, 0},
 	{R_028B54_VGT_SHADER_STAGES_EN, 0},
-	{R_028B70_DB_ALPHA_TO_MASK, 0},
 	{R_028B94_VGT_STRMOUT_CONFIG, 0},
 	{R_028B98_VGT_STRMOUT_BUFFER_CONFIG, 0},
 	{R_028BD4_PA_SC_CENTROID_PRIORITY_0, 0},
diff --git a/src/gallium/drivers/radeonsi/evergreen_state.c b/src/gallium/drivers/radeonsi/evergreen_state.c
index b36be3f..1fd5118 100644
--- a/src/gallium/drivers/radeonsi/evergreen_state.c
+++ b/src/gallium/drivers/radeonsi/evergreen_state.c
@@ -76,12 +76,6 @@ static uint32_t r600_translate_stencil_op(int s_op)
 }
 #endif
 
-/* translates straight */
-static uint32_t si_translate_ds_func(int func)
-{
-	return func;
-}
-
 static unsigned si_tex_wrap(unsigned wrap)
 {
 	switch (wrap) {
@@ -748,81 +742,6 @@ boolean si_is_format_supported(struct pipe_screen *screen,
 	return retval == usage;
 }
 
-static void *evergreen_create_dsa_state(struct pipe_context *ctx,
-				   const struct pipe_depth_stencil_alpha_state *state)
-{
-	struct r600_context *rctx = (struct r600_context *)ctx;
-	struct r600_pipe_dsa *dsa = CALLOC_STRUCT(r600_pipe_dsa);
-	unsigned db_depth_control, alpha_test_control, alpha_ref;
-	unsigned db_render_override, db_render_control;
-	struct r600_pipe_state *rstate;
-
-	if (dsa == NULL) {
-		return NULL;
-	}
-
-	dsa->valuemask[0] = state->stencil[0].valuemask;
-	dsa->valuemask[1] = state->stencil[1].valuemask;
-	dsa->writemask[0] = state->stencil[0].writemask;
-	dsa->writemask[1] = state->stencil[1].writemask;
-
-	rstate = &dsa->rstate;
-
-	rstate->id = R600_PIPE_STATE_DSA;
-	db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) |
-		S_028800_Z_WRITE_ENABLE(state->depth.writemask) |
-		S_028800_ZFUNC(state->depth.func);
-
-	/* stencil */
-	if (state->stencil[0].enabled) {
-		db_depth_control |= S_028800_STENCIL_ENABLE(1);
-		db_depth_control |= S_028800_STENCILFUNC(si_translate_ds_func(state->stencil[0].func));
-		//db_depth_control |= S_028800_STENCILFAIL(r600_translate_stencil_op(state->stencil[0].fail_op));
-		//db_depth_control |= S_028800_STENCILZPASS(r600_translate_stencil_op(state->stencil[0].zpass_op));
-		//db_depth_control |= S_028800_STENCILZFAIL(r600_translate_stencil_op(state->stencil[0].zfail_op));
-
-		if (state->stencil[1].enabled) {
-			db_depth_control |= S_028800_BACKFACE_ENABLE(1);
-			db_depth_control |= S_028800_STENCILFUNC_BF(si_translate_ds_func(state->stencil[1].func));
-			//db_depth_control |= S_028800_STENCILFAIL_BF(r600_translate_stencil_op(state->stencil[1].fail_op));
-			//db_depth_control |= S_028800_STENCILZPASS_BF(r600_translate_stencil_op(state->stencil[1].zpass_op));
-			//db_depth_control |= S_028800_STENCILZFAIL_BF(r600_translate_stencil_op(state->stencil[1].zfail_op));
-		}
-	}
-
-	/* alpha */
-	alpha_test_control = 0;
-	alpha_ref = 0;
-	if (state->alpha.enabled) {
-		//alpha_test_control = S_028410_ALPHA_FUNC(state->alpha.func);
-		//alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1);
-		alpha_ref = fui(state->alpha.ref_value);
-	}
-	dsa->alpha_ref = alpha_ref;
-
-	/* misc */
-	db_render_control = 0;
-	db_render_override = S_02800C_FORCE_HIZ_ENABLE(V_02800C_FORCE_DISABLE) |
-		S_02800C_FORCE_HIS_ENABLE0(V_02800C_FORCE_DISABLE) |
-		S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE);
-	/* TODO db_render_override depends on query */
-	r600_pipe_state_add_reg(rstate, R_028020_DB_DEPTH_BOUNDS_MIN, 0x00000000, NULL, 0);
-	r600_pipe_state_add_reg(rstate, R_028024_DB_DEPTH_BOUNDS_MAX, 0x00000000, NULL, 0);
-	r600_pipe_state_add_reg(rstate, R_028028_DB_STENCIL_CLEAR, 0x00000000, NULL, 0);
-	r600_pipe_state_add_reg(rstate, R_02802C_DB_DEPTH_CLEAR, 0x3F800000, NULL, 0);
-	//r600_pipe_state_add_reg(rstate, R_028410_SX_ALPHA_TEST_CONTROL, alpha_test_control, NULL, 0);
-	r600_pipe_state_add_reg(rstate, R_028800_DB_DEPTH_CONTROL, db_depth_control, NULL, 0);
-	r600_pipe_state_add_reg(rstate, R_028000_DB_RENDER_CONTROL, db_render_control, NULL, 0);
-	r600_pipe_state_add_reg(rstate, R_02800C_DB_RENDER_OVERRIDE, db_render_override, NULL, 0);
-	r600_pipe_state_add_reg(rstate, R_028AC0_DB_SRESULTS_COMPARE_STATE0, 0x0, NULL, 0);
-	r600_pipe_state_add_reg(rstate, R_028AC4_DB_SRESULTS_COMPARE_STATE1, 0x0, NULL, 0);
-	r600_pipe_state_add_reg(rstate, R_028AC8_DB_PRELOAD_CONTROL, 0x0, NULL, 0);
-	r600_pipe_state_add_reg(rstate, R_028B70_DB_ALPHA_TO_MASK, 0x0000AA00, NULL, 0);
-	dsa->db_render_override = db_render_override;
-
-	return rstate;
-}
-
 static void *si_create_sampler_state(struct pipe_context *ctx,
 				     const struct pipe_sampler_state *state)
 {
@@ -1135,19 +1054,16 @@ static void evergreen_set_sample_mask(struct pipe_context *pipe, unsigned sample
 void cayman_init_state_functions(struct r600_context *rctx)
 {
 	si_init_state_functions(rctx);
-	rctx->context.create_depth_stencil_alpha_state = evergreen_create_dsa_state;
 	rctx->context.create_fs_state = si_create_shader_state;
 	rctx->context.create_sampler_state = si_create_sampler_state;
 	rctx->context.create_sampler_view = evergreen_create_sampler_view;
 	rctx->context.create_vertex_elements_state = si_create_vertex_elements;
 	rctx->context.create_vs_state = si_create_shader_state;
-	rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state;
 	rctx->context.bind_fragment_sampler_states = evergreen_bind_ps_sampler;
 	rctx->context.bind_fs_state = r600_bind_ps_shader;
 	rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements;
 	rctx->context.bind_vertex_sampler_states = evergreen_bind_vs_sampler;
 	rctx->context.bind_vs_state = r600_bind_vs_shader;
-	rctx->context.delete_depth_stencil_alpha_state = r600_delete_state;
 	rctx->context.delete_fs_state = r600_delete_ps_shader;
 	rctx->context.delete_sampler_state = si_delete_sampler_state;
 	rctx->context.delete_vertex_elements_state = r600_delete_vertex_element;
@@ -1459,20 +1375,3 @@ void si_update_spi_map(struct r600_context *rctx)
 	if (rstate->nregs > 0)
 		r600_context_pipe_state_set(rctx, rstate);
 }
-
-void *cayman_create_db_flush_dsa(struct r600_context *rctx)
-{
-	struct pipe_depth_stencil_alpha_state dsa;
-	struct r600_pipe_state *rstate;
-
-	memset(&dsa, 0, sizeof(dsa));
-
-	rstate = rctx->context.create_depth_stencil_alpha_state(&rctx->context, &dsa);
-	r600_pipe_state_add_reg(rstate,
-				R_028000_DB_RENDER_CONTROL,
-				S_028000_DEPTH_COPY(1) |
-				S_028000_STENCIL_COPY(1) |
-				S_028000_COPY_CENTROID(1),
-				NULL, 0);
-	return rstate;
-}
diff --git a/src/gallium/drivers/radeonsi/r600_blit.c b/src/gallium/drivers/radeonsi/r600_blit.c
index 322cf32..57b272a 100644
--- a/src/gallium/drivers/radeonsi/r600_blit.c
+++ b/src/gallium/drivers/radeonsi/r600_blit.c
@@ -49,7 +49,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
 	r600_context_queries_suspend(rctx);
 
 	util_blitter_save_blend(rctx->blitter, rctx->qued.named.blend);
-	util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->states[R600_PIPE_STATE_DSA]);
+	util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->qued.named.dsa);
 	if (rctx->states[R600_PIPE_STATE_STENCIL_REF]) {
 		util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref);
 	}
diff --git a/src/gallium/drivers/radeonsi/r600_state_common.c b/src/gallium/drivers/radeonsi/r600_state_common.c
index 413f702..a8db271 100644
--- a/src/gallium/drivers/radeonsi/r600_state_common.c
+++ b/src/gallium/drivers/radeonsi/r600_state_common.c
@@ -120,8 +120,8 @@ static bool r600_conv_pipe_prim(unsigned pprim, unsigned *prim)
 }
 
 /* common state between evergreen and r600 */
-static void r600_set_stencil_ref(struct pipe_context *ctx,
-				 const struct r600_stencil_ref *state)
+void r600_set_stencil_ref(struct pipe_context *ctx,
+			  const struct r600_stencil_ref *state)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
 	struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
@@ -152,7 +152,7 @@ void r600_set_pipe_stencil_ref(struct pipe_context *ctx,
 			       const struct pipe_stencil_ref *state)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
-	struct r600_pipe_dsa *dsa = (struct r600_pipe_dsa*)rctx->states[R600_PIPE_STATE_DSA];
+	struct si_state_dsa *dsa = rctx->qued.named.dsa;
 	struct r600_stencil_ref ref;
 
 	rctx->stencil_ref = *state;
@@ -170,31 +170,6 @@ void r600_set_pipe_stencil_ref(struct pipe_context *ctx,
 	r600_set_stencil_ref(ctx, &ref);
 }
 
-void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
-{
-	struct r600_context *rctx = (struct r600_context *)ctx;
-	struct r600_pipe_dsa *dsa = state;
-	struct r600_pipe_state *rstate;
-	struct r600_stencil_ref ref;
-
-	if (state == NULL)
-		return;
-	rstate = &dsa->rstate;
-	rctx->states[rstate->id] = rstate;
-	rctx->alpha_ref = dsa->alpha_ref;
-	rctx->alpha_ref_dirty = true;
-	r600_context_pipe_state_set(rctx, rstate);
-
-	ref.ref_value[0] = rctx->stencil_ref.ref_value[0];
-	ref.ref_value[1] = rctx->stencil_ref.ref_value[1];
-	ref.valuemask[0] = dsa->valuemask[0];
-	ref.valuemask[1] = dsa->valuemask[1];
-	ref.writemask[0] = dsa->writemask[0];
-	ref.writemask[1] = dsa->writemask[1];
-
-	r600_set_stencil_ref(ctx, &ref);
-}
-
 void r600_sampler_view_destroy(struct pipe_context *ctx,
 			       struct pipe_sampler_view *state)
 {
@@ -625,7 +600,7 @@ static void si_update_derived_state(struct r600_context *rctx)
 void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
-	struct r600_pipe_dsa *dsa = (struct r600_pipe_dsa*)rctx->states[R600_PIPE_STATE_DSA];
+	struct si_state_dsa *dsa = rctx->qued.named.dsa;
 	struct pipe_draw_info info = *dinfo;
 	struct r600_draw rdraw = {};
 	struct pipe_index_buffer ib = {};
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
index e58a35d..f3e9cfd 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
@@ -227,7 +227,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
 			return NULL;
 		}
 		si_init_config(rctx);
-		rctx->custom_dsa_flush = cayman_create_db_flush_dsa(rctx);
 		break;
 	default:
 		R600_ERR("Unsupported chip class %d.\n", rctx->chip_class);
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
index 1e1fcc8..948a67d 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
@@ -78,7 +78,6 @@ enum r600_pipe_state_id {
 	R600_PIPE_STATE_CONFIG,
 	R600_PIPE_STATE_SEAMLESS_CUBEMAP,
 	R600_PIPE_STATE_VGT,
-	R600_PIPE_STATE_DSA,
 	R600_PIPE_STATE_STENCIL_REF,
 	R600_PIPE_STATE_PS_SHADER,
 	R600_PIPE_STATE_VS_SHADER,
@@ -119,15 +118,6 @@ struct si_pipe_sampler_state {
 	uint32_t			val[4];
 };
 
-struct r600_pipe_dsa {
-	struct r600_pipe_state		rstate;
-	unsigned			alpha_ref;
-	unsigned			db_render_override;
-	unsigned			db_render_control;
-	ubyte				valuemask[2];
-	ubyte				writemask[2];
-};
-
 struct r600_vertex_element
 {
 	unsigned			count;
@@ -322,7 +312,6 @@ void si_init_config(struct r600_context *rctx);
 void si_pipe_shader_ps(struct pipe_context *ctx, struct si_pipe_shader *shader);
 void si_pipe_shader_vs(struct pipe_context *ctx, struct si_pipe_shader *shader);
 void si_update_spi_map(struct r600_context *rctx);
-void *cayman_create_db_flush_dsa(struct r600_context *rctx);
 uint32_t si_translate_vertexformat(struct pipe_screen *screen,
 				   enum pipe_format format,
 				   const struct util_format_description *desc,
@@ -413,6 +402,8 @@ void r600_set_so_targets(struct pipe_context *ctx,
 			 unsigned append_bitmask);
 void r600_set_pipe_stencil_ref(struct pipe_context *ctx,
 			       const struct pipe_stencil_ref *state);
+void r600_set_stencil_ref(struct pipe_context *ctx,
+                          const struct r600_stencil_ref *state);
 void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info);
 
 /*
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 783bd24..80b2958 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -466,6 +466,133 @@ static void si_delete_rs_state(struct pipe_context *ctx, void *state)
 }
 
 /*
+ * DSA
+ */
+
+/* transnates straight */
+static uint32_t si_translate_ds_func(int func)
+{
+        return func;
+}
+
+static void *si_create_dsa_state(struct pipe_context *ctx,
+				 const struct pipe_depth_stencil_alpha_state *state)
+{
+	struct si_state_dsa *dsa = CALLOC_STRUCT(si_state_dsa);
+	struct si_pm4_state *pm4 = &dsa->pm4;
+	unsigned db_depth_control, /* alpha_test_control, */ alpha_ref;
+	unsigned db_render_override, db_render_control;
+
+	if (dsa == NULL) {
+		return NULL;
+	}
+
+	dsa->valuemask[0] = state->stencil[0].valuemask;
+	dsa->valuemask[1] = state->stencil[1].valuemask;
+	dsa->writemask[0] = state->stencil[0].writemask;
+	dsa->writemask[1] = state->stencil[1].writemask;
+
+	db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) |
+		S_028800_Z_WRITE_ENABLE(state->depth.writemask) |
+		S_028800_ZFUNC(state->depth.func);
+
+	/* stencil */
+	if (state->stencil[0].enabled) {
+		db_depth_control |= S_028800_STENCIL_ENABLE(1);
+		db_depth_control |= S_028800_STENCILFUNC(si_translate_ds_func(state->stencil[0].func));
+		//db_depth_control |= S_028800_STENCILFAIL(r600_translate_stencil_op(state->stencil[0].fail_op));
+		//db_depth_control |= S_028800_STENCILZPASS(r600_translate_stencil_op(state->stencil[0].zpass_op));
+		//db_depth_control |= S_028800_STENCILZFAIL(r600_translate_stencil_op(state->stencil[0].zfail_op));
+
+		if (state->stencil[1].enabled) {
+			db_depth_control |= S_028800_BACKFACE_ENABLE(1);
+			db_depth_control |= S_028800_STENCILFUNC_BF(si_translate_ds_func(state->stencil[1].func));
+			//db_depth_control |= S_028800_STENCILFAIL_BF(r600_translate_stencil_op(state->stencil[1].fail_op));
+			//db_depth_control |= S_028800_STENCILZPASS_BF(r600_translate_stencil_op(state->stencil[1].zpass_op));
+			//db_depth_control |= S_028800_STENCILZFAIL_BF(r600_translate_stencil_op(state->stencil[1].zfail_op));
+		}
+	}
+
+	/* alpha */
+	//alpha_test_control = 0;
+	alpha_ref = 0;
+	if (state->alpha.enabled) {
+		//alpha_test_control = S_028410_ALPHA_FUNC(state->alpha.func);
+		//alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1);
+		alpha_ref = fui(state->alpha.ref_value);
+	}
+	dsa->alpha_ref = alpha_ref;
+
+	/* misc */
+	db_render_control = 0;
+	db_render_override = S_02800C_FORCE_HIZ_ENABLE(V_02800C_FORCE_DISABLE) |
+		S_02800C_FORCE_HIS_ENABLE0(V_02800C_FORCE_DISABLE) |
+		S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE);
+	/* TODO db_render_override depends on query */
+	si_pm4_set_reg(pm4, R_028020_DB_DEPTH_BOUNDS_MIN, 0x00000000);
+	si_pm4_set_reg(pm4, R_028024_DB_DEPTH_BOUNDS_MAX, 0x00000000);
+	si_pm4_set_reg(pm4, R_028028_DB_STENCIL_CLEAR, 0x00000000);
+	si_pm4_set_reg(pm4, R_02802C_DB_DEPTH_CLEAR, 0x3F800000);
+	//si_pm4_set_reg(pm4, R_028410_SX_ALPHA_TEST_CONTROL, alpha_test_control);
+	si_pm4_set_reg(pm4, R_028800_DB_DEPTH_CONTROL, db_depth_control);
+	si_pm4_set_reg(pm4, R_028000_DB_RENDER_CONTROL, db_render_control);
+	si_pm4_set_reg(pm4, R_02800C_DB_RENDER_OVERRIDE, db_render_override);
+	si_pm4_set_reg(pm4, R_028AC0_DB_SRESULTS_COMPARE_STATE0, 0x0);
+	si_pm4_set_reg(pm4, R_028AC4_DB_SRESULTS_COMPARE_STATE1, 0x0);
+	si_pm4_set_reg(pm4, R_028AC8_DB_PRELOAD_CONTROL, 0x0);
+	si_pm4_set_reg(pm4, R_028B70_DB_ALPHA_TO_MASK, 0x0000AA00);
+	dsa->db_render_override = db_render_override;
+
+	return dsa;
+}
+
+static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
+{
+        struct r600_context *rctx = (struct r600_context *)ctx;
+        struct si_state_dsa *dsa = state;
+        struct r600_stencil_ref ref;
+
+        if (state == NULL)
+                return;
+
+	si_pm4_bind_state(rctx, dsa, dsa);
+
+	// TODO
+        rctx->alpha_ref = dsa->alpha_ref;
+        rctx->alpha_ref_dirty = true;
+
+        ref.ref_value[0] = rctx->stencil_ref.ref_value[0];
+        ref.ref_value[1] = rctx->stencil_ref.ref_value[1];
+        ref.valuemask[0] = dsa->valuemask[0];
+        ref.valuemask[1] = dsa->valuemask[1];
+        ref.writemask[0] = dsa->writemask[0];
+        ref.writemask[1] = dsa->writemask[1];
+
+        r600_set_stencil_ref(ctx, &ref);
+}
+
+static void si_delete_dsa_state(struct pipe_context *ctx, void *state)
+{
+	struct r600_context *rctx = (struct r600_context *)ctx;
+	si_pm4_delete_state(rctx, dsa, (struct si_state_dsa *)state);
+}
+
+static void *si_create_db_flush_dsa(struct r600_context *rctx)
+{
+	struct pipe_depth_stencil_alpha_state dsa;
+        struct si_state_dsa *state;
+
+	memset(&dsa, 0, sizeof(dsa));
+
+	state = rctx->context.create_depth_stencil_alpha_state(&rctx->context, &dsa);
+	si_pm4_set_reg(&state->pm4, R_028000_DB_RENDER_CONTROL,
+		       S_028000_DEPTH_COPY(1) | 
+		       S_028000_STENCIL_COPY(1) |
+		       S_028000_COPY_CENTROID(1));
+        return state;
+}
+
+/*
  * format translation
  */
 static uint32_t si_translate_colorformat(enum pipe_format format)
@@ -1129,6 +1256,11 @@ void si_init_state_functions(struct r600_context *rctx)
 	rctx->context.bind_rasterizer_state = si_bind_rs_state;
 	rctx->context.delete_rasterizer_state = si_delete_rs_state;
 
+	rctx->context.create_depth_stencil_alpha_state = si_create_dsa_state;
+	rctx->context.bind_depth_stencil_alpha_state = si_bind_dsa_state;
+	rctx->context.delete_depth_stencil_alpha_state = si_delete_dsa_state;
+	rctx->custom_dsa_flush = si_create_db_flush_dsa(rctx);
+
 	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;
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index 32ff414..47fb0ec 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -52,6 +52,15 @@ struct si_state_rasterizer {
 	float			offset_scale;
 };
 
+struct si_state_dsa {
+	struct si_pm4_state	pm4;
+	unsigned		alpha_ref;
+	unsigned		db_render_override;
+	unsigned		db_render_control;
+	uint8_t			valuemask[2];
+	uint8_t			writemask[2];
+};
+
 union si_state {
 	struct {
 		struct si_state_blend		*blend;
@@ -61,6 +70,7 @@ union si_state {
 		struct si_state_viewport	*viewport;
 		struct si_pm4_state		*framebuffer;
 		struct si_state_rasterizer	*rasterizer;
+		struct si_state_dsa		*dsa;
 		struct si_pm4_state		*fb_rs;
 	} named;
 	struct si_pm4_state	*array[0];
-- 
1.7.9.5



More information about the mesa-dev mailing list