Check if the Device is rendering before waiting on it

Fixes an issue where there were missed references and an ``OperationCancelled`` exception when exiting an application.
This commit is contained in:
Max
2026-05-16 23:11:55 -05:00
committed by KeatonTheBot
parent 9a4bf8f94d
commit 94cfe6930c
2 changed files with 40 additions and 38 deletions
-2
View File
@@ -177,8 +177,6 @@ namespace Ryujinx.Graphics.Vulkan
} }
} }
// This can somehow become -1.
// Logger.Info?.PrintMsg(LogClass.Gpu, $"_referenceCount: {_referenceCount}");
Debug.Assert(_referenceCount >= 0); Debug.Assert(_referenceCount >= 0);
} }
+10 -6
View File
@@ -591,15 +591,14 @@ namespace Ryujinx.Ava
// If the GPU has no work and is cancelled, we need to handle that as well. // If the GPU has no work and is cancelled, we need to handle that as well.
WaitHandle.WaitAny(new[] { _gpuDoneEvent, _gpuCancellationTokenSource.Token.WaitHandle }); WaitHandle.WaitAny(new[] { _gpuDoneEvent, _gpuCancellationTokenSource.Token.WaitHandle });
_gpuCancellationTokenSource.Dispose();
// Waiting for work to be finished before we dispose.
if (_renderingStarted) if (_renderingStarted)
{ {
// Waiting for work to be finished before we dispose.
Device.Gpu.WaitUntilGpuReady(); Device.Gpu.WaitUntilGpuReady();
} }
_gpuDoneEvent.Dispose(); _gpuDoneEvent.Dispose();
_gpuCancellationTokenSource.Dispose();
DisposeGpu(); DisposeGpu();
AppExit?.Invoke(this, EventArgs.Empty); AppExit?.Invoke(this, EventArgs.Empty);
@@ -1084,6 +1083,8 @@ namespace Ryujinx.Ava
_chrono.Start(); _chrono.Start();
Device.Gpu.Renderer.RunLoop(() => Device.Gpu.Renderer.RunLoop(() =>
{
try
{ {
Device.Gpu.SetGpuThread(); Device.Gpu.SetGpuThread();
Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token); Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token);
@@ -1112,7 +1113,8 @@ namespace Ryujinx.Ava
InitStatus(); InitStatus();
} }
Device.PresentFrame(() => (RendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.SwapBuffers()); Device.PresentFrame(() =>
(RendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.SwapBuffers());
} }
if (_ticks >= _ticksPerFrame) if (_ticks >= _ticksPerFrame)
@@ -1120,7 +1122,9 @@ namespace Ryujinx.Ava
UpdateStatus(); UpdateStatus();
} }
} }
}
finally
{
// Make sure all commands in the run loop are fully executed before leaving the loop. // Make sure all commands in the run loop are fully executed before leaving the loop.
if (Device.Gpu.Renderer is ThreadedRenderer threaded) if (Device.Gpu.Renderer is ThreadedRenderer threaded)
{ {
@@ -1128,8 +1132,8 @@ namespace Ryujinx.Ava
threaded.FlushThreadedCommands(); threaded.FlushThreadedCommands();
Logger.Info?.PrintMsg(LogClass.Gpu, "Flushed!"); Logger.Info?.PrintMsg(LogClass.Gpu, "Flushed!");
} }
_gpuDoneEvent.Set(); _gpuDoneEvent.Set();
}
}); });
(RendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(true); (RendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(true);