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 <boris.brezillon@collabora.com>
Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Reviewed-by: Eric R. Smith <eric.smith@collabora.com>
Tested-by: Eric R. Smith <eric.smith@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35555>
This commit is contained in:
Boris Brezillon 2025-06-18 12:07:23 +02:00
parent 53e5e07c4b
commit 5fe1b95b33
8 changed files with 101 additions and 75 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 <format=" \

View file

@ -287,9 +287,8 @@ panvk_image_init_layouts(struct panvk_image *image,
.planes = {&image->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);
}

View file

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