aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx/Ryujinx.csproj4
-rw-r--r--Ryujinx/Ui/GLRenderer.cs26
2 files changed, 29 insertions, 1 deletions
diff --git a/Ryujinx/Ryujinx.csproj b/Ryujinx/Ryujinx.csproj
index 1734ca6d..0bccf571 100644
--- a/Ryujinx/Ryujinx.csproj
+++ b/Ryujinx/Ryujinx.csproj
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
@@ -6,6 +6,8 @@
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>1.0.0-dirty</Version>
+ <TieredCompilation>false</TieredCompilation>
+ <TieredCompilationQuickJit>false</TieredCompilationQuickJit>
</PropertyGroup>
<ItemGroup>
diff --git a/Ryujinx/Ui/GLRenderer.cs b/Ryujinx/Ui/GLRenderer.cs
index c8887544..755121c6 100644
--- a/Ryujinx/Ui/GLRenderer.cs
+++ b/Ryujinx/Ui/GLRenderer.cs
@@ -240,13 +240,39 @@ namespace Ryujinx.Ui
};
renderLoopThread.Start();
+ Thread nvStutterWorkaround = new Thread(NVStutterWorkaround)
+ {
+ Name = "GUI.NVStutterWorkaround"
+ };
+ nvStutterWorkaround.Start();
+
MainLoop();
renderLoopThread.Join();
+ nvStutterWorkaround.Join();
Exit();
}
+ private void NVStutterWorkaround()
+ {
+ while (_isActive)
+ {
+ // When NVIDIA Threaded Optimization is on, the driver will snapshot all threads in the system whenever the application creates any new ones.
+ // The ThreadPool has something called a "GateThread" which terminates itself after some inactivity.
+ // However, it immediately starts up again, since the rules regarding when to terminate and when to start differ.
+ // This creates a new thread every second or so.
+ // The main problem with this is that the thread snapshot can take 70ms, is on the OpenGL thread and will delay rendering any graphics.
+ // This is a little over budget on a frame time of 16ms, so creates a large stutter.
+ // The solution is to keep the ThreadPool active so that it never has a reason to terminate the GateThread.
+
+ // TODO: This should be removed when the issue with the GateThread is resolved.
+
+ ThreadPool.QueueUserWorkItem((state) => { });
+ Thread.Sleep(300);
+ }
+ }
+
protected override bool OnButtonPressEvent(EventButton evnt)
{
_mouseX = evnt.X;