diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu')
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs | 7 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs | 7 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/GpuContext.cs | 11 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Memory/Buffer.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs | 35 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs | 47 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Window.cs | 4 |
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); } |
