panvk: Lower maxImageDimension{2D,3D,Cube} to match the HW caps

Maximum texture dimension is 2^16, but we're limited by the 32-bit
fields that are used to pass strides/sizes in various descriptors.
Assuming RGBA32_FLOAT is the biggest format we support, that gives us a
16k-1 image size for 2D and cube map, and 512 for 3D.

Change our GetPhysicalDeviceImageFormatProperties2() implementation so
that smaller formats can still advertise bigger image sizes.

Fixes: d5ed77800e ("panvk: Fix GetPhysicalDeviceProperties2() to report accurate info")
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35555>
This commit is contained in:
Boris Brezillon 2025-06-20 10:37:00 +02:00
parent c4f1dd1e2d
commit e25a91d919
2 changed files with 65 additions and 12 deletions

View file

@ -759,6 +759,52 @@ panvk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
}
}
#define MAX_IMAGE_SIZE_PX (1 << 16)
static VkExtent3D
get_max_2d_image_size(struct panvk_physical_device *phys_dev, VkFormat format)
{
const uint32_t max_img_size_B = UINT32_MAX;
const enum pipe_format pfmt = vk_format_to_pipe_format(format);
const uint32_t fmt_blksize = util_format_get_blocksize(pfmt);
/* Evenly split blocks across all axis. */
const uint32_t max_size_el = floor(sqrt(max_img_size_B / fmt_blksize));
const VkExtent3D ret = {
.width = MIN2(max_size_el * util_format_get_blockwidth(pfmt),
MAX_IMAGE_SIZE_PX),
.height = MIN2(max_size_el * util_format_get_blockheight(pfmt),
MAX_IMAGE_SIZE_PX),
.depth = 1,
};
assert(ret.width >= phys_dev->vk.properties.maxImageDimension2D);
assert(ret.height >= phys_dev->vk.properties.maxImageDimension2D);
return ret;
}
static VkExtent3D
get_max_3d_image_size(struct panvk_physical_device *phys_dev, VkFormat format)
{
const uint32_t max_img_size_B = UINT32_MAX;
enum pipe_format pfmt = vk_format_to_pipe_format(format);
uint32_t fmt_blksize = util_format_get_blocksize(pfmt);
/* Evenly split blocks across each axis. */
const uint32_t max_size_el = floor(cbrt(max_img_size_B / fmt_blksize));
const VkExtent3D ret = {
.width = MIN2(max_size_el * util_format_get_blockwidth(pfmt),
MAX_IMAGE_SIZE_PX),
.height = MIN2(max_size_el * util_format_get_blockheight(pfmt),
MAX_IMAGE_SIZE_PX),
.depth = MIN2(max_size_el * util_format_get_blockdepth(pfmt),
MAX_IMAGE_SIZE_PX),
};
assert(ret.width >= phys_dev->vk.properties.maxImageDimension3D);
assert(ret.height >= phys_dev->vk.properties.maxImageDimension3D);
assert(ret.depth >= phys_dev->vk.properties.maxImageDimension3D);
return ret;
}
static VkResult
get_image_format_properties(struct panvk_physical_device *physical_device,
const VkPhysicalDeviceImageFormatInfo2 *info,
@ -838,17 +884,13 @@ get_image_format_properties(struct panvk_physical_device *physical_device,
maxArraySize = 1 << 16;
break;
case VK_IMAGE_TYPE_2D:
maxExtent.width = 1 << 16;
maxExtent.height = 1 << 16;
maxExtent.depth = 1;
maxMipLevels = 17; /* log2(maxWidth) + 1 */
maxExtent = get_max_2d_image_size(physical_device, info->format);
maxMipLevels = util_logbase2(maxExtent.width) + 1;
maxArraySize = 1 << 16;
break;
case VK_IMAGE_TYPE_3D:
maxExtent.width = 1 << 16;
maxExtent.height = 1 << 16;
maxExtent.depth = 1 << 16;
maxMipLevels = 17; /* log2(maxWidth) + 1 */
maxExtent = get_max_3d_image_size(physical_device, info->format);
maxMipLevels = util_logbase2(maxExtent.width) + 1;
maxArraySize = 1;
break;
}

View file

@ -533,11 +533,22 @@ panvk_per_arch(get_physical_device_properties)(
.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
/* Vulkan 1.0 limits */
/* Maximum texture dimension is 2^16. */
/* Maximum texture dimension is 2^16, but we're limited by the
* size/surface-stride fields. The size/surface_stride field is 32-bit
* on v10-, so let's take that as a reference for now.
* The following limits are chosen so we don't overflow these
* size/surface_stride fields. We choose them so they are a power-of-two,
* except for 2D/Cube dimensions where taking a power-of-two would be
* too limiting, so we pick power-of-two-minus-one, which makes things
* fit exactly in our 32-bit budget.
*
* TODO: increase the limit on v11+ once we have all the necessary bits
* patched to handle the size/stride field extension.
*/
.maxImageDimension1D = (1 << 16),
.maxImageDimension2D = (1 << 16),
.maxImageDimension3D = (1 << 16),
.maxImageDimensionCube = (1 << 16),
.maxImageDimension2D = (1 << 14) - 1,
.maxImageDimension3D = (1 << 9),
.maxImageDimensionCube = (1 << 14) - 1,
.maxImageArrayLayers = (1 << 16),
/* Currently limited by the 1D texture size, which is 2^16.
* TODO: If we expose buffer views as 2D textures, we can increase the