繁体   English   中英

OpenCL-绘制到OpenGL纹理崩溃

[英]OpenCL - Draw To OpenGL Texture crashes

我正在尝试创建一个OpenCL raycaster。 因此,我每秒绘制多次OpenGL纹理。 但是queue.enqueueNDRangeKernel最终返回-9999。 如果我从内核代码中删除了write_imagef ,那么它将起作用,所以我认为这会导致问题。

OpenCL内核(细分)

__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));
}

这是在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);

该代码运行在每一帧:

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);

是什么原因导致-9999错误,如何解决? 另外,纹理中经常没有被吸引的大块“死像素” ...

您可以排队释放GL缓冲区,但不要等待它完成。

queue.enqueueReleaseGLObjects(&this->buffersGL);

要么取消完成事件(注意是否泄漏!),要么等待命令队列完成所有任务,然后再释放GL对象。 当队列中的一件事依赖于另一件事时,您应该自己安排它们的排序。

您还要排队一堆依赖于GL对象的任务。 等待它们完成(完成队列),或者接受它们的事件,然后将它们作为请求送入排队释放GL对象。

作为旁白:

使用更少的内核可能是一个好主意,而不是每个像素一个。

使用更少的内核可能是一个好主意,而不是每个像素一个。

非常感谢Yakk! 我首先尝试使用较小的屏幕尺寸进行了尝试,然后突然又起作用了! 事实证明,虽然我要绘制的纹理是问题所在。 它不是600x600像素大,而是导致崩溃的原因。 显然,OpenCL可以在崩溃前多次绘制到“实际上不存在”的像素。 仍然是奇怪的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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