freedreno/a6xx: Clear z32 and separate stencil with blitter
authorKristian H. Kristensen <hoegsberg@chromium.org>
Fri, 19 Oct 2018 04:41:21 +0000 (21:41 -0700)
committerRob Clark <robdclark@gmail.com>
Tue, 6 Nov 2018 13:56:38 +0000 (08:56 -0500)
Signed-off-by: Kristian H. Kristensen <hoegsberg@chromium.org>
src/gallium/drivers/freedreno/a6xx/fd6_draw.c
src/gallium/drivers/freedreno/a6xx/fd6_gmem.c

index c9c4077e3a656a8fd0deb4cc7bd2fc40e79d25be..d921a33f5f4ec757189290c18dc19f0c612c109c 100644 (file)
@@ -254,18 +254,6 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
        return true;
 }
 
-static bool is_z32(enum pipe_format format)
-{
-       switch (format) {
-       case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
-       case PIPE_FORMAT_Z32_UNORM:
-       case PIPE_FORMAT_Z32_FLOAT:
-               return true;
-       default:
-               return false;
-       }
-}
-
 static void
 fd6_clear_lrz(struct fd_batch *batch, struct fd_resource *zsbuf, double depth)
 {
@@ -391,10 +379,6 @@ fd6_clear(struct fd_context *ctx, unsigned buffers,
        struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
        struct fd_ringbuffer *ring = ctx->batch->draw;
 
-       if ((buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) &&
-                       is_z32(pfb->zsbuf->format))
-               return false;
-
        OUT_PKT4(ring, REG_A6XX_RB_BLIT_SCISSOR_TL, 2);
        OUT_RING(ring, A6XX_RB_BLIT_SCISSOR_TL_X(scissor->minx) |
                         A6XX_RB_BLIT_SCISSOR_TL_Y(scissor->miny));
@@ -474,15 +458,29 @@ fd6_clear(struct fd_context *ctx, unsigned buffers,
                }
        }
 
-       if (pfb->zsbuf && (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
+       const bool has_depth = pfb->zsbuf;
+       const bool has_separate_stencil =
+               has_depth && fd_resource(pfb->zsbuf->texture)->stencil;
+
+       /* First clear depth or combined depth/stencil. */
+       if ((has_depth && (buffers & PIPE_CLEAR_DEPTH)) ||
+               (!has_separate_stencil && (buffers & PIPE_CLEAR_STENCIL))) {
                enum pipe_format pfmt = pfb->zsbuf->format;
-               uint32_t clear = util_pack_z_stencil(pfmt, depth, stencil);
+               uint32_t clear_value;
                uint32_t mask = 0;
 
+               if (has_separate_stencil) {
+                       pfmt = util_format_get_depth_only(pfb->zsbuf->format);
+                       clear_value = util_pack_z(pfmt, depth);
+               } else {
+                       pfmt = pfb->zsbuf->format;
+                       clear_value = util_pack_z_stencil(pfmt, depth, stencil);
+               }
+
                if (buffers & PIPE_CLEAR_DEPTH)
                        mask |= 0x1;
 
-               if (buffers & PIPE_CLEAR_STENCIL)
+               if (!has_separate_stencil && (buffers & PIPE_CLEAR_STENCIL))
                        mask |= 0x2;
 
                OUT_PKT4(ring, REG_A6XX_RB_BLIT_DST_INFO, 1);
@@ -502,16 +500,41 @@ fd6_clear(struct fd_context *ctx, unsigned buffers,
                OUT_RING(ring, 0);
 
                OUT_PKT4(ring, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0, 1);
-               OUT_RING(ring, clear);
+               OUT_RING(ring, clear_value);
 
                fd6_emit_blit(ctx->batch, ring);
+       }
 
-               if (pfb->zsbuf && (buffers & PIPE_CLEAR_DEPTH)) {
-                       struct fd_resource *zsbuf = fd_resource(pfb->zsbuf->texture);
-                       if (zsbuf->lrz) {
-                               zsbuf->lrz_valid = true;
-                               fd6_clear_lrz(ctx->batch, zsbuf, depth);
-                       }
+       /* Then clear the separate stencil buffer in case of 32 bit depth
+        * formats with separate stencil. */
+       if (has_separate_stencil && (buffers & PIPE_CLEAR_STENCIL)) {
+               OUT_PKT4(ring, REG_A6XX_RB_BLIT_DST_INFO, 1);
+               OUT_RING(ring, A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR) |
+                                A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(RB6_R8_UINT));
+
+               OUT_PKT4(ring, REG_A6XX_RB_BLIT_INFO, 1);
+               OUT_RING(ring, A6XX_RB_BLIT_INFO_GMEM |
+                                //A6XX_RB_BLIT_INFO_UNK0 |
+                                A6XX_RB_BLIT_INFO_DEPTH |
+                                A6XX_RB_BLIT_INFO_CLEAR_MASK(0x1));
+
+               OUT_PKT4(ring, REG_A6XX_RB_BLIT_BASE_GMEM, 1);
+               OUT_RINGP(ring, MAX_RENDER_TARGETS + 1, &ctx->batch->gmem_patches);
+
+               OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_88D0, 1);
+               OUT_RING(ring, 0);
+
+               OUT_PKT4(ring, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0, 1);
+               OUT_RING(ring, stencil & 0xff);
+
+               fd6_emit_blit(ctx->batch, ring);
+       }
+
+       if (has_depth && (buffers & PIPE_CLEAR_DEPTH)) {
+               struct fd_resource *zsbuf = fd_resource(pfb->zsbuf->texture);
+               if (zsbuf->lrz) {
+                       zsbuf->lrz_valid = true;
+                       fd6_clear_lrz(ctx->batch, zsbuf, depth);
                }
        }
 
index 8278e48d5bde44feb0cfca35b2b94782f72c9f91..75bbcc7bac4776b637cb6244e799f51e4c068241 100644 (file)
@@ -264,7 +264,7 @@ patch_gmem_bases(struct fd_batch *batch)
                if (patch->val < MAX_RENDER_TARGETS)
                        *patch->cs = gmem->cbuf_base[patch->val];
                else
-                       *patch->cs = gmem->zsbuf_base[0];
+                       *patch->cs = gmem->zsbuf_base[patch->val - MAX_RENDER_TARGETS];
        }
        util_dynarray_resize(&batch->gmem_patches, 0);
 }