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 <alyssa@collabora.com>
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13205>
This commit is contained in:
Alyssa Rosenzweig 2021-10-16 19:44:53 -04:00
parent 93c9123c31
commit 789601a189
3 changed files with 34 additions and 0 deletions

View file

@ -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;

View file

@ -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,

View file

@ -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 */