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

[Engine] Calling game.Exit() in a game running in Fullscreen mode causes an unhandled exception error on exit. #2008

Open
SoulRider opened this issue Oct 30, 2023 · 15 comments
Labels
bug Something isn't working

Comments

@SoulRider
Copy link

Release Type: Official Release

Version: 4.1.0.1948

Platform(s): Windows

Describe the bug
Calling game.Exit() in a game running in Fullscreen mode causes an unhandled exception error on exit. It appears the render device is resetting back to it's default windowed resolution on exit of fullscreen, and is trying to reload assets which have been unloaded by the game as it exited.

To Reproduce
Steps to reproduce the behavior:

  1. Set game.Window.PreferredFullscreenSize to a size different to windowed resolution. I use:

         GraphicsOutput[] array = game.GraphicsDevice.Adapter.Outputs;
         game.Window.PreferredFullscreenSize = new Int2(array[0].CurrentDisplayMode.Height, array[0].CurrentDisplayMode.Width);
    
  2. Set game.Window.IsFullscreen = true;

  3. Call game.Exit()

Expected behavior
Game to exit silently and successfully.

Screenshots
SameErrorOtherGame

Log and callstacks
N/A

Additional context
I have a simple project available which shows this issue here - SimpleFullscreenCrashTest.zip.

I have confirmed the issue using both normal fullscreen and 'FullscreenIsBorderlessWindow'. Issue occurs whether you run from editor, Visual Studio or from a build file directly.

I upgraded a game from 4.0 which did not have this issue to the version 4.1.0.1948, and am now experiencing this in that game. I also have a game that has only had this issue since upgrading to 4.1.0.1948 from the previous patch suggesting this is a new issue in 4.1.0.1948

@SoulRider SoulRider added the bug Something isn't working label Oct 30, 2023
@SoulRider
Copy link
Author

In trying to write a workaround for this bug, I narrowed the bug down and can confirm it happens whenever you exit fullscreen mode, you do not have to be exiting the game. Exiting the game is disabling fullscreen as well. Exactly what in the disabling fullscreen process is causing the issue I haven't yet figured out.

@SoulRider
Copy link
Author

I have been investigating running the game in different contexts to see if it makes a difference. Desktop and WPF both work but still have the same fullscreen crash bug, however SDL context doesn't work at all. I get an error on launch. Attached is the error screenshot.

SDLContext error

The inner text reads: TypeLoadException: Method 'get_Windows64' in type 'Silk.NET.SDL.SDLLibraryNameContainer' from assembly 'Silk.NET.SDL, Version=2.15.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.

@SoulRider
Copy link
Author

I've downloaded the source and built the version 4.1 master and it has the same issue with Fullscreen and SDL context. My app is DX11 win64 only. Not sure if this makes any difference.

@SoulRider
Copy link
Author

SoulRider commented Nov 20, 2023

If I run a new project from self-built master-4.1 version of Stride with no code, all contexts work as expected. When I add code to set the game to fullscreen, Desktop, WPF etc context works, but SDL context displays a blank transparent window where I can see my desktop, there are no errors.

If I further add code to after 10 seconds exit fullscreen I then induce the DX11 SwapChainGraphicsPresenter error in all contexts except SDL. SDL reverts back to windowed without any error and is now displaying correctly.

So I amended the test code to flip between fullscreen and windowed every 10 seconds. As expected the other contexts all failed on the first switch to windowed mode, invoking the DX11 SwapChainGraphicsPresenter error. For the SDL context, it does the 'no display fullscreen', then switches to windowed and is visible. On the next switch back to fullscreen SDL context falls over with a DX11 SwapChainGraphicsPresenter error. This is the error generated:

SDL Fullscreen switch error

The test projects settings are Direct3D11, Windowsx64 only, tested with target versons from Windows 7 to Windows 10.0.20348 and all produce the same result.

Attached is a video showing the SDL behaviour.

2023-11-20_20-48-07.mp4

@Eideren
Copy link
Collaborator

Eideren commented Nov 20, 2023

It throws in the resize there:

GraphicsDevice.Presenter.Resize(newWidth, newHeight, newFormat);
// Change full screen if needed
GraphicsDevice.Presenter.IsFullScreen = graphicsDeviceInformation.PresentationParameters.IsFullScreen;
needToCreateNewDevice = false;
}
catch
{
// ignored
}
}
}
// If we still need to create a device, then we need to create it

Forcing a CreateDevice as the logic never sets needToCreateNewDevice back to false because of the exception.

Here's the exception that's ignored.

SharpDX.SharpDXException: HRESULT: [0x80070005], Module: [General], ApiCode: [E_ACCESSDENIED/General access denied error], Message: Access is denied.

   at SharpDX.Result.CheckError() in C:\projects\sharpdx\Source\SharpDX\Result.cs:line 195
   at SharpDX.DXGI.SwapChain.ResizeBuffers(Int32 bufferCount, Int32 width, Int32 height, Format newFormat, SwapChainFlags swapChainFlags) in C:\projects\sharpdx\Source\SharpDX.DXGI\Generated\REFERENCE\Interfaces.cs:line 4670
   at Stride.Graphics.SwapChainGraphicsPresenter.ResizeBackBuffer(Int32 width, Int32 height, PixelFormat format)
   at Stride.Graphics.GraphicsPresenter.Resize(Int32 width, Int32 height, PixelFormat format)
   at Stride.Games.GraphicsDeviceManager.ChangeOrCreateDevice(Boolean forceCreate)

So two issues in one, the one about serialization should be fixed as that serves as a failsafe to restore the game when driver crashes.

@SoulRider
Copy link
Author

It throws in the resize there:

