}
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_PITCH_ALIGNMENT => cl_prop::<cl_uint>(0),
+ CL_DEVICE_IMAGE_PITCH_ALIGNMENT => cl_prop::<cl_uint>(dev.image_pitch_alignment()),
CL_DEVICE_IMAGE_SUPPORT => cl_prop::<bool>(dev.image_supported()),
CL_DEVICE_IMAGE2D_MAX_HEIGHT => cl_prop::<usize>(dev.image_2d_size()),
CL_DEVICE_IMAGE2D_MAX_WIDTH => cl_prop::<usize>(dev.image_2d_size()),
let p = p.get_arc()?;
if !match desc.image_type {
CL_MEM_OBJECT_IMAGE1D_BUFFER => p.is_buffer(),
- CL_MEM_OBJECT_IMAGE2D => true,
+ CL_MEM_OBJECT_IMAGE2D => {
+ (p.is_buffer() && devs.iter().any(|d| d.image2d_from_buffer_supported()))
+ || p.mem_type == CL_MEM_OBJECT_IMAGE2D
+ }
_ => false,
} {
return Err(CL_INVALID_OPERATION);
// host_ptr is not NULL and image_slice_pitch = 0, image_slice_pitch is calculated as
// image_row_pitch × image_height for a 2D image array or 3D image and image_row_pitch for a 1D
// image array. If image_slice_pitch is not 0, it must be a multiple of the image_row_pitch.
+ let has_buf_parent = parent.as_ref().map_or(false, |p| p.is_buffer());
if host_ptr.is_null() {
- if desc.image_row_pitch != 0 || desc.image_slice_pitch != 0 {
+ if (desc.image_row_pitch != 0 || desc.image_slice_pitch != 0) && !has_buf_parent {
return Err(err);
}
- desc.image_row_pitch = desc.image_width * elem_size;
- desc.image_slice_pitch = desc.image_row_pitch * desc.image_height;
+
+ if desc.image_row_pitch == 0 {
+ desc.image_row_pitch = desc.image_width * elem_size;
+ }
+ if desc.image_slice_pitch == 0 {
+ desc.image_slice_pitch = desc.image_row_pitch * desc.image_height;
+ }
+
+ if has_buf_parent {
+ let pitch_alignment = devs
+ .iter()
+ .map(|d| d.image_pitch_alignment())
+ .max()
+ .unwrap() as usize;
+ if desc.image_row_pitch % (pitch_alignment * elem_size) != 0 {
+ return Err(err);
+ }
+ }
} else {
if desc.image_row_pitch == 0 {
desc.image_row_pitch = desc.image_width * elem_size;
if self.image_supported() {
add_ext(1, 0, 0, "", "__opencl_c_images");
+ if self.image2d_from_buffer_supported() {
+ add_ext(1, 0, 0, "cl_khr_image2d_from_buffer", "");
+ }
+
if self.image_read_write_supported() {
add_ext(1, 0, 0, "", "__opencl_c_read_write_images");
}
.param(pipe_cap::PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) as usize
}
+ pub fn image_pitch_alignment(&self) -> cl_uint {
+ self.screen
+ .param(pipe_cap::PIPE_CAP_LINEAR_IMAGE_PITCH_ALIGNMENT) as u32
+ }
+
pub fn image_base_address_alignment(&self) -> cl_uint {
- 0
+ self.screen
+ .param(pipe_cap::PIPE_CAP_LINEAR_IMAGE_BASE_ADDRESS_ALIGNMENT) as u32
}
pub fn image_buffer_size(&self) -> usize {
self.shader_param(pipe_shader_cap::PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS) as cl_uint
}
+ pub fn image2d_from_buffer_supported(&self) -> bool {
+ self.image_pitch_alignment() != 0 && self.image_base_address_alignment() != 0
+ }
+
pub fn image_supported(&self) -> bool {
// TODO check CL_DEVICE_IMAGE_SUPPORT reqs
self.shader_param(pipe_shader_cap::PIPE_SHADER_CAP_MAX_SHADER_IMAGES) != 0 &&