r600g: always use a tiled resource as the destination of MSAA resolve
authorMarek Olšák <maraeo@gmail.com>
Fri, 21 Dec 2012 19:34:52 +0000 (20:34 +0100)
committerMarek Olšák <maraeo@gmail.com>
Fri, 21 Dec 2012 22:43:34 +0000 (23:43 +0100)
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
src/gallium/drivers/r600/r600_resource.h
src/gallium/drivers/r600/r600_texture.c

index 6ef1d78c6fef89a0cb57c69086ca1cd4cb76cbeb..87b90ac444ea5cdccb696de40d7f9cbd302870c1 100644 (file)
@@ -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);
 
index dd0b613485c086f4bb3bf4e141d8530ee923add8..25d0be4cac94d20324ad5abea149470cffb8de5b 100644 (file)
@@ -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;
index f5ce7c113ab1d4cac357ea7b21563bac99f567ec..e0d848678d2d4ec58094e18fe96d1ea7621a10f7 100644 (file)
@@ -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;