From 9235ab65505657a81f98509b0a01688e9c630d39 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 15 May 2017 12:36:24 -0400 Subject: [PATCH] freedreno/a5xx: fallback to slow-clear for z32 We probably *could* do this with blit path, but I think it would involve clobbering settings from batch->gmem (see emit_zs()). Signed-off-by: Rob Clark --- src/gallium/drivers/freedreno/a2xx/fd2_draw.c | 4 +++- src/gallium/drivers/freedreno/a5xx/fd5_draw.c | 20 +++++++++++++++++- .../drivers/freedreno/freedreno_context.h | 2 +- .../drivers/freedreno/freedreno_draw.c | 21 ++++++++++++------- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_draw.c b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c index f7915d66c1a..8df1793a35f 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_draw.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c @@ -123,7 +123,7 @@ fd2_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, } -static void +static bool fd2_clear(struct fd_context *ctx, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil) { @@ -291,6 +291,8 @@ fd2_clear(struct fd_context *ctx, unsigned buffers, ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG; ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG | FD_DIRTY_SHADER_CONST; + + return true; } void diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c index cd315d4ac04..bc5232a4c17 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c @@ -162,7 +162,19 @@ fd5_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, return true; } -static void +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 bool fd5_clear(struct fd_context *ctx, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil) { @@ -170,6 +182,10 @@ fd5_clear(struct fd_context *ctx, unsigned buffers, struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer; struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx); + if ((buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) && + is_z32(pfb->zsbuf->format)) + return false; + /* TODO handle scissor.. or fallback to slow-clear? */ ctx->batch->max_scissor.minx = MIN2(ctx->batch->max_scissor.minx, scissor->minx); @@ -272,6 +288,8 @@ fd5_clear(struct fd_context *ctx, unsigned buffers, /* disable fast clear to not interfere w/ gmem->mem, etc.. */ OUT_PKT4(ring, REG_A5XX_RB_CLEAR_CNTL, 1); OUT_RING(ring, 0x00000000); /* RB_CLEAR_CNTL */ + + return true; } void diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index 5c63a5ff934..4472afb83e1 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -297,7 +297,7 @@ struct fd_context { /* draw: */ bool (*draw_vbo)(struct fd_context *ctx, const struct pipe_draw_info *info, unsigned index_offset); - void (*clear)(struct fd_context *ctx, unsigned buffers, + bool (*clear)(struct fd_context *ctx, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil); /* compute: */ diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c index 08cba777510..a4a19750a42 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.c +++ b/src/gallium/drivers/freedreno/freedreno_draw.c @@ -384,17 +384,22 @@ fd_clear(struct pipe_context *pctx, unsigned buffers, /* if per-gen backend doesn't implement ctx->clear() generic * blitter clear: */ - if (!ctx->clear) { - fd_blitter_clear(pctx, buffers, color, depth, stencil); - return; - } + bool fallback = true; - fd_batch_set_stage(batch, FD_STAGE_CLEAR); + if (ctx->clear) { + fd_batch_set_stage(batch, FD_STAGE_CLEAR); - ctx->clear(ctx, buffers, color, depth, stencil); + if (ctx->clear(ctx, buffers, color, depth, stencil)) { + if (fd_mesa_debug & FD_DBG_DCLEAR) + fd_context_all_dirty(ctx); - if (fd_mesa_debug & FD_DBG_DCLEAR) - fd_context_all_dirty(ctx); + fallback = false; + } + } + + if (fallback) { + fd_blitter_clear(pctx, buffers, color, depth, stencil); + } } static void -- 2.30.2