dhewm / dhewm3

dhewm 3 main repository
https://dhewm3.org/
GNU General Public License v3.0
1.78k stars 346 forks source link

wayland: regression with imgui-rebased ( https://github.com/dhewm/dhewm3/pull/576 ) #587

Closed j4reporting closed 2 months ago

j4reporting commented 2 months ago

found easy procedure to crash dhewm3 on linux with wayland ( didn´t test with x11)

wayland/gnome desktop resolution 2560x1440@144z (nvidia driver 555.58.02 )

SDL_VIDEODRIVER=x11 // no problem with SDL_VIDEODRIVER=wayland with X11 the resolution used by SDL changes to desktop resolution

r_fullscreenDesktop = "0"
r_fullscreen = "0"

r_mode = "-1" 
r_customHeight = "1080"
r_customWidth = "1920"

works with dhewm 1.5.3

several ways to reproduce

1) in main screen alt/enter to fullscreen alt/enter to window -> crash

2) in main screen alt/enter to fullscreen open imgui select video tab -> crash

3) in main screen open imgui/video change from Windowed to Fullscreen apply -> crash

bt is not very useful, need to get libbacktrace and recompile

----- Initializing Session -----
in_grabKeyboard: Will *not* grab the keyboard if mouse is grabbed, so global keyboard-shortcuts (like Alt-Tab) will still work
----- Game Map Shutdown -----
'vid_restart partial' succeeded in changing resolution and/or fullscreen mode
dhewm3: /home/markus/src/github/doom3/dhewm3-imgui/neo/sys/glimp.cpp:749: glimpParms_t GLimp_GetCurState(): Assertion `ret.width == glConfig.winWidth && ret.height == glConfig.winHeight' failed.

Looks like dhewm3 1.5.4pre crashed with signal SIGABRT (6) - sorry!

dhewm 1.5.3 switches seamlessly to full screen 2560x1440 and back to the configured resolution in windowed mode.


]r_fullscreen 1
]vid_restart 
Shutting down sound hardware
Shutting down OpenGL subsystem
----- Initializing OpenGL -----
Initializing OpenGL subsystem
Will create a fullscreen-window with resolution 1920x1080 (r_mode = -1)
SDL detected 1 displays: 
 0: 2560x1440 at (0, 0) to (2560, 1440)
Will use display 0 because mouse cursor is at (1946, 639).
Requested 8 color bits per chan, 8 alpha 24 depth, 8 stencil
Got 8 stencil bits, 24 depth bits, color bits: r8 g8 b8 a8
OpenGL vendor: NVIDIA Corporation
OpenGL renderer: NVIDIA GeForce RTX 2060/PCIe/SSE2
OpenGL version: 4.6.0 NVIDIA 555.58.02

r_fullscreen 0
]vid_restart 
Shutting down sound hardware
Shutting down OpenGL subsystem
----- Initializing OpenGL -----
Initializing OpenGL subsystem
Will create a window with resolution 1920x1080 (r_mode = -1)
SDL detected 1 displays: 
 0: 2560x1440 at (0, 0) to (2560, 1440)
Will use display 0 because mouse cursor is at (1462, 1048).
Requested 8 color bits per chan, 8 alpha 24 depth, 8 stencil
Got 8 stencil bits, 24 depth bits, color bits: r8 g8 b8 a8
j4reporting commented 2 months ago

the same assertion fails each time

here is the bt
procedure 1:


This system qualifies for Ultra quality!
Shutting down sound hardware
in_grabKeyboard: Will *not* grab the keyboard if mouse is grabbed, so global keyboard-shortcuts (like Alt-Tab) will still work
----- Game Map Shutdown -----
'vid_restart partial' succeeded in changing resolution and/or fullscreen mode
dhewm3: /home/<user>/src/github/doom3/dhewm3/neo/sys/glimp.cpp:728: glimpParms_t GLimp_GetCurState(): Assertion `ret.width == glConfig.winWidth && ret.height == glConfig.winHeight' failed.

