简体   繁体   English

OpenCL/OpenGL 互操作性纹理段错误

[英]OpenCL/OpenGL interoperability texture segfault

I'm trying to use OpenCL with OpenGL interop.我正在尝试将 OpenCL 与 OpenGL 互操作一起使用。 to compute pathtracing algorithm on GPU and then draw GL texture to quad.在 GPU 上计算路径跟踪算法,然后将 GL 纹理绘制到四边形。 Works as intended on Intel CPU but when I try to run in on GTX 970 there's segfault on unlocking that GL texture.在 Intel CPU 上按预期工作,但是当我尝试在 GTX 970 上运行时,在解锁 GL 纹理时出现段错误。 Dunno if that's the cause or the running kernel.不知道这是原因还是正在运行的内核。 I'll let the code speak for itself.我会让代码不言自明。 I'm using OpenCL C++ wrapper btw.顺便说一句,我正在使用 OpenCL C++ 包装器。

GL texture creation GL纹理创建

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
glBindTexture(GL_TEXTURE_2D, 0); //Unbind texture

CL texture allocation CL 纹理分配

m_textureCL = cl::ImageGL(m_context,
        CL_MEM_READ_WRITE, 
        GL_TEXTURE_2D,
        0,
        texture,
        &errCode);

RunKernel function运行内核函数

//-----------------------------------------------------------------------------
//  Lock texture
//-----------------------------------------------------------------------------
std::vector<cl::Memory> glObjects; //Create vector of GL objects to lock
glObjects.push_back(m_textureCL); //Add created CL texture buffer
glFlush(); //Flush GL queue

errCode = m_cmdQueue.enqueueAcquireGLObjects(&glObjects, NULL, NULL);
if(errCode != CL_SUCCESS) {
    std::cerr << "Error locking texture" << errCode << std::endl;
    return errCode;
}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
//  Run queue
//-----------------------------------------------------------------------------
errCode = m_cmdQueue.enqueueNDRangeKernel(
        m_kernel,
        cl::NullRange,
        cl::NDRange(height*width),
        cl::NullRange,
        NULL,
        NULL);
if(errCode != CL_SUCCESS) {
    std::cerr << "Error running queue: " << errCode << std::endl;
    return errCode;
}
//---------------------------------------


//-----------------------------------------------------------------------------
//  Unlock
//-----------------------------------------------------------------------------
errCode = m_cmdQueue.enqueueReleaseGLObjects(&glObjects, NULL, NULL);
if(errCode != CL_SUCCESS) {
    std::cerr << "Error unlocking texture: " << errCode << std::endl;
    return errCode;
} <<------ Here's where segfault occurs, can't get past this point

Kernel function def.内核函数定义。

__kernel void RadianceGPU (
    __write_only image2d_t texture,
    other_stuff...)

Writing to texture in kernel写入内核中的纹理

write_imagef(
        texture,
        (int2)(x, height-y-1),
        (float4)(
            clamp(framebuffer[id].x, 0.0f, 1.0f),
            clamp(framebuffer[id].y, 0.0f, 1.0f),
            clamp(framebuffer[id].z, 0.0f, 1.0f),
            1.0f) * 1.0f);

Interesting is that write_imagef() works despite the texture being UNSIGNED_BYTE.有趣的是,尽管纹理是 UNSIGNED_BYTE,但 write_imagef() 仍然有效。

EDIT: So I finally figured out what caused the problem.编辑:所以我终于弄清楚是什么导致了这个问题。 It was setting wrong display while creating CL properties.它在创建 CL 属性时设置了错误的显示。 I just pasted there window from GLFW, which causes problem on Nvidia drivers.我刚刚从 GLFW 粘贴了那里的窗口,这会导致 Nvidia 驱动程序出现问题。 You need to use glxGetCurrentDisplay or glfwGetX11Display.您需要使用 glxGetCurrentDisplay 或 glfwGetX11Display。 This fixes the segfault.这修复了段错误。

I´m not sure this is your problem but I´ll give it a shot anyway.我不确定这是你的问题,但无论如何我都会试一试。

You have not synchronized access to glObjects in a portable way.您没有以可移植的方式同步对 glObjects 的访问。 From OpenCL 1.1:从 OpenCL 1.1 开始:

Prior to calling clEnqueueAcquireGLObjects, the application must ensure that any pending GL operations which access the objects specified in mem_objects have completed.在调用 clEnqueueAcquireGLObjects 之前,应用程序必须确保访问 mem_objects 中指定的对象的任何挂起的 GL 操作都已完成。 This may be accomplished portably by issuing and waiting for completion of a glFinish command on all GL contexts with pending references to these objects.这可以通过在所有具有对这些对象的未决引用的 GL 上下文上发出并等待 glFinish 命令完成来可移植地完成。 Implementations may offer more efficient synchronization methods;实现可以提供更有效的同步方法; for example on some platforms calling glFlush may be sufficient, or synchronization may be implicit within a thread, or there may be vendor - specific extensions that enable placing a fence in the GL command stream and waiting for completion of that fence in the CL command queue.例如,在某些平台上,调用 glFlush 可能就足够了,或者同步可能隐含在一个线程中,或者可能存在特定于供应商的扩展,可以在 GL 命令流中放置一个栅栏并等待该栅栏在 CL 命令队列中完成. Note that no synchronization methods other than glFinish are portable between OpenGL implementations at this time.请注意,此时除了 glFinish 之外,没有其他同步方法可在 OpenGL 实现之间移植。

Basically glFinish is required for portable behavior.基本上,可移植行为需要 glFinish。

In the paragraph below the already quoted there is more info that might be of interest:在下面已经引用的段落中,有更多可能感兴趣的信息:

Similarly, after calling clEnqueueReleaseGLObjects, the application is responsible for ensuring that any pending OpenCL operations which access the objects specified in mem_objects have completed prior to executing subsequent GL commands which reference these objects.类似地,在调用 clEnqueueReleaseGLObjects 之后,应用程序负责确保访问 mem_objects 中指定的对象的任何挂起的 OpenCL 操作在执行引用这些对象的后续 GL 命令之前已经完成。 This may be accomplished portably by calling clWaitForEvents with the event object returned by clEnqueueRelease GL Objects, or by calling clFinish.这可以通过使用 clEnqueueRelease GL 对象返回的事件对象调用 clWaitForEvents 或通过调用 clFinish 可移植地完成。 As above, some implementations may offer more efficient methods.如上所述,一些实现可能提供更有效的方法。

Here is a link to the document quoted from: https://www.khronos.org/registry/cl/specs/opencl-1.1.pdf#nameddest=section-9.8.6这是引用自以下文件的链接: https : //www.khronos.org/registry/cl/specs/opencl-1.1.pdf#nameddest=section-9.8.6

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

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