[Mesa-dev] [PATCH 18/18] r600g: precompute color buffer state in pipe_surface and reuse it

Marek Olšák maraeo at gmail.com
Thu Aug 2 06:14:46 PDT 2012


---
 .../drivers/r600/evergreen_compute_internal.c      |   22 ++-
 src/gallium/drivers/r600/evergreen_state.c         |  143 ++++++++++----------
 src/gallium/drivers/r600/r600_pipe.h               |    6 +-
 src/gallium/drivers/r600/r600_resource.h           |   17 +++
 src/gallium/drivers/r600/r600_state.c              |  117 ++++++++--------
 5 files changed, 175 insertions(+), 130 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_compute_internal.c b/src/gallium/drivers/r600/evergreen_compute_internal.c
index fe22435..6994432 100644
--- a/src/gallium/drivers/r600/evergreen_compute_internal.c
+++ b/src/gallium/drivers/r600/evergreen_compute_internal.c
@@ -266,6 +266,9 @@ void evergreen_set_rat(
 
 	struct r600_pipe_state * state = CALLOC_STRUCT(r600_pipe_state);
 	struct pipe_surface rat_templ;
+	struct r600_surface *surf;
+	struct r600_resource *res;
+	struct r600_context *rctx = pipe->ctx;
 
 	COMPUTE_DBG("bind rat: %i \n", id);
 
@@ -291,9 +294,26 @@ void evergreen_set_rat(
 	 * of this driver. */
 	pipe->ctx->compute_cb_target_mask |= (0xf << (id * 4));
 
+	surf = (struct r600_surface*)pipe->ctx->framebuffer.cbufs[id];
+	res = (struct r600_resource*)surf->base.texture;
+
+	evergreen_init_color_surface(rctx, surf);
 
 	/* Get the CB register writes for the RAT */
-	evergreen_cb(pipe->ctx, state, &pipe->ctx->framebuffer, id);
+	r600_pipe_state_add_reg_bo(state, R_028C60_CB_COLOR0_BASE + id * 0x3C,
+				   surf->cb_color_base, res, RADEON_USAGE_READWRITE);
+	r600_pipe_state_add_reg(state, R_028C78_CB_COLOR0_DIM + id * 0x3C,
+				surf->cb_color_dim);
+	r600_pipe_state_add_reg_bo(state, R_028C70_CB_COLOR0_INFO + id * 0x3C,
+				   surf->cb_color_info, res, RADEON_USAGE_READWRITE);
+	r600_pipe_state_add_reg(state, R_028C64_CB_COLOR0_PITCH + id * 0x3C,
+				surf->cb_color_pitch);
+	r600_pipe_state_add_reg(state, R_028C68_CB_COLOR0_SLICE + id * 0x3C,
+				surf->cb_color_slice);
+	r600_pipe_state_add_reg(state, R_028C6C_CB_COLOR0_VIEW + id * 0x3C,
+				surf->cb_color_view);
+	r600_pipe_state_add_reg_bo(state, R_028C74_CB_COLOR0_ATTRIB + id * 0x3C,
+				   surf->cb_color_attrib, res, RADEON_USAGE_READWRITE);
 
 	/* Add the register blocks to the dirty list */
         free(pipe->ctx->states[R600_PIPE_STATE_FRAMEBUFFER]);
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 0e8bec9..340036c 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -1235,14 +1235,13 @@ static void evergreen_set_viewport_state(struct pipe_context *ctx,
 	r600_context_pipe_state_set(rctx, rstate);
 }
 
-void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
-			 const struct pipe_framebuffer_state *state, int cb)
+void evergreen_init_color_surface(struct r600_context *rctx,
+				  struct r600_surface *surf)
 {
 	struct r600_screen *rscreen = rctx->screen;
-	struct r600_resource_texture *rtex;
-	struct pipe_resource * pipe_tex;
-	struct r600_surface *surf;
-	unsigned level = state->cbufs[cb]->u.tex.level;
+	struct r600_resource_texture *rtex = (struct r600_resource_texture*)surf->base.texture;
+	struct pipe_resource *pipe_tex = surf->base.texture;
+	unsigned level = surf->base.u.tex.level;
 	unsigned pitch, slice;
 	unsigned color_info, color_attrib, color_dim = 0;
 	unsigned format, swap, ntype, endian;
@@ -1250,15 +1249,10 @@ void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
 	unsigned tile_type, macro_aspect, tile_split, bankh, bankw, nbanks;
 	const struct util_format_description *desc;
 	int i;
-	bool blend_clamp = 0, blend_bypass = 0, alphatest_bypass;
-
-	surf = (struct r600_surface *)state->cbufs[cb];
-	rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture;
-	pipe_tex = state->cbufs[cb]->texture;
+	bool blend_clamp = 0, blend_bypass = 0;
 
 	if (rtex->is_depth && !rtex->is_flushing_texture) {
-		r600_init_flushed_depth_texture(&rctx->context,
-				state->cbufs[cb]->texture, NULL);
+		r600_init_flushed_depth_texture(&rctx->context, pipe_tex, NULL);
 		rtex = rtex->flushed_depth_texture;
 		assert(rtex);
 	}
@@ -1266,7 +1260,7 @@ void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
 	offset = rtex->surface.level[level].offset;
 	if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
 		offset += rtex->surface.level[level].slice_size *
-			  state->cbufs[cb]->u.tex.first_layer;
+			  surf->base.u.tex.first_layer;
 	}
 	pitch = (rtex->surface.level[level].nblk_x) / 8 - 1;
 	slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
@@ -1363,14 +1357,7 @@ void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
 		blend_bypass = 1;
 	}
 
