Mesa (master): r600g: always use a tiled resource as the destination of MSAA resolve

Marek Olšák mareko at kemper.freedesktop.org
Fri Dec 21 22:46:55 UTC 2012


Module: Mesa
Branch: master
Commit: 9c6410e5c3ffc74564fae5afcc1b6982759cdd01
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9c6410e5c3ffc74564fae5afcc1b6982759cdd01

Author: Marek Olšák <maraeo at gmail.com>
Date:   Fri Dec 21 20:34:52 2012 +0100

r600g: always use a tiled resource as the destination of MSAA resolve

i.e. we have to allocate a temporary tiled resource if dst isn't tiled.

This fixes hardlocks on r6xx-r7xx, though using a linear resource is forbidden
on later asics as well.

NOTE: This is a candidate for the stable branches.

---

 src/gallium/drivers/r600/r600_blit.c     |    9 +++++++--
 src/gallium/drivers/r600/r600_resource.h |    1 +
 src/gallium/drivers/r600/r600_texture.c  |   14 ++++++++------
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index 6ef1d78..87b90ac 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -408,6 +408,8 @@ static boolean is_simple_msaa_resolve(const struct pipe_blit_info *info)
 {
 	unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level);
 	unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level);
+	struct r600_texture *dst = (struct r600_texture*)info->dst.resource;
+	unsigned dst_tile_mode = dst->surface.level[info->dst.level].mode;
 
 	return info->dst.resource->format == info->src.resource->format &&
 		info->dst.resource->format == info->dst.format &&
@@ -423,7 +425,10 @@ static boolean is_simple_msaa_resolve(const struct pipe_blit_info *info)
 		info->src.box.x == 0 &&
 		info->src.box.y == 0 &&
 		info->src.box.width == dst_width &&
-		info->src.box.height == dst_height;
+		info->src.box.height == dst_height &&
+		/* Dst must be tiled. If it's not, we have to use a temporary
+		 * resource which is tiled. */
+		dst_tile_mode >= RADEON_SURF_MODE_1D;
 }
 
 static void r600_clear(struct pipe_context *ctx, unsigned buffers,
@@ -729,7 +734,7 @@ static void r600_msaa_color_resolve(struct pipe_context *ctx,
 	templ.nr_samples = 0;
 	templ.usage = PIPE_USAGE_STATIC;
 	templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
-	templ.flags = 0;
+	templ.flags = R600_RESOURCE_FLAG_FORCE_TILING; /* dst must not have a linear layout */
 
 	tmp = screen->resource_create(screen, &templ);
 
diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h
index dd0b613..25d0be4 100644
--- a/src/gallium/drivers/r600/r600_resource.h
+++ b/src/gallium/drivers/r600/r600_resource.h
@@ -28,6 +28,7 @@
 /* flag to indicate a resource is to be used as a transfer so should not be tiled */
 #define R600_RESOURCE_FLAG_TRANSFER		PIPE_RESOURCE_FLAG_DRV_PRIV
 #define R600_RESOURCE_FLAG_FLUSHED_DEPTH	(PIPE_RESOURCE_FLAG_DRV_PRIV << 1)
+#define R600_RESOURCE_FLAG_FORCE_TILING		(PIPE_RESOURCE_FLAG_DRV_PRIV << 2)
 
 struct r600_transfer {
 	struct pipe_transfer		transfer;
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index f5ce7c1..e0d8486 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -563,12 +563,14 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
 	 * for fast uploads anyway. */
 	if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
 	    desc->layout != UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
-		if (!(templ->bind & PIPE_BIND_SCANOUT) &&
-		    templ->usage != PIPE_USAGE_STAGING &&
-		    templ->usage != PIPE_USAGE_STREAM &&
-		    templ->target != PIPE_TEXTURE_1D &&
-		    templ->target != PIPE_TEXTURE_1D_ARRAY &&
-		    templ->height0 > 3) {
+		if (templ->flags & R600_RESOURCE_FLAG_FORCE_TILING) {
+			array_mode = V_038000_ARRAY_2D_TILED_THIN1;
+		} else if (!(templ->bind & PIPE_BIND_SCANOUT) &&
+			   templ->usage != PIPE_USAGE_STAGING &&
+			   templ->usage != PIPE_USAGE_STREAM &&
+			   templ->target != PIPE_TEXTURE_1D &&
+			   templ->target != PIPE_TEXTURE_1D_ARRAY &&
+			   templ->height0 > 3) {
 			array_mode = V_038000_ARRAY_2D_TILED_THIN1;
 		} else if (util_format_is_compressed(templ->format)) {
 			array_mode = V_038000_ARRAY_1D_TILED_THIN1;




More information about the mesa-commit mailing list