【问题标题】:OpenCL and OpenGL interop extension not working (clGetGLContextInfoKHR crash)OpenCL 和 OpenGL 互操作扩展不起作用(clGetGLContextInfoKHR 崩溃)
【发布时间】:2021-07-13 23:43:27
【问题描述】:

我正在努力让 GL+CL 协同工作。

我一直在关注this tutorial。在我的代码中,我首先调用clGetPlatformIDs 并检索第一个(也是唯一一个)平台。我还从 SDL2 获得了我的 gl_context。然后我想在clGetGLContextInfoKHR的帮助下查询OpenGL使用的设备。我使用clGetExtensionFunctionAddressForPlatform(platform_id, "clGetGLContextInfoKHR") 成功获得了这个函数,但不幸的是,当我调用它时,我遇到了分段错误。我的代码是用 Rust 编写的,但我使用 low level OpenCL binding,所以它看起来几乎像它的 C 对应部分。

    pub fn new(gl_context: &GLContext) -> Result<Self, ClGlError> {
        println!("Initialising OpenCL context");
        let raw = unsafe { gl_context.raw() };
        println!("Getting default opencl platform");
        let platform_id = Self::default_platform()?; // this is valid and not null
        let mut props:[cl_sys::cl_context_properties;5] = [
            //OpenCL platform
            cl_sys::CL_CONTEXT_PLATFORM as cl_sys::cl_context_properties, platform_id as cl_sys::cl_context_properties,
            //OpenGL context
            cl_sys::CL_GL_CONTEXT_KHR,   raw as cl_sys::cl_context_properties,
            0
        ];
        let mut device: cl_device_id = std::ptr::null_mut();
        let p: *mut cl_device_id = (&mut device) as *mut cl_device_id;
        let fn_name = b"clGetGLContextInfoKHR\0" as *const u8 as *const i8;
        println!("Getting clGetGLContextInfoKHR");
        let clGetGLContextInfoKHR = unsafe{clGetExtensionFunctionAddressForPlatform(platform_id, fn_name ) as cl_sys::clGetGLContextInfoKHR_fn};
        if clGetGLContextInfoKHR.is_null(){
            // error handling here
        }
        println!("Getting device"); // this is the last thing I see before segfault
        unsafe{
            (*clGetGLContextInfoKHR)(props.as_mut_ptr(),cl_sys::CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR,std::mem::size_of::<cl_device_id>(),device as *mut c_void,std::ptr::null_mut());
        }

        panic!("All good") // this is never reached
    } 

我有一个相当新的显卡,它支持cl_khr_gl_sharing。 这里是clinfo

Number of platforms                               1
  Platform Name                                   NVIDIA CUDA
  Platform Vendor                                 NVIDIA Corporation
  Platform Version                                OpenCL 1.2 CUDA 11.2.162
  Platform Profile                                FULL_PROFILE
  Platform Extensions                             cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_fp64 cl_khr_byte_addressable_store cl_khr_icd cl_khr_gl_sharing cl_nv_compiler_options cl_nv_device_attribute_query cl_nv_pragma_unroll cl_nv_copy_opts cl_nv_create_buffer cl_khr_int64_base_atomics cl_khr_int64_extended_atomics cl_khr_device_uuid
  Platform Extensions function suffix             NV

  Platform Name                                   NVIDIA CUDA
Number of devices                                 1
  Device Name                                     GeForce GTX 960
  Device Vendor                                   NVIDIA Corporation
  Device Vendor ID                                0x10de
  Device Version                                  OpenCL 1.2 CUDA
  Driver Version                                  460.80
  Device OpenCL C Version                         OpenCL C 1.2 
  Device Type                                     GPU
  Device Extensions                               cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_fp64 cl_khr_byte_addressable_store cl_khr_icd cl_khr_gl_sharing cl_nv_compiler_options cl_nv_device_attribute_query cl_nv_pragma_unroll cl_nv_copy_opts cl_nv_create_buffer cl_khr_int64_base_atomics cl_khr_int64_extended_atomics cl_khr_device_uuid

也许最重要的线索可能是我尝试了一堆其他构建在 opencl 之上的库,并且在所有这些库中,每当我调用 clGetGLContextInfoKHR(包装在更安全和更高级别的 API 中)时,它都会崩溃。我认为所有这些库的代码中不太可能都有错误,所以这可能是我的环境中的一些问题。但是,如您所见,我的显卡显然支持所有必要的扩展。

【问题讨论】:

    标签: opengl rust opencl


    【解决方案1】:

    我不确定为什么 clGetGLContextInfoKHR 会失败,但我发现它并不是真的需要调用它。

    你可以只在 Linux 上使用它

    cl_context_properties properties[] = {
        CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(),
        CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(),
        CL_CONTEXT_PLATFORM, (cl_context_properties) platform,
        0
    };
    

    Windows 上的这个

    cl_context_properties properties[] = {
        CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(),
        CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(),
        CL_CONTEXT_PLATFORM, (cl_context_properties) platform,
        0
    };
    

    或者这个在 OS X 上

    CGLContextObj glContext = CGLGetCurrentContext();
    CGLShareGroupObj shareGroup = CGLGetShareGroup(glContext);
    cl_context_properties properties[] = {
        CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
        (cl_context_properties)shareGroup,
        0
    };
    

    更多信息可以在书中找到

    OpenCL 实战:如何加速图形和计算

    【讨论】:

      猜你喜欢
      • 2013-07-27
      • 1970-01-01
      • 2019-11-05
      • 1970-01-01
      • 2012-04-12
      • 2013-07-31
      • 1970-01-01
      • 2014-01-12
      • 2016-08-18
      相关资源
      最近更新 更多