GraphicsDevice.Presenter.Resize(newWidth, newHeight, newFormat);
// Change full screen if needed
GraphicsDevice.Presenter.IsFullScreen = graphicsDeviceInformation.PresentationParameters.IsFullScreen;
needToCreateNewDevice = false;
}
catch
{
// ignored
}
}
}
// If we still need to create a device, then we need to create it

Forcing a CreateDevice as the logic never sets needToCreateNewDevice back to false because of the exception.
So two issues in one, the one about serialization should be fixed as that serves as a failsafe to restore the game when driver >crashes.

I am just checking I have the issue straight in my head :)

We have two issues. The first issue is the exception which causes the rest of the function, including setting the bool to false, to not run. This forces a CreateDevice.

The second issue is that CreateDevice should succesfully create a new device, and not itself throw an error about the content serializer not being able to load textures.

I understand the priority of fixing the CreateDevice issue, but if we do not also deal with the other issue, wouldn't we be in a situation where whenever there is a change from fullscreen a new graphics device will be created? I understand a fullscreen swap isn't generally something that occurs very often, but recreating a device would be quite expensive on resources each time wouldn't it?

@Eideren
Copy link
Collaborator

Eideren commented Nov 21, 2023

Yes, both of them should be fixed, with the swallowed exception being higher priority.

@SoulRider
Copy link
Author

Any news on this? My 2nd game was supposed to release in December but still isn't released because of this issue, and my originally released game on Steam is currently broken because of this issue. Any chance of this getting fixed? Switching my games to DX12 just causes a whole heap of other errors & problems so I want to know if this will be fixed or if my games are now consigned to the rubbish bin because of this bug?

Utlimately it's just a progression of a bug I first posted about in 2020 - #932
but I just want to know is this going to be fixed?

@Eideren
Copy link
Collaborator

Eideren commented May 12, 2024

I believe you know that this engine is community driven, people contributing to it are doing so on their free time. I don't have time to look into this further, and it doesn't look like anyone else is interested in tackling it, so your best bet is to fix it yourself or actively find someone who would do it for you

@MeharDT
Copy link
Contributor

MeharDT commented May 15, 2024

I can replicate both the fullscreen SDL and game.Exit() crashes in the attached sample and a new project (Alt + Enter to fullscreen and Alt + F4 to close are enough to replicate the latter crash).

This is a pretty critical issue as it means fullscreen support is effectively broken in Stride 4.2 on Windows (possibly other platforms as well). We should consider a bounty.

@Doprez
Copy link
Contributor

Doprez commented May 17, 2024

Just some added info the error seems to be Directx at least from what I have tested. I dont kow if opengl/vulkan works as expected. And it happens both when exiting the game from fullscreen and changing from fullscreen to windowed but with different errors.

Crash message when exiting from fullscreen:
image

SharpDX.SharpDXException: 'HRESULT: [0x80070005], Module: [General], ApiCode: [E_ACCESSDENIED/General access denied error], Message: Access is denied.

Crash message when going back to windowed:
image

SharpDX.SharpDXException: 'HRESULT: [0x887A0022], Module: [SharpDX.DXGI], ApiCode: [DXGI_ERROR_NOT_CURRENTLY_AVAILABLE/NotCurrentlyAvailable], Message: A resource is not available at the time of the call, but may become available later.

@Ethereal77
Copy link
Contributor

In the next few days, if life and work allows, I plan to update my Silk DX branch. There we can test if it is DX related, or SharpDX-specific, because while converting from SharpDX I've found several places where we were using the API wrong.
In fact, one of the reasons I've not yet finished that PR is because although the conversion is almost finished and compiles, the DX debug runtime logs hundreds of warnings of resources not released correctly, buffers not transitioned correctly, etc.

@Doprez
Copy link
Contributor

Doprez commented May 18, 2024

a temporary work around is the below code it seems.

if (Game.Window.IsFullscreen)
{
	Game.Window.Visible = false;
	Game.Window.IsFullscreen = false;
	Game.Window.Visible = true;
}
(Game as Game).Exit();

i also have a couple PRs that should solve the Texture issue and one to check for if the game is exiting from fullscreen to avoid trying to reload. Part of the problem seems to come from the fullscreen state change which is being called on destroy due to what was a previous work around.

image

@SoulRider
Copy link
Author

SoulRider commented May 19, 2024

a temporary work around is the below code it seems.

if (Game.Window.IsFullscreen)
{
	Game.Window.Visible = false;
	Game.Window.IsFullscreen = false;
	Game.Window.Visible = true;
}
(Game as Game).Exit();

I have tested and confirmed the workaround works. You are an absolute life saver, thank you!! ❤️
Now to get my head back into game development to fix the original and release my 2nd game. I am so happy. 😸

Although I should point out the SDL context still doesn't work at all with fullscreen. This just fixes the issue for all other contexts.

@Doprez
Copy link
Contributor

Doprez commented Aug 10, 2024

One more thing to add for SDL. you can create windowed fullscreen by using the below code:

// within an inherited Game class in the BeginRun overridden method

var desktopBounds = GraphicsDevice.Adapter.Outputs[0].DesktopBounds;
Window.SetSize(new Int2(desktopBounds.Right, desktopBounds.Bottom));
Window.Position = new Int2(0, 0);

This puts the banner of the window above the screen and looks correct to the user at least. There is some funkiness still but this could be a temporary work around for at least a fullscreen affect. Proper fullscreen still has benefits of course but the SDL code in Stride needs a lot of love as its pretty unstable right now compared to the WinForms implementation.

I am also looking into some possible scaling issues but I cant confirm if its an issue with SDL or ImGui right now. Unrelated to this specific issue but I thought I would mention it somewhere in case someone else has more info. it was not SDL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants