Open VoreckLukas opened 2 months ago
This is the unwrap.
khronos_egl
maps EGL_NO_DISPLAY
to None for eglGetDisplay
.
I think we should error instead of panicking.
Still, do you have any idea why that could be None and what lib I am missing?
Maybe the DISPLAY
env var is not set? I'm not too familiar with this mechanism. I'd look online for "eglGetDisplay(EGL_DEFAULT_DISPLAY)
returns EGL_NO_DISPLAY
".
Okay here comes the weird thing: I Just created a little test program
fn main() {
unsafe {
let egl = dbg!(khronos_egl::DynamicInstance::<khronos_egl::EGL1_4>::load_required()).unwrap();
dbg!(egl.get_display(khronos_egl::DEFAULT_DISPLAY)).unwrap();
}
}
Which if I'm correct should produce the same error, right? Wrong
❯ cargo run -p testing
Finished dev [unoptimized + debuginfo] target(s) in 0.18s
Running `target/debug/testing`
[testing/src/main.rs:3:19] khronos_egl::DynamicInstance::<khronos_egl::EGL1_4>::load_required() = Ok(
Instance(Dynamic(Library@0x55aa58a70c10)),
)
[testing/src/main.rs:5:9] egl.get_display(khronos_egl::DEFAULT_DISPLAY) = Some(
Display(
0x000055aa58a7d480,
),
)
Since I just saw there are log statements, I quickly added env_logger
❯ RUST_LOG="trace" target/debug/chip8-iced
[2024-08-27T14:25:51Z DEBUG sctk] Bound new global [47] wl_output v4
[2024-08-27T14:25:51Z DEBUG sctk] Bound new global [9] zxdg_output_manager_v1 v3
[2024-08-27T14:25:51Z DEBUG sctk] Bound new global [1] wl_seat v7
[2024-08-27T14:25:51Z DEBUG sctk] Bound new global [10] wp_cursor_shape_manager_v1 v1
[2024-08-27T14:25:51Z DEBUG sctk] supported wl_shm format Argb8888
[2024-08-27T14:25:51Z DEBUG sctk] supported wl_shm format Xrgb8888
[2024-08-27T14:25:51Z DEBUG sctk] supported wl_shm format Argb2101010
[2024-08-27T14:25:51Z DEBUG sctk] supported wl_shm format Xrgb2101010
[2024-08-27T14:25:51Z DEBUG sctk] supported wl_shm format Abgr2101010
[2024-08-27T14:25:51Z DEBUG sctk] supported wl_shm format Xbgr2101010
[2024-08-27T14:25:51Z DEBUG sctk] supported wl_shm format Abgr8888
[2024-08-27T14:25:51Z DEBUG sctk] supported wl_shm format Xbgr8888
[2024-08-27T14:25:51Z TRACE calloop::loop_logic] [calloop] Inserting new source #0
[2024-08-27T14:25:51Z TRACE calloop::loop_logic] [calloop] Inserting new source #1
[2024-08-27T14:25:51Z TRACE calloop::loop_logic] [calloop] Inserting new source #2
[2024-08-27T14:25:51Z DEBUG iced_winit::application] Window builder: WindowBuilder {
window: WindowAttributes {
inner_size: Some(
Logical(
LogicalSize {
width: 1024.0,
height: 768.0,
},
),
),
min_inner_size: None,
max_inner_size: None,
position: None,
resizable: true,
enabled_buttons: WindowButtons(
CLOSE | MINIMIZE | MAXIMIZE,
),
title: "Chip8",
maximized: false,
visible: false,
transparent: false,
blur: false,
decorations: true,
window_icon: None,
preferred_theme: None,
resize_increments: None,
content_protected: false,
window_level: Normal,
active: true,
parent_window: SendSyncWrapper(
None,
),
fullscreen: SendSyncWrapper(
None,
),
},
}
[2024-08-27T14:25:51Z DEBUG wgpu_core::instance] Instance::new: failed to create Vulkan backend: InstanceError { message: "missing Vulkan entry points", source: Some(LibraryLoadFailure(DlOpen { desc: "libvulkan.so.1: cannot open shared object file: No such file or directory" })) }
[2024-08-27T14:25:51Z DEBUG wgpu_hal::gles::egl] Client extensions: []
[2024-08-27T14:25:51Z WARN wgpu_hal::gles::egl] EGL_MESA_platform_surfaceless not available. Using default platform
thread 'main' panicked at /home/lukas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-hal-0.19.5/src/gles/egl.rs:789:88:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Okay i did some more testing with the logging. I ran it via steam-run
(a magic nixos tool that loads in libraries at runtime, but itsnt suited for packaging applications, neither is it good when i want to do cargo run
)
Then it works and the logs sho me it's going into the wayland platform path while the above is crashing in the default platform path. So either the wayland library is none or the egl1_5 is none. So i threw together a minimal test
use std::{ptr, os::raw};
fn main() {
unsafe {
let egl = khronos_egl::DynamicInstance::<khronos_egl::EGL1_4>::load_required();
let egl = egl.unwrap();
let client_extensions = egl.query_string(None, khronos_egl::EXTENSIONS);
let client_ext_str = match client_extensions {
Ok(ext) => ext.to_string_lossy().into_owned(),
Err(_) => String::new(),
};
println!(
"Client extensions: {:#?}",
client_ext_str.split_whitespace().collect::<Vec<_>>()
);
let egl1_5 = egl.upcast::<khronos_egl::EGL1_5>();
dbg!(egl1_5);
let wayland_library = if client_ext_str.contains("EGL_EXT_platform_wayland") {
test_wayland_display()
} else {
None
};
dbg!(wayland_library);
}
}
fn test_wayland_display() -> Option<DisplayOwner> {
/* We try to connect and disconnect here to simply ensure there
* is an active wayland display available.
*/
let library = unsafe {
let client_library = find_library(&["libwayland-client.so.0", "libwayland-client.so"])?;
let wl_display_connect: libloading::Symbol<WlDisplayConnectFun> =
client_library.get(b"wl_display_connect").unwrap();
let wl_display_disconnect: libloading::Symbol<WlDisplayDisconnectFun> =
client_library.get(b"wl_display_disconnect").unwrap();
let display = ptr::NonNull::new(wl_display_connect(ptr::null()))?;
wl_display_disconnect(display.as_ptr());
find_library(&["libwayland-egl.so.1", "libwayland-egl.so"])?
};
Some(DisplayOwner {
library,
display: DisplayRef::Wayland,
})
}
#[derive(Debug)]
struct DisplayOwner {
library: libloading::Library,
display: DisplayRef,
}
unsafe fn find_library(paths: &[&str]) -> Option<libloading::Library> {
for path in paths {
match unsafe { libloading::Library::new(path) } {
Ok(lib) => return Some(lib),
_ => continue,
};
}
None
}
type WlDisplayConnectFun =
unsafe extern "system" fn(display_name: *const raw::c_char) -> *mut raw::c_void;
type WlDisplayDisconnectFun = unsafe extern "system" fn(display: *const raw::c_void);
#[derive(Debug)]
enum DisplayRef {
X11(ptr::NonNull<raw::c_void>),
Wayland,
}
Which includes all relevant code from the file you linked that sets those two variables. running it in the exact same environment as my binary that crashes gives me this
Client extensions: [
"EGL_EXT_device_base",
"EGL_EXT_device_enumeration",
"EGL_EXT_device_query",
"EGL_EXT_platform_base",
"EGL_KHR_client_get_all_proc_addresses",
"EGL_EXT_client_extensions",
"EGL_KHR_debug",
"EGL_EXT_platform_device",
"EGL_EXT_explicit_device",
"EGL_EXT_platform_wayland",
"EGL_KHR_platform_wayland",
"EGL_EXT_platform_x11",
"EGL_KHR_platform_x11",
"EGL_EXT_platform_xcb",
"EGL_MESA_platform_gbm",
"EGL_KHR_platform_gbm",
"EGL_MESA_platform_surfaceless",
]
[testing/src/main.rs:18:9] egl1_5 = Some(
Instance(Dynamic(Library@0x559982da5c10)),
)
[testing/src/main.rs:24:9] wayland_library = Some(
DisplayOwner {
library: Library@0x559982db30f0,
display: Wayland,
},
)```
The list of client extensions is empty here https://github.com/gfx-rs/wgpu/issues/6165#issuecomment-2312727001, but in https://github.com/gfx-rs/wgpu/issues/6165#issuecomment-2312822413 it's not.
Just to confirm, when using steam-run
will the list of client extensions always be populated? And with cargo run
it will be empty?
If so, it sounds like an env issue and it would be worth figuring out what steam-run
does.
On our end, I think we shouldn't unwrap there and instead report that there is no display available.
Just to confirm, when using steam-run will the list of client extensions always be populated? And with cargo run it will be empty?
Correct. but the second example is still a normal cargo run, but with the minimal test I threw together, no cargo required
By now I found out my issue it was a driver mismatch but it's weird that it affects one project but not the other besides both running in the same environment with the same command
On our end, I think we shouldn't unwrap there and instead report that there is no display available.
My issue is solved but I'll leave this open if you want to track that change
@VoreckLukas, would you mind sharing the config/fix if you were able to get it to run without steam-run
BTW thanks for sharing the workaround.
@VoreckLukas, would you mind sharing the config/fix if you were able to get it to run without
steam-run
BTW thanks for sharing the workaround.
The key is to keep your flake at the same version of nixpkgs as the rest of your system
So I'm using nixos and building an iced application. So far so good, everything works, i got all libraries set up. Then I pull in iced_aw and i start getting the error below and can't for the live of me figure out which library it's missing
with RUST_BACKTRACE
And with full backtrace