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];

Reply via email to