mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
[egl] Fix robust context creation failing on some devices (#7952)
This commit is contained in:
parent
4bd0f751f8
commit
68a10a01d9
@ -574,7 +574,6 @@ impl Inner {
|
|||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let needs_robustness = true;
|
|
||||||
let mut khr_context_flags = 0;
|
let mut khr_context_flags = 0;
|
||||||
let supports_khr_context = display_extensions.contains("EGL_KHR_create_context");
|
let supports_khr_context = display_extensions.contains("EGL_KHR_create_context");
|
||||||
|
|
||||||
@ -611,53 +610,108 @@ impl Inner {
|
|||||||
log::debug!("\tEGL context: -debug");
|
log::debug!("\tEGL context: -debug");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if needs_robustness {
|
|
||||||
//Note: the core version can fail if robustness is not supported
|
|
||||||
// (regardless of whether the extension is supported!).
|
|
||||||
// In fact, Angle does precisely that awful behavior, so we don't try it there.
|
|
||||||
if version >= (1, 5) && !display_extensions.contains("EGL_ANGLE_") {
|
|
||||||
log::debug!("\tEGL context: +robust access");
|
|
||||||
context_attributes.push(khronos_egl::CONTEXT_OPENGL_ROBUST_ACCESS);
|
|
||||||
context_attributes.push(khronos_egl::TRUE as _);
|
|
||||||
} else if display_extensions.contains("EGL_EXT_create_context_robustness") {
|
|
||||||
log::debug!("\tEGL context: +robust access EXT");
|
|
||||||
context_attributes.push(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT);
|
|
||||||
context_attributes.push(khronos_egl::TRUE as _);
|
|
||||||
} else {
|
|
||||||
//Note: we aren't trying `EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR`
|
|
||||||
// because it's for desktop GL only, not GLES.
|
|
||||||
log::warn!("\tEGL context: -robust access");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if khr_context_flags != 0 {
|
if khr_context_flags != 0 {
|
||||||
context_attributes.push(EGL_CONTEXT_FLAGS_KHR);
|
context_attributes.push(EGL_CONTEXT_FLAGS_KHR);
|
||||||
context_attributes.push(khr_context_flags);
|
context_attributes.push(khr_context_flags);
|
||||||
}
|
}
|
||||||
context_attributes.push(khronos_egl::NONE);
|
|
||||||
|
|
||||||
gl_context_attributes.extend(&context_attributes);
|
gl_context_attributes.extend(&context_attributes);
|
||||||
gles_context_attributes.extend(&context_attributes);
|
gles_context_attributes.extend(&context_attributes);
|
||||||
|
|
||||||
let context = if supports_opengl {
|
let context = {
|
||||||
|
enum Robustness {
|
||||||
|
Core,
|
||||||
|
Ext,
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut robustness = if version >= (1, 5) {
|
||||||
|
Some(Robustness::Core)
|
||||||
|
} else if display_extensions.contains("EGL_EXT_create_context_robustness") {
|
||||||
|
Some(Robustness::Ext)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let robustness_attributes = match robustness {
|
||||||
|
Some(Robustness::Core) => {
|
||||||
|
vec![
|
||||||
|
khronos_egl::CONTEXT_OPENGL_ROBUST_ACCESS,
|
||||||
|
khronos_egl::TRUE as _,
|
||||||
|
khronos_egl::NONE,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Some(Robustness::Ext) => {
|
||||||
|
vec![
|
||||||
|
EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT,
|
||||||
|
khronos_egl::TRUE as _,
|
||||||
|
khronos_egl::NONE,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
None => vec![khronos_egl::NONE],
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut gl_context_attributes = gl_context_attributes.clone();
|
||||||
|
gl_context_attributes.extend(&robustness_attributes);
|
||||||
|
|
||||||
|
let mut gles_context_attributes = gles_context_attributes.clone();
|
||||||
|
gles_context_attributes.extend(&robustness_attributes);
|
||||||
|
|
||||||
|
let result = if supports_opengl {
|
||||||
egl.create_context(display, config, None, &gl_context_attributes)
|
egl.create_context(display, config, None, &gl_context_attributes)
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
egl.bind_api(khronos_egl::OPENGL_ES_API).unwrap();
|
egl.bind_api(khronos_egl::OPENGL_ES_API).unwrap();
|
||||||
egl.create_context(display, config, None, &gles_context_attributes)
|
egl.create_context(display, config, None, &gles_context_attributes)
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
egl.create_context(display, config, None, &gles_context_attributes)
|
||||||
|
};
|
||||||
|
|
||||||
|
match (result, robustness) {
|
||||||
|
// We have a context at the requested robustness level
|
||||||
|
(Ok(_), robustness) => {
|
||||||
|
match robustness {
|
||||||
|
Some(Robustness::Core) => {
|
||||||
|
log::debug!("\tEGL context: +robust access");
|
||||||
|
}
|
||||||
|
Some(Robustness::Ext) => {
|
||||||
|
log::debug!("\tEGL context: +robust access EXT");
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
log::debug!("\tEGL context: -robust access");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BadAttribute could mean that context creation is not supported at the requested robustness level
|
||||||
|
// We try the next robustness level.
|
||||||
|
(Err(khronos_egl::Error::BadAttribute), Some(r)) => {
|
||||||
|
// Trying EXT robustness if Core robustness is not working
|
||||||
|
// and EXT robustness is supported.
|
||||||
|
robustness = if matches!(r, Robustness::Core)
|
||||||
|
&& display_extensions.contains("EGL_EXT_create_context_robustness")
|
||||||
|
{
|
||||||
|
Some(Robustness::Ext)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any other error, or depleted robustness levels, we give up.
|
||||||
|
_ => break result,
|
||||||
|
}
|
||||||
|
}
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
crate::InstanceError::with_source(
|
crate::InstanceError::with_source(
|
||||||
String::from("unable to create OpenGL or GLES 3.x context"),
|
String::from("unable to create OpenGL or GLES 3.x context"),
|
||||||
e,
|
e,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
egl.create_context(display, config, None, &gles_context_attributes)
|
|
||||||
.map_err(|e| {
|
|
||||||
crate::InstanceError::with_source(
|
|
||||||
String::from("unable to create GLES 3.x context"),
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
// Testing if context can be binded without surface
|
// Testing if context can be binded without surface
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user