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