[Mesa-dev] [PATCH 02/23] radeonsi: move blender to new state handling

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


Signed-off-by: Christian König <deathsimple at vodafone.de>
---
 .../drivers/radeonsi/evergreen_hw_context.c        |   11 --
 src/gallium/drivers/radeonsi/evergreen_state.c     |  152 +------------------
 src/gallium/drivers/radeonsi/r600_blit.c           |    2 +-
 src/gallium/drivers/radeonsi/r600_state_common.c   |   27 ++--
 src/gallium/drivers/radeonsi/radeonsi_pipe.h       |   10 --
 src/gallium/drivers/radeonsi/si_state.c            |  158 +++++++++++++++++++-
 src/gallium/drivers/radeonsi/si_state.h            |   11 +-
 7 files changed, 179 insertions(+), 192 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/evergreen_hw_context.c b/src/gallium/drivers/radeonsi/evergreen_hw_context.c
index 4cf6a9e..68d53d4 100644
--- a/src/gallium/drivers/radeonsi/evergreen_hw_context.c
+++ b/src/gallium/drivers/radeonsi/evergreen_hw_context.c
@@ -184,21 +184,12 @@ static const struct r600_reg si_context_reg_list[] = {
 	{R_02870C_SPI_SHADER_POS_FORMAT, 0},
 	{R_028710_SPI_SHADER_Z_FORMAT, 0},
 	{R_028714_SPI_SHADER_COL_FORMAT, 0},
-	{R_028780_CB_BLEND0_CONTROL, 0},
-	{R_028784_CB_BLEND1_CONTROL, 0},
-	{R_028788_CB_BLEND2_CONTROL, 0},
-	{R_02878C_CB_BLEND3_CONTROL, 0},
-	{R_028790_CB_BLEND4_CONTROL, 0},
-	{R_028794_CB_BLEND5_CONTROL, 0},
-	{R_028798_CB_BLEND6_CONTROL, 0},
-	{R_02879C_CB_BLEND7_CONTROL, 0},
 	{R_0287D4_PA_CL_POINT_X_RAD, 0},
 	{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_028808_CB_COLOR_CONTROL, 0},
 	{R_02880C_DB_SHADER_CONTROL, 0},
 	{R_028810_PA_CL_CLIP_CNTL, 0},
 	{R_028814_PA_SU_SC_MODE_CNTL, 0},
@@ -284,8 +275,6 @@ static const struct r600_reg si_context_reg_list[] = {
 	{R_028C2C_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1, 0},
 	{R_028C30_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2, 0},
 	{R_028C34_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3, 0},
-	{R_028C38_PA_SC_AA_MASK_X0Y0_X1Y0, 0},
-	{R_028C3C_PA_SC_AA_MASK_X0Y1_X1Y1, 0},
 	{GROUP_FORCE_NEW_BLOCK, 0},
 	{R_028C60_CB_COLOR0_BASE, REG_FLAG_NEED_BO},
 	{R_028C64_CB_COLOR0_PITCH, 0},
diff --git a/src/gallium/drivers/radeonsi/evergreen_state.c b/src/gallium/drivers/radeonsi/evergreen_state.c
index 9c45719..62f138a 100644
--- a/src/gallium/drivers/radeonsi/evergreen_state.c
+++ b/src/gallium/drivers/radeonsi/evergreen_state.c
@@ -45,76 +45,7 @@
 #include "sid.h"
 #include "r600_resource.h"
 #include "radeonsi_pipe.h"
-
-static uint32_t si_translate_blend_function(int blend_func)
-{
-	switch (blend_func) {
-	case PIPE_BLEND_ADD:
-		return V_028780_COMB_DST_PLUS_SRC;
-	case PIPE_BLEND_SUBTRACT:
-		return V_028780_COMB_SRC_MINUS_DST;
-	case PIPE_BLEND_REVERSE_SUBTRACT:
-		return V_028780_COMB_DST_MINUS_SRC;
-	case PIPE_BLEND_MIN:
-		return V_028780_COMB_MIN_DST_SRC;
-	case PIPE_BLEND_MAX:
-		return V_028780_COMB_MAX_DST_SRC;
-	default:
-		R600_ERR("Unknown blend function %d\n", blend_func);
-		assert(0);
-		break;
-	}
-	return 0;
-}
-
-static uint32_t si_translate_blend_factor(int blend_fact)
-{
-	switch (blend_fact) {
-	case PIPE_BLENDFACTOR_ONE:
-		return V_028780_BLEND_ONE;
-	case PIPE_BLENDFACTOR_SRC_COLOR:
-		return V_028780_BLEND_SRC_COLOR;
-	case PIPE_BLENDFACTOR_SRC_ALPHA:
-		return V_028780_BLEND_SRC_ALPHA;
-	case PIPE_BLENDFACTOR_DST_ALPHA:
-		return V_028780_BLEND_DST_ALPHA;
-	case PIPE_BLENDFACTOR_DST_COLOR:
-		return V_028780_BLEND_DST_COLOR;
-	case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
-		return V_028780_BLEND_SRC_ALPHA_SATURATE;
-	case PIPE_BLENDFACTOR_CONST_COLOR:
-		return V_028780_BLEND_CONSTANT_COLOR;
-	case PIPE_BLENDFACTOR_CONST_ALPHA:
-		return V_028780_BLEND_CONSTANT_ALPHA;
-	case PIPE_BLENDFACTOR_ZERO:
-		return V_028780_BLEND_ZERO;
-	case PIPE_BLENDFACTOR_INV_SRC_COLOR:
-		return V_028780_BLEND_ONE_MINUS_SRC_COLOR;
-	case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
-		return V_028780_BLEND_ONE_MINUS_SRC_ALPHA;
-	case PIPE_BLENDFACTOR_INV_DST_ALPHA:
-		return V_028780_BLEND_ONE_MINUS_DST_ALPHA;
-	case PIPE_BLENDFACTOR_INV_DST_COLOR:
-		return V_028780_BLEND_ONE_MINUS_DST_COLOR;
-	case PIPE_BLENDFACTOR_INV_CONST_COLOR:
-		return V_028780_BLEND_ONE_MINUS_CONSTANT_COLOR;
-	case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
-		return V_028780_BLEND_ONE_MINUS_CONSTANT_ALPHA;
-	case PIPE_BLENDFACTOR_SRC1_COLOR:
-		return V_028780_BLEND_SRC1_COLOR;
-	case PIPE_BLENDFACTOR_SRC1_ALPHA:
-		return V_028780_BLEND_SRC1_ALPHA;
-	case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
-		return V_028780_BLEND_INV_SRC1_COLOR;
-	case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
-		return V_028780_BLEND_INV_SRC1_ALPHA;
-	default:
-		R600_ERR("Bad blend factor %d not supported!\n", blend_fact);
-		assert(0);
-		break;
-	}
-	return 0;
-}
+#include "si_state.h"
 
 #if 0
 static uint32_t r600_translate_stencil_op(int s_op)
@@ -852,83 +783,6 @@ static void evergreen_set_blend_color(struct pipe_context *ctx,
 	r600_context_pipe_state_set(rctx, rstate);
 }
 
-static void *evergreen_create_blend_state(struct pipe_context *ctx,
-					const struct pipe_blend_state *state)
-{
-	struct r600_context *rctx = (struct r600_context *)ctx;
-	struct r600_pipe_blend *blend = CALLOC_STRUCT(r600_pipe_blend);
-	struct r600_pipe_state *rstate;
-	uint32_t color_control, target_mask;
-	/* FIXME there is more then 8 framebuffer */
-	unsigned blend_cntl[8];
-
-	if (blend == NULL) {
-		return NULL;
-	}
-
-	rstate = &blend->rstate;
-
-	rstate->id = R600_PIPE_STATE_BLEND;
-
-	target_mask = 0;
-	color_control = S_028808_MODE(V_028808_CB_NORMAL);
-	if (state->logicop_enable) {
-		color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4));
-	} else {
-		color_control |= S_028808_ROP3(0xcc);
-	}
-	/* we pretend 8 buffer are used, CB_SHADER_MASK will disable unused one */
-	if (state->independent_blend_enable) {
-		for (int i = 0; i < 8; i++) {
-			target_mask |= (state->rt[i].colormask << (4 * i));
-		}
-	} else {
-		for (int i = 0; i < 8; i++) {
-			target_mask |= (state->rt[0].colormask << (4 * i));
-		}
-	}
-	blend->cb_target_mask = target_mask;
-
-	r600_pipe_state_add_reg(rstate, R_028808_CB_COLOR_CONTROL,
-				color_control, NULL, 0);
-
-	r600_pipe_state_add_reg(rstate, R_028C38_PA_SC_AA_MASK_X0Y0_X1Y0, ~0, NULL, 0);
-	r600_pipe_state_add_reg(rstate, R_028C3C_PA_SC_AA_MASK_X0Y1_X1Y1, ~0, NULL, 0);
-
-	for (int i = 0; i < 8; i++) {
-		/* state->rt entries > 0 only written if independent blending */
-		const int j = state->independent_blend_enable ? i : 0;
-
-		unsigned eqRGB = state->rt[j].rgb_func;
-		unsigned srcRGB = state->rt[j].rgb_src_factor;
-		unsigned dstRGB = state->rt[j].rgb_dst_factor;
-		unsigned eqA = state->rt[j].alpha_func;
-		unsigned srcA = state->rt[j].alpha_src_factor;
-		unsigned dstA = state->rt[j].alpha_dst_factor;
-
-		blend_cntl[i] = 0;
-		if (!state->rt[j].blend_enable)
-			continue;
-
-		blend_cntl[i] |= S_028780_ENABLE(1);
-		blend_cntl[i] |= S_028780_COLOR_COMB_FCN(si_translate_blend_function(eqRGB));
-		blend_cntl[i] |= S_028780_COLOR_SRCBLEND(si_translate_blend_factor(srcRGB));
-		blend_cntl[i] |= S_028780_COLOR_DESTBLEND(si_translate_blend_factor(dstRGB));
-
-		if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) {
-			blend_cntl[i] |= S_028780_SEPARATE_ALPHA_BLEND(1);
-			blend_cntl[i] |= S_028780_ALPHA_COMB_FCN(si_translate_blend_function(eqA));
-			blend_cntl[i] |= S_028780_ALPHA_SRCBLEND(si_translate_blend_factor(srcA));
-			blend_cntl[i] |= S_028780_ALPHA_DESTBLEND(si_translate_blend_factor(dstA));
-		}
-	}
-	for (int i = 0; i < 8; i++) {
-		r600_pipe_state_add_reg(rstate, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl[i], NULL, 0);
-	}
-
-	return rstate;
-}
-
 static void *evergreen_create_dsa_state(struct pipe_context *ctx,
 				   const struct pipe_depth_stencil_alpha_state *state)
 {
@@ -1880,7 +1734,7 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
 
 void cayman_init_state_functions(struct r600_context *rctx)
 {
-	rctx->context.create_blend_state = evergreen_create_blend_state;
+	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_rasterizer_state = evergreen_create_rs_state;
@@ -1888,7 +1742,6 @@ void cayman_init_state_functions(struct r600_context *rctx)
 	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_blend_state = r600_bind_blend_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;
@@ -1896,7 +1749,6 @@ void cayman_init_state_functions(struct r600_context *rctx)
 	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_blend_state = r600_delete_state;
 	rctx->context.delete_depth_stencil_alpha_state = r600_delete_state;
 	rctx->context.delete_fs_state = r600_delete_ps_shader;
 	rctx->context.delete_rasterizer_state = r600_delete_rs_state;
diff --git a/src/gallium/drivers/radeonsi/r600_blit.c b/src/gallium/drivers/radeonsi/r600_blit.c
index 1681b48..be70e3a 100644
--- a/src/gallium/drivers/radeonsi/r600_blit.c
+++ b/src/gallium/drivers/radeonsi/r600_blit.c
@@ -47,7 +47,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->states[R600_PIPE_STATE_BLEND]);
+	util_blitter_save_blend(rctx->blitter, rctx->qued.named.blend);
 	util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->states[R600_PIPE_STATE_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 18ba7a8..3a9ae0a 100644
--- a/src/gallium/drivers/radeonsi/r600_state_common.c
+++ b/src/gallium/drivers/radeonsi/r600_state_common.c
@@ -33,6 +33,7 @@
 #include "r600_hw_context_priv.h"
 #include "radeonsi_pipe.h"
 #include "sid.h"
+#include "si_state.h"
 
 static void r600_emit_surface_sync(struct r600_context *rctx, struct r600_atom *atom)
 {
@@ -119,22 +120,6 @@ static bool r600_conv_pipe_prim(unsigned pprim, unsigned *prim)
 }
 
 /* common state between evergreen and r600 */
-void r600_bind_blend_state(struct pipe_context *ctx, void *state)
-{
-	struct r600_context *rctx = (struct r600_context *)ctx;
-	struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state;
-	struct r600_pipe_state *rstate;
-
-	if (state == NULL)
-		return;
-	rstate = &blend->rstate;
-	rctx->states[rstate->id] = rstate;
-	rctx->cb_target_mask = blend->cb_target_mask;
-	rctx->cb_color_control = blend->cb_color_control;
-
-	r600_context_pipe_state_set(rctx, rstate);
-}
-
 static void r600_set_stencil_ref(struct pipe_context *ctx,
 				 const struct r600_stencil_ref *state)
 {
@@ -685,6 +670,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
 	unsigned prim, mask, ls_mask = 0;
 	struct r600_block *dirty_block = NULL, *next_block = NULL;
 	struct r600_atom *state = NULL, *next_state = NULL;
+	struct si_state_blend *blend;
 	int i;
 
 	if ((!info.count && (info.indexed || !info.count_from_stream_output)) ||
@@ -696,6 +682,11 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
 	if (!rctx->ps_shader || !rctx->vs_shader)
 		return;
 
+	/* only temporary */
+	if (!rctx->qued.named.blend)
+		return;
+	blend = rctx->qued.named.blend;
+
 	si_update_derived_state(rctx);
 
 	r600_vertex_buffer_update(rctx);
@@ -745,7 +736,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
 		rctx->vgt.id = R600_PIPE_STATE_VGT;
 		rctx->vgt.nregs = 0;
 		r600_pipe_state_add_reg(&rctx->vgt, R_008958_VGT_PRIMITIVE_TYPE, prim, NULL, 0);
-		r600_pipe_state_add_reg(&rctx->vgt, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, NULL, 0);
+		r600_pipe_state_add_reg(&rctx->vgt, R_028238_CB_TARGET_MASK, blend->cb_target_mask & mask, NULL, 0);
 		r600_pipe_state_add_reg(&rctx->vgt, R_028400_VGT_MAX_VTX_INDX, ~0, NULL, 0);
 		r600_pipe_state_add_reg(&rctx->vgt, R_028404_VGT_MIN_VTX_INDX, 0, NULL, 0);
 		r600_pipe_state_add_reg(&rctx->vgt, R_028408_VGT_INDX_OFFSET, info.index_bias, NULL, 0);
@@ -763,7 +754,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
 
 	rctx->vgt.nregs = 0;
 	r600_pipe_state_mod_reg(&rctx->vgt, prim);
-	r600_pipe_state_mod_reg(&rctx->vgt, rctx->cb_target_mask & mask);
+	r600_pipe_state_mod_reg(&rctx->vgt, blend->cb_target_mask & mask);
 	r600_pipe_state_mod_reg(&rctx->vgt, ~0);
 	r600_pipe_state_mod_reg(&rctx->vgt, 0);
 	r600_pipe_state_mod_reg(&rctx->vgt, info.index_bias);
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
index 43037e9..b61d1c0 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
@@ -75,7 +75,6 @@ struct r600_atom_surface_sync {
 };
 
 enum r600_pipe_state_id {
-	R600_PIPE_STATE_BLEND = 0,
 	R600_PIPE_STATE_BLEND_COLOR,
 	R600_PIPE_STATE_CONFIG,
 	R600_PIPE_STATE_SEAMLESS_CUBEMAP,
@@ -139,12 +138,6 @@ struct r600_pipe_rasterizer {
 	float				offset_scale;
 };
 
-struct r600_pipe_blend {
-	struct r600_pipe_state		rstate;
-	unsigned			cb_target_mask;
-	unsigned			cb_color_control;
-};
-
 struct r600_pipe_dsa {
 	struct r600_pipe_state		rstate;
 	unsigned			alpha_ref;
@@ -243,8 +236,6 @@ struct r600_context {
 	struct r600_pipe_state		*states[R600_PIPE_NSTATES];
 	struct r600_vertex_element	*vertex_elements;
 	struct pipe_framebuffer_state	framebuffer;
-	unsigned			cb_target_mask;
-	unsigned			cb_color_control;
 	unsigned			pa_sc_line_stipple;
 	unsigned			pa_su_sc_mode_cntl;
 	unsigned			pa_cl_clip_cntl;
@@ -420,7 +411,6 @@ void *si_create_vertex_elements(struct pipe_context *ctx,
 				unsigned count,
 				const struct pipe_vertex_element *elements);
 void r600_delete_vertex_element(struct pipe_context *ctx, void *state);
-void r600_bind_blend_state(struct pipe_context *ctx, void *state);
 void r600_bind_dsa_state(struct pipe_context *ctx, void *state);
 void r600_bind_rs_state(struct pipe_context *ctx, void *state);
 void r600_delete_rs_state(struct pipe_context *ctx, void *state);
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 843403b..8373f42 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -22,7 +22,163 @@
  *
  * Authors:
  *      Christian König <christian.koenig at amd.com>
- *
  */
 
+#include "util/u_memory.h"
+#include "radeonsi_pipe.h"
 #include "si_state.h"
+#include "sid.h"
+
+/*
+ * Blender functions
+ */
+
+static uint32_t si_translate_blend_function(int blend_func)
+{
+	switch (blend_func) {
+	case PIPE_BLEND_ADD:
+		return V_028780_COMB_DST_PLUS_SRC;
+	case PIPE_BLEND_SUBTRACT:
+		return V_028780_COMB_SRC_MINUS_DST;
+	case PIPE_BLEND_REVERSE_SUBTRACT:
+		return V_028780_COMB_DST_MINUS_SRC;
+	case PIPE_BLEND_MIN:
+		return V_028780_COMB_MIN_DST_SRC;
+	case PIPE_BLEND_MAX:
+		return V_028780_COMB_MAX_DST_SRC;
+	default:
+		R600_ERR("Unknown blend function %d\n", blend_func);
+		assert(0);
+		break;
+	}
+	return 0;
+}
+
+static uint32_t si_translate_blend_factor(int blend_fact)
+{
+	switch (blend_fact) {
+	case PIPE_BLENDFACTOR_ONE:
+		return V_028780_BLEND_ONE;
+	case PIPE_BLENDFACTOR_SRC_COLOR:
+		return V_028780_BLEND_SRC_COLOR;
+	case PIPE_BLENDFACTOR_SRC_ALPHA:
+		return V_028780_BLEND_SRC_ALPHA;
+	case PIPE_BLENDFACTOR_DST_ALPHA:
+		return V_028780_BLEND_DST_ALPHA;
+	case PIPE_BLENDFACTOR_DST_COLOR:
+		return V_028780_BLEND_DST_COLOR;
+	case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+		return V_028780_BLEND_SRC_ALPHA_SATURATE;
+	case PIPE_BLENDFACTOR_CONST_COLOR:
+		return V_028780_BLEND_CONSTANT_COLOR;
+	case PIPE_BLENDFACTOR_CONST_ALPHA:
+		return V_028780_BLEND_CONSTANT_ALPHA;
+	case PIPE_BLENDFACTOR_ZERO:
+		return V_028780_BLEND_ZERO;
+	case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+		return V_028780_BLEND_ONE_MINUS_SRC_COLOR;
+	case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+		return V_028780_BLEND_ONE_MINUS_SRC_ALPHA;
+	case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+		return V_028780_BLEND_ONE_MINUS_DST_ALPHA;
+	case PIPE_BLENDFACTOR_INV_DST_COLOR:
+		return V_028780_BLEND_ONE_MINUS_DST_COLOR;
+	case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+		return V_028780_BLEND_ONE_MINUS_CONSTANT_COLOR;
+	case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+		return V_028780_BLEND_ONE_MINUS_CONSTANT_ALPHA;
+	case PIPE_BLENDFACTOR_SRC1_COLOR:
+		return V_028780_BLEND_SRC1_COLOR;
+	case PIPE_BLENDFACTOR_SRC1_ALPHA:
+		return V_028780_BLEND_SRC1_ALPHA;
+	case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+		return V_028780_BLEND_INV_SRC1_COLOR;
+	case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+		return V_028780_BLEND_INV_SRC1_ALPHA;
+	default:
+		R600_ERR("Bad blend factor %d not supported!\n", blend_fact);
+		assert(0);
+		break;
+	}
+	return 0;
+}
+
+static void *si_create_blend_state(struct pipe_context *ctx,
+				   const struct pipe_blend_state *state)
+{
+	struct si_state_blend *blend = CALLOC_STRUCT(si_state_blend);
+	struct si_pm4_state *pm4 = &blend->pm4;
+
+	uint32_t color_control;
+
+	if (blend == NULL)
+		return NULL;
+
+	color_control = S_028808_MODE(V_028808_CB_NORMAL);
+	if (state->logicop_enable) {
+		color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4));
+	} else {
+		color_control |= S_028808_ROP3(0xcc);
+	}
+	si_pm4_set_reg(pm4, R_028808_CB_COLOR_CONTROL, color_control);
+
+	si_pm4_set_reg(pm4, R_028C38_PA_SC_AA_MASK_X0Y0_X1Y0, ~0);
+	si_pm4_set_reg(pm4, R_028C3C_PA_SC_AA_MASK_X0Y1_X1Y1, ~0);
+
+	blend->cb_target_mask = 0;
+	for (int i = 0; i < 8; i++) {
+		/* state->rt entries > 0 only written if independent blending */
+		const int j = state->independent_blend_enable ? i : 0;
+
+		unsigned eqRGB = state->rt[j].rgb_func;
+		unsigned srcRGB = state->rt[j].rgb_src_factor;
+		unsigned dstRGB = state->rt[j].rgb_dst_factor;
+		unsigned eqA = state->rt[j].alpha_func;
+		unsigned srcA = state->rt[j].alpha_src_factor;
+		unsigned dstA = state->rt[j].alpha_dst_factor;
+
+		unsigned blend_cntl = 0;
+
+		/* we pretend 8 buffer are used, CB_SHADER_MASK will disable unused one */
+		blend->cb_target_mask |= state->rt[j].colormask << (4 * i);
+
+		if (!state->rt[j].blend_enable) {
+			si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl);
+			continue;
+		}
+
+		blend_cntl |= S_028780_ENABLE(1);
+		blend_cntl |= S_028780_COLOR_COMB_FCN(si_translate_blend_function(eqRGB));
+		blend_cntl |= S_028780_COLOR_SRCBLEND(si_translate_blend_factor(srcRGB));
+		blend_cntl |= S_028780_COLOR_DESTBLEND(si_translate_blend_factor(dstRGB));
+
+		if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) {
+			blend_cntl |= S_028780_SEPARATE_ALPHA_BLEND(1);
+			blend_cntl |= S_028780_ALPHA_COMB_FCN(si_translate_blend_function(eqA));
+			blend_cntl |= S_028780_ALPHA_SRCBLEND(si_translate_blend_factor(srcA));
+			blend_cntl |= S_028780_ALPHA_DESTBLEND(si_translate_blend_factor(dstA));
+		}
+		si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl);
+	}
+
+	return blend;
+}
+
+static void si_bind_blend_state(struct pipe_context *ctx, void *state)
+{
+	struct r600_context *rctx = (struct r600_context *)ctx;
+	si_pm4_bind_state(rctx, blend, (struct si_state_blend *)state);
+}
+
+static void si_delete_blend_state(struct pipe_context *ctx, void *state)
+{
+	struct r600_context *rctx = (struct r600_context *)ctx;
+	si_pm4_delete_state(rctx, blend, (struct si_state_blend *)state);
+}
+
+void si_init_state_functions(struct r600_context *rctx)
+{
+	rctx->context.create_blend_state = si_create_blend_state;
+	rctx->context.bind_blend_state = si_bind_blend_state;
+	rctx->context.delete_blend_state = si_delete_blend_state;
+}
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index d9020ea..8f2568e 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -29,14 +29,21 @@
 
 #include "radeonsi_pm4.h"
 
+struct si_state_blend {
+	struct si_pm4_state	pm4;
+	uint32_t		cb_target_mask;
+	uint32_t		cb_color_control;
+};
+
 union si_state {
 	struct {
+		struct si_state_blend	*blend;
 	} named;
 	struct si_pm4_state	*array[0];
 };
 
 #define si_pm4_block_idx(member) \
-	(offsetof(union si_pm4_qued, named.member) / sizeof(struct si_pm4_state *))
+	(offsetof(union si_state, named.member) / sizeof(struct si_pm4_state *))
 
 #define si_pm4_bind_state(rctx, member, value) \
 	do { \
@@ -62,4 +69,6 @@ union si_state {
 		} \
 	} while(0);
 
+void si_init_state_functions(struct r600_context *rctx);
+
 #endif
-- 
1.7.9.5



More information about the mesa-dev mailing list