What images to use for wayland with GPU support for verdin imx8mp?

I’m trying to get a Rust app which uses EGL to spawn a window on Wayland. I want to be able to automate my workflow so the templates provided by the VS Code IDE extension aren’t particularly useful.

So, I’m trying to use the Rust cross build tool which uses docker and a correctly cross compiling toolchain to cross compile, like this: cross build --target aarch64-unknown-linux-gnu

I’ve added some extra arm64 packages to the build there:

[target.aarch64-unknown-linux-gnu]
pre-build = [
    "dpkg --add-architecture $CROSS_DEB_ARCH",
    "apt-get update && apt-get --assume-yes install libxkbcommon0:$CROSS_DEB_ARCH libwayland-dev:$CROSS_DEB_ARCH libudev-dev:$CROSS_DEB_ARCH"
]

The build seems to work fine, and I’ve used binaries without video support before from this cross compiling toolchain.

I then have a Dockerfile which puts this cross compiled app in the wayland-base-imx8:stable-rc image:

FROM --platform=linux/arm64 torizon/wayland-base-imx8:stable-rc
COPY ./target/aarch64-unknown-linux-gnu/debug/my_app /home/torizon/my_app

I then have a docker-compose.yml file which looks like this:

version: "3.9"

services:
  weston:
    image: torizon/weston-imx8:4
    container_name: weston
    network_mode: host
    cap_add:
      - SYS_TTY_CONFIG
    volumes:
      - /dev:/dev
      - /tmp:/tmp
      - /run/udev:/run/udev
    device_cgroup_rules:
      - "c 4:* rmw"
      - "c 253:* rmw"
      - "c 13:* rmw"
      - "c 226:* rmw"
      - "c 10:223 rmw"
      - "c 199:0 rmw"
    command: ["--developer"]
    restart: unless-stopped

  wayland-app:
    image: my_image
    container_name: wayland-app
    cap_add:
      - SYS_TTY_CONFIG
    environment:
      ACCEPT_FSL_EULA: "1"
    volumes:
      - /dev/dri:/dev/dri
      - /dev/galcore:/dev/galcore
      - /tmp:/tmp
    device_cgroup_rules:
      - "c 199:* rmw"
      - "c 226:* rmw"
    entrypoint: ["/bin/bash"]
    depends_on: [weston]
    command: ["-c", "sleep 2 && /home/torizon/my_app"]
    restart: no

This seems to launch just fine, I don’t see any errors, it detects the outputs correctly, but when the app goes to launch, it doesn’t find a default display:

docker compose up
WARN[0000] /home/torizon/docker-compose.yml: `version` is obsolete
[+] Running 1/2
 ✔ Container weston       Created                                                                                0.0s
 ⠙ Container wayland-app  Recreated                                                                              0.1s
Attaching to wayland-app, weston
weston       | Switching VT tty1 to text mode if currently in graphics mode
weston       | Switching to VT 7
weston       | SoC is: 'i.MX8MP'
weston       | SoC has GPU: true
weston       | SoC has DPU: false
weston       | g2d implementation: viv
...
weston       | [20:44:05.691] using /dev/dri/card1
...
weston       | [20:44:06.319] Output HDMI-A-1 (crtc 33) video modes:
weston       |                1280x720@60.0, preferred, current, 74.2 MHz
...
wayland-app  | 2024-12-12T20:49:43.745871Z  INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Linux 12 Debian GNU/Linux", kernel: "6.6.23-7.0.0-g558ba3740880", cpu: "Cortex-A53", core_count: "4", memory: "7.8 GiB" }
wayland-app  | EGL: Warning: No default display support on wayland
wayland-app  | thread 'main' panicked at /cargo/registry/src/index.crates.io-6f17d22bba15001f/khronos-egl-6.0.0/src/lib.rs:1779:26:
wayland-app  | called `Option::unwrap()` on a `None` value
wayland-app  | note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
wayland-app exited with code 101

It’s like the EGL libraries are broken. What do I need to do to fix this?

Hi, I’m the Toradex AI Assistant. The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


Hello!

