在clCreateImage()函数中,参数image_desc指向cl_image_desc结构的指针。cl_image_desc图像描述符描述了图像或图像阵列的类型和位数。cl_image_desc结构定义如下:
typedef struct _cl_image_desc
{
cl_mem_object_type image_type,
size_t image_width;
size_t image_height;
size_t image_depth;
size_t image_array_size;
size_t image_row_pitch;
size_t image_slice_pitch;
cl_uint num_mip_levels;
cl_uint num_samples;
cl_mem mem_object;
} cl_image_desc;
image_type为图像类型,必须是图像格式描述符中列出的图像类型。
image_width为图像的宽度,单位为像素。对于2维图像和图像阵列,图像宽度必须小于CL_DEVICE_IMAGE2D_MAX_WIDTH。对于3维图像,图像宽度必须小于CL_DEVICE_IMAGE3D_MAX_WIDTH。对于1维图像缓冲,图像宽度必须小于CL_DEVICE_IMAGE_MAX_BUFFER_SIZE。对于1维图像和1维图像阵列,图像宽度必须小于CL_DEVICE_IMAGE2D_MAX_WIDTH。
image_height为图像高度,单位为像素。只对2维或3维图像,或2维图像阵列才有效。对于2维图像或图像阵列,图像高度必须小于CL_DEIVCE_IMAGE2D_MAX_HEIGHT。对于3维图像,图像高度必须小于CL_DEVICE_IMAGE3D_MAX_HEIGHT。
image_depth为图像深度,单位为像素。只有图像为3维图像时才有效,其值必须小于CL_DEVICE_IMAGE3D_MAX_DEPTH。
image_array_size为图像阵列中的图像个数。只有图像为1维或者2维图像时才有效。如果设置了image_array_size,其值必须小于CL_DEVICE_IMAGE_ARRAY_SIZE,大于等于1。
image_row_pitch为扫描列间隔,单位为字节。如果host_ptr为NULL,则其值必须是0,如果host_ptr不是NULL,则其值可以为0或者大于等于image_width乘以元素大小;如果host_ptr不是NULL,并且image_row_pitch=0,则用image_width乘以元素大小取代image_row_pitch。如果image_row_pitch不为0,则必须是图像像素所占字节数的整数倍。
image_slice_pitch为3维图像中每个2维平面的大小,或者1维、2维图像阵列中每个图像的大小,单位为字节。如果host_ptr为NULL,其值必须是0;如果host_ptr不是NULL,对于2维图像阵列或者3维图像,可以是0或者大于等于image_row_pitch*image_height;对于1维图像阵列,可以是0或者大于等于image_row_pitch。如果host_ptr不是NULL,并且image_slice_pitch=0,对于2维图像阵列或3维图像,则用image_row_pitch*image_height取代image_slice_pitch;对于1维图像阵列,则用image_row_pitch。如果image_slice_pitch不为0,则必须是image_row_pitch的整数倍。
num_mip_levels和num_samples必须为0。
mem_object为一个有效的缓冲区或图像存储器对象。如果图像类型为CL_MEM_OBJECT_IMAGE1D_BUFFER或CL_MEM_OBJECT_IMAGE2D(由一个缓冲区对象创建一个2维图像),则mem_object可以为一个缓冲存储器对象。如果图像类型为CL_MEM_OBJECT_IMAGE2D(由另一个图像对象创建一个图像对象),则mem_object可以为一个图像对象。对于其他情况,mem_object的值必须为NULL。
下图展示了一个3维图像对象。对于大部分图像,我们可以通过图像每行像素个数乘以像素元素大小来确定图像的行间距。但是为了在内存边界对齐,会在每行末尾填充位数,在这种情况下就没办法使用上述办法来计算图像行间距。所以在cl_image_desc结构体中有image_row_pitch成员,用来表示图像每一行的大小。类似地,在cl_image_desc结构体中有image_slice_pitch成员,用来表示每个2维平面的大小。
如下代码展示了根据图像描述符和图像格式描述符创建一个2维图像:
//图像描述符
cl_image_desc desc;
memset(&desc, 0, sizeof(desc));
desc.image_type = CL_MEM_OBJECT_IMAGE2D;
desc.image_width = 100;
desc.image_height = 100;
//图像格式描述符
cl_image_format rgb_format;
rgb_format.image_channel_order = CL_RGB;
rgb_format.image_channel_data_type = CL_UNSIGNED_INT8;
cl_mem d_inputImage = clCreateImage(context, CL_MEM_READ_ONLY,
&rgb_format, &desc, NULL, &status);