-	/* Alpha-test is done on the first colorbuffer only. */
-	if (cb == 0) {
-		alphatest_bypass = ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT;
-		if (rctx->alphatest_state.bypass != alphatest_bypass) {
-			rctx->alphatest_state.bypass = alphatest_bypass;
-			r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
-		}
-	}
+	surf->alphatest_bypass = ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT;
 
 	color_info |= S_028C70_FORMAT(format) |
 		S_028C70_COMP_SWAP(swap) |
@@ -1391,8 +1378,6 @@ void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
 	 * - 11-bit or smaller UNORM/SNORM/SRGB
 	 * - 16-bit or smaller FLOAT
 	 */
-	/* XXX: This should probably be the same for all CBs if we want
-	 * useful alpha tests. */
 	if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
 	    ((desc->channel[i].size < 12 &&
 	      desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT &&
@@ -1400,56 +1385,27 @@ void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
 	     (desc->channel[i].size < 17 &&
 	      desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) {
 		color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC);
-	} else {
-		rctx->export_16bpc = false;
-	}
-
-	/* Alpha-test is done on the first colorbuffer only. */
-	if (cb == 0 && rctx->alphatest_state.cb0_export_16bpc != rctx->export_16bpc) {
-		rctx->alphatest_state.cb0_export_16bpc = rctx->export_16bpc;
-		r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
+		surf->export_16bpc = true;
 	}
 
-	/* for possible dual-src MRT */
-	if (cb == 0 && rctx->framebuffer.nr_cbufs == 1 && !rtex->is_rat) {
-		r600_pipe_state_add_reg_bo(rstate,
-				R_028C70_CB_COLOR0_INFO + 1 * 0x3C,
-				color_info, &rtex->resource, RADEON_USAGE_READWRITE);
-	}
-
-	offset += r600_resource_va(rctx->context.screen, state->cbufs[cb]->texture);
+	offset += r600_resource_va(rctx->context.screen, pipe_tex);
 	offset >>= 8;
 
 	/* XXX handle enabling of CB beyond BASE8 which has different offset */
-	r600_pipe_state_add_reg_bo(rstate,
-				R_028C60_CB_COLOR0_BASE + cb * 0x3C,
-				offset, &rtex->resource, RADEON_USAGE_READWRITE);
-	r600_pipe_state_add_reg(rstate,
-				R_028C78_CB_COLOR0_DIM + cb * 0x3C,
-				color_dim);
-	r600_pipe_state_add_reg_bo(rstate,
-				R_028C70_CB_COLOR0_INFO + cb * 0x3C,
-				color_info, &rtex->resource, RADEON_USAGE_READWRITE);
-	r600_pipe_state_add_reg(rstate,
-				R_028C64_CB_COLOR0_PITCH + cb * 0x3C,
-				S_028C64_PITCH_TILE_MAX(pitch));
-	r600_pipe_state_add_reg(rstate,
-				R_028C68_CB_COLOR0_SLICE + cb * 0x3C,
-				S_028C68_SLICE_TILE_MAX(slice));
+	surf->cb_color_base = offset;
+	surf->cb_color_dim = color_dim;
+	surf->cb_color_info = color_info;
+	surf->cb_color_pitch = S_028C64_PITCH_TILE_MAX(pitch);
+	surf->cb_color_slice = S_028C68_SLICE_TILE_MAX(slice);
 	if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
-		r600_pipe_state_add_reg(rstate,
-					R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
-					0x00000000);
+		surf->cb_color_view = 0;
 	} else {
-		r600_pipe_state_add_reg(rstate,
-					R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
-					S_028C6C_SLICE_START(state->cbufs[cb]->u.tex.first_layer) |
-					S_028C6C_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer));
+		surf->cb_color_view = S_028C6C_SLICE_START(surf->base.u.tex.first_layer) |
+				      S_028C6C_SLICE_MAX(surf->base.u.tex.last_layer);
 	}
