mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-05-12 16:25:46 +00:00
Check if the Device is rendering before waiting on it (#86)
Fixes an issue where there were missed references and an ``OperationCancelled`` exception when exiting an application. Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/86
This commit is contained in:
@@ -176,9 +176,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This can somehow become -1.
|
||||
// Logger.Info?.PrintMsg(LogClass.Gpu, $"_referenceCount: {_referenceCount}");
|
||||
|
||||
Debug.Assert(_referenceCount >= 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -622,15 +622,15 @@ namespace Ryujinx.Ava.Systems
|
||||
// If the GPU has no work and is cancelled, we need to handle that as well.
|
||||
|
||||
WaitHandle.WaitAny(new[] { _gpuDoneEvent, _gpuCancellationTokenSource.Token.WaitHandle });
|
||||
_gpuCancellationTokenSource.Dispose();
|
||||
|
||||
// Waiting for work to be finished before we dispose.
|
||||
|
||||
if (_renderingStarted)
|
||||
{
|
||||
// Waiting for work to be finished before we dispose.
|
||||
Device.Gpu.WaitUntilGpuReady();
|
||||
}
|
||||
|
||||
_gpuDoneEvent.Dispose();
|
||||
_gpuCancellationTokenSource.Dispose();
|
||||
|
||||
DisposeGpu();
|
||||
AppExit?.Invoke(this, EventArgs.Empty);
|
||||
@@ -1095,51 +1095,56 @@ namespace Ryujinx.Ava.Systems
|
||||
|
||||
Device.Gpu.Renderer.RunLoop(() =>
|
||||
{
|
||||
Device.Gpu.SetGpuThread();
|
||||
Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token);
|
||||
|
||||
_renderer.Window.ChangeVSyncMode(Device.VSyncMode);
|
||||
|
||||
while (_isActive)
|
||||
try
|
||||
{
|
||||
_ticks += _chrono.ElapsedTicks;
|
||||
Device.Gpu.SetGpuThread();
|
||||
Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token);
|
||||
|
||||
_chrono.Restart();
|
||||
_renderer.Window.ChangeVSyncMode(Device.VSyncMode);
|
||||
|
||||
if (Device.WaitFifo())
|
||||
while (_isActive)
|
||||
{
|
||||
Device.Statistics.RecordFifoStart();
|
||||
Device.ProcessFrame();
|
||||
Device.Statistics.RecordFifoEnd();
|
||||
}
|
||||
_ticks += _chrono.ElapsedTicks;
|
||||
|
||||
while (Device.ConsumeFrameAvailable())
|
||||
{
|
||||
if (!_renderingStarted)
|
||||
_chrono.Restart();
|
||||
|
||||
if (Device.WaitFifo())
|
||||
{
|
||||
_renderingStarted = true;
|
||||
_viewModel.SwitchToRenderer(false);
|
||||
InitStatus();
|
||||
Device.Statistics.RecordFifoStart();
|
||||
Device.ProcessFrame();
|
||||
Device.Statistics.RecordFifoEnd();
|
||||
}
|
||||
|
||||
Device.PresentFrame(() => (RendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.SwapBuffers());
|
||||
}
|
||||
while (Device.ConsumeFrameAvailable())
|
||||
{
|
||||
if (!_renderingStarted)
|
||||
{
|
||||
_renderingStarted = true;
|
||||
_viewModel.SwitchToRenderer(false);
|
||||
InitStatus();
|
||||
}
|
||||
|
||||
if (_ticks >= _ticksPerFrame)
|
||||
{
|
||||
UpdateStatus();
|
||||
Device.PresentFrame(() =>
|
||||
(RendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.SwapBuffers());
|
||||
}
|
||||
|
||||
if (_ticks >= _ticksPerFrame)
|
||||
{
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure all commands in the run loop are fully executed before leaving the loop.
|
||||
if (Device.Gpu.Renderer is ThreadedRenderer threaded)
|
||||
finally
|
||||
{
|
||||
Logger.Info?.PrintMsg(LogClass.Gpu, "Flushing threaded commands...");
|
||||
threaded.FlushThreadedCommands();
|
||||
Logger.Info?.PrintMsg(LogClass.Gpu, "Flushed!");
|
||||
// Make sure all commands in the run loop are fully executed before leaving the loop.
|
||||
if (Device.Gpu.Renderer is ThreadedRenderer threaded)
|
||||
{
|
||||
Logger.Info?.PrintMsg(LogClass.Gpu, "Flushing threaded commands...");
|
||||
threaded.FlushThreadedCommands();
|
||||
Logger.Info?.PrintMsg(LogClass.Gpu, "Flushed!");
|
||||
}
|
||||
_gpuDoneEvent.Set();
|
||||
}
|
||||
|
||||
_gpuDoneEvent.Set();
|
||||
});
|
||||
|
||||
(RendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(true);
|
||||
|
||||
Reference in New Issue
Block a user