Module: Mesa Branch: main Commit: c49f22188847a6d783f5574bacc5450e1ea97f90 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=c49f22188847a6d783f5574bacc5450e1ea97f90
Author: Boris Brezillon <[email protected]> Date: Mon Sep 6 12:38:22 2021 +0200 pan/blit: Fix 3D blittering Fixes several problems in the pan_blit() logic: 1. We actually need the reciprocal of the depth scaling in z_scale (maybe we should rename this field z_scale_rcp to make it clear) 2. When Z end < Z start we should remove one to the cur_layer/layer_offset instead of doing it on the last_layer field, otherwise there's an off-by-one error 3. The Z src offset should be adjusted to account for scaling. If we don't do that we won't sample from the right layer when upscaling. Signed-off-by: Boris Brezillon <[email protected]> Reviewed-by: Tomeu Vizoso <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12961> --- src/panfrost/lib/pan_blitter.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/panfrost/lib/pan_blitter.c b/src/panfrost/lib/pan_blitter.c index 053896ad85a..16980bf5cbd 100644 --- a/src/panfrost/lib/pan_blitter.c +++ b/src/panfrost/lib/pan_blitter.c @@ -1310,19 +1310,23 @@ GENX(pan_blit_ctx_init)(struct panfrost_device *dev, ctx->src.end.x = info->src.end.x; ctx->src.end.y = info->src.end.y; ctx->src.dim = sviews[0].dim; - if (sviews[0].dim == MALI_TEXTURE_DIMENSION_3D) - ctx->src.z_offset = info->src.start.z; - else - ctx->src.layer_offset = info->src.start.layer; if (info->dst.planes[0].image->layout.dim == MALI_TEXTURE_DIMENSION_3D) { unsigned max_z = u_minify(info->dst.planes[0].image->layout.depth, info->dst.level) - 1; - ctx->dst.layer_offset = info->dst.start.z; - ctx->dst.cur_layer = info->dst.start.z; - ctx->dst.last_layer = MIN2(MAX2(info->dst.end.z, 0), max_z); - ctx->z_scale = (float)(info->dst.end.z - info->dst.start.z) / - (info->src.end.z - info->src.start.z); + ctx->z_scale = (float)(info->src.end.z - info->src.start.z) / + (info->dst.end.z - info->dst.start.z); + assert(info->dst.start.z != info->dst.end.z); + if (info->dst.start.z > info->dst.end.z) { + ctx->dst.cur_layer = info->dst.start.z - 1; + ctx->dst.last_layer = info->dst.end.z; + } else { + ctx->dst.cur_layer = info->dst.start.z; + ctx->dst.last_layer = info->dst.end.z - 1; + } + ctx->dst.cur_layer = MIN2(MAX2(ctx->dst.cur_layer, 0), max_z); + ctx->dst.last_layer = MIN2(MAX2(ctx->dst.last_layer, 0), max_z); + ctx->dst.layer_offset = ctx->dst.cur_layer; } else { unsigned max_layer = info->dst.planes[0].image->layout.array_size - 1; ctx->dst.layer_offset = info->dst.start.layer; @@ -1331,6 +1335,15 @@ GENX(pan_blit_ctx_init)(struct panfrost_device *dev, ctx->z_scale = 1; } + if (sviews[0].dim == MALI_TEXTURE_DIMENSION_3D) { + if (info->src.start.z < info->src.end.z) + ctx->src.z_offset = info->src.start.z + fabs(ctx->z_scale * 0.5f); + else + ctx->src.z_offset = info->src.start.z - fabs(ctx->z_scale * 0.5f); + } else { + ctx->src.layer_offset = info->src.start.layer; + } + /* Split depth and stencil */ if (util_format_is_depth_and_stencil(sviews[0].format)) { sviews[1] = sviews[0];
