重新安排一些OpenCL / GL互操作代码后,它停止工作并在标题中给出了错误。
我已经阅读了很多讨论过这个问题的线程,并指责(nvidia)驱动程序。但是,在此之前运行的代码应该不是我的问题。
代码
正如我已经说过的,我有太多代码要发布所有内容。此外,到目前为止,我无法在最小的示例中重现行为,所以我将用伪代码描述大部分程序,并从我的实际代码中摘录部分。
我使用Qt,因此以下函数都是我的QGLWidget子类的所有成员:
void initializeGL()
{
glewInit();
cl::Platform::get(&clPlatforms);
cl_context_properties props[] = {
CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
CL_CONTEXT_PLATFORM, (cl_context_properties)clPlatforms[0](),
0
};
clContext = cl::Context(CL_DEVICE_TYPE_GPU, props, cl_notify, &err);
std::vector<cl::Device> devices = clContext.getInfo<CL_CONTEXT_DEVICES>();
clDevice = devices[0];
clQueue = cl::CommandQueue(clContext, clDevice, 0, 0);
clProgram = cl::Program(context, sources);
clProgram.build();
clKernel = cl::Kernel(clProgram, "main");
glGenBuffers(1, &vbo);
glBindBuffers(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, bufferSize, buffer, GL_DYNAMIC_DRAW);
glBindBuffers(GL_ARRAY_BUFFER, 0);
vboBuffer = cl::BufferGL(clContext, CL_MEM_READ_WRITE, vbo);
clKernel.setArg(0, vboBuffer);
}
void paintGL()
{
simulate();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//camera transformations ...
glEnable(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexPointer(3, GL_FLOAT, sizeof(cl_float3), 0);
glDrawElements(GL_TRIANGLES, 3 * numTriangles, GL_UNSIGNED_INT, triangleIdicesArray);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void simulate()
{
std::vector<cl::Memory> sharedObjects;
sharedObjects.push_back(vboBuffer);
clQueue.enqueueAcquireGLObjects(&sharedObjects); //this triggers the error
clQueue.enqueNDRangKernel(clKernel, cl::NullRange, cl::NDRangle(numVertices), cl::NullRange);
clQueue.enqueueReleaseGLObjects(&sharedObjects);
}
关于glEnqueueAcquireGLObjects的进一步调查(在备注部分中):
在调用clEnqueueAcquireGLObjects之前,应用程序必须确保访问mem_objects中指定的对象的任何挂起GL操作已完成。这可以通过在具有对这些对象的挂起引用的所有GL上下文上发出并等待完成glFinish命令来便携地完成。
在获取/发布之前和之后在OpenCL命令队列上添加一个结尾使我摆脱了这些错误。
与其他错误一样,我发现错误代码具有误导性,并且通知功能没有添加任何有价值的信息(它说的相同)。