From 789601a189eb8b0ff0b0f2a19ed276d9881877a7 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Sat, 16 Oct 2021 19:44:53 -0400 Subject: [PATCH] panfrost: Decompress for incompatible AFBC formats AFBC is keyed to the format. Depending on the hardware, we'll get an Invalid Data Fault or a GPU timeout if we attempt to sample from an AFBC-compressed RGBA8 texture as R32F (for example). Fixes Piglit ./bin/arb_texture_view-rendering-formats_gles3 with AFBC. Signed-off-by: Alyssa Rosenzweig Cc: mesa-stable Part-of: --- src/gallium/drivers/panfrost/pan_cmdstream.c | 3 +++ src/gallium/drivers/panfrost/pan_resource.c | 26 ++++++++++++++++++++ src/gallium/drivers/panfrost/pan_resource.h | 5 ++++ 3 files changed, 34 insertions(+) diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index d295aa15a9d..ae5e116b7a8 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -3374,8 +3374,11 @@ panfrost_create_sampler_view( struct pipe_resource *texture, const struct pipe_sampler_view *template) { + struct panfrost_context *ctx = pan_context(pctx); struct panfrost_sampler_view *so = rzalloc(pctx, struct panfrost_sampler_view); + pan_legalize_afbc_format(ctx, pan_resource(texture), template->format); + pipe_reference(NULL, &texture->reference); so->base = *template; diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index 1e2453599b6..18c43ea7e47 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -218,8 +218,11 @@ panfrost_create_surface(struct pipe_context *pipe, struct pipe_resource *pt, const struct pipe_surface *surf_tmpl) { + struct panfrost_context *ctx = pan_context(pipe); struct pipe_surface *ps = NULL; + pan_legalize_afbc_format(ctx, pan_resource(pt), surf_tmpl->format); + ps = CALLOC_STRUCT(pipe_surface); if (ps) { @@ -1067,6 +1070,29 @@ pan_resource_modifier_convert(struct panfrost_context *ctx, pipe_resource_reference(&tmp_prsrc, NULL); } +/* Validate that an AFBC resource may be used as a particular format. If it may + * not, decompress it on the fly. Failure to do so can produce wrong results or + * invalid data faults when sampling or rendering to AFBC */ + +void +pan_legalize_afbc_format(struct panfrost_context *ctx, + struct panfrost_resource *rsrc, + enum pipe_format format) +{ + struct panfrost_device *dev = pan_device(ctx->base.screen); + + if (!drm_is_afbc(rsrc->image.layout.modifier)) + return; + + if (panfrost_afbc_format(dev, pan_blit_format(rsrc->base.format)) == + panfrost_afbc_format(dev, pan_blit_format(format))) + return; + + pan_resource_modifier_convert(ctx, rsrc, + DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED, + "Reinterpreting AFBC surface as incompatible format"); +} + static bool panfrost_should_linear_convert(struct panfrost_device *dev, struct panfrost_resource *prsrc, diff --git a/src/gallium/drivers/panfrost/pan_resource.h b/src/gallium/drivers/panfrost/pan_resource.h index cb1260ce799..1d7bb817816 100644 --- a/src/gallium/drivers/panfrost/pan_resource.h +++ b/src/gallium/drivers/panfrost/pan_resource.h @@ -156,4 +156,9 @@ pan_resource_modifier_convert(struct panfrost_context *ctx, struct panfrost_resource *rsrc, uint64_t modifier, const char *reason); +void +pan_legalize_afbc_format(struct panfrost_context *ctx, + struct panfrost_resource *rsrc, + enum pipe_format format); + #endif /* PAN_RESOURCE_H */