From f6131d4ec7a24b9731bb01b6b3bd786ea48ba3bb Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Thu, 18 Oct 2018 21:41:21 -0700 Subject: [PATCH] freedreno/a6xx: Clear z32 and separate stencil with blitter Signed-off-by: Kristian H. Kristensen --- src/gallium/drivers/freedreno/a6xx/fd6_draw.c | 75 ++++++++++++------- src/gallium/drivers/freedreno/a6xx/fd6_gmem.c | 2 +- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c index c9c4077e3a6..d921a33f5f4 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c @@ -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); } } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c index 8278e48d5bd..75bbcc7bac4 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c @@ -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); } -- 2.30.2