asahi: Decompress with format reinterpretation

The internal layout used with compression partially depends on the pixel format.
Some limited reinterpretation is definitely allowed (linear vs sRGB views of the
same physical format are documented by Apple as allowed). Some reinterpretations
are definitely forbidden (R8G8B8A8 vs R32, I think). At some point we'll need to
work out the exact rule. I suspect the answer is that "you can reinterpret iff
the Channels field matches". Meaning that R8G8B8A8_UNORM and B8G8R8A8_SINT would
be compatible, but not R16G16_UNORM. But I haven't tested that.

Fixes all fails in:

   dEQP-GLES31.functional.image_load_store.*.format_reinterpret.*

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23480>
This commit is contained in:
Alyssa Rosenzweig 2023-05-29 19:51:21 -04:00 committed by Marge Bot
parent d499bf10a3
commit 35d849025b

View file

@ -38,6 +38,39 @@
#include "util/u_transfer.h"
#include "agx_disk_cache.h"
static void
agx_legalize_compression(struct agx_context *ctx, struct agx_resource *rsrc,
enum pipe_format format)
{
/* If the resource isn't compressed, we can reinterpret */
if (rsrc->layout.tiling != AIL_TILING_TWIDDLED_COMPRESSED)
return;
/* Normalize due to Gallium shenanigans */
if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT ||
format == PIPE_FORMAT_Z24X8_UNORM)
format = PIPE_FORMAT_Z32_FLOAT;
/* The physical format */
enum pipe_format storage = rsrc->layout.format;
/* sRGB vs linear are always compatible */
storage = util_format_linear(storage);
format = util_format_linear(format);
/* If no reinterpretation happens, we don't have to decompress */
if (storage == format)
return;
/* Otherwise, decompress. TODO: Reverse-engineer which formats are compatible
* and don't need decompression. There are some vague hints in the Metal
* documentation:
*
* https://developer.apple.com/documentation/metal/mtltextureusage/mtltextureusagepixelformatview?language=objc
*/
agx_decompress(ctx, rsrc, "Incompatible formats");
}
static void
agx_set_shader_images(struct pipe_context *pctx, enum pipe_shader_type shader,
unsigned start_slot, unsigned count,
@ -82,6 +115,11 @@ agx_set_shader_images(struct pipe_context *pctx, enum pipe_shader_type shader,
agx_decompress(ctx, rsrc, "Shader image");
}
/* Readable images may be compressed but are still subject to format
* reinterpretation rules.
*/
agx_legalize_compression(ctx, rsrc, image->format);
/* FIXME: Decompress here once we have texture compression */
util_copy_image_view(&ctx->stage[shader].images[start_slot + i], image);
}
@ -768,6 +806,8 @@ agx_create_sampler_view(struct pipe_context *pctx,
}
}
agx_legalize_compression(agx_context(pctx), rsrc, format);
/* Save off the resource that we actually use, with the stencil fixed up */
so->rsrc = rsrc;
agx_pack_texture(&so->desc, rsrc, format, state, false);
@ -831,6 +871,9 @@ static struct pipe_surface *
agx_create_surface(struct pipe_context *ctx, struct pipe_resource *texture,
const struct pipe_surface *surf_tmpl)
{
agx_legalize_compression(agx_context(ctx), agx_resource(texture),
surf_tmpl->format);
struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface);
if (!surface)