etnaviv: blt: fix multisampled blits

The BLT blit currently assumes that all blits with src samples > 1
are downsampling blits. This isn't correct, as we can also blit
between two multisampled resources with src and dst samples > 1.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23595>
This commit is contained in:
Lucas Stach
2023-06-12 12:35:07 +02:00
committed by Marge Bot
parent 7552f481dc
commit 334bcb31a5

View File

@@ -396,14 +396,26 @@ etna_try_blt_blit(struct pipe_context *pctx,
struct etna_context *ctx = etna_context(pctx);
struct etna_resource *src = etna_resource(blit_info->src.resource);
struct etna_resource *dst = etna_resource(blit_info->dst.resource);
int msaa_xscale = 1, msaa_yscale = 1;
int src_xscale, src_yscale, dst_xscale, dst_yscale;
bool downsample_x = false, downsample_y = false;
/* Ensure that the level is valid */
assert(blit_info->src.level <= src->base.last_level);
assert(blit_info->dst.level <= dst->base.last_level);
if (!translate_samples_to_xyscale(src->base.nr_samples, &msaa_xscale, &msaa_yscale))
if (!translate_samples_to_xyscale(src->base.nr_samples, &src_xscale, &src_yscale))
return false;
if (!translate_samples_to_xyscale(dst->base.nr_samples, &dst_xscale, &dst_yscale))
return false;
/* BLT does not support upscaling */
if ((src_xscale < dst_xscale) || (src_yscale < dst_yscale))
return false;
if (src_xscale > dst_xscale)
downsample_x = true;
if (src_yscale > dst_yscale)
downsample_y = true;
/* The width/height are in pixels; they do not change as a result of
* multi-sampling. So, when blitting from a 4x multisampled surface
@@ -439,7 +451,7 @@ etna_try_blt_blit(struct pipe_context *pctx,
/* When not resolving MSAA, but only doing a layout conversion, we can get
* away with a fallback format of matching size.
*/
if (format == ETNA_NO_MATCH && msaa_xscale == 1 && msaa_yscale == 1)
if (format == ETNA_NO_MATCH && !downsample_x && !downsample_y)
format = etna_compatible_blt_format(blit_info->dst.format);
if (format == ETNA_NO_MATCH)
return false;
@@ -495,8 +507,8 @@ etna_try_blt_blit(struct pipe_context *pctx,
op.src.format = format;
op.src.stride = src_lev->stride;
op.src.tiling = src->layout;
op.src.downsample_x = msaa_xscale > 1;
op.src.downsample_y = msaa_yscale > 1;
op.src.downsample_x = downsample_x;
op.src.downsample_y = downsample_y;
for (unsigned x=0; x<4; ++x)
op.src.swizzle[x] = x;
@@ -537,10 +549,10 @@ etna_try_blt_blit(struct pipe_context *pctx,
op.src_y += blit_info->src.box.height;
}
op.src_x *= msaa_xscale;
op.src_y *= msaa_yscale;
op.rect_w *= msaa_xscale;
op.rect_h *= msaa_yscale;
op.src_x *= src_xscale;
op.src_y *= src_yscale;
op.rect_w *= src_xscale;
op.rect_h *= src_yscale;
assert(op.src_x < src_lev->padded_width);
assert(op.src_y < src_lev->padded_height);