pvr: Fix cubemap layer stride

The hw calculates the layer stride with the assumption of a full
mip chain being there even though certain levels might never be
used.

Fix the `layer_size` by accounting for any missing mip levels.

Fixes: 8991e6464 ("pvr: Add a Vulkan driver for Imagination Technologies PowerVR Rogue GPUs")
Reported-by: James Glanville <james.glanville@imgtec.com>
Signed-off-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com>
Reviewed-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25344>
This commit is contained in:
Karmjit Mahil 2023-09-19 17:08:41 +01:00 committed by Marge Bot
parent 3808cb0696
commit 2a3aa6da50

View file

@ -98,20 +98,36 @@ static void pvr_image_setup_mip_levels(struct pvr_image *image)
image->layer_size = 0;
for (uint32_t i = 0; i < image->vk.mip_levels; i++) {
const uint32_t height = u_minify(extent.height, i);
const uint32_t width = u_minify(extent.width, i);
const uint32_t depth = u_minify(extent.depth, i);
struct pvr_mip_level *mip_level = &image->mip_levels[i];
mip_level->pitch = cpp * ALIGN(width, extent_alignment);
mip_level->height_pitch = ALIGN(height, extent_alignment);
mip_level->pitch = cpp * ALIGN(extent.width, extent_alignment);
mip_level->height_pitch = ALIGN(extent.height, extent_alignment);
mip_level->size = image->vk.samples * mip_level->pitch *
mip_level->height_pitch *
ALIGN(depth, extent_alignment);
ALIGN(extent.depth, extent_alignment);
mip_level->size = ALIGN(mip_level->size, level_alignment);
mip_level->offset = image->layer_size;
image->layer_size += mip_level->size;
extent.height = u_minify(extent.height, 1);
extent.width = u_minify(extent.width, 1);
extent.depth = u_minify(extent.depth, 1);
}
/* The hw calculates layer strides as if a full mip chain up until 1x1x1
* were present so we need to account for that in the `layer_size`.
*/
while (extent.height != 1 || extent.width != 1 || extent.depth != 1) {
const uint32_t height_pitch = ALIGN(extent.height, extent_alignment);
const uint32_t pitch = cpp * ALIGN(extent.width, extent_alignment);
image->layer_size += image->vk.samples * pitch * height_pitch *
ALIGN(extent.depth, extent_alignment);
extent.height = u_minify(extent.height, 1);
extent.width = u_minify(extent.width, 1);
extent.depth = u_minify(extent.depth, 1);
}
/* TODO: It might be useful to store the alignment in the image so it can be