[Mesa-dev] [PATCH 5/7] r600g: move fast color clear code to a common place

Marek Olšák maraeo at gmail.com
Fri Mar 7 10:54:19 PST 2014


From: Marek Olšák <marek.olsak at amd.com>

---
 src/gallium/drivers/r600/r600_blit.c          | 82 +-------------------------
 src/gallium/drivers/radeon/r600_pipe_common.h |  7 ++-
 src/gallium/drivers/radeon/r600_texture.c     | 83 ++++++++++++++++++++++++++-
 3 files changed, 88 insertions(+), 84 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index e0f3373..98c07b5 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -386,85 +386,6 @@ static bool r600_decompress_subresource(struct pipe_context *ctx,
 	return true;
 }
 
-static void r600_clear_buffer(struct pipe_context *ctx, struct pipe_resource *dst,
-			      unsigned offset, unsigned size, unsigned value);
-
-static void evergreen_set_clear_color(struct pipe_surface *cbuf,
-				      const union pipe_color_union *color)
-{
-	unsigned *clear_value = ((struct r600_texture *)cbuf->texture)->color_clear_value;
-	union util_color uc;
-
-	memset(&uc, 0, sizeof(uc));
-
-	if (util_format_is_pure_uint(cbuf->format)) {
-		util_format_write_4ui(cbuf->format, color->ui, 0, &uc, 0, 0, 0, 1, 1);
-	} else if (util_format_is_pure_sint(cbuf->format)) {
-		util_format_write_4i(cbuf->format, color->i, 0, &uc, 0, 0, 0, 1, 1);
-	} else {
-		util_pack_color(color->f, cbuf->format, &uc);
-	}
-
-	memcpy(clear_value, &uc, 2 * sizeof(uint32_t));
-}
-
-static void r600_try_fast_color_clear(struct r600_context *rctx, unsigned *buffers,
-				      const union pipe_color_union *color)
-{
-	struct pipe_framebuffer_state *fb = &rctx->framebuffer.state;
-	int i;
-
-	for (i = 0; i < fb->nr_cbufs; i++) {
-		struct r600_texture *tex;
-		unsigned clear_bit = PIPE_CLEAR_COLOR0 << i;
-
-		if (!fb->cbufs[i])
-			continue;
-
-		/* if this colorbuffer is not being cleared */
-		if (!(*buffers & clear_bit))
-			continue;
-
-		tex = (struct r600_texture *)fb->cbufs[i]->texture;
-
-		/* 128-bit formats are unusupported */
-		if (util_format_get_blocksizebits(fb->cbufs[i]->format) > 64) {
-			continue;
-		}
-
-		/* the clear is allowed if all layers are bound */
-		if (fb->cbufs[i]->u.tex.first_layer != 0 ||
-		    fb->cbufs[i]->u.tex.last_layer != util_max_layer(&tex->resource.b.b, 0)) {
-			continue;
-		}
-
-		/* cannot clear mipmapped textures */
-		if (fb->cbufs[i]->texture->last_level != 0) {
-			continue;
-		}
-
-		/* only supported on tiled surfaces */
-		if (tex->surface.level[0].mode < RADEON_SURF_MODE_1D) {
-			continue;
-		}
-
-		/* ensure CMASK is enabled */
-		r600_texture_alloc_cmask_separate(&rctx->screen->b, tex);
-		if (tex->cmask.size == 0) {
-			continue;
-		}
-
-		/* Do the fast clear. */
-		evergreen_set_clear_color(fb->cbufs[i], color);
-		r600_clear_buffer(&rctx->b.b, &tex->cmask_buffer->b.b,
-				  tex->cmask.offset, tex->cmask.size, 0);
-
-		tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
-		rctx->framebuffer.atom.dirty = true;
-		*buffers &= ~clear_bit;
-	}
-}
-
 static void r600_clear(struct pipe_context *ctx, unsigned buffers,
 		       const union pipe_color_union *color,
 		       double depth, unsigned stencil)
@@ -473,7 +394,8 @@ static void r600_clear(struct pipe_context *ctx, unsigned buffers,
 	struct pipe_framebuffer_state *fb = &rctx->framebuffer.state;
 
 	if (buffers & PIPE_CLEAR_COLOR && rctx->b.chip_class >= EVERGREEN) {
-		r600_try_fast_color_clear(rctx, &buffers, color);
+		evergreen_do_fast_color_clear(&rctx->b, fb, &rctx->framebuffer.atom,
+					      &buffers, color);
 	}
 
 	if (buffers & PIPE_CLEAR_COLOR) {
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index 35a769b..42b424d 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -414,8 +414,6 @@ void r600_texture_get_fmask_info(struct r600_common_screen *rscreen,
 void r600_texture_get_cmask_info(struct r600_common_screen *rscreen,
 				 struct r600_texture *rtex,
 				 struct r600_cmask_info *out);
-void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen,
-				       struct r600_texture *rtex);
 bool r600_init_flushed_depth_texture(struct pipe_context *ctx,
 				     struct pipe_resource *texture,
 				     struct r600_texture **staging);
@@ -426,6 +424,11 @@ struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe,
 						const struct pipe_surface *templ,
 						unsigned width, unsigned height);
 unsigned r600_translate_colorswap(enum pipe_format format);
+void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
+				   struct pipe_framebuffer_state *fb,
+				   struct r600_atom *fb_state,
+				   unsigned *buffers,
+				   const union pipe_color_union *color);
 void r600_init_screen_texture_functions(struct r600_common_screen *rscreen);
 void r600_init_context_texture_functions(struct r600_common_context *rctx);
 
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index e21ebb2..837e97e 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -28,6 +28,7 @@
 #include "r600_cs.h"
 #include "util/u_format.h"
 #include "util/u_memory.h"
+#include "util/u_pack_color.h"
 #include <errno.h>
 #include <inttypes.h>
 
@@ -449,8 +450,8 @@ static void r600_texture_allocate_cmask(struct r600_common_screen *rscreen,
 		rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
 }
 
-void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen,
-				       struct r600_texture *rtex)
+static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen,
+					      struct r600_texture *rtex)
 {
 	if (rtex->cmask_buffer)
                 return;
@@ -1197,6 +1198,84 @@ unsigned r600_translate_colorswap(enum pipe_format format)
 	return ~0U;
 }
 
+static void evergreen_set_clear_color(struct r600_texture *rtex,
+				      enum pipe_format surface_format,
+				      const union pipe_color_union *color)
+{
+	union util_color uc;
+
+	memset(&uc, 0, sizeof(uc));
+
+	if (util_format_is_pure_uint(surface_format)) {
+		util_format_write_4ui(surface_format, color->ui, 0, &uc, 0, 0, 0, 1, 1);
+	} else if (util_format_is_pure_sint(surface_format)) {
+		util_format_write_4i(surface_format, color->i, 0, &uc, 0, 0, 0, 1, 1);
+	} else {
+		util_pack_color(color->f, surface_format, &uc);
+	}
+
+	memcpy(rtex->color_clear_value, &uc, 2 * sizeof(uint32_t));
+}
+
+void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
+				   struct pipe_framebuffer_state *fb,
+				   struct r600_atom *fb_state,
+				   unsigned *buffers,
+				   const union pipe_color_union *color)
+{
+	int i;
+
+	for (i = 0; i < fb->nr_cbufs; i++) {
+		struct r600_texture *tex;
+		unsigned clear_bit = PIPE_CLEAR_COLOR0 << i;
+
+		if (!fb->cbufs[i])
+			continue;
+
+		/* if this colorbuffer is not being cleared */
+		if (!(*buffers & clear_bit))
+			continue;
+
+		tex = (struct r600_texture *)fb->cbufs[i]->texture;
+
+		/* 128-bit formats are unusupported */
+		if (util_format_get_blocksizebits(fb->cbufs[i]->format) > 64) {
+			continue;
+		}
+
+		/* the clear is allowed if all layers are bound */
+		if (fb->cbufs[i]->u.tex.first_layer != 0 ||
+		    fb->cbufs[i]->u.tex.last_layer != util_max_layer(&tex->resource.b.b, 0)) {
+			continue;
+		}
+
+		/* cannot clear mipmapped textures */
+		if (fb->cbufs[i]->texture->last_level != 0) {
+			continue;
+		}
+
+		/* only supported on tiled surfaces */
+		if (tex->surface.level[0].mode < RADEON_SURF_MODE_1D) {
+			continue;
+		}
+
+		/* ensure CMASK is enabled */
+		r600_texture_alloc_cmask_separate(rctx->screen, tex);
+		if (tex->cmask.size == 0) {
+			continue;
+		}
+
+		/* Do the fast clear. */
+		evergreen_set_clear_color(tex, fb->cbufs[i]->format, color);
+		rctx->clear_buffer(&rctx->b, &tex->cmask_buffer->b.b,
+				   tex->cmask.offset, tex->cmask.size, 0);
+
+		tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
+		fb_state->dirty = true;
+		*buffers &= ~clear_bit;
+	}
+}
+
 void r600_init_screen_texture_functions(struct r600_common_screen *rscreen)
 {
 	rscreen->b.resource_from_handle = r600_texture_from_handle;
-- 
1.8.3.2



More information about the mesa-dev mailing list