I have a byte array with values in RGBA format and tried to copy the array as an image to the device memory. But the content of the image on the device doesn’t contain anything.
I tried to copy the content of one image to another one as a first example.
I also tried to set the pixel of the second image with a color directly and copied the content back from device to the host. That worked. Just the other way around is not working. I of course checked that the byte array was not empty.
Can someone help me please?
Here is my code:
const char *KernelSource = "
" \
"__kernel void luminance(__read_only image2d_t input,
" \
" __write_only image2d_t output,
" \
" sampler_t sampler)
" \
"{
" \
"
" \
" int2 pos = (int2)(get_global_id(0), get_global_id(1));
" \
" float4 color = read_imagef(input, sampler, pos);
" \
" //float4 color = (float4)(0,0,0,0.5);
" \
" write_imagef(output, pos, color);
" \
"}
" \
"
";
inline void ImageBuffer::platformConvertToLuminanceMask()
{
IntRect luminanceRect(IntPoint(), size());
RefPtr<ByteArray> srcPixelArray = getUnmultipliedImageData(luminanceRect);
unsigned char* data = srcPixelArray->data();
cl_device_id clDeviceId;
cl_int error = clGetDeviceIDs(0, CL_DEVICE_TYPE_CPU, 1, &clDeviceId, 0);
errorCode(error);
if (error != CL_SUCCESS)
return;
cl_context clContext = clCreateContext(0, 1, &clDeviceId, 0, 0, &error);
errorCode(error);
if (!clContext)
return;
cl_command_queue clQueue = clCreateCommandQueue(clContext, clDeviceId, 0, &error);
if (!clQueue)
return;
errorCode(error);
cl_program clProgram = clCreateProgramWithSource(clContext, 1, (const char **) & KernelSource, 0, &error);
if (!clProgram)
return;
error = clBuildProgram(clProgram, 0, 0, 0, 0, 0);
errorCode(error);
if (error != CL_SUCCESS)
return;
cl_kernel clKernel = clCreateKernel(clProgram, "luminance", &error);
errorCode(error);
if (!clKernel || error != CL_SUCCESS)
return;
cl_image_format imageFormat;
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageFormat.image_channel_order = CL_RGBA;
cl_mem clInputImage = clCreateImage2D(clContext, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &imageFormat, luminanceRect.width(), luminanceRect.height(), 0, data, &error);
errorCode(error);
RefPtr<ByteArray> result = ByteArray::create(srcPixelArray->length());
unsigned char* dest = result->data();
cl_mem clOutputImage = clCreateImage2D(clContext, CL_MEM_WRITE_ONLY, &imageFormat, luminanceRect.width(), luminanceRect.height(), 0, 0, &error);
errorCode(error);
if (!clInputImage || !clOutputImage)
return;
size_t region[3] = {luminanceRect.width(), luminanceRect.height(), 1};
size_t origin[3] = {0, 0, 0};
// Didn't work either:
//cl_mem clInputImage = clCreateImage2D(clContext, CL_MEM_READ_ONLY, &imageFormat, luminanceRect.width(), luminanceRect.height(), 0, 0, &error);
//error = clEnqueueWriteImage(clQueue, clInputImage, CL_TRUE, origin, region, 0, 0, data, 0, 0, 0);
//errorCode(error);
if (error != CL_SUCCESS)
return;
cl_sampler sampler = clCreateSampler(clContext, CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &error);
errorCode(error);
error = 0;
error = clSetKernelArg(clKernel, 0, sizeof(cl_mem), &clInputImage);
error |= clSetKernelArg(clKernel, 1, sizeof(cl_mem), &clOutputImage);
error |= clSetKernelArg(clKernel, 2, sizeof(cl_sampler), &sampler);
errorCode(error);
if (error != CL_SUCCESS)
return;
// Get the maximum work group size for executing the kernel on the device
size_t clLocalWorkSize[1] = {1};
//error = clGetKernelWorkGroupInfo(clKernel, clDeviceId, CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), &clLocalWorkSize, 0);
//errorCode(error);
if (error != CL_SUCCESS)
return;
size_t clGlobalWorkSize[1] = {luminanceRect.width() * luminanceRect.height()};
error = clEnqueueNDRangeKernel(clQueue, clKernel, 1, 0, clGlobalWorkSize, clLocalWorkSize, 0, 0, 0);
errorCode(error);
if (error)
return;
clFinish(clQueue);
error = clEnqueueReadImage(clQueue, clOutputImage, CL_TRUE, origin, region, 0, 0, dest, 0, 0, 0);
errorCode(error);
RefPtr<ByteArray> temp = ByteArray::create(srcPixelArray->length());
unsigned char* tmp = temp->data();
error = clEnqueueReadImage(clQueue, clInputImage, CL_TRUE, origin, region, 0, 0, tmp, 0, NULL, NULL);
errorCode(error);
if (error != CL_SUCCESS)
return;
putUnmultipliedImageData(result.get(), luminanceRect.size(), luminanceRect, IntPoint());
// Shutdown and cleanup
clReleaseMemObject(clInputImage);
clReleaseMemObject(clOutputImage);
clReleaseProgram(clProgram);
clReleaseKernel(clKernel);
clReleaseCommandQueue(clQueue);
clReleaseContext(clContext);
}
I did not get any error and the function completed.