To address the issue where your Rust application using EGL cannot find a default display on Wayland, here are some steps you can follow:

  1. Verify Weston Compositor: Ensure that the Weston compositor is running correctly. Check the logs of the Weston container to confirm it starts without errors and is ready to accept Wayland clients.

  2. Set Environment Variables: Make sure the WAYLAND_DISPLAY environment variable is correctly set in your wayland-app container. This variable should match the Wayland socket used by Weston, typically WAYLAND_DISPLAY=wayland-0.

  3. Check Device Permissions: Confirm that your wayland-app container has the necessary permissions to access GPU and display devices. You’ve mounted /dev/dri and /dev/galcore, which is good, but also ensure your device cgroup rules are correctly configured.

  4. Install Required Libraries: Verify that all necessary EGL and Wayland libraries are installed in your wayland-app container. You may need packages like libegl1-mesa, libwayland-client0, and libwayland-egl1 to ensure proper functionality.

  5. Cross-Compilation Checks: Ensure that the correct versions of libraries are linked during cross-compilation. Mismatches between host and target library versions can lead to runtime issues.

  6. Enable Debugging: Set the RUST_BACKTRACE=1 environment variable to get a stack trace, which can provide more insight into where the failure occurs.

By following these steps, you should be able to resolve the issue with EGL not finding a default display on Wayland. If the problem persists, consider testing with a simple Wayland application to determine if the issue is with the environment or your specific Rust application.

Best regards,
Toradex AI Assistant.

Please, also check if these links can help you solve your problem:

Electron segfaults when enabling hardware acceleration on iMX8MP.

Greetings @alexkl,

First of all what version of Torizon OS are you running on your Verdin i.MX8M Plus?

I see you’re using torizon/weston-imx8:4. So, I assume you’re using some version 7.X since that is the OS version to use for our container tag 4, but I just want to be sure.

Second, on your side do you even see the Weston container go up on your display?

Assuming you are on some version 7.X. I did various tests to check GPU and EGL on our Torizon OS 7.0.0 release image. Everything seems to be working as expected. For reference I ran the following tests:

  • Tested some Qt6 OpenGLES examples:
# Weston container first
$ docker container run -d --name=weston --net=host \
    --cap-add CAP_SYS_TTY_CONFIG \
    -v /dev:/dev -v /tmp:/tmp -v /run/udev/:/run/udev/ \
    --device-cgroup-rule="c 4:* rmw" --device-cgroup-rule="c 253:* rmw" \
    --device-cgroup-rule="c 13:* rmw" --device-cgroup-rule="c 226:* rmw" \
    --device-cgroup-rule="c 10:223 rmw" --device-cgroup-rule="c 199:0 rmw" \
    torizon/weston-imx8:4 \
    --developer
# Container with Qt examples
$ docker run -e ACCEPT_FSL_EULA=1 --rm -it --name=qt6 \
           -v /tmp:/tmp \
           -v /dev/dri:/dev/dri -v /dev/galcore:/dev/galcore \
           --device-cgroup-rule='c 199:* rmw' --device-cgroup-rule='c 226:* rmw' \
           torizon/qt6-wayland-examples-imx8:4 \
           bash
# Inside the Qt container now
$ /usr/lib/aarch64-linux-gnu/qt6/examples/opengl/contextinfo/contextinf

This example should bring up a window that lets you render something using OpenGL ES.

  • I also ran kmscube using our graphics-test container:
$ docker run -e ACCEPT_FSL_EULA=1 -it -v /dev:/dev -v /tmp:/tmp --device-cgroup-rule="c 4:* rmw" --device-cgroup-rule="c 13:* rmw" --device-cgroup-rule="c 199:* rmw" --device-cgroup-rule="c 226:* rmw" torizon/graphics-tests-imx8:4 kmscube

Besides the graphics on the screen the kmscube output on the console also shows EGL information:

Using display 0x55a54a45e0 with EGL version 1.5
===================================
EGL information:
  version: "1.5"
  vendor: "Vivante Corporation"
  client extensions: "EGL_EXT_client_extensions EGL_EXT_platform_base EGL_KHR_platform_wayland EGL_EXT_platform_wayland EGL_EXT_device_query EGL_EXT_device_drm EGL_EXT_device_drm_render_node EGL_KHR_platform_gbm"
  display extensions: "EGL_KHR_fence_sync EGL_KHR_reusable_sync EGL_KHR_wait_sync EGL_KHR_image EGL_KHR_image_base EGL_KHR_image_pixmap EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_gl_renderbuffer_image EGL_EXT_image_dma_buf_import EGL_EXT_image_dma_buf_import_modifiers EGL_KHR_lock_surface EGL_KHR_create_context EGL_KHR_no_config_context EGL_KHR_surfaceless_context EGL_KHR_get_all_proc_addresses EGL_EXT_create_context_robustness EGL_EXT_protected_surface EGL_EXT_protected_content EGL_EXT_buffer_age EGL_ANDROID_native_fence_sync EGL_WL_bind_wayland_display EGL_WL_create_wayland_buffer_from_image EGL_KHR_partial_update EGL_EXT_swap_buffers_with_damage EGL_KHR_swap_buffers_with_damage EGL_EXT_pixel_format_float EGL_KHR_surfaceless_context_opengl"