-	r600_pipe_state_add_reg_bo(rstate,
-				R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C,
-				color_attrib,
-				&rtex->resource, RADEON_USAGE_READWRITE);
+	surf->cb_color_attrib = color_attrib;
+
+	surf->color_initialized = true;
 }
 
 static void evergreen_init_depth_surface(struct r600_context *rctx,
@@ -1550,16 +1506,58 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
 	/* build states */
 	rctx->export_16bpc = true;
 	rctx->nr_cbufs = state->nr_cbufs;
+
 	for (i = 0; i < state->nr_cbufs; i++) {
-		evergreen_cb(rctx, rstate, state, i);
-	}
-	/* CB_COLOR1_INFO is already initialized for possible dual-src blending */
-	if (i == 1)
+		surf = (struct r600_surface*)state->cbufs[i];
+		res = (struct r600_resource*)surf->base.texture;
+
+		if (!surf->color_initialized) {
+			evergreen_init_color_surface(rctx, surf);
+		}
+
+		if (!surf->export_16bpc) {
+			rctx->export_16bpc = false;
+		}
+
+		r600_pipe_state_add_reg_bo(rstate, R_028C60_CB_COLOR0_BASE + i * 0x3C,
+					   surf->cb_color_base, res, RADEON_USAGE_READWRITE);
+		r600_pipe_state_add_reg(rstate, R_028C78_CB_COLOR0_DIM + i * 0x3C,
+					surf->cb_color_dim);
+		r600_pipe_state_add_reg_bo(rstate, R_028C70_CB_COLOR0_INFO + i * 0x3C,
+					   surf->cb_color_info, res, RADEON_USAGE_READWRITE);
+		r600_pipe_state_add_reg(rstate, R_028C64_CB_COLOR0_PITCH + i * 0x3C,
+					surf->cb_color_pitch);
+		r600_pipe_state_add_reg(rstate, R_028C68_CB_COLOR0_SLICE + i * 0x3C,
+					surf->cb_color_slice);
+		r600_pipe_state_add_reg(rstate, R_028C6C_CB_COLOR0_VIEW + i * 0x3C,
+					surf->cb_color_view);
+		r600_pipe_state_add_reg_bo(rstate, R_028C74_CB_COLOR0_ATTRIB + i * 0x3C,
+					   surf->cb_color_attrib, res, RADEON_USAGE_READWRITE);
+	}
+	/* set CB_COLOR1_INFO for possible dual-src blending */
+	if (i == 1 && !((struct r600_resource_texture*)res)->is_rat) {
+		r600_pipe_state_add_reg_bo(rstate, R_028C70_CB_COLOR0_INFO + 1 * 0x3C,
+					   surf->cb_color_info, res, RADEON_USAGE_READWRITE);
 		i++;
+	}
 	for (; i < 8 ; i++) {
 		r600_pipe_state_add_reg(rstate, R_028C70_CB_COLOR0_INFO + i * 0x3C, 0);
 	}
 
