Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Runtime crash: Crash when raising resolution above desktop resolution. #671

Closed
BryanFRitt opened this issue Oct 18, 2022 · 9 comments
Closed
Assignees
Labels

Comments

@BryanFRitt
Copy link

BryanFRitt commented Oct 18, 2022

Linux
Debian Stable, Debian GNU/Linux 11 (bullseye)
KDE desktop with Compiz

d2x-rebirth crashes if resolution is raised higher than the desktop resolution, even if the display, etc.. is capable of handling it.
e.g. if on a 3840x2160 display, d2x-rebirth is set to 3200x1800, and the desktop is also at that 3200x1800 resolution when d2x-rebirth starts, and then d2x-rebirth is later set to 3840x2160, d2x-rebirth will crash.

Crash Error Message:

X Error of failed request: BadValue (integer parameter out of range for operation)
Major opcode of failed request: 153 (XFree86-VidModeExtension)
Minor opcode of failed request: 10 (XF86VidModeSwitchToMode)
Value in failed request: 0x7bc
Serial number of failed request: 209
Current serial number in output stream: 211
DXX-Rebirth: OpenGL: fence sync object was never destroyed!

(didn't test with d1x-rebirth)

@BryanFRitt BryanFRitt added the bug label Oct 18, 2022
@BryanFRitt BryanFRitt changed the title Runtime bug: Crash when raising resolution above desktop resolution. Runtime crash: Crash when raising resolution above desktop resolution. Oct 18, 2022
@vLKp
Copy link
Contributor

vLKp commented Oct 19, 2022

I cannot reproduce this here. While set to run in windowed mode, I successfully set my game to a window dimension that is much larger than my available screen space, and it resized itself as requested. Even getting that far required that I choose Custom Resolution, because Rebirth only offers me resolutions that the display can actually handle. This list is acquired from SDL, which acquires it from the system. In testing, SDL only offered resolutions the display could handle, but did offer resolutions larger than the current display. Choosing those also had no negative effect.

I also tried instructing the game to use non-windowed mode. It properly failed to pick the oversized resolution, and dropped back to a safe 640x480.

Note that an X error of BadValue is an X library issue, not a Rebirth issue. Rebirth might be able to detect that you have requested something impossible and prevent it, but the value of Custom Resolution is to let you override the game's detection of supported modes. Adding a limiter to prevent you choosing something the game believes is unsupported would impair that purpose.

@BryanFRitt
Copy link
Author

For these dxx-rebirth resolution changes I was doing them in full screen mode.

set desktop dxx-rebirth's and desktop resolution to a lower resolution than the display/system is capable of, exit and restart dxx-rebirth, then in full screen mode, change the dxx-rebirth resolution to a higher resolution than these that the system/display is capable of.

Rebirth might be able to detect that you have requested something impossible and prevent it,

I'm not changing the full screen resolution to anything the system/display can't handle. I've had and can do desktops and 3d games at these resolutions before on this setup without any issues. Would the bug be it thinking the the maximum full screen a game could go should be limited to whatever the desktop is set to, even if the system/display could handle more?

Note that an X error of BadValue is an X library issue, not a Rebirth issue.

Ok, If so, where should the issue be forwarded to? url?

@vLKp
Copy link
Contributor

vLKp commented Oct 20, 2022

Confirmed.

  • Use xrandr to set a low resolution.
  • Start the game in that resolution.
  • Tell the game to switch to a resolution that the monitor can handle, but which is higher than the current resolution.
  • Xlib raises BadValue and kills the program. No backtrace is available, because the program did not crash. Xlib deliberately killed it.

More debugging will be required. Given SDL's automatic and forced grab when in full screen mode, this will be somewhat tedious, so it may need to wait a few days. That grab is one of the reasons that I prefer and recommend people use a full desktop dimension window, rather than run in full screen mode. In SDL1, full screen always grabs. A desktop-sized window can choose whether to grab, and can automatically drop the grab when a menu is open.

@vLKp
Copy link
Contributor

vLKp commented Oct 22, 2022

I am now satisfied that this is not a bug in Rebirth. To demonstrate:

  1. Compile the below program with g++ -O2 sdl.cpp -lSDL -o sdl-modeset
  2. Set your screen resolution to 1920x1080.
  3. Run the program. Observe successful output:
Checking video mode ...
SDL_VideoModeOK=32
Changing video mode ...
SDL_SetVideoMode returned 0x5555555a6cb0
  1. Set your screen resolution to 800x600.
  2. Run the program again.
  3. Desired results: your screen changes to 1024x768 again. Observed results on my system: program terminates with an error:
Checking video mode ...
SDL_VideoModeOK=32
Changing video mode ...
X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  152 (XFree86-VidModeExtension)
  Minor opcode of failed request:  10 (XF86VidModeSwitchToMode)
  Value in failed request:  0x6bc
  Serial number of failed request:  128
  Current serial number in output stream:  130

In my opinion, if SDL were behaving properly, it would return a failure status from SDL_SetVideoMode, which could then be observed and handled. Instead, it invokes Xlib in a way that leads to the program's termination. None of the comments I see in SDL_video.h lead me to believe that SDL_SetVideoMode can terminate the program like this. If you have a reference that states that the program is obligated to perform specific checks before hand, please link to it and I will investigate whether it will enable Rebirth to survive this configuration. I explored whether SDL_VideoModeOK could serve this purpose, but since it returns the same value in both the good and bad cases, it does not appear to be useful here.

Demo program source:

#include <SDL/SDL.h>
#include <SDL/SDL_video.h>
#include <stdio.h>

int main(int argc, char **argv)
{
	const int width = 1024;
	const int height = 768;
	const int bpp = 32;
	const Uint32 flags = SDL_OPENGL | SDL_FULLSCREEN;
	SDL_Init(SDL_INIT_VIDEO);
	printf("Checking video mode ...\n");
	fflush(stdout);
	int ok = SDL_VideoModeOK(width, height, bpp, flags);
	printf("SDL_VideoModeOK=%i\nChanging video mode ...\n", ok);
	fflush(stdout);
	SDL_Surface *s = SDL_SetVideoMode(width, height, bpp, flags);
	printf("SDL_SetVideoMode returned %p\n", s);
	return 0;
}

I also experimented (not shown) with changing the resolution without setting fullscreen, then adding fullscreen later. The first call, which changed the resolution without going to full screen mode, succeeded. The second call, which added the full screen flag, still caused Xlib to terminate the program.


I should also note that SDL2 does not offer SDL_SetVideoMode, and therefore cannot exhibit this failure mode. Window management is done differently in SDL2.

@BryanFRitt
Copy link
Author

Tried something like this with Supper Tux Kart, instead of crashing, it simply changed the game to the desktop resolution; It didn't even have an error message saying that it changed to a resolution other than what it was set to go to.

@vLKp
Copy link
Contributor

vLKp commented Nov 2, 2022

It appears that Super Tux Kart always uses SDL2. I noted above that SDL2 does not even provide the function which causes the hard exit in this scenario. Rebirth optionally can use SDL2, if requested at build time. Does the demo program I posted in #671 (comment) work for you, or abort like Rebirth does?

@BryanFRitt
Copy link
Author

BryanFRitt commented Nov 2, 2022

Does the demo program I posted in #671 (comment) work for you, or abort like Rebirth does?

saved the code from #671 (comment) as sdl.cpp, then ran g++ -O2 sdl.cpp -lSDL -o sdl-modeset and then ./sdl-modeset for each code run.

Desktop 3840x2160, The first run it changed the resolution, I set the resolution back, but after that, each run just blinked the display and showed a blank window very briefly, and outputted text. Then tried setting desktop to 800x600, then each run all it did was blink the display briefly and outputted text.

Checking video mode ...
SDL_VideoModeOK=32
Changing video mode ...
SDL_SetVideoMode returned 0x560f8ac1f2b0

The SDL_SetVideoMod returned always started with a 0x5 and always ended with 2b0, the stuff in-between varied each run.

UPDATE: I set resolution to 800x600, rebooted, and ran script, ./sdl-modeset , and got

Checking video mode ...
SDL_VideoModeOK=32
Changing video mode ...
X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  153 (XFree86-VidModeExtension)
  Minor opcode of failed request:  10 (XF86VidModeSwitchToMode)
  Value in failed request:  0x7bc
  Serial number of failed request:  131
  Current serial number in output stream:  133

Still at 800x600.

Set it back to 3840x2160, rebooted, and tried again.
Same thing as before. The first time it changed the resolution. I set the resolution back *1, and from then on it just briefly blinked the display and briefly showed and a blank window, as well as outputted that text with SDL_SetVideoMode. Setting to 800x600 *2 and running again, displayed that same SDL_SetVideoMode message and not the X Error of failed request message it showed after a reboot to 800x600 resolution.

*1 xrandr --output eDP-1 --mode "3840x2160"
*2 xrandr --output eDP-1 --mode "800x600"
Well technically, I set up alias for each of these, and ran the corresponding alias, like
alias 800x600='xrandr --output eDP-1 --mode "800x600"'

@parkerlreed
Copy link

parkerlreed commented Nov 2, 2022

SDL2 is the way forwards anyways. Are there still things keeping DXX from being full time SDL2?

I stopped using SDL1 for the exact reason of poor monitor handling and the fact that it COULD change video modes. Have a portrait monitor rotated to landscape? Say goodbye to your layout on SDL1.

SDL2 will leave your native desktop resolution and render at whatever you request internally preserving alt tab, monitors blanking out, and your sanity.

Upstream SDL2 even provides a backwards compat 1.2 library that shims over to SDL2 for all of these same reasons.

@vLKp
Copy link
Contributor

vLKp commented Dec 3, 2022

#474 reported several problems with SDL2. All but the sound problem were fixed quite a while ago. @raptor contributed #651 to try to fix the sound problem. However, according to #474 (comment), there are problems with it. I have not yet had time to fix those.

As I understand #671 (comment), that confirms my prior posts: SDL1 provokes an Xlib problem in these circumstances, even when Rebirth is not used. Since Rebirth is only telling SDL1 to set the video mode, and is relying on SDL1 to do that or report an error (but not terminate the program), I do not see that there is anything I can do here. As I invited above, if you have a reference for how I can detect that the requested mode will be fatal, I could look at handling it. Otherwise, this will need to be treated as an SDL1 bug.

@vLKp vLKp closed this as completed Dec 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants