mirror of
https://git.zaroz.cloud/nintendo-back-up/Ryujinx.git
synced 2025-12-16 15:32:41 +00:00
Compare commits
1 Commits
1.1.848
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2aed882d6 |
@@ -32,7 +32,7 @@
|
|||||||
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.7.7" />
|
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.7.7" />
|
||||||
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" />
|
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.3" />
|
||||||
<PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" />
|
<PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" />
|
||||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.26.3-build25" />
|
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.26.3-build25" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
|
|||||||
@@ -92,8 +92,6 @@ namespace Ryujinx.Ava
|
|||||||
private bool _isActive;
|
private bool _isActive;
|
||||||
private bool _renderingStarted;
|
private bool _renderingStarted;
|
||||||
|
|
||||||
private ManualResetEvent _gpuDoneEvent;
|
|
||||||
|
|
||||||
private IRenderer _renderer;
|
private IRenderer _renderer;
|
||||||
private readonly Thread _renderingThread;
|
private readonly Thread _renderingThread;
|
||||||
private readonly CancellationTokenSource _gpuCancellationTokenSource;
|
private readonly CancellationTokenSource _gpuCancellationTokenSource;
|
||||||
@@ -185,7 +183,6 @@ namespace Ryujinx.Ava
|
|||||||
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Event += UpdateLanInterfaceIdState;
|
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Event += UpdateLanInterfaceIdState;
|
||||||
|
|
||||||
_gpuCancellationTokenSource = new CancellationTokenSource();
|
_gpuCancellationTokenSource = new CancellationTokenSource();
|
||||||
_gpuDoneEvent = new ManualResetEvent(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TopLevel_PointerEnterOrMoved(object sender, PointerEventArgs e)
|
private void TopLevel_PointerEnterOrMoved(object sender, PointerEventArgs e)
|
||||||
@@ -426,10 +423,10 @@ namespace Ryujinx.Ava
|
|||||||
|
|
||||||
_isActive = false;
|
_isActive = false;
|
||||||
|
|
||||||
// NOTE: The render loop is allowed to stay alive until the renderer itself is disposed, as it may handle resource dispose.
|
if (_renderingThread.IsAlive)
|
||||||
// We only need to wait for all commands submitted during the main gpu loop to be processed.
|
{
|
||||||
_gpuDoneEvent.WaitOne();
|
_renderingThread.Join();
|
||||||
_gpuDoneEvent.Dispose();
|
}
|
||||||
|
|
||||||
DisplaySleep.Restore();
|
DisplaySleep.Restore();
|
||||||
|
|
||||||
@@ -920,14 +917,6 @@ namespace Ryujinx.Ava
|
|||||||
UpdateStatus();
|
UpdateStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure all commands in the run loop are fully executed before leaving the loop.
|
|
||||||
if (Device.Gpu.Renderer is ThreadedRenderer threaded)
|
|
||||||
{
|
|
||||||
threaded.FlushThreadedCommands();
|
|
||||||
}
|
|
||||||
|
|
||||||
_gpuDoneEvent.Set();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(null);
|
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(null);
|
||||||
|
|||||||
@@ -58,20 +58,11 @@
|
|||||||
JustifyContent="SpaceAround"
|
JustifyContent="SpaceAround"
|
||||||
RowSpacing="2">
|
RowSpacing="2">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
FontSize="28"
|
FontSize="28"
|
||||||
FontWeight="Bold"
|
FontWeight="Bold"
|
||||||
Text="Ryujinx"
|
Text="Ryujinx"
|
||||||
TextAlignment="Center"
|
TextAlignment="Left" />
|
||||||
Width="100" />
|
<TextBlock Text="(REE-YOU-JINX)" TextAlignment="Left" />
|
||||||
<TextBlock
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
FontSize="11"
|
|
||||||
Text="(REE-YOU-JINX)"
|
|
||||||
TextAlignment="Center"
|
|
||||||
Width="100" />
|
|
||||||
</flex:FlexPanel>
|
</flex:FlexPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.GAL
|
namespace Ryujinx.Graphics.GAL
|
||||||
{
|
{
|
||||||
@@ -53,7 +52,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
|
|
||||||
void ResetCounter(CounterType type);
|
void ResetCounter(CounterType type);
|
||||||
|
|
||||||
void RunLoop(ThreadStart gpuLoop)
|
void RunLoop(Action gpuLoop)
|
||||||
{
|
{
|
||||||
gpuLoop();
|
gpuLoop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
private IRenderer _baseRenderer;
|
private IRenderer _baseRenderer;
|
||||||
private Thread _gpuThread;
|
private Thread _gpuThread;
|
||||||
private Thread _backendThread;
|
private Thread _backendThread;
|
||||||
|
private bool _disposed;
|
||||||
private bool _running;
|
private bool _running;
|
||||||
|
|
||||||
private AutoResetEvent _frameComplete = new AutoResetEvent(true);
|
private AutoResetEvent _frameComplete = new AutoResetEvent(true);
|
||||||
@@ -97,17 +98,19 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
_refQueue = new object[MaxRefsPerCommand * QueueCount];
|
_refQueue = new object[MaxRefsPerCommand * QueueCount];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RunLoop(ThreadStart gpuLoop)
|
public void RunLoop(Action gpuLoop)
|
||||||
{
|
{
|
||||||
_running = true;
|
_running = true;
|
||||||
|
|
||||||
_backendThread = Thread.CurrentThread;
|
_backendThread = Thread.CurrentThread;
|
||||||
|
|
||||||
_gpuThread = new Thread(gpuLoop)
|
_gpuThread = new Thread(() => {
|
||||||
{
|
gpuLoop();
|
||||||
Name = "GPU.MainThread"
|
_running = false;
|
||||||
};
|
_galWorkAvailable.Set();
|
||||||
|
});
|
||||||
|
|
||||||
|
_gpuThread.Name = "GPU.MainThread";
|
||||||
_gpuThread.Start();
|
_gpuThread.Start();
|
||||||
|
|
||||||
RenderLoop();
|
RenderLoop();
|
||||||
@@ -117,7 +120,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
{
|
{
|
||||||
// Power through the render queue until the Gpu thread work is done.
|
// Power through the render queue until the Gpu thread work is done.
|
||||||
|
|
||||||
while (_running)
|
while (_running && !_disposed)
|
||||||
{
|
{
|
||||||
_galWorkAvailable.Wait();
|
_galWorkAvailable.Wait();
|
||||||
_galWorkAvailable.Reset();
|
_galWorkAvailable.Reset();
|
||||||
@@ -485,23 +488,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
return _baseRenderer.PrepareHostMapping(address, size);
|
return _baseRenderer.PrepareHostMapping(address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FlushThreadedCommands()
|
|
||||||
{
|
|
||||||
SpinWait wait = new();
|
|
||||||
|
|
||||||
while (Volatile.Read(ref _commandCount) > 0)
|
|
||||||
{
|
|
||||||
wait.SpinOnce();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
// Dispose must happen from the render thread, after all commands have completed.
|
// Dispose must happen from the render thread, after all commands have completed.
|
||||||
|
|
||||||
// Stop the GPU thread.
|
// Stop the GPU thread.
|
||||||
_running = false;
|
_disposed = true;
|
||||||
_galWorkAvailable.Set();
|
|
||||||
|
|
||||||
if (_gpuThread != null && _gpuThread.IsAlive)
|
if (_gpuThread != null && _gpuThread.IsAlive)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -390,6 +390,7 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
Renderer.Dispose();
|
||||||
GPFifo.Dispose();
|
GPFifo.Dispose();
|
||||||
HostInitalized.Dispose();
|
HostInitalized.Dispose();
|
||||||
|
|
||||||
@@ -402,8 +403,6 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
PhysicalMemoryRegistry.Clear();
|
PhysicalMemoryRegistry.Clear();
|
||||||
|
|
||||||
RunDeferredActions();
|
RunDeferredActions();
|
||||||
|
|
||||||
Renderer.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
private readonly ResourceCounts _resourceCounts;
|
private readonly ResourceCounts _resourceCounts;
|
||||||
private readonly int _stageIndex;
|
private readonly int _stageIndex;
|
||||||
|
|
||||||
|
private readonly int[] _constantBufferBindings;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new GPU accessor.
|
/// Creates a new GPU accessor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -26,6 +28,12 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
_context = context;
|
_context = context;
|
||||||
_resourceCounts = resourceCounts;
|
_resourceCounts = resourceCounts;
|
||||||
_stageIndex = stageIndex;
|
_stageIndex = stageIndex;
|
||||||
|
|
||||||
|
if (context.Capabilities.Api != TargetApi.Vulkan)
|
||||||
|
{
|
||||||
|
_constantBufferBindings = new int[Constants.TotalGpUniformBuffers];
|
||||||
|
_constantBufferBindings.AsSpan().Fill(-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int QueryBindingConstantBuffer(int index)
|
public int QueryBindingConstantBuffer(int index)
|
||||||
@@ -37,7 +45,15 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return _resourceCounts.UniformBuffersCount++;
|
int binding = _constantBufferBindings[index];
|
||||||
|
|
||||||
|
if (binding < 0)
|
||||||
|
{
|
||||||
|
binding = _resourceCounts.UniformBuffersCount++;
|
||||||
|
_constantBufferBindings[index] = binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
return binding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
private readonly HashSet<int> _usedConstantBufferBindings;
|
private readonly HashSet<int> _usedConstantBufferBindings;
|
||||||
|
|
||||||
public ShaderProperties Properties => _properties;
|
|
||||||
|
|
||||||
public ResourceManager(ShaderStage stage, IGpuAccessor gpuAccessor, ShaderProperties properties)
|
public ResourceManager(ShaderStage stage, IGpuAccessor gpuAccessor, ShaderProperties properties)
|
||||||
{
|
{
|
||||||
_gpuAccessor = gpuAccessor;
|
_gpuAccessor = gpuAccessor;
|
||||||
@@ -100,6 +98,19 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
_properties.AddConstantBuffer(binding, new BufferDefinition(BufferLayout.Std140, 0, binding, name, type));
|
_properties.AddConstantBuffer(binding, new BufferDefinition(BufferLayout.Std140, 0, binding, name, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void InheritFrom(ResourceManager other)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < other._cbSlotToBindingMap.Length; i++)
|
||||||
|
{
|
||||||
|
int binding = other._cbSlotToBindingMap[i];
|
||||||
|
|
||||||
|
if (binding >= 0)
|
||||||
|
{
|
||||||
|
_cbSlotToBindingMap[i] = binding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static string GetShaderStagePrefix(ShaderStage stage)
|
public static string GetShaderStagePrefix(ShaderStage stage)
|
||||||
{
|
{
|
||||||
uint index = (uint)stage;
|
uint index = (uint)stage;
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
public TranslationOptions Options { get; }
|
public TranslationOptions Options { get; }
|
||||||
|
|
||||||
public ShaderProperties Properties => ResourceManager.Properties;
|
public ShaderProperties Properties { get; }
|
||||||
|
|
||||||
public ResourceManager ResourceManager { get; set; }
|
public ResourceManager ResourceManager { get; }
|
||||||
|
|
||||||
public bool TransformFeedbackEnabled { get; }
|
public bool TransformFeedbackEnabled { get; }
|
||||||
|
|
||||||
@@ -159,7 +159,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
_sbSlots = new Dictionary<int, int>();
|
_sbSlots = new Dictionary<int, int>();
|
||||||
_sbSlotsReverse = new Dictionary<int, int>();
|
_sbSlotsReverse = new Dictionary<int, int>();
|
||||||
|
|
||||||
ResourceManager = new ResourceManager(stage, gpuAccessor, new ShaderProperties());
|
Properties = new ShaderProperties();
|
||||||
|
ResourceManager = new ResourceManager(stage, gpuAccessor, Properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderConfig(
|
public ShaderConfig(
|
||||||
@@ -428,6 +429,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
public void InheritFrom(ShaderConfig other)
|
public void InheritFrom(ShaderConfig other)
|
||||||
{
|
{
|
||||||
|
ResourceManager.InheritFrom(other.ResourceManager);
|
||||||
|
|
||||||
ClipDistancesWritten |= other.ClipDistancesWritten;
|
ClipDistancesWritten |= other.ClipDistancesWritten;
|
||||||
UsedFeatures |= other.UsedFeatures;
|
UsedFeatures |= other.UsedFeatures;
|
||||||
|
|
||||||
|
|||||||
@@ -155,9 +155,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
{
|
{
|
||||||
other._config.MergeOutputUserAttributes(_config.UsedOutputAttributes, Enumerable.Empty<int>());
|
other._config.MergeOutputUserAttributes(_config.UsedOutputAttributes, Enumerable.Empty<int>());
|
||||||
|
|
||||||
// We need to share the resource manager since both shaders accesses the same constant buffers.
|
|
||||||
other._config.ResourceManager = _config.ResourceManager;
|
|
||||||
|
|
||||||
FunctionCode[] otherCode = EmitShader(other._program, other._config, initializeOutputs: true, out int aStart);
|
FunctionCode[] otherCode = EmitShader(other._program, other._config, initializeOutputs: true, out int aStart);
|
||||||
|
|
||||||
code = Combine(otherCode, code, aStart);
|
code = Combine(otherCode, code, aStart);
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance)
|
public void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance)
|
||||||
{
|
{
|
||||||
if (!_program.IsLinked || vertexCount == 0)
|
if (!_program.IsLinked)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -422,7 +422,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int firstVertex, int firstInstance)
|
public void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int firstVertex, int firstInstance)
|
||||||
{
|
{
|
||||||
if (!_program.IsLinked || indexCount == 0)
|
if (!_program.IsLinked)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
private readonly long _ticksPerFrame;
|
private readonly long _ticksPerFrame;
|
||||||
private readonly CancellationTokenSource _gpuCancellationTokenSource;
|
private readonly CancellationTokenSource _gpuCancellationTokenSource;
|
||||||
private readonly ManualResetEvent _exitEvent;
|
private readonly ManualResetEvent _exitEvent;
|
||||||
private readonly ManualResetEvent _gpuDoneEvent;
|
|
||||||
|
|
||||||
private long _ticks;
|
private long _ticks;
|
||||||
private bool _isActive;
|
private bool _isActive;
|
||||||
@@ -92,7 +91,6 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
_ticksPerFrame = Stopwatch.Frequency / TargetFps;
|
_ticksPerFrame = Stopwatch.Frequency / TargetFps;
|
||||||
_gpuCancellationTokenSource = new CancellationTokenSource();
|
_gpuCancellationTokenSource = new CancellationTokenSource();
|
||||||
_exitEvent = new ManualResetEvent(false);
|
_exitEvent = new ManualResetEvent(false);
|
||||||
_gpuDoneEvent = new ManualResetEvent(false);
|
|
||||||
_aspectRatio = aspectRatio;
|
_aspectRatio = aspectRatio;
|
||||||
_enableMouse = enableMouse;
|
_enableMouse = enableMouse;
|
||||||
HostUiTheme = new HeadlessHostUiTheme();
|
HostUiTheme = new HeadlessHostUiTheme();
|
||||||
@@ -277,14 +275,6 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
_ticks = Math.Min(_ticks - _ticksPerFrame, _ticksPerFrame);
|
_ticks = Math.Min(_ticks - _ticksPerFrame, _ticksPerFrame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure all commands in the run loop are fully executed before leaving the loop.
|
|
||||||
if (Device.Gpu.Renderer is ThreadedRenderer threaded)
|
|
||||||
{
|
|
||||||
threaded.FlushThreadedCommands();
|
|
||||||
}
|
|
||||||
|
|
||||||
_gpuDoneEvent.Set();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
FinalizeWindowRenderer();
|
FinalizeWindowRenderer();
|
||||||
@@ -414,10 +404,7 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
|
|
||||||
MainLoop();
|
MainLoop();
|
||||||
|
|
||||||
// NOTE: The render loop is allowed to stay alive until the renderer itself is disposed, as it may handle resource dispose.
|
renderLoopThread.Join();
|
||||||
// We only need to wait for all commands submitted during the main gpu loop to be processed.
|
|
||||||
_gpuDoneEvent.WaitOne();
|
|
||||||
_gpuDoneEvent.Dispose();
|
|
||||||
nvStutterWorkaround?.Join();
|
nvStutterWorkaround?.Join();
|
||||||
|
|
||||||
Exit();
|
Exit();
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ namespace Ryujinx.Ui
|
|||||||
private KeyboardHotkeyState _prevHotkeyState;
|
private KeyboardHotkeyState _prevHotkeyState;
|
||||||
|
|
||||||
private readonly ManualResetEvent _exitEvent;
|
private readonly ManualResetEvent _exitEvent;
|
||||||
private readonly ManualResetEvent _gpuDoneEvent;
|
|
||||||
|
|
||||||
private readonly CancellationTokenSource _gpuCancellationTokenSource;
|
private readonly CancellationTokenSource _gpuCancellationTokenSource;
|
||||||
|
|
||||||
@@ -111,7 +110,6 @@ namespace Ryujinx.Ui
|
|||||||
| EventMask.KeyReleaseMask));
|
| EventMask.KeyReleaseMask));
|
||||||
|
|
||||||
_exitEvent = new ManualResetEvent(false);
|
_exitEvent = new ManualResetEvent(false);
|
||||||
_gpuDoneEvent = new ManualResetEvent(false);
|
|
||||||
|
|
||||||
_gpuCancellationTokenSource = new CancellationTokenSource();
|
_gpuCancellationTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
@@ -501,14 +499,6 @@ namespace Ryujinx.Ui
|
|||||||
_ticks = Math.Min(_ticks - _ticksPerFrame, _ticksPerFrame);
|
_ticks = Math.Min(_ticks - _ticksPerFrame, _ticksPerFrame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure all commands in the run loop are fully executed before leaving the loop.
|
|
||||||
if (Device.Gpu.Renderer is ThreadedRenderer threaded)
|
|
||||||
{
|
|
||||||
threaded.FlushThreadedCommands();
|
|
||||||
}
|
|
||||||
|
|
||||||
_gpuDoneEvent.Set();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,10 +542,7 @@ namespace Ryujinx.Ui
|
|||||||
|
|
||||||
MainLoop();
|
MainLoop();
|
||||||
|
|
||||||
// NOTE: The render loop is allowed to stay alive until the renderer itself is disposed, as it may handle resource dispose.
|
renderLoopThread.Join();
|
||||||
// We only need to wait for all commands submitted during the main gpu loop to be processed.
|
|
||||||
_gpuDoneEvent.WaitOne();
|
|
||||||
_gpuDoneEvent.Dispose();
|
|
||||||
nvStutterWorkaround?.Join();
|
nvStutterWorkaround?.Join();
|
||||||
|
|
||||||
Exit();
|
Exit();
|
||||||
|
|||||||
Reference in New Issue
Block a user