From c8d7fad1534702973074429cf6752e9c33fb147c Mon Sep 17 00:00:00 2001 From: Ahmed Hesham Date: Tue, 31 Mar 2026 00:09:37 +0100 Subject: [PATCH] rusticl: return correct error from clCreateSubBuffer From the OpenCL specification, `clCreateSubBuffer` should return: `CL_MISALIGNED_SUB_BUFFER_OFFSET` if there are no devices in `context` associated with `buffer` for which the `origin` field of the `cl_buffer_region` structure passed in `buffer_create_info` is aligned to the `CL_DEVICE_MEM_BASE_ADDR_ALIGN` value. This was previously unhandled in the entrypoint, marked as TODO. Add two functions to `Device` for querying the address alignment in both bits and bytes, for convenience. Properly retrieving the alignment value from the underlying device/screen is still marked as TODO. Signed-off-by: Ahmed Hesham Reviewed-by: Karol Herbst Part-of: --- src/gallium/frontends/rusticl/api/device.rs | 3 +-- src/gallium/frontends/rusticl/api/memory.rs | 15 ++++++++++++--- src/gallium/frontends/rusticl/core/device.rs | 10 ++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/gallium/frontends/rusticl/api/device.rs b/src/gallium/frontends/rusticl/api/device.rs index 98840dcf021..379023d51df 100644 --- a/src/gallium/frontends/rusticl/api/device.rs +++ b/src/gallium/frontends/rusticl/api/device.rs @@ -200,8 +200,7 @@ unsafe impl CLInfo for cl_device_id { CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS => v.write::(dev.max_grid_dimensions()), CL_DEVICE_MAX_WORK_ITEM_SIZES => v.write::<&[usize]>(&dev.max_block_sizes()), CL_DEVICE_MAX_WRITE_IMAGE_ARGS => v.write::(dev.caps.max_write_images), - // TODO proper retrival from devices - CL_DEVICE_MEM_BASE_ADDR_ALIGN => v.write::(0x1000), + CL_DEVICE_MEM_BASE_ADDR_ALIGN => v.write::(dev.mem_base_addr_align_bits()), CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE => { v.write::(16 * size_of::() as cl_uint) } diff --git a/src/gallium/frontends/rusticl/api/memory.rs b/src/gallium/frontends/rusticl/api/memory.rs index ef949eef067..a60537d907f 100644 --- a/src/gallium/frontends/rusticl/api/memory.rs +++ b/src/gallium/frontends/rusticl/api/memory.rs @@ -452,10 +452,19 @@ fn create_sub_buffer( _ => return Err(CL_INVALID_VALUE), }; - Ok(MemBase::new_sub_buffer(b, flags, offset, size).into_cl()) + // CL_MISALIGNED_SUB_BUFFER_OFFSET if there are no devices in context associated with buffer for + // which offset is aligned to CL_DEVICE_MEM_BASE_ADDR_ALIGN. + let is_aligned_for_any_dev = b + .context + .devs + .iter() + .any(|&dev| offset % dev.mem_base_addr_align_bytes() == 0); - // TODO - // CL_MISALIGNED_SUB_BUFFER_OFFSET if there are no devices in context associated with buffer for which the origin field of the cl_buffer_region structure passed in buffer_create_info is aligned to the CL_DEVICE_MEM_BASE_ADDR_ALIGN value. + if !is_aligned_for_any_dev { + return Err(CL_MISALIGNED_SUB_BUFFER_OFFSET); + } + + Ok(MemBase::new_sub_buffer(b, flags, offset, size).into_cl()) } #[cl_entrypoint(clSetMemObjectDestructorCallback)] diff --git a/src/gallium/frontends/rusticl/core/device.rs b/src/gallium/frontends/rusticl/core/device.rs index bac5df0f808..5cf9be80f85 100644 --- a/src/gallium/frontends/rusticl/core/device.rs +++ b/src/gallium/frontends/rusticl/core/device.rs @@ -1362,6 +1362,16 @@ impl DeviceBase { } impl Device { + pub fn mem_base_addr_align_bytes(&self) -> usize { + // TODO: proper retrieval from the underlying device/screen + 0x200 + } + + pub fn mem_base_addr_align_bits(&self) -> u32 { + const BITS_PER_BYTE: u32 = 8; + (self.mem_base_addr_align_bytes() as u32) * BITS_PER_BYTE + } + fn new(screen: PipeScreenWithLdev) -> Option { if !Self::check_valid(&screen) { return None;