1

一部の 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 コマンド キューに終了を追加すると、これらのエラーが解消されました。

他のエラーと同様に、エラー コードは誤解を招くものであり、通知機能は有益な情報を追加しませんでした (同じことを言いました)。

4

0 に答える 0