Looks like dhewm3 1.5.4pre crashed with signal SIGABRT (6) - sorry!
  140478365763343 (unknown symbol)
  140478366122308 __pthread_kill_implementation
  140478365763165 gsignal
  140478365665537 abort
  140478365665309 __assert_fail_base.cold
  140478365731190 __assert_fail
  6365685 neo/sys/glimp.cpp:728 GLimp_GetCurState()
  6365747 neo/sys/glimp.cpp:612 GLimp_SetScreenParms(glimpParms_t)
  4618797 neo/renderer/RenderSystem_init.cpp:1998 R_VidRestart_f(idCmdArgs const&)
  4948776 neo/framework/CmdSystem.cpp:476 idCmdSystemLocal::ExecuteTokenizedString(idCmdArgs const&)
  4948776 neo/framework/CmdSystem.cpp:679 idCmdSystemLocal::ExecuteCommandBuffer()
  5205252 neo/framework/EventLoop.cpp:184 idEventLoop::RunEventLoop(bool)
  4967703 neo/framework/Common.cpp:2440 idCommonLocal::Frame()
  4295852 neo/sys/linux/main.cpp:452 main
  140478365671559 __libc_start_call_main
  140478365671754 __libc_start_main_alias_2
  4297860 _start
  18446744073709551615 (unknown symbol)
Aborted (core dumped)
DanielGibson commented 2 months ago

Does that also happen in the current master branch? Because imgui-rebased as been merged

j4reporting commented 2 months ago

yes sorry, I used the master branch.

DanielGibson commented 2 months ago

Ok - can you tell me what imgui menu -> video options says about "Current Resolution" and "Display Size", both in windowed mode and fullscreen mode (if needed because using imgui menu crashes on apply, configure that through console and use a full vid_restart)

Oh right, and if that also doesn't work because the assertion triggers just by opening the video menu, comment out the line with the assertion (neo/sys/glimp.cpp:728)

j4reporting commented 2 months ago

seems to work fine w/o the assertion.

windowed mode: current: 1920x1080 display: 2560x1440

fullscreen mode: SDL_VIDEODRIVER=x11 current 2560x1440 (is correct ) display: 1920x1080 <===

fullscreen mode: with SDL_VIDEDRIVER=wayland
current 1920x1080 display 2560x1440 and it's scaled to fullscreen

the same with vkquake or ironwail. with SDL_VIDEODRIVER=x11 fullscreen uses the real resolution 2560x1440 shown in options/video mode and with SDL_VIDEODRIVER=wayland the compositor scales the program to full screen. video mode remains at 1920x1080 and in case of quake the gui gets bigger because of the scaling.

DanielGibson commented 2 months ago

does it say anything about "Physical" (it does when detecting display scaling) in the menu, next to Current Resolution and Display Size?

j4reporting commented 2 months ago

no.

in fullscreen mode the desktop size always equals the configured game resolution. ( x11 driver )

update: probably can´t detect any scaling, because the desktop is not scaled ( 100 % )

Yamagi commented 2 months ago

If I understand the problem right this behavior is kind of expected: Under Wayland the fullscreen handling is compositor dependent. In my experience tho common compositors (kwin, mutter, wlroots) don't support implement switching initiated by clients. When a client requests fullscreen mode, the client is a) put in exclusive fullscreen mode when it's drawable size matches the current resolution of the given display or b) scaled up / down if it's drawable size is lower / higher than the resolution of the given display. Fractional scaling and scaling awareness of the client shouldn't matter in exclusive fullscreen, the common compositors communicate a scaled display mode, but an unscaled drawable size. That might break assumptions made by the client, though.

DanielGibson commented 2 months ago

Does it help if at the end of GLimp_SetScreenParms(), around here: https://github.com/dhewm/dhewm3/blob/master/neo/sys/glimp.cpp#L685, maybe after that glConfig.isFullscreen = (SDL_GetWindowFlags( window ) & SDL_WINDOW_FULLSCREEN) != 0; line, you add GLimp_UpdateWindowSize(); ?

j4reporting commented 2 months ago

no change.

all what was needed was commenting out the assert at line 728

DanielGibson commented 2 months ago

no change.

ok, I'll have to debug this on wayland

all what was needed was commenting out the assert at line 728

that's no solution - if the values in glConfig aren't correct (consistent with the actual sizes), other code will behave wrong (for example mouse cursor speed, possibly even rendering itself)

DanielGibson commented 2 months ago

I pushed a fix for this to master.

Overall that case is still kinda broken (no crash anymore, but mousecursor behaves weird), and that's a bug in SDL or Wayland.

