Results 1 to 3 of 3

Thread: How do you represent an image in OpenCL

Hybrid View

  1. #1
    Newbie
    Join Date
    Aug 2013
    Posts
    1

    How do you represent an image in OpenCL

    I have sample code but it completely leaves out what my (void*)should_be!

    I setup a cl_image_desc, cl_image_format, buffer, origin, and region:

    Code :
    cl_image_desc desc;
    desc.image_type = CL_MEM_OBJECT_IMAGE2D;
    desc.image_width = width;
    desc.image_height = height;
    desc.image_depth = 0;
    desc.image_array_size = 0;
    desc.image_row_pitch = 0;
    desc.image_slice_pitch = 0;
    desc.num_mip_levels = 0;
    desc.num_samples = 0;
    desc.buffer = NULL;
     
    cl_image_format format;
    format.image_channel_order = CL_R;
    format.image_channel_data_type = CL_FLOAT;
     
    cl_mem bufferSourceImage = clCreateImage(context, CL_MEM_READ_ONLY, &format, &desc, NULL, NULL);
    size_t origin[3] = {0, 0, 0};
    size_t region[3] = {width, height,1};

    In this next snippet sourceImage is a void pointer to my image. But what is my image? For every pixel there are r, g, b, a, x, and y values.

    Code :
    clEnqueueWriteImage(queue, bufferSourceImage, CL_TRUE, origin, region, 0, 0, sourceImage, 0, NULL, NULL);

    How do I turn my image (a bunch of (r,g,b,a,x,y)'s) into a suitable array?

    This is the kernel they provide:

    Code :
    __kernel void convolution(__read_only image2d_t sourceImage, __write_only image2d_t outputImage, int rows, int cols, __constant float* filter, int filterWidth, sampler_t sampler)
    {
        int column = get_global_id(0);
        int row = get_global_id(1);
        int halfWidth = (int)(filterWidth/2);
     
        float4 sum = {0.0f, 0.0f, 0.0f, 0.0f};
     
        int filterIdx = 0;
        int2 coords;
        for(int i = -halfWidth; i <= halfWidth; i++)
        {
            coords.y = row + i;
            for(int i2 = -halfWidth; i2 <= halfWidth; i2++) 
            {
                coords.x = column + i2;
                float4 pixel;
                pixel = read_imagef(sourceImage, sampler, coords);
                sum.x += pixel.x * filter[filterIdx++];
     
            }
        }
        if(myRow < rows && myCol < cols)
        {
            coords.x = column;
            coords.y = row;
            write_imagef(outputImage, coords, sum);
        }
    }

  2. #2
    Senior Member
    Join Date
    Oct 2012
    Posts
    165
    One pixel in the image is just one float becuase image Format is float and Order is CL_R. So every Pixel you read has just this one float value. To pass a valid array just insert a normal float array with size float[width * height]

  3. #3
    Quote Originally Posted by clint3112 View Post
    One pixel in the image is just one float becuase image Format is float and Order is CL_R. So every Pixel you read has just this one float value. To pass a valid array just insert a normal float array with size float[width * height]
    Extending clint's answer a little:

    The type of image created is a single color per location - only R. (if you wish to work with RGBA, you need to modify the format). As such:
    1. The buffer that you need to allocate (and later pass as a void*) is of width*height floats - something like float* A= malloc(height*width*4);
    2. A[0] is the first pixel in the image - This is the pixel value at index x=0, y=0. A[1] is the second pixel, correlates to x=1, y=0, and so on.
    3. Image is assumed to be organized at rows, so A[0] to A[width-1] are the pixels of first row, A[width] to A[width*2-1] are the pixels of second row, etc.

    If the compiler that you're using is C99 compatible, you could allocate a variable 2D array:
    float (*A)[height] = malloc(sizeof(float[width][height]));
    and then use A[i][j] for accesing it.

Posting Permissions

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