struct r600_texture *dst = (struct r600_texture*)info->dst.resource;
unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level);
unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level);
- enum pipe_format format = info->dst.format;
+ enum pipe_format format = info->src.format;
unsigned sample_mask = ~0;
+ struct pipe_resource *tmp, templ;
+ struct pipe_blit_info blit;
+
+ /* Check basic requirements for hw resolve. */
+ if (!(info->src.resource->nr_samples > 1 &&
+ info->dst.resource->nr_samples <= 1 &&
+ !util_format_is_pure_integer(format) &&
+ !util_format_is_depth_or_stencil(format) &&
+ util_max_layer(info->src.resource, 0) == 0))
+ return false;
/* Hardware MSAA resolve doesn't work if SPI format = NORM16_ABGR and
* the format is R16G16. Use R16A16, which does work.
if (format == PIPE_FORMAT_R16G16_SNORM)
format = PIPE_FORMAT_R16A16_SNORM;
- if (info->src.resource->nr_samples > 1 &&
- info->dst.resource->nr_samples <= 1 &&
- util_max_layer(info->src.resource, 0) == 0 &&
- util_max_layer(info->dst.resource, info->dst.level) == 0 &&
- util_is_format_compatible(util_format_description(info->src.format),
- util_format_description(info->dst.format)) &&
- !util_format_is_pure_integer(format) &&
- !util_format_is_depth_or_stencil(format) &&
+ /* Check the remaining requirements for hw resolve. */
+ if (util_max_layer(info->dst.resource, info->dst.level) == 0 &&
!info->scissor_enable &&
(info->mask & PIPE_MASK_RGBA) == PIPE_MASK_RGBA &&
+ util_is_format_compatible(util_format_description(info->src.format),
+ util_format_description(info->dst.format)) &&
dst_width == info->src.resource->width0 &&
dst_height == info->src.resource->height0 &&
info->dst.box.x == 0 &&
si_blitter_end(ctx);
return true;
}
- return false;
+
+ /* Shader-based resolve is VERY SLOW. Instead, resolve into
+ * a temporary texture and blit.
+ */
+ memset(&templ, 0, sizeof(templ));
+ 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.usage = PIPE_USAGE_DEFAULT;
+ templ.flags = R600_RESOURCE_FLAG_FORCE_TILING;
+
+ tmp = ctx->screen->resource_create(ctx->screen, &templ);
+ if (!tmp)
+ return false;
+
+ /* resolve */
+ si_blitter_begin(ctx, SI_COLOR_RESOLVE |
+ (info->render_condition_enable ? 0 : SI_DISABLE_RENDER_COND));
+ util_blitter_custom_resolve_color(sctx->blitter, tmp, 0, 0,
+ info->src.resource, info->src.box.z,
+ sample_mask, sctx->custom_blend_resolve,
+ format);
+ si_blitter_end(ctx);
+
+ /* blit */
+ blit = *info;
+ blit.src.resource = tmp;
+ blit.src.box.z = 0;
+
+ si_blitter_begin(ctx, SI_BLIT |
+ (info->render_condition_enable ? 0 : SI_DISABLE_RENDER_COND));
+ util_blitter_blit(sctx->blitter, &blit);
+ si_blitter_end(ctx);
+
+ pipe_resource_reference(&tmp, NULL);
+ return true;
}
static void si_blit(struct pipe_context *ctx,