===================================
OpenGL ES 2.x information:
  version: "OpenGL ES 3.1 V6.4.11.p2.745085"
  shading language version: "OpenGL ES GLSL ES 3.10"
  vendor: "Vivante Corporation"
  renderer: "Vivante GC7000UL"
  extensions: "GL_OES_vertex_type_10_10_10_2 GL_OES_vertex_half_float GL_OES_element_index_uint GL_OES_mapbuffer GL_OES_vertex_array_object GL_OES_compressed_ETC1_RGB8_texture GL_OES_compressed_paletted_texture GL_OES_texture_npot GL_OES_rgb8_rgba8 GL_OES_depth_texture GL_OES_depth_texture_cube_map GL_OES_depth24 GL_OES_depth32 GL_OES_packed_depth_stencil GL_OES_fbo_render_mipmap GL_OES_get_program_binary GL_OES_fragment_precision_high GL_OES_standard_derivatives GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_EGL_image_external_essl3 GL_OES_EGL_sync GL_OES_texture_stencil8 GL_OES_shader_image_atomic GL_OES_texture_storage_multisample_2d_array GL_OES_required_internalformat GL_OES_surfaceless_context GL_OES_draw_buffers_indexed GL_OES_texture_border_clamp GL_OES_texture_buffer GL_OES_texture_cube_map_array GL_OES_draw_elements_base_vertex GL_OES_texture_half_float GL_OES_texture_float GL_KHR_blend_equation_advanced GL_KHR_debug GL_KHR_robustness GL_KHR_robust_buffer_access_behavior GL_EXT_texture_type_2_10_10_10_REV GL_EXT_texture_compression_dxt1 GL_EXT_texture_format_BGRA8888 GL_EXT_texture_compression_s3tc GL_EXT_read_format_bgra GL_EXT_multi_draw_arrays GL_EXT_frag_depth GL_EXT_discard_framebuffer GL_EXT_blend_minmax GL_EXT_multisampled_render_to_texture GL_EXT_color_buffer_half_float GL_EXT_color_buffer_float GL_EXT_robustness GL_EXT_texture_sRGB_decode GL_EXT_draw_buffers_indexed GL_EXT_texture_border_clamp GL_EXT_texture_buffer GL_EXT_texture_cube_map_array GL_EXT_multi_draw_indirect GL_EXT_draw_elements_base_vertex GL_EXT_texture_rg GL_EXT_protected_textures GL_EXT_sRGB GL_EXT_draw_buffers GL_EXT_unpack_subimage GL_EXT_timer_query GL_VIV_direct_texture "
===================================

Based on these tests, it doesn’t appear that there is anything wrong with EGL. Not sure what else to suggest specifically for your use-case since I’m not too familiar with this Rust application.

Best Regards,
Jeremias

