+ switch (format) {
+#define REPLACE_FORMAT_SIGN(format,sign) \
+ case PIPE_FORMAT_##format##_##sign##INT: \
+ return PIPE_FORMAT_##format##_##sign##NORM
+#define REPLACE_FORMAT(format) \
+ REPLACE_FORMAT_SIGN(format, U); \
+ REPLACE_FORMAT_SIGN(format, S)
+
+ REPLACE_FORMAT_SIGN(B10G10R10A2, U);
+ REPLACE_FORMAT(R8);
+ REPLACE_FORMAT(R8G8);
+ REPLACE_FORMAT(R8G8B8X8);
+ REPLACE_FORMAT(R8G8B8A8);
+ REPLACE_FORMAT(A8);
+ REPLACE_FORMAT(I8);
+ REPLACE_FORMAT(L8);
+ REPLACE_FORMAT(L8A8);
+ REPLACE_FORMAT(R16);
+ REPLACE_FORMAT(R16G16);
+ REPLACE_FORMAT(R16G16B16X16);
+ REPLACE_FORMAT(R16G16B16A16);
+ REPLACE_FORMAT(A16);
+ REPLACE_FORMAT(I16);
+ REPLACE_FORMAT(L16);
+ REPLACE_FORMAT(L16A16);
+
+#undef REPLACE_FORMAT
+#undef REPLACE_FORMAT_SIGN
+ default:
+ return format;
+ }
+}
+
+static void r600_msaa_color_resolve(struct pipe_context *ctx,
+ const struct pipe_blit_info *info)
+{
+ struct r600_context *rctx = (struct r600_context *)ctx;
+ struct pipe_screen *screen = ctx->screen;
+ struct pipe_resource *tmp, templ;
+ struct pipe_blit_info blit;
+ unsigned sample_mask =
+ rctx->b.chip_class == CAYMAN ? ~0 :
+ ((1ull << MAX2(1, info->src.resource->nr_samples)) - 1);
+
+ assert(info->src.level == 0);
+ assert(info->src.box.depth == 1);
+ assert(info->dst.box.depth == 1);
+
+ if (is_simple_msaa_resolve(info)) {
+ r600_blitter_begin(ctx, R600_COLOR_RESOLVE);
+ util_blitter_custom_resolve_color(rctx->blitter,
+ info->dst.resource, info->dst.level,
+ info->dst.box.z,
+ info->src.resource, info->src.box.z,
+ sample_mask, rctx->custom_blend_resolve,
+ int_to_norm_format(info->dst.format));
+ r600_blitter_end(ctx);
+ return;
+ }
+
+ /* resolve into a temporary texture, then blit */
+ templ.target = PIPE_TEXTURE_2D;
+ templ.format = info->src.resource->format;
+ templ.width0 = info->src.resource->width0;
+ templ.height0 = info->src.resource->height0;
+ 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 = R600_RESOURCE_FLAG_FORCE_TILING; /* dst must not have a linear layout */
+
+ tmp = screen->resource_create(screen, &templ);
+
+ /* resolve */
+ r600_blitter_begin(ctx, R600_COLOR_RESOLVE);
+ util_blitter_custom_resolve_color(rctx->blitter,
+ tmp, 0, 0,
+ info->src.resource, info->src.box.z,
+ sample_mask, rctx->custom_blend_resolve,
+ int_to_norm_format(tmp->format));
+ r600_blitter_end(ctx);
+
+ /* blit */
+ blit = *info;
+ blit.src.resource = tmp;
+ blit.src.box.z = 0;
+
+ r600_blitter_begin(ctx, R600_BLIT);
+ util_blitter_blit(rctx->blitter, &blit);
+ r600_blitter_end(ctx);
+
+ pipe_resource_reference(&tmp, NULL);
+}
+
+static void r600_blit(struct pipe_context *ctx,
+ const struct pipe_blit_info *info)
+{
+ struct r600_context *rctx = (struct r600_context*)ctx;
+
+ assert(util_blitter_is_blit_supported(rctx->blitter, info));
+
+ if (info->src.resource->nr_samples > 1 &&
+ info->dst.resource->nr_samples <= 1 &&
+ !util_format_is_depth_or_stencil(info->src.resource->format) &&
+ !util_format_is_pure_integer(int_to_norm_format(info->src.resource->format))) {
+ r600_msaa_color_resolve(ctx, info);
+ return;
+ }
+
+ /* The driver doesn't decompress resources automatically while
+ * u_blitter is rendering. */
+ if (!r600_decompress_subresource(ctx, info->src.resource, info->src.level,
+ info->src.box.z,
+ info->src.box.z + info->src.box.depth - 1)) {
+ return; /* error */
+ }
+
+ r600_blitter_begin(ctx, R600_BLIT);
+ util_blitter_blit(rctx->blitter, info);
+ r600_blitter_end(ctx);