diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index d924c3c6cdd..5ac43cdeeae 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -85,6 +85,12 @@ panfrost_clear_render_target(struct pipe_context *pipe, height); } +static uint64_t +panfrost_max_res_size_b(unsigned arch) +{ + return u_uintN_max(arch < 11 ? 32 : 48); +} + static bool panfrost_resource_init_image( struct pipe_screen *screen, struct panfrost_resource *rsc, @@ -111,22 +117,32 @@ panfrost_resource_init_image( /* The rest of the resource planes will be initialized when we hit the first * plane. */ - if (plane_idx > 0 || format_plane_count == 1) + if (plane_idx > 0) return true; - plane_idx = 1; - for (struct panfrost_resource *plane = pan_resource(rsc->base.next); - plane && plane_idx < ARRAY_SIZE(rsc->image.planes); - plane = pan_resource(plane->base.next)) - rsc->image.planes[plane_idx++] = &plane->plane; + if (format_plane_count > 1) { + plane_idx = 1; + for (struct panfrost_resource *plane = pan_resource(rsc->base.next); + plane && plane_idx < ARRAY_SIZE(rsc->image.planes); + plane = pan_resource(plane->base.next)) + rsc->image.planes[plane_idx++] = &plane->plane; - assert(plane_idx == util_format_get_num_planes(iprops->format)); + assert(plane_idx == util_format_get_num_planes(iprops->format)); - for (struct panfrost_resource *plane = pan_resource(rsc->base.next); - plane; plane = pan_resource(plane->base.next)) { - memcpy(plane->image.planes, rsc->image.planes, sizeof(plane->image.planes)); + for (struct panfrost_resource *plane = pan_resource(rsc->base.next); + plane; plane = pan_resource(plane->base.next)) { + memcpy(plane->image.planes, rsc->image.planes, sizeof(plane->image.planes)); + } } + /* validate layout */ + uint64_t res_size = 0; + for (uint32_t i = 0; i < util_format_get_num_planes(iprops->format); i++) + res_size += rsc->image.planes[i]->layout.data_size_B; + + if (res_size > panfrost_max_res_size_b(dev->arch)) + return false; + return true; } diff --git a/src/panfrost/lib/pan_mod.c b/src/panfrost/lib/pan_mod.c index ede832d56ec..f480946de7d 100644 --- a/src/panfrost/lib/pan_mod.c +++ b/src/panfrost/lib/pan_mod.c @@ -16,14 +16,6 @@ #include "util/format/u_format.h" -#if PAN_ARCH <= 10 -#define MAX_SIZE_B u_uintN_max(32) -#define MAX_SLICE_STRIDE_B u_uintN_max(32) -#else -#define MAX_SIZE_B u_uintN_max(48) -#define MAX_SLICE_STRIDE_B u_uintN_max(37) -#endif - static bool pan_mod_afbc_match(uint64_t mod) { @@ -179,8 +171,7 @@ pan_mod_afbc_init_slice_layout( slayout->afbc.surface_stride_B = surf_stride_B; slayout->size_B = surf_stride_B * mip_extent_px.depth; - if (hdr_surf_size_B > UINT32_MAX || surf_stride_B > MAX_SLICE_STRIDE_B || - slayout->size_B > MAX_SIZE_B) + if (hdr_surf_size_B > UINT32_MAX) return false; return true; @@ -427,11 +418,6 @@ pan_mod_afrc_init_slice_layout( slayout->size_B = surf_stride_B * aligned_extent_px.depth * props->nr_samples; - /* Make sure the stride/size fits in the descriptor fields. */ - if (slayout->size_B > MAX_SIZE_B || - slayout->tiled_or_linear.surface_stride_B > MAX_SLICE_STRIDE_B) - return false; - return true; } @@ -571,11 +557,6 @@ pan_mod_u_tiled_init_slice_layout( slayout->tiled_or_linear.surface_stride_B = surf_stride_B; slayout->size_B = surf_stride_B * mip_extent_el.depth * props->nr_samples; - /* Make sure the stride/size fits in the descriptor fields. */ - if (slayout->size_B > MAX_SIZE_B || - slayout->tiled_or_linear.surface_stride_B > MAX_SLICE_STRIDE_B) - return false; - return true; } @@ -620,10 +601,6 @@ pan_mod_interleaved_64k_init_slice_layout( slayout->tiled_or_linear.row_stride_B = row_stride_B; slayout->tiled_or_linear.surface_stride_B = surf_stride_B; - if (slayout->size_B > MAX_SIZE_B || - slayout->tiled_or_linear.surface_stride_B > MAX_SLICE_STRIDE_B) - return false; - return true; } @@ -802,11 +779,6 @@ pan_mod_linear_init_slice_layout( (uint64_t)slayout->tiled_or_linear.row_stride_B * mip_extent_el.height; surf_stride_B = ALIGN_POT(surf_stride_B, (uint64_t)align_mask + 1); - /* Surface stride is passed as a 32-bit unsigned integer to RT/ZS and texture - * descriptors, make sure it fits. */ - if (surf_stride_B > MAX_SLICE_STRIDE_B) - return false; - slayout->tiled_or_linear.surface_stride_B = surf_stride_B; slayout->size_B = surf_stride_B * mip_extent_el.depth * props->nr_samples; return true; diff --git a/src/panfrost/lib/tests/test-layout.cpp b/src/panfrost/lib/tests/test-layout.cpp index a09e2f4bb82..b168e190ba7 100644 --- a/src/panfrost/lib/tests/test-layout.cpp +++ b/src/panfrost/lib/tests/test-layout.cpp @@ -249,6 +249,25 @@ layout_init(unsigned arch, const struct pan_image_props *props, return true; } +TEST(Layout, LargeImage) +{ + struct pan_image_props p = { + .modifier = DRM_FORMAT_MOD_LINEAR, + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .extent_px = { + .width = 65536, + .height = 65536, + .depth = 1, + }, + .nr_samples = 1, + .dim = MALI_TEXTURE_DIMENSION_2D, + .nr_slices = 1, + }; + struct pan_image_layout l = {}; + + ASSERT_TRUE(layout_init(0, &p, 0, NULL, &l)); +} + /* dEQP-GLES3.functional.texture.format.compressed.etc1_2d_pot */ TEST(Layout, ImplicitLayoutInterleavedETC2) {