Skip to content

Bevy picks descrete GPU without a present queue causing "No supported formats for surface" #21987

@kitt-cat

Description

@kitt-cat

Bevy version and features

  • b2f5212
  • default features (running the breakout example)

Relevant system information

  • linux
  • sway (xwayland enabled)
  • a laptop with a discrete NVIDIA GeForce GTX 1050 Ti and an integrated Intel UHD Graphics 630

What you did

% cargo run --example=breakout 
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.49s
     Running `target/debug/examples/breakout`
2025-11-30T23:36:33.645180Z  INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Linux (Arch Linux rolling)", kernel: "6.17.8-arch1-1", cpu: "Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz", core_count: "3", memory: "31.0 GiB" }
2025-11-30T23:36:33.738699Z  INFO bevy_render::renderer: AdapterInfo { name: "NVIDIA GeForce GTX 1050 Ti with Max-Q Design", vendor: 4318, device: 7308, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "580.105.08", backend: Vulkan }
2025-11-30T23:36:34.526437Z  INFO bevy_render::batching::gpu_preprocessing: GPU preprocessing is fully supported on this device.
2025-11-30T23:36:34.553701Z  INFO bevy_winit::system: Creating new window breakout (0v0)
2025-11-30T23:36:34.558380Z  INFO breakout::stepping: Bevy was compiled without stepping support. Run with `--features=bevy_debug_stepping` to enable stepping.

thread 'main' panicked at crates/bevy_render/src/view/window/mod.rs:355:51:
No supported formats for surface

For context, vkcube works with the integrated GPU but not the discrete one:

% vkcube
Selected WSI platform: wayland
Selected GPU 1: Intel(R) UHD Graphics 630 (CFL GT2), type: IntegratedGpu
# the cube is properly displayed
% vkcube --gpu_number 1
Selected WSI platform: wayland
Selected GPU 1: NVIDIA GeForce GTX 1050 Ti with Max-Q Design, type: DiscreteGpu
Could not find both graphics and present queues
# non-zero exit (1)

What went wrong

If it's not clear, break this out into:

  • What did you expect to happen?
    • Bevy checks what GPUs have an associated present queue or can otherwise render to a surface, and picks appropriately (in my case, picks the integrated GPU).
  • what actually happened?
    • Bevy picked the discrete GPU and subsequently encountered an error when trying to present.

Additional information

I tried running the example with WGPU_ADAPTER='Intel(R) UHD Graphics 630 (CFL GT2)', but bevy still picked the discrete gpu. I added some debug prints and I believe it was skipped due to compatible_surface being None here, which caused bevy to fall back to automatic adapter selection.

I tried to trace why the surface is None, and it seems the RawWindowWrapperHolder from this query doesn't contain a window.

Judging by the ordering of log messages it appears that bevy_render is setting up before bevy_winit, is it possible they are racing? Is there a way to get render setup to occur after window setup?


I confirmed the example does run on my integrated gpu by replacing the add_plugin(DefaultPlugins) call in breakout.rs with

        .add_plugins(DefaultPlugins.set({
            use bevy_render::{RenderPlugin, settings::{RenderCreation, PowerPreference, WgpuSettings}};
            RenderPlugin {
                render_creation: RenderCreation::Automatic(
                    WgpuSettings {
                        power_preference: PowerPreference::LowPower,
                        ..default()
                }),
                ..default()
        }}))

With this, the breakout example displayed and ran as expected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-BugAn unexpected or incorrect behaviorS-Needs-TriageThis issue needs to be labelled

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions