简体   繁体   中英

OpenCL - Draw To OpenGL Texture crashes

I am trying to create an OpenCL raycaster. Therefore I am drawing to an OpenGL texture many times a second. However queue.enqueueNDRangeKernel eventually returns -9999. If I remove write_imagef from my kernel code, it works, so i figured this causes the problem.

OpenCL kernel (broken down)

__kernel void main(__write_only image2d_t screen)
{
    unsigned int x = get_global_id(0);
    unsigned int y = get_global_id(1);

    int2 coords = (int2) (x, y);
    write_imagef(screen, coords, (float4)(1,0,1,1));
}

This is the code that runs once in c++:

cl::Program::Sources sources;
string code = ResourceLoader::loadFile(filename);
sources.push_back({ code.c_str(),code.length() });

program = cl::Program(OpenCL::context, sources);

if (program.build({ OpenCL::default_device }) != CL_SUCCESS)
{
    cout << "Could not build program \"" << filename << "\"! Error:" << endl;
    cout << "OpenCL: Error building: " << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(OpenCL::default_device) << "\n";
    system("PAUSE");
    exit(1);
}
queue = CommandQueue(OpenCL::context, OpenCL::default_device);
kernel = Kernel(program, "main");
//OpenGL texture
ImageGL b(OpenCL::context, CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0, argument, &error);

if (error != 0)
{
    cout << "CL Error: " << OpenCL::get_cl_error_string(error) << endl;
    system("PAUSE");
    exit(error);
}
kernel.setArg(0, b);

This Code runs every frame:

glFinish();
queue.enqueueAcquireGLObjects(&this->buffersGL);
NDRange range;
if (lengthZ <= 0 && lengthY <= 0)
    range = NDRange(lengthX);
else if (lengthZ <= 0)
    range = NDRange(lengthX, lengthY);
else
    range = NDRange(lengthX, lengthY, lengthZ);

cl::Event wait;

cl_int run_err = queue.enqueueNDRangeKernel(kernel, NDRange(), range, NullRange, NULL, &wait);


if (run_err != 0)
{
    cout << OpenCL::get_cl_error_string(run_err) << " (" << run_err << ")" << endl;
    system("PAUSE");
}
queue.enqueueReleaseGLObjects(&this->buffersGL);

What could be causing the -9999 error and how can I fix it? Also, there are often big chunks of "dead pixels" that have not been drawn to in the texture...

You enqueue the release of GL buffers, but do not wait for it to complete.

queue.enqueueReleaseGLObjects(&this->buffersGL);

either get the finish event out of this (watch out for leaks!), or wait on the command queue to finish all tasks before proceeding to releasing the GL objects. When one thing in a queue depends on another, you are supposed to arrange their ordering yourself.

You also queue a bunch of tasks that depend on the GL objects. Either wait for them to complete (finish the queue), or take their events and feed them to the enqueue release GL objects as perquisites.

As an aside:

Using fewer kernels might be a good idea, instead of one per pixel.

Using fewer kernels might be a good idea, instead of one per pixel.

Thanks alot Yakk! I tried that by first simply using a smaller screen size and it suddenly worked again! As it turns out though the texture I was drawing to was the problem. It was not 600x600 pixels big and that's what caused the crash. Apparently OpenCL can draw to pixels that "don't actually exist" a couple of times before crashing. It still is weird behaviour...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM