From 1061a6864468e0024dd7830fdc128af595cf27d1 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sun, 13 Jun 2021 11:02:59 -0700 Subject: [PATCH] freedreno: Avoid recursive re-entry of u_blitter Normally when demotion to uncompressed is required, it is handled when various state is attached (sampler-view, framebuffer, etc). But in this one path into u_blitter we need to handle it up front, to avoid recursing back into u_blitter for a decompress blit. Signed-off-by: Rob Clark Part-of: --- src/gallium/drivers/freedreno/a6xx/fd6_blitter.c | 7 +++++-- src/gallium/drivers/freedreno/freedreno_blitter.c | 13 +++++++++++++ src/gallium/drivers/freedreno/freedreno_context.h | 4 ++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c index 21c1ba0..8ca0d95 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c @@ -1136,12 +1136,15 @@ fd6_blit(struct fd_context *ctx, const struct pipe_blit_info *info) assert_dt void fd6_blitter_init(struct pipe_context *pctx) disable_thread_safety_analysis { - fd_context(pctx)->clear_ubwc = fd6_clear_ubwc; + struct fd_context *ctx = fd_context(pctx); + + ctx->clear_ubwc = fd6_clear_ubwc; + ctx->validate_format = fd6_validate_format; if (FD_DBG(NOBLIT)) return; - fd_context(pctx)->blit = fd6_blit; + ctx->blit = fd6_blit; } unsigned diff --git a/src/gallium/drivers/freedreno/freedreno_blitter.c b/src/gallium/drivers/freedreno/freedreno_blitter.c index 8f2f3b1..bc23791 100644 --- a/src/gallium/drivers/freedreno/freedreno_blitter.c +++ b/src/gallium/drivers/freedreno/freedreno_blitter.c @@ -129,6 +129,19 @@ fd_blitter_blit(struct fd_context *ctx, const struct pipe_blit_info *info) struct pipe_sampler_view src_templ, *src_view; bool discard = false; + /* The blit format may not match the resource format in this path, so + * we need to validate that we can use the src/dst resource with the + * requested format (and uncompress if necessary). Normally this would + * happen in ->set_sampler_view(), ->set_framebuffer_state(), etc. But + * that would cause recursion back into u_blitter, which ends in tears. + * + * To avoid recursion, this needs to be done before util_blitter_save_*() + */ + if (ctx->validate_format) { + ctx->validate_format(ctx, fd_resource(dst), info->dst.format); + ctx->validate_format(ctx, fd_resource(src), info->src.format); + } + if (!info->scissor_enable && !info->alpha_blend) { discard = util_texrange_covers_whole_level( info->dst.resource, info->dst.level, info->dst.box.x, info->dst.box.y, diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index dc2a978..5438da4 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -502,6 +502,10 @@ struct fd_context { bool (*blit)(struct fd_context *ctx, const struct pipe_blit_info *info) dt; void (*clear_ubwc)(struct fd_batch *batch, struct fd_resource *rsc) dt; + /* uncompress resource, if necessary, to use as the specified format: */ + void (*validate_format)(struct fd_context *ctx, struct fd_resource *rsc, + enum pipe_format format) dt; + /* handling for barriers: */ void (*framebuffer_barrier)(struct fd_context *ctx) dt; -- 2.7.4