From 2952c6d789ce48e340c62bfd387c3858d7163a42 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 19 May 2025 10:19:24 +0200 Subject: [PATCH] pan: Add a pan_image_mip_level_size() helper and use it for 3D attribute initialization Right now, 3D attribute buffers are set to cover the bytes remaining in the BO starting from the plane surface offset, which works but doesn't provide an accurate information about where the storage image section is supposed to stop. Let's provide a pan_image helper to query the size covered by a MIP level, and use it in panvk/panfrost. Signed-off-by: Boris Brezillon Reviewed-by: Mary Guillemard Reviewed-by: Lars-Ivar Hesselberg Simonsen Acked-by: Eric R. Smith Part-of: --- src/gallium/drivers/panfrost/pan_cmdstream.c | 3 ++- src/panfrost/lib/pan_layout.h | 13 +++++++++++++ src/panfrost/vulkan/panvk_vX_image_view.c | 14 ++++++++------ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index e68ec0df159..f9f6de68bef 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -2035,7 +2035,8 @@ emit_image_bufs(struct panfrost_batch *batch, enum pipe_shader_type shader, cfg.type = pan_modifier_to_attr_type(rsrc->image.layout.modifier); cfg.pointer = rsrc->image.data.base + offset; cfg.stride = util_format_get_blocksize(image->format); - cfg.size = panfrost_bo_size(rsrc->bo) - offset; + cfg.size = pan_image_mip_level_size( + &rsrc->image.layout, is_buffer ? 0 : image->u.tex.level); } if (is_buffer) { diff --git a/src/panfrost/lib/pan_layout.h b/src/panfrost/lib/pan_layout.h index 69a96db11bb..9642ce024fe 100644 --- a/src/panfrost/lib/pan_layout.h +++ b/src/panfrost/lib/pan_layout.h @@ -128,6 +128,19 @@ unsigned pan_image_surface_offset(const struct pan_image_layout *layout, unsigned level, unsigned array_idx, unsigned surface_idx); +static inline uint64_t +pan_image_mip_level_size(const struct pan_image_layout *layout, unsigned level) +{ + assert(level < layout->nr_slices); + uint64_t size = layout->slices[level].size; + + /* If this is an array, we need to cover the whole array. */ + if (layout->array_size > 1) + size += (uint64_t)layout->array_stride * (layout->array_size - 1); + + return size; +} + bool pan_image_layout_init(unsigned arch, struct pan_image_layout *layout, const struct pan_image_wsi_layout *wsi_layout); diff --git a/src/panfrost/vulkan/panvk_vX_image_view.c b/src/panfrost/vulkan/panvk_vX_image_view.c index 9a0f8f0a384..9e54a426953 100644 --- a/src/panfrost/vulkan/panvk_vX_image_view.c +++ b/src/panfrost/vulkan/panvk_vX_image_view.c @@ -240,12 +240,13 @@ prepare_attr_buf_descs(struct panvk_image_view *view) vk_format_get_blocksize(view->vk.view_format) == 1))) plane_idx = 1; - bool is_3d = - image->planes[plane_idx].layout.dim == MALI_TEXTURE_DIMENSION_3D; + const struct pan_image_layout *plane_layout = + &image->planes[plane_idx].layout; + bool is_3d = plane_layout->dim == MALI_TEXTURE_DIMENSION_3D; unsigned offset = image->planes[plane_idx].data.offset; - offset += pan_image_surface_offset( - &image->planes[plane_idx].layout, view->pview.first_level, - is_3d ? 0 : view->pview.first_layer, is_3d ? view->pview.first_layer : 0); + offset += pan_image_surface_offset(plane_layout, view->pview.first_level, + is_3d ? 0 : view->pview.first_layer, + is_3d ? view->pview.first_layer : 0); pan_pack(&view->descs.img_attrib_buf[0], ATTRIBUTE_BUFFER, cfg) { /* The format is the only thing we lack to emit attribute descriptors @@ -266,7 +267,8 @@ prepare_attr_buf_descs(struct panvk_image_view *view) : MALI_ATTRIBUTE_TYPE_3D_INTERLEAVED; cfg.pointer = image->planes[plane_idx].data.base + offset; cfg.stride = fmt_blksize | (hw_fmt << 10); - cfg.size = pan_kmod_bo_size(image->bo) - offset; + cfg.size = + pan_image_mip_level_size(plane_layout, view->pview.first_level); } struct mali_attribute_buffer_packed *buf = &view->descs.img_attrib_buf[1];