I think the main underlying issue is that Wayland does not support real fullscreen mode. It does not allow applications to switch the resolution (or display refreshrate, by the way).

So all you get is fugly hacks: In the native Wayland case (SDL_VIDEODRIVER=wayland) the Window uses the given resolution (1920x1080 in your case) but the compositor scales it to be a borderless fullscreen window (at 2560x1440 in your case). So the window renders at the lower resolution and all the coordinates are at that resolution and it at least kinda works.

In the XWayland case however it apparently creates a borderless fullscreen window at the desktop resolution (2560x1440 in your case, not the one you requested!). For some reason however, one SDL function (SDL_GetWindowDisplayMode() - which is supposed to return the resolution for the currently used fullscreen mode!) returns the requested resolution (1920x1080), while another (SDL_GetWindowSize() returns the actual resolution (2560x1440).

Due to dhewm3 using the wrong size (at least consistently now..), the mouse input can behave weird in this specific case (XWayland + "real" fullscreen at lower resolution).

Extra unfortunate: think in the past I've seen SDL_GetWindowSize() not returning the correct resolution when in real fullscreen mode (on systems that, unlike Wayland, actually support that), so I don't really want to use SDL_GetWindowSize() for everything..

j4reporting commented 2 months ago

So the mouse cursor could behave strangely in the GUI /PDA ? But mouse movement in game should not be affected?

Have to reboot to fedora again to test. The scaling with native Wayland and use of real desktop resolution with Xwayland is consistent with other apps I tried so far. And so far I wasn't able to find any regression besides the crash in dhewm.

DanielGibson commented 2 months ago

So the mouse cursor could behave strangely in the GUI /PDA ? But mouse movement in game should not be affected?

Yeah, I think so. I specifically noticed that the cursor position in ImGui isn't consistent with the one in the main menu anymore.

I recommend using only "fullscreen desktop" mode with Wayland, because real fullscreen isn't supported anyway. Though if you want to run the game at a lower resolution for performance reasons (but scaled over the whole screen), "real" fullscreen with native Wayland probably works well enough.

j4reporting commented 2 months ago

My motivation for this was the advantage of having a configured lower resolution for windowed mode and a full desktop resolution at one click or keyboard shortcut like alt/enter. Otherwise aliases are needed. like this in case of quake:

alias to_fullscreen "vid_width 2560; vid_height 1440; vid_fullscreen 2; vid_restart; bind f10 to_windowed"
alias to_windowed "vid_width 1920; vid_height 1080; vid_fullscreen 0; vid_restart; bind f10 to_fullscreen"
bind f10 to_fullscreen

is something like this available in doom3?

j4reporting commented 2 months ago

Wouldn't SDL_GL_GetDrawableSize() be a more suitable call? It should report the real dimensions of the drawable.

The window size in screen coordinates may differ from the size in pixels, if the window was created with SDL_WINDOW_ALLOW_HIGHDPI on a platform with high-dpi support (e.g. iOS or macOS). Use SDL_GL_GetDrawableSize(), SDL_Vulkan_GetDrawableSize(), or SDL_GetRendererOutputSize() to get the real client area size in pixels.

DanielGibson commented 2 months ago

Wouldn't SDL_GL_GetDrawableSize() be a more suitable call? It should report the real dimensions of the drawable.

No, because the mouse coordinates don't use the drawable size but the window size (when they're different, like in HighDPI/desktop scaling mode).

is something like this available in doom3?

You can also use aliases and all that, but the easiest way is to enable fullscreen desktop (r_fullscreenDesktop) mode. Then the configured resolution will only be used (and remembered) for windowed mode, and when pressing Alt-Enter (or generally enabling r_fullscreen) dhewm3 will switch to a borderless fullscreen window at the current display resolution. It looks just like normal fullscreen.

j4reporting commented 2 months ago

ok, there are other more serious issues if Xwayland is involved. This happens after a switch r_fullscreen 0 -> 1 or 1 -> 0 regardless of r_fullscreendesktop 0 or 1

all viewports (?) for windows have a wrong angle, show the wrong parts of the room. Screenshots are also incomplete and sometimes have other garbage.
Only a vid_restart fixes this until the next windowed <-> fullscreen switch. !! UPDATE: changing the game resolution will trigger this. /UPDATE !

is there an option to disable the vid_restart partial codepath?

shot01

shot02

shot03

