一部の 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 コマンド キューに終了を追加すると、これらのエラーが解消されました。
他のエラーと同様に、エラー コードは誤解を招くものであり、通知機能は有益な情報を追加しませんでした (同じことを言いました)。