It looks like the EGL driver does not support EGL_DEFAULT_DISPLAY on Wayland to get the default display. (see: No EGL_DEFAULT_DISPLAY on GL Backend + Wayland (Vivante/OpenGL2) · Issue #3176 · gfx-rs/wgpu · GitHub) It seems like if Vulkan were supported that this issue with the EGL driver wouldn’t be an issue. Vulkan seems to be supported in the I.MX Linux BSP, but none of the templates have this working:
vscode-torizon-templates/GPU.md at dev · torizon/vscode-torizon-templates · GitHub

Looks like the reason Vulkan doesn’t work is that the imx-gpu-viv package is missing the imx_icd.json file:

app# cat /etc/vulkan/icd.d/imx_icd.json
{
    "file_format_version": "1.0.0",
    "ICD": {
        "library_path": "/usr/lib/aarch64-linux-gnu/libvulkan_VSI.so.1",
        "api_version": "1.3.239"
    }
}

Though, the Vulkan backend of wgpu-rs currently segfaults. I’ll try XWayland + OpenGL ES.

The reason for the “no default display” error is that the EGL driver provided by IMX seems to simply not support the feature - and the wgpu-rs project currently needs this to function. I experimented with forking it but I found that similar experiments were done, and that the project isn’t in the most stable state. GitHub - alextechcc/wgpu: A cross-platform, safe, pure-Rust graphics API.

I am using TorizonOS 7.0.0.

I can’t seem to get literally any non-trivial GPU application running… Could I get some dedicated engineering support here?

  1. EGL_DEFAULT_DISPLAY support is broken on Wayland as above.
  2. GPU package (imx-gpu-viv / imx-gpu-viv-wayland-dev) is missing /etc/vulkan/icd.d/imx_icd.json.
  3. When I patch wgpu to work around EGL_DEFAULT_DISPLAY, OpenGL ES and Vulkan both crash on trivial examples. (GitHub - gfx-rs/wgpu: A cross-platform, safe, pure-Rust graphics API.)
  4. Xauthority file doesn’t get created by Weston - I couldn’t get an application to run targeting x11 for XWayland which probably would have had EGL_DEFAULT_DISPLAY.

The link here is broken:

Using this simple docker compose I intuited that just runs the kiosk image and weston, things crash, maybe the same issue as the Rust stuff?:

version: "3.9"

services:
  weston:
    image: torizon/weston-imx8:4
    container_name: weston
    network_mode: host
    cap_add:
      - SYS_TTY_CONFIG
    volumes:
      - /dev:/dev
      - /tmp:/tmp
      - /run/udev:/run/udev
      - /home/torizon:/home/torizon/app
    device_cgroup_rules:
      - "c 4:* rmw"
      - "c 253:* rmw"
      - "c 13:* rmw"
      - "c 226:* rmw"
      - "c 10:223 rmw"
      - "c 199:0 rmw"
    command: ["--developer"]
    restart: unless-stopped

  kiosk:
    container_name: kiosk
    environment:
      - MACHINE
    image: torizon/chromium:4
    command: --window-mode http://example.com
    security_opt:
      - seccomp:unconfined
    network_mode: host
    volumes:
      - type: bind
        source: /tmp
        target: /tmp
      - type: bind
        source: /var/run/dbus
        target: /var/run/dbus
      - type: bind
        source: /dev/galcore
        target: /dev/galcore
    depends_on:
      - weston
    shm_size: '256mb'
    device_cgroup_rules:
      # ... for /dev/galcore device on i.MX8
      - 'c 199:* rmw'
    restart: unless-stopped

I get these logs:

weston  | [     9] wl_drm_is_format_supported, format = 0x30335241
weston  | [    10] wl_drm_is_format_supported, format = 0x30335258
weston  | [    11] wl_drm_is_format_supported, format = 0x30334241
weston  | [    12] wl_drm_is_format_supported, format = 0x30334258
kiosk   | [7:33:1216/215700.771742:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
kiosk   | [7:33:1216/215700.772943:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
kiosk   | [7:33:1216/215700.773052:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
kiosk   | [7:33:1216/215700.773115:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
kiosk   | [7:33:1216/215700.773678:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
kiosk   | *** stack smashing detected ***: terminated
kiosk   | [7:33:1216/215700.795790:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
kiosk   | [7:33:1216/215700.860723:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
kiosk   | [7:33:1216/215700.860827:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
kiosk   | *** stack smashing detected ***: terminated
kiosk   | [7:67:1216/215700.945153:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
kiosk   | [7:49:1216/215700.945163:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
kiosk   | *** stack smashing detected ***: terminated
kiosk   | *** stack smashing detected ***: terminated
kiosk   | [7:7:1216/215701.150307:ERROR:gpu_process_host.cc(982)] GPU process exited unexpectedly: exit_code=134
kiosk   | [7:7:1216/215701.153338:ERROR:object_proxy.cc(576)] Failed to call method: org.freedesktop.DBus.NameHasOwner: object_path= /org/freedesktop/DBus: unknown error type:
kiosk   | *** stack smashing detected ***: terminated
kiosk   | *** stack smashing detected ***: terminated
kiosk   | [7:7:1216/215701.176833:ERROR:object_proxy.cc(576)] Failed to call method: org.freedesktop.DBus.NameHasOwner: object_path= /org/freedesktop/DBus: unknown error type:
kiosk   | [7:7:1216/215701.177243:ERROR:object_proxy.cc(576)] Failed to call method: org.freedesktop.DBus.NameHasOwner: object_path= /org/freedesktop/DBus: unknown error type:
kiosk   | [7:30:1216/215701.178306:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
kiosk   | [7:81:1216/215701.220251:ERROR:object_proxy.cc(576)] Failed to call method: org.freedesktop.DBus.Properties.Get: object_path= /org/freedesktop/UPower: org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.UPower was not provided by any .service files
kiosk   | [7:81:1216/215701.221367:ERROR:object_proxy.cc(576)] Failed to call method: org.freedesktop.UPower.GetDisplayDevice: object_path= /org/freedesktop/UPower: org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.UPower was not provided by any .service files
kiosk   | [7:81:1216/215701.223108:ERROR:object_proxy.cc(576)] Failed to call method: org.freedesktop.UPower.EnumerateDevices: object_path= /org/freedesktop/UPower: org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.UPower was not provided by any .service files
kiosk   | [7:7:1216/215701.232799:ERROR:gpu_process_host.cc(982)] GPU process exited unexpectedly: exit_code=134
kiosk   | [7:7:1216/215701.238566:ERROR:object_proxy.cc(576)] Failed to call method: org.freedesktop.DBus.NameHasOwner: object_path= /org/freedesktop/DBus: unknown error type:
kiosk   | [7:31:1216/215701.239586:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
kiosk   | *** stack smashing detected ***: terminated
kiosk   | *** stack smashing detected ***: terminated
kiosk   | [7:7:1216/215701.257646:ERROR:object_proxy.cc(576)] Failed to call method: org.freedesktop.DBus.NameHasOwner: object_path= /org/freedesktop/DBus: unknown error type:
kiosk   | [7:29:1216/215701.258699:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")
kiosk   | [7:7:1216/215701.267612:ERROR:gpu_process_host.cc(982)] GPU process exited unexpectedly: exit_code=134
kiosk   | [7:7:1216/215701.267717:FATAL:gpu_data_manager_impl_private.cc(423)] GPU process isn't usable. Goodbye.
kiosk   | [57:73:1216/215701.365232:ERROR:ssl_client_socket_impl.cc(878)] handshake failed; returned -1, SSL error code 1, net_error -3
kiosk   | Trace/breakpoint trap (core dumped)

Running pygame in python3:

>>> screen = pygame.display.set_mode([500, 500])
Bus error (core dumped)

EGL_DEFAULT_DISPLAY support is broken on Wayland as above.

Well there’s not much we can do there if the support is missing. We’re simply using the proprietary GPU driver from NXP here.

GPU package (imx-gpu-viv / imx-gpu-viv-wayland-dev) is missing /etc/vulkan/icd.d/imx_icd.json.

I’m confused here. What do you mean “missing”? For example in the Weston container I can see this file does exist:

# cat /etc/vulkan/icd.d/imx_icd.json
{
    "file_format_version": "1.0.0",
    "ICD": {
        "library_path": "/usr/lib/aarch64-linux-gnu/libvulkan_VSI.so.1",
        "api_version": "1.3.239"
    }
}

This is practically the same file that NXP packages as well: meta-freescale/recipes-graphics/imx-gpu-viv/imx-gpu-viv/imx_icd.json at scarthgap · Freescale/meta-freescale · GitHub

When I patch wgpu to work around EGL_DEFAULT_DISPLAY, OpenGL ES and Vulkan both crash on trivial examples

We’re not familiar with this wgpu framework/platform, so it’s difficult to comment further on this point.

Xauthority file doesn’t get created by Weston - I couldn’t get an application to run targeting x11 for XWayland which probably would have had EGL_DEFAULT_DISPLAY.

Hmm I believe we never shipped the Xauthority file in our container images. That said executing xterm which uses XWayland does work so, it should at least be possible to run X/X11 applications.

It should also be noted that we only have minimal support for X11 since NXP themselves doesn’t even support X11 themselves anymore. They don’t even support XWayland in fact.

The link here is broken:

I don’t know what article you’re referencing here in this screenshot.

Using this simple docker compose I intuited that just runs the kiosk image and weston, things crash, maybe the same issue as the Rust stuff?:

No this is a known issue. If you see our article on Web Browsers: Web Browser / Kiosk Mode with Torizon OS | Toradex Developer Center

There is a notice at the top that our browser containers including chromium are not fully stable and working yet for Torizon OS 7.

Running pygame in python3:

Not very familiar with pygame either. It’s hard to tell whether the issue is with the framework or with the proprietary driver from NXP, of which we have limited visibility into the inner workings of.

As for further comments. I’ve been able to run various Qt example applications, which I would not say are exactly trivial, especially given how heavy the Qt framework can be sometimes. I’ve brought this to our team for further comments, but none are personally familiar with the rust framework you’re trying to use here.

The only other suggestion I can give for now is to maybe try Torizon OS 6.8.0 with the version 3 container tags instead of the 4. We’ve worked longer on the 6.X series compared to the 7.X series that just released, so it’s probably more stable in several aspects. If you do use the 6.8.0 version make sure you reference the correct version of our documentation (see the version selector in the upper right of our developer site).

Best Regards,
Jeremias