From 0ac90296a092f846647812318913b0e492775f31 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 21 Dec 2012 20:34:52 +0100 Subject: [PATCH] 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. (cherry picked from commit 9c6410e5c3ffc74564fae5afcc1b6982759cdd01) Conflicts: src/gallium/drivers/r600/r600_blit.c src/gallium/drivers/r600/r600_texture.c --- src/gallium/drivers/r600/r600_blit.c | 9 +++++++-- src/gallium/drivers/r600/r600_resource.h | 1 + src/gallium/drivers/r600/r600_texture.c | 4 +++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 072df14..76c8e6b 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -387,6 +387,8 @@ static boolean is_simple_resolve(const struct pipe_resolve_info *info) { unsigned dst_width = u_minify(info->dst.res->width0, info->dst.level); unsigned dst_height = u_minify(info->dst.res->height0, info->dst.level); + struct r600_texture *dst = (struct r600_texture*)info->dst.res; + unsigned dst_tile_mode = dst->surface.level[info->dst.level].mode; return info->dst.res->format == info->src.res->format && dst_width == info->src.res->width0 && @@ -398,7 +400,10 @@ static boolean is_simple_resolve(const struct pipe_resolve_info *info) info->src.x0 == 0 && info->src.y0 == 0 && info->src.x1 == dst_width && - info->src.y1 == dst_height; + info->src.y1 == 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_color_resolve(struct pipe_context *ctx, @@ -434,7 +439,7 @@ static void r600_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 a5a5404..c935698 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 1c52ff8..b2886de 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -454,7 +454,9 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, int r; if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER)) { - if (!(templ->bind & PIPE_BIND_SCANOUT) && + 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) { array_mode = V_038000_ARRAY_2D_TILED_THIN1; -- 2.7.4