cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

krinosx
Adept I

OpenCL Image2D Format

Hello Guys,

I am starting with OpenCL to image processing... So I am starting to learn the basics of Image objects and how to upload image data to an OpenCL device.

I read the specification, even bought a book ( OpenCL in Action ) and I am doing fine until now.

But... I am facing a problem, ( I think its a problem ) about image data format.

To make my project some kind of portable I am using ANSI C and OpenCL ( to processing ) + SDL to GUI and image loading functions.

SDL load image functions give me an byte array of pixel data... the format is the same of a simple BMP 3Bytes per pixel data ( 1byte to BLUE, GREEN and RED ).

To create an image2d ( clCreateImage2d ) I got the following method declaration:





































cl_mem clCreateImage2D (cl_context context,
cl_mem_flags flags,
const cl_image_format *image_format,
size_t image_width,
size_t image_height,
size_t image_row_pitch,
void *host_ptr,
cl_int *errcode_ret)

The imageFormat argument is intriguing me... ( cl_image_format ). The docs say I can use a "CL_BGRA" format.. so I must put an extra byte for each pixel in my buffer right? ( today my buffer is [b,g,r][b,g,r]... I will add an extra byte so it will become [b,g,r,1][b,g,r,1] )... its the right approach?

What really intrigues me is the second field of cl_image_format. ( cl_channel_type image_channel_data_type ) the cl_channel_type enumeration says I can use CL_UNSIGNED_INT8 as data type... It is messing with my mind...