+	/* Update alpha-test state dependencies.
+	 * Alpha-test is done on the first colorbuffer only. */
+	if (state->nr_cbufs) {
+		surf = (struct r600_surface*)state->cbufs[0];
+		if (rctx->alphatest_state.bypass != surf->alphatest_bypass) {
+			rctx->alphatest_state.bypass = surf->alphatest_bypass;
+			r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
+		}
+		if (rctx->alphatest_state.cb0_export_16bpc != surf->export_16bpc) {
+			rctx->alphatest_state.cb0_export_16bpc = surf->export_16bpc;
+			r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
+		}
+	}
+
 	if (state->zsbuf) {
 		surf = (struct r600_surface*)state->zsbuf;
 		res = (struct r600_resource*)surf->base.texture;
@@ -1606,6 +1604,11 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
 		rctx->cb_misc_state.nr_cbufs = state->nr_cbufs;
 		r600_atom_dirty(rctx, &rctx->cb_misc_state.atom);
 	}
+
+	if (state->nr_cbufs == 0 && rctx->alphatest_state.bypass) {
+		rctx->alphatest_state.bypass = false;
+		r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
+	}
 }
 
 static void evergreen_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom *atom)
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 09a7f34..f41fa8f 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -453,10 +453,8 @@ boolean evergreen_is_format_supported(struct pipe_screen *screen,
 				      enum pipe_texture_target target,
 				      unsigned sample_count,
 				      unsigned usage);
-void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
-                         const struct pipe_framebuffer_state *state, int cb);
-
-
+void evergreen_init_color_surface(struct r600_context *rctx,
+				  struct r600_surface *surf);
 void evergreen_update_dual_export_state(struct r600_context * rctx);
 
 /* r600_blit.c */
diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h
index d56fe4a..0eaf10a 100644
--- a/src/gallium/drivers/r600/r600_resource.h
+++ b/src/gallium/drivers/r600/r600_resource.h
@@ -70,8 +70,25 @@ struct r600_resource_texture {
 struct r600_surface {
 	struct pipe_surface		base;
 
+	bool color_initialized;
 	bool depth_initialized;
 
+	/* Misc. color flags. */
+	bool alphatest_bypass;
+	bool export_16bpc;
+
+	/* Color registers. */
+	unsigned cb_color_info;
+	unsigned cb_color_base;
+	unsigned cb_color_view;
+	unsigned cb_color_size;		/* R600 only */
+	unsigned cb_color_frag;		/* R600 only */
+	unsigned cb_color_tile;		/* R600 only */
+	unsigned cb_color_dim;		/* EG only */
+	unsigned cb_color_pitch;	/* EG only */
+	unsigned cb_color_slice;	/* EG only */
+	unsigned cb_color_attrib;	/* EG only */
+
 	/* DB registers. */
 	unsigned db_depth_info;		/* DB_Z_INFO (EG) or DB_DEPTH_INFO (r600) */
 	unsigned db_depth_base;		/* DB_Z_READ/WRITE_BASE (EG) or DB_DEPTH_BASE (r600) */
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 6a6ac05..842808a 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -1281,31 +1281,29 @@ static void r600_set_viewport_state(struct pipe_context *ctx,
 	r600_context_pipe_state_set(rctx, rstate);
 }
 
-static void r600_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
-			const struct pipe_framebuffer_state *state, int cb)
+static void r600_init_color_surface(struct r600_context *rctx,
+				    struct r600_surface *surf)
 {
-	struct r600_resource_texture *rtex;
-	struct r600_surface *surf;
-	unsigned level = state->cbufs[cb]->u.tex.level;
+	struct r600_resource_texture *rtex = (struct r600_resource_texture*)surf->base.texture;
+	unsigned level = surf->base.u.tex.level;
 	unsigned pitch, slice;
 	unsigned color_info;
 	unsigned format, swap, ntype, endian;
 	unsigned offset;
 	const struct util_format_description *desc;
 	int i;
-	bool blend_bypass = 0, blend_clamp = 1, alphatest_bypass;
-
-	surf = (struct r600_surface *)state->cbufs[cb];
-	rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture;
+	bool blend_bypass = 0, blend_clamp = 1;
 
 	if (rtex->is_depth && !rtex->is_flushing_texture) {
+		r600_init_flushed_depth_texture(&rctx->context, surf->base.texture, NULL);
 		rtex = rtex->flushed_depth_texture;
+		assert(rtex);
 	}
 
 	offset = rtex->surface.level[level].offset;
 	if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
 		offset += rtex->surface.level[level].slice_size *
-			  state->cbufs[cb]->u.tex.first_layer;
+			  surf->base.u.tex.first_layer;
 	}
 	pitch = rtex->surface.level[level].nblk_x / 8 - 1;
 	slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
@@ -1373,14 +1371,7 @@ static void r600_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
 		blend_bypass = 1;
 	}
 
