dkg
dkg

Reputation: 1775

enqueueWriteImage fail on GPU

I am developing some kernels which works with image buffers. The problem is that when I create my Image2D by directly copying the data of the image, everything works well.

If I try to enqueue a write to my image buffer, it won't works for my GPU.

Here is a basic kernel :

__kernel void myKernel(__read_only image2d_t in, __write_only image2d_t out) {
    const int x = get_global_id(0);
    const int y = get_global_id(1);
    const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;

    uint4 pixel = read_imageui(in, sampler, (int2)(x, y));
    write_imageui(out, (int2)(x, y), pixel);
}

Well, that simple kernel give me a black image on my GPU, but works well on my CPU.

To make it works, I have to do release the buffer image and creating a new one by directly passing data using CL_MEM_COPY_HOST_PTR. I use the good data format : CL_RGBA, CL_UNSIGNED_INT8 and the size of my image is good.

The problem has been encountered with JOCL and the C++ binding of the API. (I didn't test the C API).

Finally, it runs by recreating the buffer, but is it a good idea ? Is it just normal ? Which actions can I perform to avoid it ?

By the way, I'm running on Intel SDK for OpenCL (Intel Core I7) and ATI AMD APP SDK (HD6800).

[edit]

Here is the code I use to write in my buffers.

First, the allocation part :

cl_image_format imageFormat = new cl_image_format();
imageFormat.image_channel_order = CL_RGBA;
imageFormat.image_channel_data_type = CL_UNSIGNED_INT8;

inputImageMem = clCreateImage2D(
    context, CL_MEM_READ_ONLY,
    new cl_image_format[]{imageFormat}, imageSizeX, imageSizeY,
    0, null, null);

And when running, called for each frame, the part which doesn't work on GPU :

clEnqueueWriteImage(commandQueue, inputImageMem, CL_TRUE, new long[]{0, 0, 0},
        new long[]{imageSizeX, imageSizeY, 1}, 0, 0,
        Pointer.to(data), 0, null, null);

The part which works on both GPU and CPU but force me to recreate the buffer :

clReleaseMemObject(inputImageMem);
cl_image_format imageFormat = new cl_image_format();
imageFormat.image_channel_order = CL_RGBA;
imageFormat.image_channel_data_type = CL_UNSIGNED_INT8;
inputImageMem = clCreateImage2D(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, new cl_image_format[]{imageFormat}, imageSizeX, imageSizeY, 0, Pointer.to(data), null);

The data sent is an array of int of size imageSizeX*imageSizeY. I get it by this code :

DataBufferInt dataBuffer = (DataBufferInt)image.getRaster().getDataBuffer();
int data[] = dataBuffer.getData();

The code above is in java using JOCL, the same problem appear in an another C++ program using the C++ OpenCL Wrapper. The only differences are that in Java the virtual machine crash (after 3~4 frames) and in C++ the result is a black image.

Upvotes: 0

Views: 1106

Answers (1)

dkg
dkg

Reputation: 1775

Well, I found the problem. That was my drivers acting weird.

I was using the 12.4 version (the version I installed when I began to work with OpenCL) and I just installed the 12.6 version and the problem just disappeared.

So, keep your drivers up to date !

Upvotes: 2

Related Questions