[Mesa-dev] [PATCH 11/19] r600g: implement alpha-to-one

Marek Olšák maraeo at gmail.com
Thu Aug 9 09:07:23 PDT 2012


---
 src/gallium/drivers/r600/evergreen_state.c   |    4 ++++
 src/gallium/drivers/r600/r600_pipe.h         |    5 +++++
 src/gallium/drivers/r600/r600_shader.c       |    3 ++-
 src/gallium/drivers/r600/r600_state.c        |    5 +++++
 src/gallium/drivers/r600/r600_state_common.c |    5 ++++-
 5 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 6e338ae..98e0338 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -743,6 +743,7 @@ static void *evergreen_create_blend_state(struct pipe_context *ctx,
 		r600_pipe_state_add_reg(rstate, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl[i]);
 	}
 
+	blend->alpha_to_one = state->alpha_to_one;
 	return rstate;
 }
 
@@ -836,6 +837,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
 		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->multisample_enable = state->multisample;
 
 	/* offset */
 	rs->offset_units = state->offset_units;
@@ -1472,6 +1474,8 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
 	/* build states */
 	rctx->export_16bpc = true;
 	rctx->nr_cbufs = state->nr_cbufs;
+	rctx->cb0_is_integer = state->nr_cbufs &&
+			       util_format_is_pure_integer(state->cbufs[0]->format);
 
 	for (i = 0; i < state->nr_cbufs; i++) {
 		surf = (struct r600_surface*)state->cbufs[i];
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 0464183..926f6eb 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -180,6 +180,7 @@ struct r600_pipe_rasterizer {
 	float				offset_units;
 	float				offset_scale;
 	bool				scissor_enable;
+	bool				multisample_enable;
 };
 
 struct r600_pipe_blend {
@@ -187,6 +188,7 @@ struct r600_pipe_blend {
 	unsigned			cb_target_mask;
 	unsigned			cb_color_control;
 	bool				dual_src_blend;
+	bool				alpha_to_one;
 };
 
 struct r600_pipe_dsa {
@@ -347,6 +349,9 @@ struct r600_context {
 	boolean				flatshade;
 	boolean				export_16bpc;
 	unsigned			nr_cbufs;
+	bool				alpha_to_one;
+	bool				multisample_enable;
+	bool				cb0_is_integer;
 
 	struct u_upload_mgr	        *uploader;
 	struct util_slab_mempool	pool_transfers;
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 2422d00..d87e2af 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -1568,6 +1568,7 @@ static int r600_shader_from_tgsi(struct r600_context * rctx, struct r600_pipe_sh
 					j--;
 					continue;
 				}
+				output[j].swizzle_w = rctx->alpha_to_one && rctx->multisample_enable && !rctx->cb0_is_integer ? 5 : 3;
 				output[j].array_base = next_pixel_base++;
 				output[j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
 				shader->nr_ps_color_exports++;
@@ -1580,7 +1581,7 @@ static int r600_shader_from_tgsi(struct r600_context * rctx, struct r600_pipe_sh
 						output[j].swizzle_x = 0;
 						output[j].swizzle_y = 1;
 						output[j].swizzle_z = 2;
-						output[j].swizzle_w = 3;
+						output[j].swizzle_w = rctx->alpha_to_one && rctx->multisample_enable && !rctx->cb0_is_integer ? 5 : 3;
 						output[j].burst_count = 1;
 						output[j].barrier = 1;
 						output[j].array_base = next_pixel_base++;
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index c1061dd..831630a 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -753,6 +753,8 @@ static void *r600_create_blend_state(struct pipe_context *ctx,
 		if (i == 0)
 			r600_pipe_state_add_reg(rstate, R_028804_CB_BLEND_CONTROL, bc);
 	}
+
+	blend->alpha_to_one = state->alpha_to_one;
 	return rstate;
 }
 
@@ -846,6 +848,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
 		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->multisample_enable = state->multisample;
 
 	/* offset */
 	rs->offset_units = state->offset_units;
@@ -1398,6 +1401,8 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
 	/* build states */
 	rctx->export_16bpc = true;
 	rctx->nr_cbufs = state->nr_cbufs;
+	rctx->cb0_is_integer = state->nr_cbufs &&
+			       util_format_is_pure_integer(state->cbufs[0]->format);
 
 	for (i = 0; i < state->nr_cbufs; i++) {
 		surf = (struct r600_surface*)state->cbufs[i];
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 4a75c14..97a7c7e 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -177,6 +177,7 @@ void r600_bind_blend_state(struct pipe_context *ctx, void *state)
 	rstate = &blend->rstate;
 	rctx->states[rstate->id] = rstate;
 	rctx->dual_src_blend = blend->dual_src_blend;
+	rctx->alpha_to_one = blend->alpha_to_one;
 	r600_context_pipe_state_set(rctx, rstate);
 
 	if (rctx->cb_misc_state.blend_colormask != blend->cb_target_mask) {
@@ -320,6 +321,7 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state)
 	rctx->two_side = rs->two_side;
 	rctx->pa_sc_line_stipple = rs->pa_sc_line_stipple;
 	rctx->pa_cl_clip_cntl = rs->pa_cl_clip_cntl;
+	rctx->multisample_enable = rs->multisample_enable;
 
 	rctx->rasterizer = rs;
 
@@ -636,7 +638,8 @@ static INLINE unsigned r600_shader_selector_key(struct pipe_context * ctx,
 
 	if (sel->type == PIPE_SHADER_FRAGMENT) {
 		key = rctx->two_side |
-				MIN2(sel->nr_ps_max_color_exports, rctx->nr_cbufs + rctx->dual_src_blend) << 1;
+		      ((rctx->alpha_to_one && rctx->multisample_enable && !rctx->cb0_is_integer) << 1) |
+		      (MIN2(sel->nr_ps_max_color_exports, rctx->nr_cbufs + rctx->dual_src_blend) << 2);
 	} else
 		key = 0;
 
-- 
1.7.9.5



More information about the mesa-dev mailing list