From bb07343c28fc172e83e3ef23c994b9e43a30fa02 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 22 May 2025 15:55:34 +0200 Subject: [PATCH] pan/image: Start checking image view consistency We recently found a weird case where an image was re-interpreted with a format that had a bigger size than the image format, which led the resulting texture descriptor to have a size that was bigger than what the plane descriptors were covering. Let's make sure this sort of unexpected use don't slip through in the future by introducing basic image view consistency checks. Signed-off-by: Boris Brezillon Reviewed-by: Mary Guillemard Reviewed-by: Erik Faye-Lund Part-of: --- src/panfrost/lib/pan_desc.c | 19 ++++++++++++++++ src/panfrost/lib/pan_image.h | 40 ++++++++++++++++++++++++++++++++++ src/panfrost/lib/pan_texture.c | 4 ++++ 3 files changed, 63 insertions(+) diff --git a/src/panfrost/lib/pan_desc.c b/src/panfrost/lib/pan_desc.c index e173fa06804..b5e4cf9ece5 100644 --- a/src/panfrost/lib/pan_desc.c +++ b/src/panfrost/lib/pan_desc.c @@ -837,11 +837,30 @@ pan_force_clean_write(const struct pan_fb_info *fb, unsigned tile_size) #endif +static void +check_fb_attachments(const struct pan_fb_info *fb) +{ +#ifndef NDEBUG + for (unsigned i = 0; i < fb->rt_count; i++) { + if (fb->rts[i].view) + pan_image_view_check(fb->rts[i].view); + } + + if (fb->zs.view.zs) + pan_image_view_check(fb->zs.view.zs); + + if (fb->zs.view.s) + pan_image_view_check(fb->zs.view.s); +#endif +} + unsigned GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx, const struct pan_tls_info *tls, const struct pan_tiler_context *tiler_ctx, void *out) { + check_fb_attachments(fb); + void *fbd = out; void *rtd = out + pan_size(FRAMEBUFFER); diff --git a/src/panfrost/lib/pan_image.h b/src/panfrost/lib/pan_image.h index c3b8764db96..fab92f7ab09 100644 --- a/src/panfrost/lib/pan_image.h +++ b/src/panfrost/lib/pan_image.h @@ -17,6 +17,8 @@ #include "pan_format.h" #include "pan_layout.h" +#include "util/log.h" + #ifdef __cplusplus extern "C" { #endif @@ -221,6 +223,44 @@ pan_iview_get_surface(const struct pan_image_view *iview, unsigned level, } } +static inline void +pan_image_view_check(const struct pan_image_view *iview) +{ +#ifndef NDEBUG + unsigned nplanes = util_format_get_num_planes(iview->format); + struct pan_image_plane_ref pref; + + for (unsigned i = 0; i < nplanes; i++) { + if (util_format_is_depth_or_stencil(iview->format)) { + const struct util_format_description *fdesc = + util_format_description(iview->format); + + if (util_format_has_stencil(fdesc)) + pref = pan_image_view_get_s_plane(iview); + else + pref = pan_image_view_get_zs_plane(iview); + } else { + pref = iview->planes[i]; + } + + /* Make sure we have an image and the plane we point to exists. */ + assert(pref.image); + assert(pref.plane_idx < + util_format_get_num_planes(pref.image->props.format)); + + enum pipe_format view_format = + util_format_get_plane_format(iview->format, i); + enum pipe_format img_format = + util_format_get_plane_format(pref.image->props.format, pref.plane_idx); + + /* View-based pixel re-interpretation only allowed if the formats + * blocksize match. */ + assert(util_format_get_blocksize(view_format) == + util_format_get_blocksize(img_format)); + } +#endif +} + #ifdef __cplusplus } /* extern C */ #endif diff --git a/src/panfrost/lib/pan_texture.c b/src/panfrost/lib/pan_texture.c index eabc1a03a08..5bdeae86184 100644 --- a/src/panfrost/lib/pan_texture.c +++ b/src/panfrost/lib/pan_texture.c @@ -837,6 +837,8 @@ GENX(pan_sampled_texture_emit)(const struct pan_image_view *iview, struct mali_texture_packed *out, const struct pan_ptr *payload) { + pan_image_view_check(iview); + const struct util_format_description *desc = util_format_description(iview->format); const struct pan_image_plane_ref first_plane = pan_image_view_get_first_plane(iview); @@ -892,6 +894,8 @@ GENX(pan_storage_texture_emit)(const struct pan_image_view *iview, struct mali_texture_packed *out, const struct pan_ptr *payload) { + pan_image_view_check(iview); + const struct util_format_description *desc = util_format_description(iview->format); const struct pan_image_plane_ref first_plane =