mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-12 05:31:31 +11:00
Merge pull request #454 from tomaka/opengl-3
Fix GLX creating only 3.0 contexts
This commit is contained in:
commit
476d91c9d8
|
@ -35,52 +35,6 @@ impl Context {
|
||||||
fb_config: ffi::glx::types::GLXFBConfig, mut visual_infos: ffi::glx::types::XVisualInfo)
|
fb_config: ffi::glx::types::GLXFBConfig, mut visual_infos: ffi::glx::types::XVisualInfo)
|
||||||
-> Result<Context, CreationError>
|
-> Result<Context, CreationError>
|
||||||
{
|
{
|
||||||
// creating GL context
|
|
||||||
let (context, extra_functions) = unsafe {
|
|
||||||
let mut attributes = Vec::new();
|
|
||||||
|
|
||||||
match builder.gl_version {
|
|
||||||
GlRequest::Latest => {},
|
|
||||||
GlRequest::Specific(Api::OpenGl, (major, minor)) => {
|
|
||||||
attributes.push(ffi::glx_extra::CONTEXT_MAJOR_VERSION_ARB as libc::c_int);
|
|
||||||
attributes.push(major as libc::c_int);
|
|
||||||
attributes.push(ffi::glx_extra::CONTEXT_MINOR_VERSION_ARB as libc::c_int);
|
|
||||||
attributes.push(minor as libc::c_int);
|
|
||||||
},
|
|
||||||
GlRequest::Specific(_, _) => panic!("Only OpenGL is supported"),
|
|
||||||
GlRequest::GlThenGles { opengl_version: (major, minor), .. } => {
|
|
||||||
attributes.push(ffi::glx_extra::CONTEXT_MAJOR_VERSION_ARB as libc::c_int);
|
|
||||||
attributes.push(major as libc::c_int);
|
|
||||||
attributes.push(ffi::glx_extra::CONTEXT_MINOR_VERSION_ARB as libc::c_int);
|
|
||||||
attributes.push(minor as libc::c_int);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(profile) = builder.gl_profile {
|
|
||||||
let flag = match profile {
|
|
||||||
GlProfile::Compatibility =>
|
|
||||||
ffi::glx_extra::CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
|
||||||
GlProfile::Core =>
|
|
||||||
ffi::glx_extra::CONTEXT_CORE_PROFILE_BIT_ARB,
|
|
||||||
};
|
|
||||||
attributes.push(ffi::glx_extra::CONTEXT_PROFILE_MASK_ARB as libc::c_int);
|
|
||||||
attributes.push(flag as libc::c_int);
|
|
||||||
}
|
|
||||||
|
|
||||||
if builder.gl_debug {
|
|
||||||
attributes.push(ffi::glx_extra::CONTEXT_FLAGS_ARB as libc::c_int);
|
|
||||||
attributes.push(ffi::glx_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int);
|
|
||||||
}
|
|
||||||
|
|
||||||
attributes.push(0);
|
|
||||||
|
|
||||||
// loading the extra GLX functions
|
|
||||||
let extra_functions = ffi::glx_extra::Glx::load_with(|addr| {
|
|
||||||
with_c_str(addr, |s| {
|
|
||||||
glx.GetProcAddress(s as *const u8) as *const libc::c_void
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
let share = if let Some(win) = builder.sharing {
|
let share = if let Some(win) = builder.sharing {
|
||||||
match win {
|
match win {
|
||||||
&PlatformWindow::X(ref win) => match win.x.context {
|
&PlatformWindow::X(ref win) => match win.x.context {
|
||||||
|
@ -93,22 +47,43 @@ impl Context {
|
||||||
ptr::null()
|
ptr::null()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut context = if extra_functions.CreateContextAttribsARB.is_loaded() {
|
// loading the extra GLX functions
|
||||||
extra_functions.CreateContextAttribsARB(display as *mut ffi::glx_extra::types::Display,
|
let extra_functions = ffi::glx_extra::Glx::load_with(|addr| {
|
||||||
fb_config, share, 1, attributes.as_ptr())
|
with_c_str(addr, |s| {
|
||||||
|
unsafe { glx.GetProcAddress(s as *const u8) as *const _ }
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// creating GL context
|
||||||
|
let context = match builder.gl_version {
|
||||||
|
GlRequest::Latest => {
|
||||||
|
if let Ok(ctxt) = create_context(&glx, &extra_functions, (3, 2),
|
||||||
|
builder.gl_profile, builder.gl_debug, share,
|
||||||
|
display, fb_config, &mut visual_infos)
|
||||||
|
{
|
||||||
|
ctxt
|
||||||
|
} else if let Ok(ctxt) = create_context(&glx, &extra_functions, (3, 1),
|
||||||
|
builder.gl_profile, builder.gl_debug,
|
||||||
|
share, display, fb_config,
|
||||||
|
&mut visual_infos)
|
||||||
|
{
|
||||||
|
ctxt
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ptr::null()
|
try!(create_context(&glx, &extra_functions, (1, 0), builder.gl_profile,
|
||||||
};
|
builder.gl_debug, share, display, fb_config,
|
||||||
|
&mut visual_infos))
|
||||||
if context.is_null() {
|
|
||||||
context = glx.CreateContext(display as *mut _, &mut visual_infos, share, 1)
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
if context.is_null() {
|
GlRequest::Specific(Api::OpenGl, (major, minor)) => {
|
||||||
return Err(CreationError::OsError(format!("GL context creation failed")));
|
try!(create_context(&glx, &extra_functions, (major, minor), builder.gl_profile,
|
||||||
}
|
builder.gl_debug, share, display, fb_config, &mut visual_infos))
|
||||||
|
},
|
||||||
(context, extra_functions)
|
GlRequest::Specific(_, _) => panic!("Only OpenGL is supported"),
|
||||||
|
GlRequest::GlThenGles { opengl_version: (major, minor), .. } => {
|
||||||
|
try!(create_context(&glx, &extra_functions, (major, minor), builder.gl_profile,
|
||||||
|
builder.gl_debug, share, display, fb_config, &mut visual_infos))
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// vsync
|
// vsync
|
||||||
|
@ -210,3 +185,53 @@ impl Drop for Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_context(glx: &ffi::glx::Glx, extra_functions: &ffi::glx_extra::Glx,
|
||||||
|
version: (u8, u8), profile: Option<GlProfile>, debug: bool,
|
||||||
|
share: ffi::GLXContext, display: *mut ffi::Display,
|
||||||
|
fb_config: ffi::glx::types::GLXFBConfig,
|
||||||
|
visual_infos: &mut ffi::glx::types::XVisualInfo)
|
||||||
|
-> Result<ffi::GLXContext, CreationError>
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
let context = if extra_functions.CreateContextAttribsARB.is_loaded() {
|
||||||
|
let mut attributes = Vec::with_capacity(9);
|
||||||
|
|
||||||
|
attributes.push(ffi::glx_extra::CONTEXT_MAJOR_VERSION_ARB as libc::c_int);
|
||||||
|
attributes.push(version.0 as libc::c_int);
|
||||||
|
attributes.push(ffi::glx_extra::CONTEXT_MINOR_VERSION_ARB as libc::c_int);
|
||||||
|
attributes.push(version.1 as libc::c_int);
|
||||||
|
|
||||||
|
if let Some(profile) = profile {
|
||||||
|
let flag = match profile {
|
||||||
|
GlProfile::Compatibility =>
|
||||||
|
ffi::glx_extra::CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
||||||
|
GlProfile::Core =>
|
||||||
|
ffi::glx_extra::CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||||
|
};
|
||||||
|
|
||||||
|
attributes.push(ffi::glx_extra::CONTEXT_PROFILE_MASK_ARB as libc::c_int);
|
||||||
|
attributes.push(flag as libc::c_int);
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
attributes.push(ffi::glx_extra::CONTEXT_FLAGS_ARB as libc::c_int);
|
||||||
|
attributes.push(ffi::glx_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int);
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes.push(0);
|
||||||
|
|
||||||
|
extra_functions.CreateContextAttribsARB(display as *mut _, fb_config, share, 1,
|
||||||
|
attributes.as_ptr())
|
||||||
|
|
||||||
|
} else {
|
||||||
|
glx.CreateContext(display as *mut _, visual_infos, share, 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
if context.is_null() {
|
||||||
|
return Err(CreationError::OsError(format!("GL context creation failed")));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue