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 <boris.brezillon@collabora.com>
Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com>
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35317>
This commit is contained in:
Boris Brezillon
2025-05-22 15:55:34 +02:00
committed by Marge Bot
parent eb476fd2c6
commit bb07343c28
3 changed files with 63 additions and 0 deletions

View File

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

View File

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

View File

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