aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Gpu')
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs7
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs7
-rw-r--r--Ryujinx.Graphics.Gpu/GpuContext.cs11
-rw-r--r--Ryujinx.Graphics.Gpu/Memory/Buffer.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs35
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs47
-rw-r--r--Ryujinx.Graphics.Gpu/Window.cs4
7 files changed, 79 insertions, 34 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs
index 2443917c..e01938bd 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs
@@ -224,9 +224,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_instanceIndex = 0;
}
- _context.Renderer.Pipeline.SetPrimitiveTopology(topology);
+ if (_drawState.Topology != topology)
+ {
+ _context.Renderer.Pipeline.SetPrimitiveTopology(topology);
- _drawState.Topology = topology;
+ _drawState.Topology = topology;
+ }
}
/// <summary>
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs
index 37fa51c4..cb0d593d 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs
@@ -1,5 +1,6 @@
using Ryujinx.Common;
using Ryujinx.Graphics.GAL;
+using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.Gpu.Engine.Threed
{
@@ -184,13 +185,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
resultHandler(null, 0);
break;
case ReportCounterType.SamplesPassed:
- counter = _context.Renderer.ReportCounter(CounterType.SamplesPassed, resultHandler);
+ counter = _context.Renderer.ReportCounter(CounterType.SamplesPassed, resultHandler, false);
break;
case ReportCounterType.PrimitivesGenerated:
- counter = _context.Renderer.ReportCounter(CounterType.PrimitivesGenerated, resultHandler);
+ counter = _context.Renderer.ReportCounter(CounterType.PrimitivesGenerated, resultHandler, false);
break;
case ReportCounterType.TransformFeedbackPrimitivesWritten:
- counter = _context.Renderer.ReportCounter(CounterType.TransformFeedbackPrimitivesWritten, resultHandler);
+ counter = _context.Renderer.ReportCounter(CounterType.TransformFeedbackPrimitivesWritten, resultHandler, false);
break;
}
diff --git a/Ryujinx.Graphics.Gpu/GpuContext.cs b/Ryujinx.Graphics.Gpu/GpuContext.cs
index 734fc492..034c8fcb 100644
--- a/Ryujinx.Graphics.Gpu/GpuContext.cs
+++ b/Ryujinx.Graphics.Gpu/GpuContext.cs
@@ -185,6 +185,17 @@ namespace Ryujinx.Graphics.Gpu
}
/// <summary>
+ /// Processes the queue of shaders that must save their binaries to the disk cache.
+ /// </summary>
+ public void ProcessShaderCacheQueue()
+ {
+ foreach (var physicalMemory in PhysicalMemoryRegistry.Values)
+ {
+ physicalMemory.ShaderCache.ProcessShaderCacheQueue();
+ }
+ }
+
+ /// <summary>
/// Advances internal sequence number.
/// This forces the update of any modified GPU resource.
/// </summary>
diff --git a/Ryujinx.Graphics.Gpu/Memory/Buffer.cs b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
index 3f869a50..af69e693 100644
--- a/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
@@ -449,7 +449,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
(address, size) = PageAlign(address, size);
ranges.WaitForAndGetRanges(address, size, Flush);
}
- });
+ }, true);
}
/// <summary>
diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs b/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
index 594dd066..9e5c5e84 100644
--- a/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
@@ -1,4 +1,5 @@
-using Ryujinx.Memory.Range;
+using Ryujinx.Common.Pools;
+using Ryujinx.Memory.Range;
using System;
using System.Linq;
@@ -63,10 +64,6 @@ namespace Ryujinx.Graphics.Gpu.Memory
private object _lock = new object();
- // The list can be accessed from both the GPU thread, and a background thread.
- private BufferModifiedRange[] _foregroundOverlaps = new BufferModifiedRange[1];
- private BufferModifiedRange[] _backgroundOverlaps = new BufferModifiedRange[1];
-
/// <summary>
/// Creates a new instance of a modified range list.
/// </summary>
@@ -87,11 +84,13 @@ namespace Ryujinx.Graphics.Gpu.Memory
lock (_lock)
{
// Slices a given region using the modified regions in the list. Calls the action for the new slices.
- int count = FindOverlapsNonOverlapping(address, size, ref _foregroundOverlaps);
+ ref var overlaps = ref ThreadStaticArray<BufferModifiedRange>.Get();
+
+ int count = FindOverlapsNonOverlapping(address, size, ref overlaps);
for (int i = 0; i < count; i++)
{
- BufferModifiedRange overlap = _foregroundOverlaps[i];
+ BufferModifiedRange overlap = overlaps[i];
if (overlap.Address > address)
{
@@ -124,7 +123,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
lock (_lock)
{
// We may overlap with some existing modified regions. They must be cut into by the new entry.
- int count = FindOverlapsNonOverlapping(address, size, ref _foregroundOverlaps);
+ ref var overlaps = ref ThreadStaticArray<BufferModifiedRange>.Get();
+
+ int count = FindOverlapsNonOverlapping(address, size, ref overlaps);
ulong endAddress = address + size;
ulong syncNumber = _context.SyncNumber;
@@ -133,7 +134,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
{
// The overlaps must be removed or split.
- BufferModifiedRange overlap = _foregroundOverlaps[i];
+ BufferModifiedRange overlap = overlaps[i];
if (overlap.Address == address && overlap.Size == size)
{
@@ -174,15 +175,17 @@ namespace Ryujinx.Graphics.Gpu.Memory
{
int count = 0;
+ ref var overlaps = ref ThreadStaticArray<BufferModifiedRange>.Get();
+
// Range list must be consistent for this operation.
lock (_lock)
{
- count = FindOverlapsNonOverlapping(address, size, ref _foregroundOverlaps);
+ count = FindOverlapsNonOverlapping(address, size, ref overlaps);
}
for (int i = 0; i < count; i++)
{
- BufferModifiedRange overlap = _foregroundOverlaps[i];
+ BufferModifiedRange overlap = overlaps[i];
rangeAction(overlap.Address, overlap.Size);
}
}
@@ -198,7 +201,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
// Range list must be consistent for this operation.
lock (_lock)
{
- return FindOverlapsNonOverlapping(address, size, ref _foregroundOverlaps) > 0;
+ return FindOverlapsNonOverlapping(address, size, ref ThreadStaticArray<BufferModifiedRange>.Get()) > 0;
}
}
@@ -221,10 +224,12 @@ namespace Ryujinx.Graphics.Gpu.Memory
int rangeCount = 0;
+ ref var overlaps = ref ThreadStaticArray<BufferModifiedRange>.Get();
+
// Range list must be consistent for this operation
lock (_lock)
{
- rangeCount = FindOverlapsNonOverlapping(address, size, ref _backgroundOverlaps);
+ rangeCount = FindOverlapsNonOverlapping(address, size, ref overlaps);
}
if (rangeCount == 0)
@@ -239,7 +244,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
for (int i = 0; i < rangeCount; i++)
{
- BufferModifiedRange overlap = _backgroundOverlaps[i];
+ BufferModifiedRange overlap = overlaps[i];
long diff = (long)(overlap.SyncNumber - currentSync);
@@ -262,7 +267,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
{
for (int i = 0; i < rangeCount; i++)
{
- BufferModifiedRange overlap = _backgroundOverlaps[i];
+ BufferModifiedRange overlap = overlaps[i];
long diff = (long)(overlap.SyncNumber - currentSync);
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
index 91edbf2a..e5289bc0 100644
--- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
@@ -35,6 +35,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
private Dictionary<Hash128, ShaderBundle> _gpProgramsDiskCache;
private Dictionary<Hash128, ShaderBundle> _cpProgramsDiskCache;
+ private Queue<(IProgram, Action<byte[]>)> _programsToSaveQueue;
+
/// <summary>
/// Version of the codegen (to be changed when codegen or guest format change).
/// </summary>
@@ -59,6 +61,31 @@ namespace Ryujinx.Graphics.Gpu.Shader
_gpPrograms = new Dictionary<ShaderAddresses, List<ShaderBundle>>();
_gpProgramsDiskCache = new Dictionary<Hash128, ShaderBundle>();
_cpProgramsDiskCache = new Dictionary<Hash128, ShaderBundle>();
+
+ _programsToSaveQueue = new Queue<(IProgram, Action<byte[]>)>();
+ }
+
+ /// <summary>
+ /// Processes the queue of shaders that must save their binaries to the disk cache.
+ /// </summary>
+ public void ProcessShaderCacheQueue()
+ {
+ // Check to see if the binaries for previously compiled shaders are ready, and save them out.
+
+ while (_programsToSaveQueue.Count > 0)
+ {
+ (IProgram program, Action<byte[]> dataAction) = _programsToSaveQueue.Peek();
+
+ if (program.CheckProgramLink(false) != ProgramLinkStatus.Incomplete)
+ {
+ dataAction(program.GetBinary());
+ _programsToSaveQueue.Dequeue();
+ }
+ else
+ {
+ break;
+ }
+ }
}
/// <summary>
@@ -597,10 +624,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
IProgram hostProgram = _context.Renderer.CreateProgram(new IShader[] { shader.HostShader }, null);
- hostProgram.CheckProgramLink(true);
-
- byte[] hostProgramBinary = HostShaderCacheEntry.Create(hostProgram.GetBinary(), new ShaderCodeHolder[] { shader });
-
cpShader = new ShaderBundle(hostProgram, shader);
if (isShaderCacheEnabled)
@@ -609,7 +632,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
if (!isShaderCacheReadOnly)
{
- _cacheManager.SaveProgram(ref programCodeHash, CacheHelper.CreateGuestProgramDump(shaderCacheEntries), hostProgramBinary);
+ byte[] guestProgramDump = CacheHelper.CreateGuestProgramDump(shaderCacheEntries);
+ _programsToSaveQueue.Enqueue((hostProgram, (byte[] hostProgramBinary) =>
+ {
+ _cacheManager.SaveProgram(ref programCodeHash, guestProgramDump, HostShaderCacheEntry.Create(hostProgramBinary, new ShaderCodeHolder[] { shader }));
+ }));
}
}
}
@@ -740,10 +767,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
IProgram hostProgram = _context.Renderer.CreateProgram(hostShaders.ToArray(), tfd);
- hostProgram.CheckProgramLink(true);
-
- byte[] hostProgramBinary = HostShaderCacheEntry.Create(hostProgram.GetBinary(), shaders);
-
gpShaders = new ShaderBundle(hostProgram, shaders);
if (isShaderCacheEnabled)
@@ -752,7 +775,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
if (!isShaderCacheReadOnly)
{
- _cacheManager.SaveProgram(ref programCodeHash, CacheHelper.CreateGuestProgramDump(shaderCacheEntries, tfd), hostProgramBinary);
+ byte[] guestProgramDump = CacheHelper.CreateGuestProgramDump(shaderCacheEntries, tfd);
+ _programsToSaveQueue.Enqueue((hostProgram, (byte[] hostProgramBinary) =>
+ {
+ _cacheManager.SaveProgram(ref programCodeHash, guestProgramDump, HostShaderCacheEntry.Create(hostProgramBinary, shaders));
+ }));
}
}
}
diff --git a/Ryujinx.Graphics.Gpu/Window.cs b/Ryujinx.Graphics.Gpu/Window.cs
index 541a80cc..1432ef3b 100644
--- a/Ryujinx.Graphics.Gpu/Window.cs
+++ b/Ryujinx.Graphics.Gpu/Window.cs
@@ -201,9 +201,7 @@ namespace Ryujinx.Graphics.Gpu
texture.SynchronizeMemory();
- _context.Renderer.Window.Present(texture.HostTexture, pt.Crop);
-
- swapBuffersCallback();
+ _context.Renderer.Window.Present(texture.HostTexture, pt.Crop, swapBuffersCallback);
pt.ReleaseCallback(pt.UserObj);
}