DanielGibson commented 2 months ago

uhh.. wtf.. didn't have that issue

is this on master or kickstart-my-hertz?

j4reporting commented 2 months ago

both!

those are screenshots created with the engine. only windows and the ship engines look strange.

DanielGibson commented 2 months ago

Does it only look broken in screenshots or also on the actual screen?

So far I really can't reproduce this, even with Wayland + Gnome

j4reporting commented 2 months ago

everythinig looks fine in game but the windows and the engine exhausts of the ship's engines. Glas doors (infirmary are also fine). The projection for the fixed windows, what the player should see, is totally off. Like in the 2nd screenshot. and the 3rd screenshot shows the window in the same room (the first room with the scanners ) ignore the upper offset ( that's the screenshot issue ) Is a shader involved to render the window? this only happens after update of window dimensions. If I revert to the original resolution everything looks fine again. Or vid_restart.

what distribution? This is on upto date fedora 40 with the new NFB nvidia branch 555.58.02

DanielGibson commented 2 months ago

I tested with latest Arch Linux (live image with Gnome from http://dl.gnutux.fr/archuseriso/img/, but updated that while running and additionally installed gnome-control-center) on a laptop with AMD iGPU (Ryzen 5 7640U).

I just had a maybe similar issue: When changing the resolution (or toggling fullscreen) after taking a screenshot, the window remained black or invisible. I just pushed a potential fix for that to the kickstart-my-hertz branch, can you test if it also resolves your bug? :)

j4reporting commented 2 months ago

ignore screenshots for a moment (it did not help btw.)

here is a short video . you see everything is fine until I resize the window. now the projections on the windows in the infirmary are wrong. Wrong parts of the map are shown to me. It seems maybe something is still calculating with the previous resolution. I then restore the original resolution and everything is back to normal. Screenshots are affected by the same thing, only after the "vid_restart partly " things go south.

Xwayland 24.1 libsdl2 3.30.3 mutter 46.3 updated today from 46.2

DanielGibson commented 2 months ago

I don't really see much in the video (at least no details in the reflections), maybe due to the low resolution. Does it still happen both with SDL_VIDEODRIVER=wayland and the default (XWayland)?

I tested with the space ship at the beginning of the game and didn't see any graphical bugs there. I'll test again with the Infirmary

Could also be a graphics driver bug, of course

j4reporting commented 2 months ago

download the video
it happens only with SDL_VIDEODRIVER=x11 (Xwayland) Native wayland is ok.

j4reporting commented 2 months ago

the 2nd screenshot above shows is very good. look at the window area. You should see the operator who initiates the scan. But we see the ceiling or parts of it instead

driver bug: of course, have avoided the short lived NFB branch most of the time.

DanielGibson commented 2 months ago

Ok, with the downloaded video I can see that it looks wrong.

Can't reproduce it though.

Here it's the same XWayland and mutter versions, but SDL 2.30.4 (and of course no nvidia driver but the open source AMD driver)

DanielGibson commented 2 months ago

Can't reproduce it with real X11 and nvidia driver 535.183 either.

However, I just added a CVar r_vidRestartAlwaysFull that forces all vid_restarts to be full. You should also set r_windowResizable 0, because when resizing a window by dragging or maximizing it, vid_restart isn't called at all.

j4reporting commented 2 months ago

You should also set r_windowResizable 0, because when resizing a window by dragging or maximizing it, vid_restart isn't called at all.

enabled window resizing only for the ideo :)

quck update:

This looks indeed like a driver issue. Reverted nvidia driver to the latest stable 550.90.07 and it looks similar, but for short moments the windows are rendered correctly and then it may be fail back again. But this driver has other issues with the new 144hz branch. So I will go back to the NFB version which support explicit sync wayland protocol.

The NFB driver showed better results with the 144Hz branch. It's only this window rendering after changing the dimentions of the game window. This will be fixed eventually by nvidia.

This issue is tiggered by resizing the game window / changing game resolution w/o a hard vid_restart on wayland with Xwayland server. Native wayland is fine!

DanielGibson commented 2 months ago

So do you think we can consider this bug resolved (from dhewm3's point of view, I can't do anything about nvidias driver) by setting r_vidRestartAlwaysFull 1?

j4reporting commented 2 months ago

Yes, I think so.

DanielGibson commented 2 months ago

Great!