From f6fb189cbd0732e0fb0cefd626222bca51babe87 Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Sat, 15 Apr 2023 00:18:20 +0200 Subject: [PATCH] rusticl/mem: more region and origin validation Fixes piglit's api@clenqueuefillimage test Signed-off-by: Karol Herbst Part-of: --- .../drivers/llvmpipe/ci/llvmpipe-rusticl-fails.txt | 3 -- src/gallium/frontends/rusticl/api/memory.rs | 56 +++++++++++++++++----- src/gallium/frontends/rusticl/core/memory.rs | 5 ++ 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/ci/llvmpipe-rusticl-fails.txt b/src/gallium/drivers/llvmpipe/ci/llvmpipe-rusticl-fails.txt index e53c880..35c6b9d 100644 --- a/src/gallium/drivers/llvmpipe/ci/llvmpipe-rusticl-fails.txt +++ b/src/gallium/drivers/llvmpipe/ci/llvmpipe-rusticl-fails.txt @@ -9,9 +9,6 @@ api@clcompileprogram,Fail # Failed to compile binary program. api@clcreateprogramwithbinary,Fail -# Failed (error code: CL_SUCCESS): CL_INVALID_VALUE if values in region do not follow rules described in the argument description for region. -api@clenqueuefillimage,Fail - # Failed (error code: CL_INVALID_COMMAND_QUEUE): Get size of CL_QUEUE_SIZE. api@clgetcommandqueueinfo,Fail diff --git a/src/gallium/frontends/rusticl/api/memory.rs b/src/gallium/frontends/rusticl/api/memory.rs index 04b1bd4..e5c0546 100644 --- a/src/gallium/frontends/rusticl/api/memory.rs +++ b/src/gallium/frontends/rusticl/api/memory.rs @@ -538,10 +538,26 @@ fn validate_image_desc( } fn validate_image_bounds(i: &Mem, origin: CLVec, region: CLVec) -> CLResult<()> { + let dims = i.image_desc.dims_with_array(); let bound = region + origin; if bound > i.image_desc.size() { return Err(CL_INVALID_VALUE); } + + // If image is a 2D image object, origin[2] must be 0. If image is a 1D image or 1D image buffer + // object, origin[1] and origin[2] must be 0. If image is a 1D image array object, origin[2] + // must be 0. + if dims < 3 && origin[2] != 0 || dims < 2 && origin[1] != 0 { + return Err(CL_INVALID_VALUE); + } + + // If image is a 2D image object, region[2] must be 1. If image is a 1D image or 1D image buffer + // object, region[1] and region[2] must be 1. If image is a 1D image array object, region[2] + // must be 1. The values in region cannot be 0. + if dims < 3 && region[2] != 1 || dims < 2 && region[1] != 1 || region.contains(&0) { + return Err(CL_INVALID_VALUE); + } + Ok(()) } @@ -1677,6 +1693,8 @@ pub fn enqueue_read_image( // CL_INVALID_VALUE if the region being read or written specified by origin and region is out of // bounds. + // CL_INVALID_VALUE if values in origin and region do not follow rules described in the argument + // description for origin and region. validate_image_bounds(&i, o, r)?; // If row_pitch (or input_row_pitch) is set to 0, the appropriate row pitch is calculated based @@ -1713,7 +1731,6 @@ pub fn enqueue_read_image( }), ) - //• CL_INVALID_VALUE if values in origin and region do not follow rules described in the argument description for origin and region. //• CL_INVALID_IMAGE_SIZE if image dimensions (image width, height, specified or compute row and/or slice pitch) for image are not supported by device associated with queue. //• CL_IMAGE_FORMAT_NOT_SUPPORTED if image format (image channel order and data type) for image are not supported by device associated with queue. //• CL_INVALID_OPERATION if the device associated with command_queue does not support images (i.e. CL_DEVICE_IMAGE_SUPPORT specified in the Device Queries table is CL_FALSE). @@ -1766,6 +1783,8 @@ pub fn enqueue_write_image( // CL_INVALID_VALUE if the region being read or written specified by origin and region is out of // bounds. + // CL_INVALID_VALUE if values in origin and region do not follow rules described in the argument + // description for origin and region. validate_image_bounds(&i, o, r)?; // If row_pitch (or input_row_pitch) is set to 0, the appropriate row pitch is calculated based @@ -1802,7 +1821,6 @@ pub fn enqueue_write_image( }), ) - //• CL_INVALID_VALUE if values in origin and region do not follow rules described in the argument description for origin and region. //• CL_INVALID_IMAGE_SIZE if image dimensions (image width, height, specified or compute row and/or slice pitch) for image are not supported by device associated with queue. //• CL_IMAGE_FORMAT_NOT_SUPPORTED if image format (image channel order and data type) for image are not supported by device associated with queue. //• CL_INVALID_OPERATION if the device associated with command_queue does not support images (i.e. CL_DEVICE_IMAGE_SUPPORT specified in the Device Queries table is CL_FALSE). @@ -1845,11 +1863,11 @@ pub fn enqueue_copy_image( let src_origin = unsafe { CLVec::from_raw(src_origin) }; // CL_INVALID_VALUE if the 2D or 3D rectangular region specified by src_origin and - // src_origin + region refers to a region outside src_image, ... + // src_origin + region refers to a region outside src_image, or if the 2D or 3D rectangular + // region specified by dst_origin and dst_origin + region refers to a region outside dst_image. + // CL_INVALID_VALUE if values in src_origin, dst_origin and region do not follow rules described + // in the argument description for src_origin, dst_origin and region. validate_image_bounds(&src_image, src_origin, region)?; - - // ... or if the 2D or 3D rectangular region specified by dst_origin and dst_origin + region - // refers to a region outside dst_image. validate_image_bounds(&dst_image, dst_origin, region)?; create_and_queue( @@ -1863,7 +1881,6 @@ pub fn enqueue_copy_image( }), ) - //• CL_INVALID_VALUE if values in src_origin, dst_origin and region do not follow rules described in the argument description for src_origin, dst_origin and region. //• CL_INVALID_IMAGE_SIZE if image dimensions (image width, height, specified or compute row and/or slice pitch) for src_image or dst_image are not supported by device associated with queue. //• CL_IMAGE_FORMAT_NOT_SUPPORTED if image format (image channel order and data type) for src_image or dst_image are not supported by device associated with queue. //• CL_INVALID_OPERATION if the device associated with command_queue does not support images (i.e. CL_DEVICE_IMAGE_SUPPORT specified in the Device Queries table is CL_FALSE). @@ -1900,6 +1917,8 @@ pub fn enqueue_fill_image( // CL_INVALID_VALUE if the region being filled as specified by origin and region is out of // bounds. + // CL_INVALID_VALUE if values in origin and region do not follow rules described in the argument + // description for origin and region. validate_image_bounds(&i, origin, region)?; // we have to copy memory and it's always a 4 component int value @@ -1914,7 +1933,6 @@ pub fn enqueue_fill_image( Box::new(move |q, ctx| i.fill_image(q, ctx, &fill_color, &origin, ®ion)), ) - //• CL_INVALID_VALUE if values in origin and region do not follow rules described in the argument description for origin and region. //• CL_INVALID_IMAGE_SIZE if image dimensions (image width, height, specified or compute row and/or slice pitch) for image are not supported by device associated with queue. //• CL_IMAGE_FORMAT_NOT_SUPPORTED if image format (image channel order and data type) for //image are not supported by device associated with queue. @@ -1951,6 +1969,12 @@ pub fn enqueue_copy_buffer_to_image( let src_origin = CLVec::new([src_offset, 0, 0]); let dst_origin = unsafe { CLVec::from_raw(dst_origin) }; + // CL_INVALID_VALUE if values in dst_origin and region do not follow rules described in the + // argument description for dst_origin and region. + // CL_INVALID_VALUE if the 1D, 2D or 3D rectangular region specified by dst_origin and + // dst_origin + region refer to a region outside dst_image, + validate_image_bounds(&dst, dst_origin, region)?; + create_and_queue( q, CL_COMMAND_COPY_BUFFER_TO_IMAGE, @@ -1961,8 +1985,7 @@ pub fn enqueue_copy_buffer_to_image( ) //• CL_INVALID_MEM_OBJECT if src_buffer is not a valid buffer object or dst_image is not a valid image object or if dst_image is a 1D image buffer object created from src_buffer. - //• CL_INVALID_VALUE if the 1D, 2D or 3D rectangular region specified by dst_origin and dst_origin + region refer to a region outside dst_image, or if the region specified by src_offset and src_offset + src_cb refer to a region outside src_buffer. - //• CL_INVALID_VALUE if values in dst_origin and region do not follow rules described in the argument description for dst_origin and region. + //• CL_INVALID_VALUE ... if the region specified by src_offset and src_offset + src_cb refer to a region outside src_buffer. //• CL_MISALIGNED_SUB_BUFFER_OFFSET if src_buffer is a sub-buffer object and offset specified when the sub-buffer object is created is not aligned to CL_DEVICE_MEM_BASE_ADDR_ALIGN value for device associated with queue. //• CL_INVALID_IMAGE_SIZE if image dimensions (image width, height, specified or compute row and/or slice pitch) for dst_image are not supported by device associated with queue. //• CL_IMAGE_FORMAT_NOT_SUPPORTED if image format (image channel order and data type) for dst_image are not supported by device associated with queue. @@ -2001,6 +2024,13 @@ pub fn enqueue_copy_image_to_buffer( let src_origin = unsafe { CLVec::from_raw(src_origin) }; let dst_origin = CLVec::new([dst_offset, 0, 0]); + // CL_INVALID_VALUE if values in src_origin and region do not follow rules described in the + // argument description for src_origin and region. + // CL_INVALID_VALUE if the 1D, 2D or 3D rectangular region specified by src_origin and + // src_origin + region refers to a region outside src_image, or if the region specified by + // dst_offset and dst_offset + dst_cb to a region outside dst_buffer. + validate_image_bounds(&src, src_origin, region)?; + create_and_queue( q, CL_COMMAND_COPY_IMAGE_TO_BUFFER, @@ -2011,8 +2041,7 @@ pub fn enqueue_copy_image_to_buffer( ) //• CL_INVALID_MEM_OBJECT if src_image is not a valid image object or dst_buffer is not a valid buffer object or if src_image is a 1D image buffer object created from dst_buffer. - //• CL_INVALID_VALUE if the 1D, 2D or 3D rectangular region specified by src_origin and src_origin + region refers to a region outside src_image, or if the region specified by dst_offset and dst_offset + dst_cb to a region outside dst_buffer. - //• CL_INVALID_VALUE if values in src_origin and region do not follow rules described in the argument description for src_origin and region. + //• CL_INVALID_VALUE ... if the region specified by dst_offset and dst_offset + dst_cb to a region outside dst_buffer. //• CL_MISALIGNED_SUB_BUFFER_OFFSET if dst_buffer is a sub-buffer object and offset specified when the sub-buffer object is created is not aligned to CL_DEVICE_MEM_BASE_ADDR_ALIGN value for device associated with queue. This error code is missing before version 1.1. //• CL_INVALID_IMAGE_SIZE if image dimensions (image width, height, specified or compute row and/or slice pitch) for src_image are not supported by device associated with queue. //• CL_IMAGE_FORMAT_NOT_SUPPORTED if image format (image channel order and data type) for src_image are not supported by device associated with queue. @@ -2056,6 +2085,8 @@ pub fn enqueue_map_image( let origin = unsafe { CLVec::from_raw(origin) }; // CL_INVALID_VALUE if region being mapped given by (origin, origin + region) is out of bounds + // CL_INVALID_VALUE if values in origin and region do not follow rules described in the argument + // description for origin and region. validate_image_bounds(&i, origin, region)?; let mut dummy_slice_pitch: usize = 0; @@ -2089,7 +2120,6 @@ pub fn enqueue_map_image( Ok(ptr) - //• CL_INVALID_VALUE if values in origin and region do not follow rules described in the argument description for origin and region. //• CL_INVALID_IMAGE_SIZE if image dimensions (image width, height, specified or compute row and/or slice pitch) for image are not supported by device associated with queue. //• CL_IMAGE_FORMAT_NOT_SUPPORTED if image format (image channel order and data type) for image are not supported by device associated with queue. //• CL_MAP_FAILURE if there is a failure to map the requested region into the host address space. This error cannot occur for image objects created with CL_MEM_USE_HOST_PTR or CL_MEM_ALLOC_HOST_PTR. diff --git a/src/gallium/frontends/rusticl/core/memory.rs b/src/gallium/frontends/rusticl/core/memory.rs index 060529e..87dabeb 100644 --- a/src/gallium/frontends/rusticl/core/memory.rs +++ b/src/gallium/frontends/rusticl/core/memory.rs @@ -136,6 +136,11 @@ pub trait CLImageDescInfo { self.type_info().0 } + fn dims_with_array(&self) -> u8 { + let array: u8 = self.is_array().into(); + self.dims() + array + } + fn has_slice(&self) -> bool { self.dims() == 3 || self.is_array() } -- 2.7.4