Image format not supported for write only Why does it work for read only, but not write only

I am writing my first OpenCL imaging application. It opens up an image, runs a kernel on it and then saves the image back to file.

I can create the Input image, but I can not create the output image. I get -10: Image format not supported. I tried using the same image format as was used for the input image, but that doesn’t work. I tried other combinations, but none of them have worked. If I don’t set one of the CL_MEM_*_HOST_PTR, then I get -37: Invalid host ptr. The following is the code snippet. Any suggestions?

System: MacBookPro 8600M GT

if (pInImage->triplet_type == TT_GRAY) {
// grayscale image. just create image objects
// one for input and the other for output
cl_image_format imageFormat = { CL_R, CL_UNORM_INT8}; // Not supported by outputImage for some strange reason
// my system does not support luminance or intensity !!!
// cl_image_format imageFormat = { CL_LUMINANCE, CL_UNORM_INT8}; // Not supported by inputImage
// cl_image_format imageFormat = { CL_INTENSITY, CL_UNORM_INT8}; // Not supported by inputImage
cl_image_format imageFormat2 = { CL_R, CL_UNSIGNED_INT8}; // test format for output image
// cl_image_format imageFormat2 = { CL_R, CL_UNORM_INT8}; // test format for output image

// create input image
// not sure if CL_MEM_COPY_HOST_PTR is necessary or beneficial
// IT IS necessary (CL_MEM_COPY_HOST_PTR)
inputImage = clCreateImage2D(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &imageFormat, pInImage->width, pInImage->height, pInImage->stride, pInImage->image, &err);
if (err != CL_SUCCESS) {
printf(“Error creating input imgage rc=%d\n”,err);
rc=9;
goto cleanup;
}

//create output image
pOutImage = DapAllocAnotherImage(pInImage);
if (!pOutImage)
{
printf(“Error allocating output image\n”);
rc=10;
goto cleanup;
}
// outputImage = clCreateImage2D(context, CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, &imageFormat, pOutImage->width, pOutImage->height, pOutImage->stride, pOutImage->image, &err);
// outputImage = clCreateImage2D(context, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, &imageFormat, pOutImage->width, pOutImage->height, pOutImage->stride, pOutImage->image, &err);
// outputImage = clCreateImage2D(context, CL_MEM_WRITE_ONLY, &imageFormat2, pOutImage->width, pOutImage->height, pOutImage->stride, NULL, &err);
outputImage = clCreateImage2D(context, CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, &imageFormat2, pOutImage->width, pOutImage->height, pOutImage->stride, NULL, &err);
if (err != CL_SUCCESS) {
printf(“Error creating output image rc=%d\n”,err);
rc=11;
goto cleanup;
}

I am writing my first OpenCL imaging application. It opens up an image, runs a kernel on it and then saves the image back to file.

I can create the Input image, but I can not create the output image. I get -10: Image format not supported. I tried using the same image format as was used for the input image, but that doesn’t work. I tried other combinations, but none of them have worked. If I don’t set one of the CL_MEM_*_HOST_PTR, then I get -37: Invalid host ptr. The following is the code snippet. Any suggestions?

System: MacBookPro 8600M GT

if (pInImage->triplet_type == TT_GRAY) {
// grayscale image. just create image objects
// one for input and the other for output
cl_image_format imageFormat = { CL_R, CL_UNORM_INT8}; // Not supported by outputImage for some strange reason
// my system does not support luminance or intensity !!!
// cl_image_format imageFormat = { CL_LUMINANCE, CL_UNORM_INT8}; // Not supported by inputImage
// cl_image_format imageFormat = { CL_INTENSITY, CL_UNORM_INT8}; // Not supported by inputImage
cl_image_format imageFormat2 = { CL_R, CL_UNSIGNED_INT8}; // test format for output image
// cl_image_format imageFormat2 = { CL_R, CL_UNORM_INT8}; // test format for output image

// create input image
// not sure if CL_MEM_COPY_HOST_PTR is necessary or beneficial
// IT IS necessary (CL_MEM_COPY_HOST_PTR)
inputImage = clCreateImage2D(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &imageFormat, pInImage->width, pInImage->height, pInImage->stride, pInImage->image, &err);
if (err != CL_SUCCESS) {
printf(“Error creating input imgage rc=%d\n”,err);
rc=9;
goto cleanup;
}

//create output image
pOutImage = DapAllocAnotherImage(pInImage);
if (!pOutImage)
{
printf(“Error allocating output image\n”);
rc=10;
goto cleanup;
}
// outputImage = clCreateImage2D(context, CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, &imageFormat, pOutImage->width, pOutImage->height, pOutImage->stride, pOutImage->image, &err);
// outputImage = clCreateImage2D(context, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, &imageFormat, pOutImage->width, pOutImage->height, pOutImage->stride, pOutImage->image, &err);
// outputImage = clCreateImage2D(context, CL_MEM_WRITE_ONLY, &imageFormat2, pOutImage->width, pOutImage->height, pOutImage->stride, NULL, &err);
outputImage = clCreateImage2D(context, CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, &imageFormat2, pOutImage->width, pOutImage->height, pOutImage->stride, NULL, &err);
if (err != CL_SUCCESS) {
printf(“Error creating output image rc=%d\n”,err);
rc=11;
goto cleanup;
}

Well, you should read more carefully the docs (clCreateImage2D). Don’t provide any image stride and pass 0 in function call instead of data pointer.

outputImage = clCreateImage2D(context, CL_MEM_WRITE_ONLY, &imageFormat2, pOutImage->width, pOutImage->height, 0, NULL, &err);

Well, you should read more carefully the docs (clCreateImage2D). Don’t provide any image stride and pass 0 in function call instead of data pointer.

outputImage = clCreateImage2D(context, CL_MEM_WRITE_ONLY, &imageFormat2, pOutImage->width, pOutImage->height, 0, NULL, &err);

I thought that I could pre-allocate the buffer and then have clCreateImage2D point to it.

Are you saying that I just create the image with CL_MEM_ALLOC_HOST_PTR or without any CL_MEM___PTR set at all and then just use CLEnqueueReadImage pointing to my host image buffer?

I will give that a try.

I thought that I could pre-allocate the buffer and then have clCreateImage2D point to it.

Are you saying that I just create the image with CL_MEM_ALLOC_HOST_PTR or without any CL_MEM___PTR set at all and then just use CLEnqueueReadImage pointing to my host image buffer?

I will give that a try.

I found that only 4 channel modes are supported by clCreateImage2D with CL_MEM_WRITE_ONLY.


2D Image Write Formats Supported (12)

Channel Order Channel Type

1 CL_RGBA CL_UNORM_INT8
2 CL_ARGB CL_UNORM_INT8
3 CL_BGRA CL_UNORM_INT8
4 CL_RGBA CL_UNORM_INT16
5 CL_RGBA CL_SIGNED_INT8
6 CL_RGBA CL_UNSIGNED_INT8
7 CL_RGBA CL_SIGNED_INT16
8 CL_RGBA CL_UNSIGNED_INT16
9 CL_RGBA CL_SIGNED_INT32
10 CL_RGBA CL_UNSIGNED_INT32
11 CL_RGBA CL_HALF_FLOAT
12 CL_RGBA CL_FLOAT

I found that only 4 channel modes are supported by clCreateImage2D with CL_MEM_WRITE_ONLY.


2D Image Write Formats Supported (12)

Channel Order Channel Type

1 CL_RGBA CL_UNORM_INT8
2 CL_ARGB CL_UNORM_INT8
3 CL_BGRA CL_UNORM_INT8
4 CL_RGBA CL_UNORM_INT16
5 CL_RGBA CL_SIGNED_INT8
6 CL_RGBA CL_UNSIGNED_INT8
7 CL_RGBA CL_SIGNED_INT16
8 CL_RGBA CL_UNSIGNED_INT16
9 CL_RGBA CL_SIGNED_INT32
10 CL_RGBA CL_UNSIGNED_INT32
11 CL_RGBA CL_HALF_FLOAT
12 CL_RGBA CL_FLOAT

I tried the following and it still fails.

outputImage = clCreateImage2D(context, CL_MEM_WRITE_ONLY, &imageFormat2, pOutImage->width, pOutImage->height, 0, NULL, &err);

For some reason, they don’t like single channel write only images in OpenCL 1.0 on Mac OS X.6.

I tried the following and it still fails.

outputImage = clCreateImage2D(context, CL_MEM_WRITE_ONLY, &imageFormat2, pOutImage->width, pOutImage->height, 0, NULL, &err);

For some reason, they don’t like single channel write only images in OpenCL 1.0 on Mac OS X.6.

Second is right, by clCreateImage2D you just allocate data buffer at GPU. CL_MEM___PTR would mean, that host API will immediately try to upload data to GPU and as you are providing NULL pointer, it will fail.

I’m testing on Linux (Ubuntu) and I’m successfully using one channel format (CL_R, CL_SIGNED_INT32). What error are you receiving now? Are all previous API calls and kernel runs OK?

Second is right, by clCreateImage2D you just allocate data buffer at GPU. CL_MEM___PTR would mean, that host API will immediately try to upload data to GPU and as you are providing NULL pointer, it will fail.

I’m testing on Linux (Ubuntu) and I’m successfully using one channel format (CL_R, CL_SIGNED_INT32). What error are you receiving now? Are all previous API calls and kernel runs OK?

The same error: Image format not supported (-10)

For some reason, OpenCL 1.0 on 10.6 on a MacBookPro (8600M GT) doesn’t support 1 bit write only fields. I will try READ_WRITE and see if that works. (mark it as write only in the kernel)

The same error: Image format not supported (-10)

For some reason, OpenCL 1.0 on 10.6 on a MacBookPro (8600M GT) doesn’t support 1 bit write only fields. I will try READ_WRITE and see if that works. (mark it as write only in the kernel)

READ_WRITE doesn’t help.

I was using OpenCL to hopefully have better cross GPU and cross OS support. Looks like it isn’t quite as robust as I would like.

READ_WRITE doesn’t help.

I was using OpenCL to hopefully have better cross GPU and cross OS support. Looks like it isn’t quite as robust as I would like.

Well, OpenCL is still at the beginnings, but it’s worth trying, I suppose :-)

Have you tried querying clGetSupportedImageFormats? Perhaps it’s only your graphic card that doesn’t support that format.

Well, OpenCL is still at the beginnings, but it’s worth trying, I suppose :-)

Have you tried querying clGetSupportedImageFormats? Perhaps it’s only your graphic card that doesn’t support that format.