diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c index 21c1ba0f723..8ca0d958f53 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 8f2f3b1b9e3..bc237914ab4 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 dc2a97843ca..5438da48589 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;