+ src_box = &sbox;
+ } else if (!util_blitter_is_copy_supported(rctx->blitter, dst, src,
+ PIPE_MASK_RGBAZS)) {
+ if (util_format_is_subsampled_2x1_32bpp(src->format)) {
+
+ src_templ.format = PIPE_FORMAT_R8G8B8A8_UINT;
+ dst_templ.format = PIPE_FORMAT_R8G8B8A8_UINT;
+
+ dst_width = util_format_get_nblocksx(dst->format, dst_width);
+ src_width0 = util_format_get_nblocksx(src->format, src_width0);
+ src_widthFL = util_format_get_nblocksx(src->format, src_widthFL);
+
+ dstx = util_format_get_nblocksx(dst->format, dstx);
+
+ sbox = *src_box;
+ sbox.x = util_format_get_nblocksx(src->format, src_box->x);
+ sbox.width = util_format_get_nblocksx(src->format, src_box->width);
+ src_box = &sbox;
+ } else {
+ unsigned blocksize = util_format_get_blocksize(src->format);
+
+ switch (blocksize) {
+ case 1:
+ dst_templ.format = PIPE_FORMAT_R8_UNORM;
+ src_templ.format = PIPE_FORMAT_R8_UNORM;
+ break;
+ case 2:
+ dst_templ.format = PIPE_FORMAT_R8G8_UNORM;
+ src_templ.format = PIPE_FORMAT_R8G8_UNORM;
+ break;
+ case 4:
+ dst_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM;
+ src_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM;
+ break;
+ case 8:
+ dst_templ.format = PIPE_FORMAT_R16G16B16A16_UINT;
+ src_templ.format = PIPE_FORMAT_R16G16B16A16_UINT;
+ break;
+ case 16:
+ dst_templ.format = PIPE_FORMAT_R32G32B32A32_UINT;
+ src_templ.format = PIPE_FORMAT_R32G32B32A32_UINT;
+ break;
+ default:
+ fprintf(stderr, "Unhandled format %s with blocksize %u\n",
+ util_format_short_name(src->format), blocksize);
+ assert(0);
+ }
+ }
+ }
+
+ dst_view = r600_create_surface_custom(ctx, dst, &dst_templ, dst_width, dst_height);
+
+ if (rctx->b.chip_class >= EVERGREEN) {
+ src_view = evergreen_create_sampler_view_custom(ctx, src, &src_templ,
+ src_width0, src_height0);
+ } else {
+ src_view = r600_create_sampler_view_custom(ctx, src, &src_templ,
+ src_widthFL, src_heightFL);
+ }
+
+ u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height),
+ abs(src_box->depth), &dstbox);
+
+ /* Copy. */
+ r600_blitter_begin(ctx, R600_COPY_TEXTURE);
+ util_blitter_blit_generic(rctx->blitter, dst_view, &dstbox,
+ src_view, src_box, src_width0, src_height0,
+ PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
+ TRUE);
+ r600_blitter_end(ctx);
+
+ pipe_surface_reference(&dst_view, NULL);
+ pipe_sampler_view_reference(&src_view, NULL);
+}
+
+/* For MSAA integer resolving to work, we change the format to NORM using this function. */
+static enum pipe_format int_to_norm_format(enum pipe_format format)
+{
+ 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;