mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 11:28:05 +02:00
pan/lib: validate data_size_B in drivers
In order to be able to properly check for maxResourceSize on Vulkan, we need to be able to report the size even for resources that overflow that limit. Otherwise we end up failing to find a usable modifier rather than properly report the problem to the application. This means we need to move the check out of the mod-handler. There's no need to validate the slice-stride. The reason is a little bit complicated, but we have two possible cases: 1. V10 and before: the image-size and the slice-stride are both limited to UINT32_MAX. Since the image-size is always at least as large as the slice-stride, it's enough to check the image-stride. 2. V11 and later: 37 bits is large enough to store any valid slice-stride. The only way we could blow this one up, would be to pass out-of-range width or height, which is already either validated by higher-level logic (gallium) or UB (vulkan). This is important, because we don't have another mandate to reject large resources on Vulkan; we can only reject due to maxResourceSize, not an individual plane. So let's move this out to the call-site. We don't need to do anything for PanVK, becuase it already checks for maxResourceSize. To keep the Gallium and Vulkan driver as similar as reasonably possible, check against the whole resource even in Gallium, where we could have gotten away with checking a plane at the time instead. Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40999>
This commit is contained in:
parent
57a80ff78c
commit
d76e4f6054
3 changed files with 46 additions and 39 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue