Reputation: 1775
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
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