The docs says ( about CL_UNSIGNED_INT8 😞 Each channel component is an unnormalized unsigned 8-bit integer value.

In my host program, my byte array is made of "unsigned int" ( 4byte each )... so If I send it to a clCreateImage2D using the CL_UNSIGNED_INT8 as a cl_channel_type in my cl_image_format parameter it will work? OpenCL will convert my 4byte info to a 8byte info?

or may I convert my byte buffer from integer to long/double values?

What I am missing? I think it maybe simpler... but I am missing something I cant see... May someone give-me a hand?

0 Likes
1 Solution

Hi krinosx,

1. You can find support for CL_RGB channel format here cl_image_format. But one thing i missed in my above post is that CL_RGB format can be used only if channel data type is either CL_UNORM_SHORT_565, CL_UNORM_SHORT_555 or CL_UNORM_INT101010.

For CL_UNORM_SHORT_565: R is 5 bits, G is 6 bits and B is 5 bits.

For CL_UNORM_SHORT_555: each R, G and B is 5 bits.

For CL_UNORM_INT101010: each R, G and B is 10 bits.

For your case, as you mentioned that each R, G and B is 1 byte and hence it is recommended that you should not use CL_RGB format.

2. About channel data type: As nou pointed it correctly that it does not matter what data type you used in host program. It depends on how data is layout in memory.

Further, 24bit RGB is not supported by OpenCL and hence you have to first convert it to 32 bit RGB. To convert it to 32bit, you must set the fourth byte to a value which will be interpreted as alpha value. (It can be either first or forth byte depends on your endianess, moreover you choose the order). Now you can use image_channel_order=CL_RGBA and image_channel_data_type=CL_UNSIGNED_INT8. By doing so, OpenCL will understand that each pixel is 32bit and each component of pixel is 8bit.


Thanks,

AMD_Support

View solution in original post

6 Replies
gopal
Staff

Hi krinosx,

As we know there are two types of memory objects in OpenCL, buffer and image.

Images require a format descriptor, cl_image_format to define the size and type of data they store and the channel layout that they use to store it.

1. channel layout is specified using image_channel_order. The channel_order specifies the number of elements that make up an image element (up to four elements, based on traditional uses of RGBA pixels).

As you mentioned that each pixel is 3 bytes data (BGR). So you can specify channel layout as image_channel_order=CL_BGR. You don't need to add an extra byte to make it four bytes

2. The size of each element is specified using image_channel_data_type. The channel type specifies the size of each element. These elements can be sized from 1 to 4 bytes and in various different formats (i.e. integers or floating point).

You also mentioned that each element is made of "unsigned int" and hence you can specify the channel data type of each element as image_channel_data_type=CL_UNSIGNED_INT32.


For more detail about how images are implemented in OpenCL, please have a look on Image Convolution Example of Chapter 4 of B. Gaster, L. Howes, D. R. Kaeli, P. Mistry, D.Schaa — Heterogeneous Computing with OpenCL — 2011.pd...book.

Thanks,

AMD_Support

Hi Ratul,

thanks for your fast answer!

1. There is something strange... I cant find the CL_BGR enum element even in api reference docs or in my header files. Are you sure its really an option? I can just find the CL_BGRA in my cl.h header file. I will love to have an option to do not need to put an extra byte in my buffer.

2. About channel data type: Its not related with my host data format, right? Because my host data format is an simple 4byte integer... if I use CL_UNSIGNED_INT32 it will not be a mess??

About the book, I cant access the link you provided, but thanks for the tip! I will try to find its book and take a look in chapter 4!!

thanks!

0 Likes

Hi krinosx,

1. You can find support for CL_RGB channel format here cl_image_format. But one thing i missed in my above post is that CL_RGB format can be used only if channel data type is either CL_UNORM_SHORT_565, CL_UNORM_SHORT_555 or CL_UNORM_INT101010.

For CL_UNORM_SHORT_565: R is 5 bits, G is 6 bits and B is 5 bits.

For CL_UNORM_SHORT_555: each R, G and B is 5 bits.

For CL_UNORM_INT101010: each R, G and B is 10 bits.

For your case, as you mentioned that each R, G and B is 1 byte and hence it is recommended that you should not use CL_RGB format.

2. About channel data type: As nou pointed it correctly that it does not matter what data type you used in host program. It depends on how data is layout in memory.

Further, 24bit RGB is not supported by OpenCL and hence you have to first convert it to 32 bit RGB. To convert it to 32bit, you must set the fourth byte to a value which will be interpreted as alpha value. (It can be either first or forth byte depends on your endianess, moreover you choose the order). Now you can use image_channel_order=CL_RGBA and image_channel_data_type=CL_UNSIGNED_INT8. By doing so, OpenCL will understand that each pixel is 32bit and each component of pixel is 8bit.


Thanks,

AMD_Support

Hi support team!


Thanks for your help!! I think its now clear! Just some considerations:

1. I think the misunderstanding in the last reply was about CL_BGR... I can find the CL_RGB in my headers... the problem is the CL_BGR it does not exist... but, as you explained, in my case, with 1byte per channel, I may not use CL_BGR or CL_RGB but I must use CL_BGRA. Its fine, I will just convert my image data to add 1 byte to alpha value and its done!

2. About data type:

I'm embarrassed, it was a big misunderstanding of mine.. When I read the docs I saw CL_UNSIGNED_INT8 and thought that it was 8 BYTEs long.. it was my mistake... After reading you reply I realised its 8 BITs long, or 1byte... so, its fine, all make sense now!

Sorry about wasting your time with this dumb question about CL_UNSIGNED_INT8 format!

I really appreciate your replies and attention!!

Thanks so much!

0 Likes
nou
Exemplar

yes you must add another byte so it is four per pixel.

if you use unsigned int that mean each pixel is in single int? it doesn’t matter what data type is used in host program. what matter is real layout of data. so if red pixel have value 0x00FF0000 and blue one 0x000000FF then you are good. (you must be careful about that x86 architecture is little endian) but if your pixel have three int values then you must convert it.

Hi Nou!!

Thanks for your help!

Well, my original data is packed as a byte array with 1byte for each information, so, 3 bytes for each pixel in the BGR order. I was reading it as unsigned integers, so I can put the last byte of my integer ( my int have 4 bytes ) as Alpha information.

You say 'It doesn't matter what data type is used in host program'... right, I agree, but how do I tell the OpenCL that my data type is 4byte longs for each pixel? ( in OpenGL its pretty simple, we does not use enums to specify the buffer data layout, we just put the size of data as integer parameters ) If I use the cl_image_format.image_channel_data_type=CL_UNSIGNED_INT32.  will OpenCL understand my data buffer as a 32bytes per element ( per pixel ) ?

This is the point that is messing with me

Thanks guys! I really appreciate your help!

0 Likes