From 5fe1b95b33f2eb083a57335af3e21a2965c59256 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 18 Jun 2025 12:07:23 +0200 Subject: [PATCH] pan: Make it so all pan_image_xxx helpers get passed an image Some layout related helpers are being passed images subfields. Let's make things consistent by always passing an image, plus extra parameters to specify which part of the image is addressed. While at it, move these helpers protypes/definitions to pan_image.h. Signed-off-by: Boris Brezillon Reviewed-by: Lars-Ivar Hesselberg Simonsen Reviewed-by: Eric R. Smith Tested-by: Eric R. Smith Part-of: --- src/gallium/drivers/panfrost/pan_cmdstream.c | 6 +- src/gallium/drivers/panfrost/pan_resource.c | 62 ++++++++++---------- src/panfrost/lib/pan_image.h | 38 +++++++++++- src/panfrost/lib/pan_layout.c | 18 ++++-- src/panfrost/lib/pan_layout.h | 26 -------- src/panfrost/lib/tests/test-layout.cpp | 19 ++++-- src/panfrost/vulkan/panvk_image.c | 5 +- src/panfrost/vulkan/panvk_vX_image_view.c | 2 +- 8 files changed, 101 insertions(+), 75 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index 9b620f25b71..e226edd33ee 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -2069,9 +2069,9 @@ emit_image_bufs(struct panfrost_batch *batch, enum pipe_shader_type shader, cfg.type = pan_modifier_to_attr_type(rsrc->image.props.modifier); cfg.pointer = rsrc->plane.base + offset; cfg.stride = util_format_get_blocksize(image->format); - cfg.size = - pan_image_mip_level_size(&rsrc->image.props, &rsrc->plane.layout, - is_buffer ? 0 : image->u.tex.level); + cfg.size = pan_image_mip_level_size( + &rsrc->image, pan_resource_plane_index(rsrc), + is_buffer ? 0 : image->u.tex.level); } if (is_buffer) { diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index d727da2eb8f..9b46a1b8341 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -104,20 +104,34 @@ panfrost_clear_render_target(struct pipe_context *pipe, height); } -static void -panfrost_resource_init_image(struct panfrost_resource *rsc, - const struct pan_mod_handler *mod_handler, - const struct pan_image_props *iprops, - unsigned plane_idx) +static bool +panfrost_resource_init_image( + struct pipe_screen *screen, struct panfrost_resource *rsc, + const struct pan_image_props *iprops, unsigned plane_idx, + const struct pan_image_layout_constraints *explicit_layout) { - rsc->image.mod_handler = mod_handler; - rsc->image.props = *iprops; + struct panfrost_device *dev = pan_device(screen); + const unsigned format_plane_count = util_format_get_num_planes(iprops->format); + + /* Some planar formats are lowered by the frontend, assume each plane is + * independent in that case. */ + if (format_plane_count == 1) + plane_idx = 0; + + rsc->image = (struct pan_image){ + .mod_handler = pan_mod_get_handler(dev->arch, iprops->modifier), + .props = *iprops, + }; rsc->image.planes[plane_idx] = &rsc->plane; + if (!pan_image_layout_init(dev->arch, &rsc->image, plane_idx, + explicit_layout)) + return false; + /* The rest of the resource planes will be initialized when we hit the first * plane. */ - if (plane_idx > 0 || util_format_get_num_planes(iprops->format) == 1) - return; + if (plane_idx > 0 || format_plane_count == 1) + return true; plane_idx = 1; for (struct panfrost_resource *plane = pan_resource(rsc->base.next); @@ -133,6 +147,8 @@ panfrost_resource_init_image(struct panfrost_resource *rsc, memcpy(plane->image.planes, rsc->image.planes, plane_idx * sizeof(plane->image.planes[0])); } + + return true; } static bool @@ -340,22 +356,13 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen, return NULL; } - unsigned format_plane = - util_format_get_num_planes(iprops.format) > 1 ? whandle->plane : 0; - - const struct pan_mod_handler *mod_handler = - pan_mod_get_handler(dev->arch, iprops.modifier); - bool valid = - pan_image_layout_init(dev->arch, mod_handler, &iprops, format_plane, - &explicit_layout, &rsc->plane.layout); - + bool valid = panfrost_resource_init_image(pscreen, rsc, &iprops, + whandle->plane, &explicit_layout); if (!valid) { panfrost_resource_destroy(pscreen, &rsc->base); return NULL; } - panfrost_resource_init_image(rsc, mod_handler, &iprops, whandle->plane); - int ret = panfrost_resource_import_bo(rsc, dev, whandle->handle); /* Sometimes an import can fail e.g. on an invalid buffer fd, out of * memory space to mmap it etc. @@ -439,8 +446,7 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen, } handle->stride = pan_image_get_wsi_row_pitch(&rsrc->image, handle->plane, 0); - handle->offset = - pan_image_get_wsi_offset(&rsrc->image.planes[handle->plane]->layout, 0); + handle->offset = pan_image_get_wsi_offset(&rsrc->image, handle->plane, 0); /* SW detiling on MTK_TILED resources. This forces us to treat such * resources as linear images with: @@ -479,7 +485,7 @@ panfrost_resource_get_param(struct pipe_screen *pscreen, *value = pan_image_get_wsi_row_pitch(&rsrc->image, plane, level); return true; case PIPE_RESOURCE_PARAM_OFFSET: - *value = pan_image_get_wsi_offset(&rsrc->plane.layout, level); + *value = pan_image_get_wsi_offset(&rsrc->image, plane, level); return true; case PIPE_RESOURCE_PARAM_MODIFIER: *value = rsrc->modifier; @@ -808,15 +814,7 @@ panfrost_resource_try_setup(struct pipe_screen *screen, * want the real bitrate and not DEFAULT */ pres->base.compression_rate = pan_afrc_get_rate(fmt, chosen_mod); - const struct pan_mod_handler *mod_handler = - pan_mod_get_handler(dev->arch, iprops.modifier); - - if (!pan_image_layout_init(dev->arch, mod_handler, &iprops, plane_idx, NULL, - &pres->plane.layout)) - return false; - - panfrost_resource_init_image(pres, mod_handler, &iprops, plane_idx); - return true; + return panfrost_resource_init_image(screen, pres, &iprops, plane_idx, NULL); } static void diff --git a/src/panfrost/lib/pan_image.h b/src/panfrost/lib/pan_image.h index 34b257dc2e7..4356510a30e 100644 --- a/src/panfrost/lib/pan_image.h +++ b/src/panfrost/lib/pan_image.h @@ -200,7 +200,27 @@ pan_image_view_check(const struct pan_image_view *iview) #endif } -static inline unsigned +static inline uint64_t +pan_image_mip_level_size(const struct pan_image *image, unsigned plane_idx, + unsigned mip_level) +{ + assert(plane_idx < ARRAY_SIZE(image->planes) && + plane_idx < util_format_get_num_planes(image->props.format)); + assert(mip_level < image->props.nr_slices); + assert(image->planes[plane_idx]); + + uint64_t size = image->planes[plane_idx]->layout.slices[mip_level].size_B; + + /* If this is an array, we need to cover the whole array. */ + if (image->props.array_size > 1) { + size += image->planes[plane_idx]->layout.array_stride_B * + (image->props.array_size - 1); + } + + return size; +} + +static inline uint32_t pan_image_get_wsi_row_pitch(const struct pan_image *image, unsigned plane_idx, unsigned mip_level) { @@ -213,6 +233,22 @@ pan_image_get_wsi_row_pitch(const struct pan_image *image, unsigned plane_idx, return image->mod_handler->get_wsi_row_pitch(image, plane_idx, mip_level); } +static inline uint64_t +pan_image_get_wsi_offset(const struct pan_image *image, unsigned plane_idx, + unsigned mip_level) +{ + assert(plane_idx < ARRAY_SIZE(image->planes) && + plane_idx < util_format_get_num_planes(image->props.format)); + assert(mip_level < image->props.nr_slices); + assert(image->planes[plane_idx]); + + return image->planes[plane_idx]->layout.slices[mip_level].offset_B; +} + +bool pan_image_layout_init( + unsigned arch, struct pan_image *image, unsigned plane_idx, + const struct pan_image_layout_constraints *explicit_layout_constraints); + #ifdef __cplusplus } /* extern C */ #endif diff --git a/src/panfrost/lib/pan_layout.c b/src/panfrost/lib/pan_layout.c index 3b8dac1a278..5659c46bb97 100644 --- a/src/panfrost/lib/pan_layout.c +++ b/src/panfrost/lib/pan_layout.c @@ -23,12 +23,13 @@ * */ +#include "pan_layout.h" #include "util/log.h" #include "util/macros.h" #include "util/u_math.h" #include "pan_afbc.h" #include "pan_afrc.h" -#include "pan_layout.h" +#include "pan_image.h" #include "pan_mod.h" #include "pan_props.h" @@ -81,11 +82,18 @@ get_mip_level_extent(const struct pan_image_props *props, unsigned plane_idx, bool pan_image_layout_init( - unsigned arch, const struct pan_mod_handler *mod_handler, - const struct pan_image_props *props, unsigned plane_idx, - const struct pan_image_layout_constraints *explicit_layout_constraints, - struct pan_image_layout *layout) + unsigned arch, struct pan_image *image, unsigned plane_idx, + const struct pan_image_layout_constraints *explicit_layout_constraints) { + assert(image->mod_handler); + assert(plane_idx < ARRAY_SIZE(image->planes) && + plane_idx < util_format_get_num_planes(image->props.format)); + assert(image->planes[plane_idx]); + + const struct pan_mod_handler *mod_handler = image->mod_handler; + const struct pan_image_props *props = &image->props; + struct pan_image_layout *layout = &image->planes[plane_idx]->layout; + /* Use explicit layout only when wsi_row_pitch_B is non-zero */ struct pan_image_layout_constraints layout_constraints = {0}; if (explicit_layout_constraints) diff --git a/src/panfrost/lib/pan_layout.h b/src/panfrost/lib/pan_layout.h index 41616d49199..cd131a49035 100644 --- a/src/panfrost/lib/pan_layout.h +++ b/src/panfrost/lib/pan_layout.h @@ -164,32 +164,6 @@ pan_image_slice_align(uint64_t modifier) return 64; } -static inline uint64_t -pan_image_mip_level_size(const struct pan_image_props *props, - const struct pan_image_layout *layout, unsigned level) -{ - assert(level < props->nr_slices); - uint64_t size = layout->slices[level].size_B; - - /* If this is an array, we need to cover the whole array. */ - if (props->array_size > 1) - size += layout->array_stride_B * (props->array_size - 1); - - return size; -} - -bool pan_image_layout_init( - unsigned arch, const struct pan_mod_handler *mod_handler, - const struct pan_image_props *props, unsigned plane_idx, - const struct pan_image_layout_constraints *layout_constraints, - struct pan_image_layout *layout); - -static inline uint64_t -pan_image_get_wsi_offset(const struct pan_image_layout *layout, unsigned level) -{ - return layout->slices[level].offset_B; -} - static inline uint32_t pan_linear_or_tiled_row_align_req(unsigned arch, enum pipe_format format, unsigned plane_idx) diff --git a/src/panfrost/lib/tests/test-layout.cpp b/src/panfrost/lib/tests/test-layout.cpp index 7e10776ce49..65ba93b78d9 100644 --- a/src/panfrost/lib/tests/test-layout.cpp +++ b/src/panfrost/lib/tests/test-layout.cpp @@ -251,9 +251,20 @@ layout_init(unsigned arch, const struct pan_image_props *props, if (!arch) arch = 4; - return pan_image_layout_init(arch, - pan_mod_get_handler(arch, props->modifier), - props, plane_idx, layout_constraints, layout); + struct pan_image_plane plane = { + }; + struct pan_image img = { + .props = *props, + .mod_handler = pan_mod_get_handler(arch, props->modifier), + }; + + img.planes[plane_idx] = &plane; + + if (!pan_image_layout_init(arch, &img, plane_idx, layout_constraints)) + return false; + + *layout = plane.layout; + return true; } /* dEQP-GLES3.functional.texture.format.compressed.etc1_2d_pot */ @@ -562,7 +573,7 @@ static unsigned archs[] = {4, 5, 6, 7, 9, 12, 13}; img.planes[__plane] = &img_plane; \ unsigned __export_row_pitch_B = \ pan_image_get_wsi_row_pitch(&img, __plane, 0); \ - unsigned __export_offset_B = pan_image_get_wsi_offset(&layout, 0); \ + unsigned __export_offset_B = pan_image_get_wsi_offset(&img, __plane, 0); \ EXPECT_TRUE(__export_row_pitch_B == (__wsi_layout)->wsi_row_pitch_B && \ __export_offset_B == (__wsi_layout)->offset_B) \ << " mismatch between import and export for planes[plane].plane}, }; - if (!pan_image_layout_init( - arch, mod_handler, &image->planes[plane].image.props, 0, - &plane_layout, &image->planes[plane].plane.layout)) { + if (!pan_image_layout_init(arch, &image->planes[plane].image, 0, + &plane_layout)) { return panvk_error(image->vk.base.device, VK_ERROR_INITIALIZATION_FAILED); } diff --git a/src/panfrost/vulkan/panvk_vX_image_view.c b/src/panfrost/vulkan/panvk_vX_image_view.c index f2608340a73..9e479a8034d 100644 --- a/src/panfrost/vulkan/panvk_vX_image_view.c +++ b/src/panfrost/vulkan/panvk_vX_image_view.c @@ -272,7 +272,7 @@ prepare_attr_buf_descs(struct panvk_image_view *view) : MALI_ATTRIBUTE_TYPE_3D_INTERLEAVED; cfg.pointer = image->planes[plane_idx].plane.base + offset; cfg.stride = fmt_blksize | (hw_fmt << 10); - cfg.size = pan_image_mip_level_size(plane_props, plane_layout, + cfg.size = pan_image_mip_level_size(&image->planes[plane_idx].image, 0, view->pview.first_level); }