-	/* Alpha-test is done on the first colorbuffer only. */
-	if (cb == 0) {
-		alphatest_bypass = ntype == V_0280A0_NUMBER_UINT || ntype == V_0280A0_NUMBER_SINT;
-		if (rctx->alphatest_state.bypass != alphatest_bypass) {
-			rctx->alphatest_state.bypass = alphatest_bypass;
-			r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
-		}
-	}
+	surf->alphatest_bypass = ntype == V_0280A0_NUMBER_UINT || ntype == V_0280A0_NUMBER_SINT;
 
 	color_info |= S_0280A0_FORMAT(format) |
 		S_0280A0_COMP_SWAP(swap) |
@@ -1406,8 +1397,7 @@ static void r600_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
 		    G_0280A0_BLEND_CLAMP(color_info) &&
 		    !G_0280A0_BLEND_FLOAT32(color_info)) {
 			color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM);
-		} else {
-			rctx->export_16bpc = false;
+			surf->export_16bpc = true;
 		}
 	} else {
 		/* EXPORT_NORM can be enabled if:
@@ -1421,44 +1411,22 @@ static void r600_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
 		    (desc->channel[i].size < 17 &&
 		     desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) {
 			color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM);
-		} else {
-			rctx->export_16bpc = false;
+			surf->export_16bpc = true;
 		}
 	}
 
-	/* for possible dual-src MRT write color info 1 */
-	if (cb == 0 && rctx->framebuffer.nr_cbufs == 1) {
-		r600_pipe_state_add_reg_bo(rstate,
-				R_0280A0_CB_COLOR0_INFO + 1 * 4,
-				color_info, &rtex->resource, RADEON_USAGE_READWRITE);
-	}
-
-	r600_pipe_state_add_reg_bo(rstate,
-				R_028040_CB_COLOR0_BASE + cb * 4,
-				offset >> 8, &rtex->resource, RADEON_USAGE_READWRITE);
-	r600_pipe_state_add_reg_bo(rstate,
-				R_0280A0_CB_COLOR0_INFO + cb * 4,
-				color_info, &rtex->resource, RADEON_USAGE_READWRITE);
-	r600_pipe_state_add_reg(rstate,
-				R_028060_CB_COLOR0_SIZE + cb * 4,
-				S_028060_PITCH_TILE_MAX(pitch) |
-				S_028060_SLICE_TILE_MAX(slice));
+	surf->cb_color_base = offset >> 8;
+	surf->cb_color_info = color_info;
+	surf->cb_color_size = S_028060_PITCH_TILE_MAX(pitch) |
+			      S_028060_SLICE_TILE_MAX(slice);
 	if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
-		r600_pipe_state_add_reg(rstate,
-					R_028080_CB_COLOR0_VIEW + cb * 4,
-					0x00000000);
+		surf->cb_color_view = 0;
 	} else {
-		r600_pipe_state_add_reg(rstate,
-					R_028080_CB_COLOR0_VIEW + cb * 4,
-					S_028080_SLICE_START(state->cbufs[cb]->u.tex.first_layer) |
-					S_028080_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer));
+		surf->cb_color_view = S_028080_SLICE_START(surf->base.u.tex.first_layer) |
+				      S_028080_SLICE_MAX(surf->base.u.tex.last_layer);
 	}
