无法使用 EGL/OpenGLES 上下文创建 OpenCL 上下文共享

Posted

技术标签:

【中文标题】无法使用 EGL/OpenGLES 上下文创建 OpenCL 上下文共享【英文标题】:Can't create OpenCL context sharing with EGL/OpenGLES context 【发布时间】:2020-07-14 21:55:45 【问题描述】:

我正在尝试通过使用 cl_khr_gl_sharing 扩展来使用 OpenCL 与 OpenGL-ES 的互操作。但是当我尝试创建一个与我的 OpenGL 上下文共享的 OpenCL 上下文时,clCreateContext 失败并出现错误 -59 (CL_INVALID_OPERATION)。

从文档 (OpenCL Docs) 中,我看到的唯一可能性是我的“设备 [...] 无法支持共享 OpenGL 对象数据存储的 OpenCL 对象”。 我检查了clGetDeviceInfo 我使用的 OpenCL 设备确实支持扩展:它支持。 我现在正在尝试使用屏幕外渲染,但我尝试使用 PBuffer 表面,我还尝试了屏幕渲染,仍然是同样的错误。

我在 Ubuntu 18.04 上使用 EGL。这是我在查询 OpenGL 和 OpenCL 时得到的关于我的 GPU 的信息:

OpenGL 信息 (glGetString):

Opengl context: NVIDIA Corporation : GeForce GTX 750 Ti/PCIe/SSE2 : OpenGL ES 3.2 NVIDIA 435.21

OpenCL 信息(clGetPlatformInfoclGetDeviceInfo):

CL_PLATFORM_PROFILE FULL_PROFILE
CL_PLATFORM_VERSION OpenCL 1.2 CUDA 10.1.0
CL_PLATFORM_NAME NVIDIA CUDA
CL_PLATFORM_VENDOR NVIDIA Corporation
CL_DEVICE_NAME GeForce GTX 750 Ti
CL_DEVICE_PROFILE FULL_PROFILE
CL_DEVICE_VENDOR NVIDIA Corporation
CL_DEVICE_VERSION OpenCL 1.2 CUDA
CL_DRIVER_VERSION 435.21

这是我尝试运行的代码的简化版本:

int main()

    /// OpenGL Setup
    EGLDisplay egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    eglInitialize(egl_dpy, NULL, NULL);

    const EGLint config_attribs[] = 
            EGL_RED_SIZE, 8,
            EGL_GREEN_SIZE, 8,
            EGL_BLUE_SIZE, 8,
            EGL_ALPHA_SIZE, 8,
            EGL_DEPTH_SIZE, 16,
            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
            EGL_NONE;

    EGLConfig cfg;
    EGLint count;
    eglChooseConfig(egl_dpy, config_attribs, &cfg, 1, &count);
    eglBindAPI(EGL_OPENGL_ES_API);

    static const EGLint attribs[] = EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE;
    EGLContext core_ctx = eglCreateContext(egl_dpy, cfg, EGL_NO_CONTEXT, attribs);

    eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, core_ctx);


    /// OpenCL setup
    cl_platform_id platform_id = NULL;
    cl_uint ret_num_platforms;
    auto retPlat = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
    if (retPlat != CL_SUCCESS)
    
        assert(0);
    

    cl_device_id device_id = NULL;
    auto retDev = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);
    if (retDev != CL_SUCCESS)
    
        assert(0);
    

    cl_context_properties props[] = CL_CONTEXT_PLATFORM, (cl_context_properties)platform_id, CL_GL_CONTEXT_KHR,
            (cl_context_properties)eglGetCurrentContext(), CL_EGL_DISPLAY_KHR,
            (cl_context_properties)eglGetCurrentDisplay(), 0;


    cl_int retContext;
    cl_context myContext = clCreateContext(props, 1, &device_id, NULL, NULL, &retContext);
    if (retContext != CL_SUCCESS)
    
        std::cout << "clCreateContext " << retContext << "\n";
        assert(0);
    

【问题讨论】:

【参考方案1】:

我发现了问题。 似乎 Nvidia OpenCL 驱动程序不支持 OpenGL 与 EGL 上下文共享。 我能够在 OpenCL 库中进行跟踪,并注意到如果使用了 CL_EGL_DISPLAY_KHR 属性,则返回此特定错误的 switch 语句。 如果我改用 GLX OpenGL 上下文,一切都运行良好。 我不知道他们怎样才能更好地记录这一事实,但它会为我节省一周的时间。

【讨论】:

以上是关于无法使用 EGL/OpenGLES 上下文创建 OpenCL 上下文共享的主要内容,如果未能解决你的问题,请参考以下文章

是啥原因导致:“创建模型时无法使用上下文。”?

无法在 spark 中使用 hive 支持创建 sql 上下文

ASP.NET Identity 出现“创建模型时无法使用上下文”异常

LINQ 和 EF6:创建模型时无法使用上下文

无法为“ApplicationUser”创建 DbSet,因为此类型未包含在上下文模型中

DbContext.set() 无法为实体创建 DbSet,因为此类型未包含在上下文的模型中