rusticl/device: limit CL_DEVICE_IMAGE_MAX_BUFFER_SIZE more aggressively

We can't exceed c_int::MAX, because the CTS casts to ints in a few places.

We also need to take into account max pixel size when restricting to
max_mem_alloc as this cap is pixel based, not byte based.

Cc: mesa-stable

Reviewed-by: @LingMan
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30739>
(cherry picked from commit eef1af8128)
This commit is contained in:
Karol Herbst 2024-08-15 14:34:38 +02:00 committed by Eric Engestrom
parent 54fea2435e
commit 6f48c16b0f
5 changed files with 18 additions and 8 deletions

View file

@ -984,7 +984,7 @@
"description": "rusticl/device: limit CL_DEVICE_IMAGE_MAX_BUFFER_SIZE more aggressively",
"nominated": true,
"nomination_type": 0,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null,
"notes": null

View file

@ -106,7 +106,7 @@ impl CLInfo<cl_device_info> for cl_device_id {
cl_prop::<cl_uint>(dev.image_base_address_alignment())
}
CL_DEVICE_IMAGE_MAX_ARRAY_SIZE => cl_prop::<usize>(dev.image_array_size()),
CL_DEVICE_IMAGE_MAX_BUFFER_SIZE => cl_prop::<usize>(dev.image_buffer_size()),
CL_DEVICE_IMAGE_MAX_BUFFER_SIZE => cl_prop::<usize>(dev.image_buffer_max_size_pixels()),
CL_DEVICE_IMAGE_PITCH_ALIGNMENT => cl_prop::<cl_uint>(dev.image_pitch_alignment()),
CL_DEVICE_IMAGE_SUPPORT => cl_prop::<bool>(dev.caps.has_images),
CL_DEVICE_IMAGE2D_MAX_HEIGHT => cl_prop::<usize>(dev.caps.image_2d_size as usize),

View file

@ -454,7 +454,7 @@ fn validate_image_desc(
let max_size = if dims == 3 {
devs.iter().map(|d| d.image_3d_size()).min()
} else if desc.image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER {
devs.iter().map(|d| d.image_buffer_size()).min()
devs.iter().map(|d| d.image_buffer_max_size_pixels()).min()
} else {
devs.iter().map(|d| d.caps.image_2d_size as usize).min()
}

View file

@ -452,7 +452,7 @@ impl Device {
// The minimum value is 2048 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE
self.image_array_size() < 2048 ||
// The minimum value is 65536 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE
self.image_buffer_size() < 65536
self.image_buffer_max_size_pixels() < 65536
{
return true;
}
@ -509,7 +509,7 @@ impl Device {
// The minimum value is 256 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE
if self.image_array_size() < 256 ||
// The minimum value is 2048 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE
self.image_buffer_size() < 2048
self.image_buffer_max_size_pixels() < 2048
{
res = CLVersion::Cl1_1;
}
@ -858,11 +858,18 @@ impl Device {
}
}
pub fn image_buffer_size(&self) -> usize {
pub fn image_buffer_max_size_pixels(&self) -> usize {
if self.caps.has_images {
min(
// the CTS requires it to not exceed `CL_MAX_MEM_ALLOC_SIZE`
self.max_mem_alloc(),
// The CTS requires it to not exceed `CL_MAX_MEM_ALLOC_SIZE`, also we need to divide
// by the max pixel size, because this cap is in pixels, not bytes.
//
// The CTS also casts this to int in a couple of places,
// see: https://github.com/KhronosGroup/OpenCL-CTS/issues/2056
min(
self.max_mem_alloc() / MAX_PIXEL_SIZE_BYTES,
c_int::MAX as cl_ulong,
),
self.screen
.param(pipe_cap::PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT)
as cl_ulong,

View file

@ -11,6 +11,9 @@ use std::ptr::addr_of;
use std::ptr::addr_of_mut;
use std::sync::Once;
/// Maximum size a pixel can be across all supported image formats.
pub const MAX_PIXEL_SIZE_BYTES: u64 = 4 * 4;
#[repr(C)]
pub struct Platform {
dispatch: &'static cl_icd_dispatch,