Results 1 to 5 of 5

Thread: RGBA to (single channel) grayscale : clEnqueueReadBuffer pbl

  1. #1

    RGBA to (single channel) grayscale : clEnqueueReadBuffer pbl

    Hi,

    I'm trying to convert RGBA grayscale image to single channel buffer. But I have problem with clEnqueueReadBuffer . There is no compilation error but during execution, "Bus error " at execution.

    Code :
    error = clEnqueueReadBuffer(command_queue,
    							gpu_graybuffer,
    							CL_TRUE,
    							0,
    							sizeof(unsigned char)*SIZE,
    							&cpu_graybuffer,
    							0, NULL, NULL);

    additional codes :
    Code :
    #define WIDTH 32
    #define HEIGHT 32
     
    #define SIZE WIDTH * HEIGHT
    ...
    unsigned char *cpu_graybuffer;
    cpu_graybuffer = (unsigned char*)malloc(SIZE);
    ...
    cl_mem gpu_image = clCreateImage2D (context,
    									CL_MEM_READ_ONLY ,
    									&format,
    									width,
    									height,
    									rowpitch,
    									0,
    									&error);
    ...
     
    cl_mem gpu_graybuffer = clCreateBuffer (	context,
     
    										CL_MEM_WRITE_ONLY,
     
    										sizeof(unsigned char)*SIZE,
     
    										NULL,
     
    										&error);

    and maybe where the problem comes, the kernel :

    Code :
    // rgb to grayscale & multi-channel to simple channel
    __kernel void rgb_to_gray(__read_only image2d_t image, __global unsigned char *grayscale)	
    {
    	const sampler_t sampler=CLK_NORMALIZED_COORDS_FALSE|CLK_ADDRESS_CLAMP|CLK_FILTER_NEAREST;
    	int x = get_global_id(0);		// width
    	int y = get_global_id(1);		// height
    	uint4 pixel;
     
    	//READ PIXEL
    	pixel = read_imageui(imageIn,sampler,(int2)(x,y));
     
    	grayscale[ (HEIGHT-y-1)  *  HEIGHT + x ] = pixel.x;
    //	grayscale[0]='a';	
    }
     
    Maybe, "clEnqueueCopyImageToBuffer" can be another/better solution? 
     
    Thanks for sharing your experience.

  2. #2
    Senior Member
    Join Date
    May 2010
    Location
    Toronto, Canada
    Posts
    845

    Re: RGBA to (single channel) grayscale : clEnqueueReadBuffer

    Okay, so your source image data is grayscale (1 byte per pixel). What is the value of "format" that you pass to clCreateImage2D()?

    You are right that clEnqueueCopyImageToBuffer() is a good way to achieve what you want. You could also call clEnqueueMapImage() and that would give you a regular pointer to the image data, which is like having the image as a 1-D buffer. Even if EnqueueMapImage looks a bit scary with so many arguments, in reality it's not very difficult to use and it usually has the best performance.

    One more thing: the kernel should say:

    Code :
    grayscale[ (HEIGHT-y-1)  * WIDTH + x ] = pixel.x;

    ...although that's not what is causing the issue.
    Disclaimer: Employee of Qualcomm Canada. Any opinions expressed here are personal and do not necessarily reflect the views of my employer. LinkedIn profile.

  3. #3

    Re: RGBA to (single channel) grayscale : clEnqueueReadBuffer

    Actually a have RGBA grayscale image R=graylevel, G=graylevel, B=graylevel.
    format :
    Code :
    cl_image_format format;
    format.image_channel_order = CL_RGBA;
    format.image_channel_data_type = CL_UNSIGNED_INT8;


    I tried to do it with clEnqueueCopyImageToBuffer :

    Code :
    error = clEnqueueWriteImage (command_queue,
    								gpu_image, //cl_mem image,
    								CL_TRUE, //cl_bool blocking_write,
    								origin, //const size_t origin[3],
    								region, //const size_t region[3],
    								width * sizeof(char)*4,//size_t input_row_pitch, width * sizeof(unsigned char) * 4
    								0, //size_t input_slice_pitch,
    								image, //const void * ptr,
    								0, //cl_uint num_events_in_wait_list,
    								NULL, //const cl_event *event_wait_list,
    								NULL //cl_event *event
    								);
    if(error != CL_SUCCESS){cerr << "Error Code : clEnqueueWriteImage 1 : " << error << endl;return 1;}
     
     
    error = clEnqueueCopyImageToBuffer (command_queue,
    								gpu_image, //cl_mem image,
    								gpu_graybuffer, 
    								origin, //const size_t origin[3],
    								region, //const size_t region[3],
    								0,//dst_offset
    								0, //cl_uint num_events_in_wait_list,
    								NULL, //const cl_event *event_wait_list,
    								NULL //cl_event *event
    								);
    if(error != CL_SUCCESS){cerr << "Error Code : clEnqueueCopyImageToBuffer : " << error << endl;return 1;}
    /*
    result = clEnqueueNDRangeKernel (command_queue,
    									kernel,
    									2,
    									NULL,
    									&global_work_size[0],
    				//					&local_work_size[0],
    									NULL,
    									0, NULL, NULL);
    //*/
     
    error = clEnqueueReadBuffer(command_queue,
    							gpu_graybuffer,
    							CL_TRUE,
    							0,
    							sizeof(unsigned char)*SIZE,
    							&cpu_graybuffer,
    							0, NULL, NULL);

    Like you can see, I commented clEnqueueNDRangeKernel . I throught there is no kernel to execute, maybe i am wrong ?
    But I have segmentation fault during execution at clEnqueueReadBuffer.

    Moreover, the image that I use is (SIZE*4) size and grayscale buffer ise (SIZE) size. It can cause the error ?

  4. #4
    Senior Member
    Join Date
    May 2010
    Location
    Toronto, Canada
    Posts
    845

    Re: RGBA to (single channel) grayscale : clEnqueueReadBuffer

    Moreover, the image that I use is (SIZE*4) size and grayscale buffer ise (SIZE) size. It can cause the error ?
    Yes, it is. All that MapImage does is give you a pointer to the image data. Since your image is RGBA8888, it contains 4*SIZE bytes (plus padding).
    Disclaimer: Employee of Qualcomm Canada. Any opinions expressed here are personal and do not necessarily reflect the views of my employer. LinkedIn profile.

  5. #5

    Re: RGBA to (single channel) grayscale : clEnqueueReadBuffer

    I think that it was a size problem like you said. For now, I do the conversion on CPU, like :
    Code :
    rgba_buffer[4*i] = gray_buffer[i]

    I'll try to do it soon on GPU.

Similar Threads

  1. Replies: 3
    Last Post: 08-11-2011, 12:52 AM
  2. Rendering a texture grayscale using multi-texturing
    By grok in forum OpenGL ES 1.X - fixed function hardware
    Replies: 1
    Last Post: 06-01-2009, 09:05 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •