bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
36.68k stars 3.61k forks source link

Steam Deck dpi scale reported incorrectly #9369

Open paul-hansen opened 1 year ago

paul-hansen commented 1 year ago

Bevy version

0.11.0

System information

Steam Deck.

AdapterInfo { name: "AMD Custom GPU 0405 (RADV VANGOG)", vendor: 4098, device: 5695, device_type: IntegratedGpu, backend: Vulkan }

What you did

Ran our Bevy game on the Steam deck

What went wrong

The UI is scaled to be too large to understand. This happens always in desktop mode, and now I've seen it happening on a friend's Steam deck in gaming mode (a dedicated big picture mode) as well.

Additional information

I don't believe this is Bevy's fault but it may be something we want to apply a hack to work around so Bevy works out of the box on Steam deck. I don't believe it is Bevy's or even Winit's fault because I've seen C++ apps with the same problem: https://github.com/flyinghead/flycast/issues/769

There is some C++ code for how this was worked around by the above mentioned app here: https://github.com/flyinghead/flycast/commit/0cbf6f6601e5c0bbd849cf6cdde4ab6ae4b030ff#diff-a4bb38db71ecb0f6ce33b7d980ef616330afaf94e9b69a80e86e1d5bd0e26569R733-R741 Basically if the dpi scale is over 500, it checks if it's the Steam deck's resolution and checks the display name and if all matches it uses a corrected DPI scale instead of the reported scale.

Currently to work around this we are forcing the scale factor to be 1.0 in our game:

app.set(WindowPlugin {
    primary_window: Some(Window {
        resolution: WindowResolution::new(1280.0, 800.0)
            .with_scale_factor_override(1.0),
        ..default()
    }),
    ..default()
}),

Update: if you want to keep dpi scaling on other platforms, you can use something like in this comment: https://github.com/rust-windowing/winit/issues/2401#issuecomment-1530108455

paul-hansen commented 1 year ago

I'm part opening this issue so the workaround is something that can be found when searching. If we're interested in applying a workaround I'd be happy to work up a PR for this. I totally understand if this isn't something we want to take on the burden of though. I'm planning on opening a support ticket with Valve as well and will update this issue if I hear back.

paul-hansen commented 1 year ago

Anyone know much about the calls Winit/Bevy is using to get the dpi scale? Valve asked in their response.

image

To be clear their suggestions about proton shouldn't be relevant as I'm using native Linux builds and proton is for running Windows builds on Linux. I'll let them know that in my response.

paul-hansen commented 1 year ago

I found this in the Winit docs, I'll link them that.

X11: Many man-hours have been spent trying to figure out how to handle DPI in X11. Winit currently uses a three-pronged approach:

Use the value in the WINIT_X11_SCALE_FACTOR environment variable, if present. If not present, use the value set in Xft.dpi in Xresources. Otherwise, calculate the scale factor based on the millimeter monitor dimensions provided by XRandR. If WINIT_X11_SCALE_FACTOR is set to randr, it’ll ignore the Xft.dpi field and use the XRandR scaling method. Generally speaking, you should try to configure the standard system variables to do what you want before resorting to WINIT_X11_SCALE_FACTOR.

Wayland: On Wayland, scale factors are set per-screen by the server, and are always integers (most often 1 or 2).

paul-hansen commented 10 months ago

Got a response from Valve today:

Sorry for the late reply there. It's possible that SteamOS 3.5 has improved the situation there, as we're now reporting the correct screen physical dimensions in our EDID. But XWayland might be getting in the way there. We'll take a closer look in parallel, but can you check again now that SteamOS 3.5 has been released?

I tried it on SteamOS 3.5 and I'm still seeing similar results though so I let them know.

Misza13 commented 1 month ago

I'm part opening this issue so the workaround is something that can be found when searching.

Thank you for that. I ran into this issue one year later (SteamOS 3.5.19) and your workaround saved my skin. There isn't a lot of info out there on Steam Deck + Bevy, so it's worth its weight in gold.

BTW, do we know if enabling the wayland feature in bevy crate gives any benefit on the Steam Deck? You'd think it should (e.g. getting the correct resolution and DPI by talking to the compositor directly instead of via XWayland) because the Deck uses Wayland everywhere as far as we know, but I couldn't even begin to know how to tell.

paul-hansen commented 1 month ago

Glad it helped!

On desktop mode the deck is still using plasma 5 with x11 so even if you enable the Wayland feature on bevy, it will still fallback to using x11 there. In gaming mode however, it uses gamescope which is a custom Wayland compositor so enabling Wayland should benefit you there.

I haven't seen scaling issues in game mode since Valve said they worked on that (see my last comment) but in desktop mode it's still an issue.

Misza13 commented 1 month ago

Actually, I'm having the problem both in desktop and game mode, with Wayland feature enabled. So for now I just have to resort to detecting the Deck via /proc/cpuinfo (I think finding "AMD Custom APU 0405" in there is the most reliable indicator) and forcing resolution and scale per your finding.

paul-hansen commented 1 month ago

Oh weird, it has been awhile since I tried it. You might consider opening a support ticket with Valve, I think they would consider the wrong dpi in gamemode a bigger problem than just on desktop mode (which is probably going to change anyway once they update to plasma 6).

If you are implementing logic for detecting it, you might also want to consider what happens when the Steam deck is plugged into a TV/external display. E.g. Display scale 1.0 on a 4k tv might make things too small if you've designed your UI around a 1080p screen.