OpenCL 和 OpenGL 互操作扩展不工作(clGetGLContextInfoKHR 崩溃)
OpenCL and OpenGL interop extension not working (clGetGLContextInfoKHR crash)
我正在努力让 GL+CL 协同工作。
我一直在关注 this tutorial. In my code I first call clGetPlatformIDs
and retrieve the first (and only) platform. I also get my gl_context
from SDL2. Then I want to query the device used by OpenGL with help of clGetGLContextInfoKHR
. I successfully obtain this function with clGetExtensionFunctionAddressForPlatform(platform_id, "clGetGLContextInfoKHR")
but unfortunately when I call it, I get a segmentation fault. My code is written in Rust but I use 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[=10=]" 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
也许最重要的线索可能是,每当我调用 clGetGLContextInfoKHR
(包装在更安全和更高级别的 API) 它崩溃了。我认为所有这些库的代码中都存在错误的可能性很小,所以这可能是我环境中的一些问题。但是,如您所见,我的显卡显然支持所有必要的扩展。
我不确定为什么 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 in Action: How to Accelerate Graphics and Computations
我正在努力让 GL+CL 协同工作。
我一直在关注 this tutorial. In my code I first call clGetPlatformIDs
and retrieve the first (and only) platform. I also get my gl_context
from SDL2. Then I want to query the device used by OpenGL with help of clGetGLContextInfoKHR
. I successfully obtain this function with clGetExtensionFunctionAddressForPlatform(platform_id, "clGetGLContextInfoKHR")
but unfortunately when I call it, I get a segmentation fault. My code is written in Rust but I use 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[=10=]" 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
也许最重要的线索可能是,每当我调用 clGetGLContextInfoKHR
(包装在更安全和更高级别的 API) 它崩溃了。我认为所有这些库的代码中都存在错误的可能性很小,所以这可能是我环境中的一些问题。但是,如您所见,我的显卡显然支持所有必要的扩展。
我不确定为什么 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 in Action: How to Accelerate Graphics and Computations