freedreno/a6xx: Fall back to masked RGBA blits for depth/stencil
authorKristian H. Kristensen <hoegsberg@chromium.org>
Fri, 8 Feb 2019 23:07:22 +0000 (15:07 -0800)
committerKristian H. Kristensen <hoegsberg@chromium.org>
Mon, 11 Feb 2019 20:26:21 +0000 (12:26 -0800)
The blitter doesn't seem to have a write mask, so for depth only and
stencil only blits to Z24S8 we cast the Z24S8 buffer to an RGBA UNORM8
buffer and fall back to pipeline blits with corresponding write mask.

Fixes

  dEQP-GLES3.functional.fbo.blit.depth_stencil.depth24_stencil8_stencil_only
  dEQP-GLES3.functional.fbo.invalidate.sub.unbind_blit_depth
  dEQP-GLES3.functional.fbo.invalidate.sub.unbind_blit_msaa_depth
  dEQP-GLES3.functional.fbo.invalidate.whole.unbind_blit_depth
  dEQP-GLES3.functional.fbo.invalidate.whole.unbind_blit_msaa_depth
  dEQP-GLES3.functional.fbo.msaa.2_samples.stencil_index8
  dEQP-GLES3.functional.fbo.msaa.4_samples.stencil_index8

Reviewed-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Kristian H. Kristensen <hoegsberg@chromium.org>
src/gallium/drivers/freedreno/a6xx/fd6_blitter.c

index 08fbe4b70579df9f803d2a2bc70174d8a5e82fd8..8febe605b44a23f50844dd91335ecc091050171f 100644 (file)
@@ -147,11 +147,6 @@ can_do_blit(const struct pipe_blit_info *info)
 
        fail_if(info->alpha_blend);
 
-       /* We can blit depth and stencil in most cases, except for depth only or
-        * stencil only to combined zs. */
-       fail_if(info->dst.format == PIPE_FORMAT_Z24_UNORM_S8_UINT &&
-                       info->mask != PIPE_MASK_ZS);
-
        return true;
 }
 
@@ -567,6 +562,7 @@ rewrite_zs_blit(struct fd_ringbuffer *ring, const struct pipe_blit_info *info)
                break;
 
        case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+               debug_assert(info->mask == PIPE_MASK_ZS);
        case PIPE_FORMAT_Z24X8_UNORM:
        case PIPE_FORMAT_X8Z24_UNORM:
                separate.mask = PIPE_MASK_R;
@@ -580,11 +576,54 @@ rewrite_zs_blit(struct fd_ringbuffer *ring, const struct pipe_blit_info *info)
        }
 }
 
+static void
+rewrite_combined_zs_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
+{
+       struct pipe_blit_info separate = *info;
+
+       if (DEBUG_BLIT_FALLBACK) {
+               fprintf(stderr, "---- rewrite_combined_zs_blit: ");
+               util_dump_blit_info(stderr, info);
+               fprintf(stderr, "\ndst resource: ");
+               util_dump_resource(stderr, info->dst.resource);
+               fprintf(stderr, "\nsrc resource: ");
+               util_dump_resource(stderr, info->src.resource);
+               fprintf(stderr, "\n");
+       }
+
+       switch (info->mask) {
+       case PIPE_MASK_Z:
+               separate.mask = PIPE_MASK_R | PIPE_MASK_G | PIPE_MASK_B;
+               separate.src.format = PIPE_FORMAT_R8G8B8A8_UNORM;
+               separate.dst.format = PIPE_FORMAT_R8G8B8A8_UNORM;
+
+               fd_blitter_blit(ctx, &separate);
+               break;
+
+       case PIPE_MASK_S:
+               separate.mask = PIPE_MASK_A;
+               separate.src.format = PIPE_FORMAT_R8G8B8A8_UNORM;
+               separate.dst.format = PIPE_FORMAT_R8G8B8A8_UNORM;
+
+               fd_blitter_blit(ctx, &separate);
+               break;
+
+       default:
+               unreachable("");
+       }
+}
+
 static bool
 fd6_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
 {
        struct fd_batch *batch;
 
+       if (info->dst.format == PIPE_FORMAT_Z24_UNORM_S8_UINT &&
+               info->mask != PIPE_MASK_ZS)  {
+               rewrite_combined_zs_blit(ctx, info);
+               return true;
+       }
+
        if (!can_do_blit(info))
                return false;