summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2012-12-21 20:34:52 +0100
committerMarek Olšák <maraeo@gmail.com>2012-12-22 02:31:31 +0100
commit0ac90296a092f846647812318913b0e492775f31 (patch)
tree395446aa8f9ed31f0390b1df6d48c5583b7cca3f
parent42f71b4861b9d01a8f925fea3182fc1a292222f3 (diff)
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
-rw-r--r--src/gallium/drivers/r600/r600_blit.c9
-rw-r--r--src/gallium/drivers/r600/r600_resource.h1
-rw-r--r--src/gallium/drivers/r600/r600_texture.c4
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 072df143f13..76c8e6bed91 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -384,24 +384,29 @@ static void r600_copy_first_sample(struct pipe_context *ctx,
}
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 &&
dst_height == info->src.res->height0 &&
info->dst.x0 == 0 &&
info->dst.y0 == 0 &&
info->dst.x1 == dst_width &&
info->dst.y1 == dst_height &&
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,
const struct pipe_resolve_info *info)
{
struct r600_context *rctx = (struct r600_context *)ctx;
@@ -431,13 +436,13 @@ static void r600_color_resolve(struct pipe_context *ctx,
templ.depth0 = 1;
templ.array_size = 1;
templ.last_level = 0;
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);
/* XXX use scissor, so that only the needed part of the resource is resolved */
r600_blitter_begin(ctx, R600_COLOR_RESOLVE);
util_blitter_custom_resolve_color(rctx->blitter,
diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h
index a5a540439e6..c935698c228 100644
--- a/src/gallium/drivers/r600/r600_resource.h
+++ b/src/gallium/drivers/r600/r600_resource.h
@@ -25,12 +25,13 @@
#include "r600.h"
/* 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;
struct r600_resource *staging;
unsigned offset;
};
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 1c52ff8c83b..b2886de68d8 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -451,13 +451,15 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
struct r600_screen *rscreen = (struct r600_screen*)screen;
struct radeon_surface surface;
unsigned array_mode = 0;
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;
} else if (util_format_is_compressed(templ->format)) {
array_mode = V_038000_ARRAY_1D_TILED_THIN1;
}