4

I have a opencl shader that attempts to write a color to a texture, but for some reason, only the red channel is applied to the texture, the rest are ignored. Not only that, but this red channel value gets copied to all the other channels, giving me white with some transparency. Anybody know why this would happen? Am programming using Xcode on a Mac, (OpenCL 1.2). Texture is first created using OpenGL and shared with OpenCL.

This is how I declare the texture I write to using OpenGL:

void TextureManager::createTexture3D(TextureManager::TexturesInfo 
*texturesInfo, GLuint textureName)
{
    glError();
    glBindTexture(GL_TEXTURE_3D, texturesInfo->tex[textureName]);
    glError();
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glError();
    GLint level = 0, border = 0;

    GLint rgbType = GL_RGBA32F;
    GLint format = GL_RGBA;
    glTexImage3D(GL_TEXTURE_3D, level, rgbType, LPV::LPV_WIDTH, LPV::LPV_HEIGHT, LPV::LPV_DEPTH, border, format, GL_FLOAT, NULL);
    glError();
}

This is the code that creates the shared resource with OpenCL:

GLint error;
accume_buffer = clCreateFromGLTexture(context,CL_MEM_READ_ONLY, GL_TEXTURE_3D, 0, _lpvTextures.accumeBuffer, &error);
assert(error == CL_SUCCESS);
accume_buffer2 = clCreateFromGLTexture(context,CL_MEM_WRITE_ONLY, GL_TEXTURE_3D, 0, _lpvTextures.accumeBuffer2, &error);
assert(error == CL_SUCCESS);

This is the code that runs the opencl shader:

void LPV::runComputeShader(){

glFlush();
glFinish();
GLint error = 0;
cl_event opengl_get_completion;
error =clEnqueueAcquireGLObjects(command_queue, 1, &accume_buffer, 0,0,&opengl_get_completion);
clWaitForEvents(1, &opengl_get_completion);
clReleaseEvent(opengl_get_completion);
assert(error == CL_SUCCESS);
error =clEnqueueAcquireGLObjects(command_queue, 1, &accume_buffer2, 0,0,0);
assert(error == CL_SUCCESS);

error |= clSetKernelArg(computeKernel, 0, sizeof(cl_image), &accume_buffer);
assert( error == CL_SUCCESS);
error |= clSetKernelArg(computeKernel, 1, sizeof(cl_image), (void*)&accume_buffer2);
assert( error == CL_SUCCESS);


GLuint dimensions = 3;
size_t globalWorkSize[] = {LPV::LPV_WIDTH, LPV_HEIGHT, LPV_DEPTH };
size_t localWorkSize[] = { 1, 1, 1};

cl_event kernel_completion;
error = clEnqueueNDRangeKernel(command_queue, computeKernel, dimensions, NULL, globalWorkSize, nullptr, 0, NULL, &kernel_completion);
assert(error == CL_SUCCESS);
error = clWaitForEvents(1, &kernel_completion);
error |= clReleaseEvent(kernel_completion);
assert(error == CL_SUCCESS);


error = clEnqueueReleaseGLObjects(command_queue, 1, &accume_buffer, 0, 0, 0);
assert(error == CL_SUCCESS);
error = clEnqueueReleaseGLObjects(command_queue, 1, &accume_buffer2, 0, 0, 0);
assert(error == CL_SUCCESS);

clFlush(command_queue);
clFinish(command_queue);


}

And finally, this is the opencl shader itself:

#pragma OPENCL EXTENSION cl_khr_3d_image_writes : enable

const sampler_t lpvSampler = CLK_NORMALIZED_COORDS_FALSE | 
CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;


kernel void propagate_lpv
                    (
                      read_only image3d_t src_buffer,
                      write_only image3d_t dest_buffer
                    )
{
    int4 coord;
    coord.x = (int)get_global_id(0);
    coord.y = (int)get_global_id(1);
    coord.z = (int)get_global_id(2);
    coord.w = 1;

float4 color = float4(1.0f, 0.0f, 0.0f, 1.0f);
write_imagef(dest_buffer, coord, color);


}

Does anyone have any clue why this would happen? Thanks

Rafael Sabino
  • 165
  • 1
  • 8

1 Answers1

2

The problem was that I was using the wrong syntax. Sadly OpenCL and GLSL do not seem to follow the same syntax which was my assumption. The correct syntax according to the OpenCL Programming Guide is this:

(float4)( float, float, float, float )
(float4)( float2, float, float )
(float4)( float, float2, float )
(float4)( float, float, float2 )
(float4)( float2, float2 )
(float4)( float3, float )
(float4)( float, float3 )
(float4)( float )

so changing my line:

float4 color = float4(1.0f, 0.0f, 0.0f, 1.0f);

to:

float4 color = (float4)(1.0f, 0.0f, 0.0f, 1.0f);

Gives me a red texture, which is what I expect.

Rafael Sabino
  • 165
  • 1
  • 8