-	r600_pipe_state_add_reg_bo(rstate,
-				   R_0280E0_CB_COLOR0_FRAG + cb * 4,
-				   0, &rtex->resource, RADEON_USAGE_READWRITE);
-	r600_pipe_state_add_reg_bo(rstate,
-				   R_0280C0_CB_COLOR0_TILE + cb * 4,
-				   0, &rtex->resource, RADEON_USAGE_READWRITE);
+
+	surf->color_initialized = true;
 }
 
 static void r600_init_depth_surface(struct r600_context *rctx,
@@ -1506,7 +1474,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
 	struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
 	struct r600_surface *surf;
 	struct r600_resource *res;
-	uint32_t tl, br;
+	uint32_t tl, br, i;
 
 	if (rstate == NULL)
 		return;
@@ -1522,9 +1490,48 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
 	rctx->export_16bpc = true;
 	rctx->nr_cbufs = state->nr_cbufs;
 
-	for (int i = 0; i < state->nr_cbufs; i++) {
-		r600_cb(rctx, rstate, state, i);
+	for (i = 0; i < state->nr_cbufs; i++) {
+		surf = (struct r600_surface*)state->cbufs[i];
+		res = (struct r600_resource*)surf->base.texture;
+
+		if (!surf->color_initialized) {
+			r600_init_color_surface(rctx, surf);
+		}
+
+		if (!surf->export_16bpc) {
+			rctx->export_16bpc = false;
+		}
+
+		r600_pipe_state_add_reg_bo(rstate, R_028040_CB_COLOR0_BASE + i * 4,
+					   surf->cb_color_base, res, RADEON_USAGE_READWRITE);
+		r600_pipe_state_add_reg_bo(rstate, R_0280A0_CB_COLOR0_INFO + i * 4,
+					   surf->cb_color_info, res, RADEON_USAGE_READWRITE);
+		r600_pipe_state_add_reg(rstate, R_028060_CB_COLOR0_SIZE + i * 4,
+					surf->cb_color_size);
+		r600_pipe_state_add_reg(rstate, R_028080_CB_COLOR0_VIEW + i * 4,
+					surf->cb_color_view);
+		r600_pipe_state_add_reg_bo(rstate, R_0280E0_CB_COLOR0_FRAG + i * 4,
+					   surf->cb_color_frag, res, RADEON_USAGE_READWRITE);
+		r600_pipe_state_add_reg_bo(rstate, R_0280C0_CB_COLOR0_TILE + i * 4,
+					   surf->cb_color_tile, res, RADEON_USAGE_READWRITE);
+	}
+	/* set CB_COLOR1_INFO for possible dual-src blending */
+	if (i == 1) {
+		r600_pipe_state_add_reg_bo(rstate, R_0280A0_CB_COLOR0_INFO + 1 * 4,
+					   surf->cb_color_info, res, RADEON_USAGE_READWRITE);
+		i++;
+	}
+
+	/* Update alpha-test state dependencies.
+	 * Alpha-test is done on the first colorbuffer only. */
+	if (state->nr_cbufs) {
+		surf = (struct r600_surface*)state->cbufs[0];
+		if (rctx->alphatest_state.bypass != surf->alphatest_bypass) {
+			rctx->alphatest_state.bypass = surf->alphatest_bypass;
+			r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
+		}
 	}
+
 	if (state->zsbuf) {
 		surf = (struct r600_surface*)state->zsbuf;
 		res = (struct r600_resource*)surf->base.texture;
-- 
1.7.9.5



More information about the mesa-dev mailing list