diff --git a/ARMeilleure/Memory/MemoryManager.cs b/ARMeilleure/Memory/MemoryManager.cs index 562747f567..05fda87a5a 100644 --- a/ARMeilleure/Memory/MemoryManager.cs +++ b/ARMeilleure/Memory/MemoryManager.cs @@ -1,6 +1,7 @@ using ARMeilleure.State; using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; @@ -552,6 +553,50 @@ namespace ARMeilleure.Memory return data; } + public ReadOnlySpan GetSpan(ulong address, ulong size) + { + if (IsContiguous(address, size)) + { + return new ReadOnlySpan((void*)Translate((long)address), (int)size); + } + else + { + return ReadBytes((long)address, (long)size); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool IsContiguous(ulong address, ulong size) + { + if (!IsValidPosition((long)address)) + { + return false; + } + + ulong endVa = (address + size + PageMask) & ~(ulong)PageMask; + + address &= ~(ulong)PageMask; + + int pages = (int)((endVa - address) / PageSize); + + for (int page = 0; page < pages - 1; page++) + { + if (!IsValidPosition((long)address + PageSize)) + { + return false; + } + + if (GetPtEntry((long)address) + PageSize != GetPtEntry((long)address + PageSize)) + { + return false; + } + + address += PageSize; + } + + return true; + } + public void WriteSByte(long position, sbyte value) { WriteByte(position, (byte)value); diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs index d7b28d0b16..b73fa09268 100644 --- a/ARMeilleure/Translation/Translator.cs +++ b/ARMeilleure/Translation/Translator.cs @@ -78,9 +78,12 @@ namespace ARMeilleure.Translation { if (Interlocked.Increment(ref _threadCount) == 1) { - Thread backgroundTranslatorThread = new Thread(TranslateQueuedSubs); + Thread backgroundTranslatorThread = new Thread(TranslateQueuedSubs) + { + Name = "CPU.BackgroundTranslatorThread", + Priority = ThreadPriority.Lowest + }; - backgroundTranslatorThread.Priority = ThreadPriority.Lowest; backgroundTranslatorThread.Start(); } diff --git a/Ryujinx.Audio/Renderers/OpenAL/OpenALAudioOut.cs b/Ryujinx.Audio/Renderers/OpenAL/OpenALAudioOut.cs index 69f36a4daf..30b325a51a 100644 --- a/Ryujinx.Audio/Renderers/OpenAL/OpenALAudioOut.cs +++ b/Ryujinx.Audio/Renderers/OpenAL/OpenALAudioOut.cs @@ -70,7 +70,10 @@ namespace Ryujinx.Audio _context = new AudioContext(); _tracks = new ConcurrentDictionary(); _keepPolling = true; - _audioPollerThread = new Thread(AudioPollerWork); + _audioPollerThread = new Thread(AudioPollerWork) + { + Name = "Audio.PollerThread" + }; _audioPollerThread.Start(); } diff --git a/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs b/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs index c6605e0e0e..73b0e2b6ac 100644 --- a/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs +++ b/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs @@ -18,8 +18,13 @@ namespace Ryujinx.Common.Logging sb.AppendFormat(@"{0:hh\:mm\:ss\.fff}", args.Time); sb.Append(" | "); - sb.AppendFormat("{0:d4}", args.ThreadId); - sb.Append(' '); + + if (args.ThreadName != null) + { + sb.Append(args.ThreadName); + sb.Append(' '); + } + sb.Append(args.Message); if (args.Data != null) diff --git a/Ryujinx.Common/Logging/LogEventArgs.cs b/Ryujinx.Common/Logging/LogEventArgs.cs index 2330dedd36..af33463240 100644 --- a/Ryujinx.Common/Logging/LogEventArgs.cs +++ b/Ryujinx.Common/Logging/LogEventArgs.cs @@ -4,28 +4,28 @@ namespace Ryujinx.Common.Logging { public class LogEventArgs : EventArgs { - public LogLevel Level { get; private set; } - public TimeSpan Time { get; private set; } - public int ThreadId { get; private set; } + public LogLevel Level { get; private set; } + public TimeSpan Time { get; private set; } + public string ThreadName { get; private set; } public string Message { get; private set; } public object Data { get; private set; } - public LogEventArgs(LogLevel level, TimeSpan time, int threadId, string message) + public LogEventArgs(LogLevel level, TimeSpan time, string threadName, string message) { - Level = level; - Time = time; - ThreadId = threadId; - Message = message; + Level = level; + Time = time; + ThreadName = threadName; + Message = message; } - public LogEventArgs(LogLevel level, TimeSpan time, int threadId, string message, object data) + public LogEventArgs(LogLevel level, TimeSpan time, string threadName, string message, object data) { - Level = level; - Time = time; - ThreadId = threadId; - Message = message; - Data = data; + Level = level; + Time = time; + ThreadName = threadName; + Message = message; + Data = data; } } } \ No newline at end of file diff --git a/Ryujinx.Common/Logging/Logger.cs b/Ryujinx.Common/Logging/Logger.cs index 83af97b122..e3d82201d4 100644 --- a/Ryujinx.Common/Logging/Logger.cs +++ b/Ryujinx.Common/Logging/Logger.cs @@ -155,7 +155,7 @@ namespace Ryujinx.Common.Logging { if (m_EnabledLevels[(int)logLevel] && m_EnabledClasses[(int)logClass]) { - Updated?.Invoke(null, new LogEventArgs(logLevel, m_Time.Elapsed, Thread.CurrentThread.ManagedThreadId, message)); + Updated?.Invoke(null, new LogEventArgs(logLevel, m_Time.Elapsed, Thread.CurrentThread.Name, message)); } } @@ -163,7 +163,7 @@ namespace Ryujinx.Common.Logging { if (m_EnabledLevels[(int)logLevel] && m_EnabledClasses[(int)logClass]) { - Updated?.Invoke(null, new LogEventArgs(logLevel, m_Time.Elapsed, Thread.CurrentThread.ManagedThreadId, message, data)); + Updated?.Invoke(null, new LogEventArgs(logLevel, m_Time.Elapsed, Thread.CurrentThread.Name, message, data)); } } diff --git a/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs b/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs index c946b67880..43c62d319c 100644 --- a/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs +++ b/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs @@ -57,6 +57,7 @@ namespace Ryujinx.Common.Logging } }); + _messageThread.Name = "Logger.MessageThread"; _messageThread.IsBackground = true; _messageThread.Start(); } diff --git a/Ryujinx.Graphics.GAL/IBuffer.cs b/Ryujinx.Graphics.GAL/IBuffer.cs index 000efd67aa..43e3769186 100644 --- a/Ryujinx.Graphics.GAL/IBuffer.cs +++ b/Ryujinx.Graphics.GAL/IBuffer.cs @@ -8,8 +8,8 @@ namespace Ryujinx.Graphics.GAL byte[] GetData(int offset, int size); - void SetData(Span data); + void SetData(ReadOnlySpan data); - void SetData(int offset, Span data); + void SetData(int offset, ReadOnlySpan data); } } \ No newline at end of file diff --git a/Ryujinx.Graphics.GAL/IPipeline.cs b/Ryujinx.Graphics.GAL/IPipeline.cs index 1a502913b7..41e35dd40a 100644 --- a/Ryujinx.Graphics.GAL/IPipeline.cs +++ b/Ryujinx.Graphics.GAL/IPipeline.cs @@ -4,6 +4,8 @@ namespace Ryujinx.Graphics.GAL { public interface IPipeline { + void Barrier(); + void ClearRenderTargetColor(int index, uint componentMask, ColorF color); void ClearRenderTargetDepthStencil( diff --git a/Ryujinx.Graphics.GAL/IRenderer.cs b/Ryujinx.Graphics.GAL/IRenderer.cs index 1139ba0609..56856b2368 100644 --- a/Ryujinx.Graphics.GAL/IRenderer.cs +++ b/Ryujinx.Graphics.GAL/IRenderer.cs @@ -18,8 +18,6 @@ namespace Ryujinx.Graphics.GAL ISampler CreateSampler(SamplerCreateInfo info); ITexture CreateTexture(TextureCreateInfo info); - void FlushPipelines(); - Capabilities GetCapabilities(); ulong GetCounter(CounterType type); diff --git a/Ryujinx.Graphics.GAL/ITexture.cs b/Ryujinx.Graphics.GAL/ITexture.cs index f5bc1b4705..5278e3b74d 100644 --- a/Ryujinx.Graphics.GAL/ITexture.cs +++ b/Ryujinx.Graphics.GAL/ITexture.cs @@ -11,6 +11,6 @@ namespace Ryujinx.Graphics.GAL byte[] GetData(); - void SetData(Span data); + void SetData(ReadOnlySpan data); } } \ No newline at end of file diff --git a/Ryujinx.Graphics.Gpu/Engine/Compute.cs b/Ryujinx.Graphics.Gpu/Engine/Compute.cs index 1f52467126..d24d2d8d72 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Compute.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Compute.cs @@ -77,7 +77,7 @@ namespace Ryujinx.Graphics.Gpu.Engine sbDescAddress += (ulong)sbDescOffset; - Span sbDescriptorData = _context.PhysicalMemory.Read(sbDescAddress, 0x10); + ReadOnlySpan sbDescriptorData = _context.PhysicalMemory.GetSpan(sbDescAddress, 0x10); SbDescriptor sbDescriptor = MemoryMarshal.Cast(sbDescriptorData)[0]; diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs b/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs index 6b6742ff10..9f638f504c 100644 --- a/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs +++ b/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs @@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Gpu.Engine ulong srcAddress = srcBaseAddress + (ulong)srcOffset; ulong dstAddress = dstBaseAddress + (ulong)dstOffset; - Span pixel = _context.PhysicalMemory.Read(srcAddress, (ulong)srcBpp); + ReadOnlySpan pixel = _context.PhysicalMemory.GetSpan(srcAddress, (ulong)srcBpp); _context.PhysicalMemory.Write(dstAddress, pixel); } diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs index 90935b34c0..823ac878a6 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs @@ -235,7 +235,7 @@ namespace Ryujinx.Graphics.Gpu.Engine sbDescAddress += (ulong)sbDescOffset; - Span sbDescriptorData = _context.PhysicalMemory.Read(sbDescAddress, 0x10); + ReadOnlySpan sbDescriptorData = _context.PhysicalMemory.GetSpan(sbDescAddress, 0x10); SbDescriptor sbDescriptor = MemoryMarshal.Cast(sbDescriptorData)[0]; diff --git a/Ryujinx.Graphics.Gpu/Image/SamplerPool.cs b/Ryujinx.Graphics.Gpu/Image/SamplerPool.cs index f10f800cd7..2abf96de90 100644 --- a/Ryujinx.Graphics.Gpu/Image/SamplerPool.cs +++ b/Ryujinx.Graphics.Gpu/Image/SamplerPool.cs @@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.Gpu.Image { ulong address = Address + (ulong)(uint)id * DescriptorSize; - Span data = Context.PhysicalMemory.Read(address, DescriptorSize); + ReadOnlySpan data = Context.PhysicalMemory.GetSpan(address, DescriptorSize); SamplerDescriptor descriptor = MemoryMarshal.Cast(data)[0]; diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs index e33de1fa4e..7d5e9079da 100644 --- a/Ryujinx.Graphics.Gpu/Image/Texture.cs +++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs @@ -304,7 +304,7 @@ namespace Ryujinx.Graphics.Gpu.Image return; } - Span data = _context.PhysicalMemory.Read(Address, Size); + ReadOnlySpan data = _context.PhysicalMemory.GetSpan(Address, Size); if (Info.IsLinear) { diff --git a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs index 984d45a952..7cc7f04688 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs @@ -197,7 +197,7 @@ namespace Ryujinx.Graphics.Gpu.Image address = bufferManager.GetGraphicsUniformBufferAddress(stageIndex, binding.CbufSlot); } - packedId = MemoryMarshal.Cast(_context.PhysicalMemory.Read(address + (ulong)binding.CbufOffset * 4, 4))[0]; + packedId = MemoryMarshal.Cast(_context.PhysicalMemory.GetSpan(address + (ulong)binding.CbufOffset * 4, 4))[0]; } else { @@ -321,7 +321,7 @@ namespace Ryujinx.Graphics.Gpu.Image address += (uint)wordOffset * 4; - return BitConverter.ToInt32(_context.PhysicalMemory.Read(address, 4)); + return BitConverter.ToInt32(_context.PhysicalMemory.GetSpan(address, 4)); } /// diff --git a/Ryujinx.Graphics.Gpu/Image/TexturePool.cs b/Ryujinx.Graphics.Gpu/Image/TexturePool.cs index f6aede7979..a4f54c5206 100644 --- a/Ryujinx.Graphics.Gpu/Image/TexturePool.cs +++ b/Ryujinx.Graphics.Gpu/Image/TexturePool.cs @@ -85,7 +85,7 @@ namespace Ryujinx.Graphics.Gpu.Image { ulong address = Address + (ulong)(uint)id * DescriptorSize; - Span data = Context.PhysicalMemory.Read(address, DescriptorSize); + ReadOnlySpan data = Context.PhysicalMemory.GetSpan(address, DescriptorSize); return MemoryMarshal.Cast(data)[0]; } @@ -107,7 +107,7 @@ namespace Ryujinx.Graphics.Gpu.Image if (texture != null) { - Span data = Context.PhysicalMemory.Read(address, DescriptorSize); + ReadOnlySpan data = Context.PhysicalMemory.GetSpan(address, DescriptorSize); TextureDescriptor descriptor = MemoryMarshal.Cast(data)[0]; diff --git a/Ryujinx.Graphics.Gpu/Memory/Buffer.cs b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs index 4210ecb982..a0339cce69 100644 --- a/Ryujinx.Graphics.Gpu/Memory/Buffer.cs +++ b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs @@ -123,7 +123,7 @@ namespace Ryujinx.Graphics.Gpu.Memory int offset = (int)(mAddress - Address); - HostBuffer.SetData(offset, _context.PhysicalMemory.Read(mAddress, mSize)); + HostBuffer.SetData(offset, _context.PhysicalMemory.GetSpan(mAddress, mSize)); } } @@ -157,7 +157,7 @@ namespace Ryujinx.Graphics.Gpu.Memory /// public void Invalidate() { - HostBuffer.SetData(0, _context.PhysicalMemory.Read(Address, Size)); + HostBuffer.SetData(0, _context.PhysicalMemory.GetSpan(Address, Size)); } /// diff --git a/Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs b/Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs index 1877933317..17c0006288 100644 --- a/Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs +++ b/Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs @@ -27,23 +27,23 @@ namespace Ryujinx.Graphics.Gpu.Memory /// Byte array with the data public byte[] ReadBytes(ulong gpuVa, ulong size) { - return Read(gpuVa, size).ToArray(); + return GetSpan(gpuVa, size).ToArray(); } /// - /// Reads data from GPU mapped memory. + /// Gets a read-only span of data from GPU mapped memory. /// This reads as much data as possible, up to the specified maximum size. /// /// GPU virtual address where the data is located /// Maximum size of the data - /// The data at the specified memory location - public Span Read(ulong gpuVa, ulong maxSize) + /// The span of the data at the specified memory location + public ReadOnlySpan GetSpan(ulong gpuVa, ulong maxSize) { ulong processVa = _context.MemoryManager.Translate(gpuVa); ulong size = Math.Min(_context.MemoryManager.GetSubSize(gpuVa), maxSize); - return _context.PhysicalMemory.Read(processVa, size); + return _context.PhysicalMemory.GetSpan(processVa, size); } /// @@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Gpu.Memory ulong size = (uint)Marshal.SizeOf(); - return MemoryMarshal.Cast(_context.PhysicalMemory.Read(processVa, size))[0]; + return MemoryMarshal.Cast(_context.PhysicalMemory.GetSpan(processVa, size))[0]; } /// @@ -70,7 +70,7 @@ namespace Ryujinx.Graphics.Gpu.Memory { ulong processVa = _context.MemoryManager.Translate(gpuVa); - return BitConverter.ToInt32(_context.PhysicalMemory.Read(processVa, 4)); + return BitConverter.ToInt32(_context.PhysicalMemory.GetSpan(processVa, 4)); } /// @@ -82,7 +82,7 @@ namespace Ryujinx.Graphics.Gpu.Memory { ulong processVa = _context.MemoryManager.Translate(gpuVa); - return BitConverter.ToUInt64(_context.PhysicalMemory.Read(processVa, 8)); + return BitConverter.ToUInt64(_context.PhysicalMemory.GetSpan(processVa, 8)); } /// diff --git a/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs b/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs index 71384df237..ca28f31d11 100644 --- a/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs +++ b/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs @@ -22,14 +22,14 @@ namespace Ryujinx.Graphics.Gpu.Memory } /// - /// Reads data from the application process. + /// Gets a span of data from the application process. /// - /// Address to be read - /// Size in bytes to be read - /// The data at the specified memory location - public Span Read(ulong address, ulong size) + /// Start address of the range + /// Size in bytes to be range + /// A read only span of the data at the specified memory location + public ReadOnlySpan GetSpan(ulong address, ulong size) { - return _cpuMemory.ReadBytes((long)address, (long)size); + return _cpuMemory.GetSpan(address, size); } /// @@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Memory /// /// Address to write into /// Data to be written - public void Write(ulong address, Span data) + public void Write(ulong address, ReadOnlySpan data) { _cpuMemory.WriteBytes((long)address, data.ToArray()); } diff --git a/Ryujinx.Graphics.Gpu/NvGpuFifo.cs b/Ryujinx.Graphics.Gpu/NvGpuFifo.cs index 853e5dfdd3..11a9e3fba4 100644 --- a/Ryujinx.Graphics.Gpu/NvGpuFifo.cs +++ b/Ryujinx.Graphics.Gpu/NvGpuFifo.cs @@ -154,7 +154,7 @@ namespace Ryujinx.Graphics.Gpu { _context.Methods.PerformDeferredDraws(); - _context.Renderer.FlushPipelines(); + _context.Renderer.Pipeline.Barrier(); break; } diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index 548a7e07ab..dad1b0ac2e 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -265,7 +265,7 @@ namespace Ryujinx.Graphics.Gpu.Shader ShaderProgram program; - Span code = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize); + ReadOnlySpan code = _context.MemoryAccessor.GetSpan(gpuVa, MaxProgramSize); program = Translator.Translate(code, callbacks, DefaultFlags | TranslationFlags.Compute); @@ -319,8 +319,8 @@ namespace Ryujinx.Graphics.Gpu.Shader if (gpuVaA != 0) { - Span codeA = _context.MemoryAccessor.Read(gpuVaA, MaxProgramSize); - Span codeB = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize); + ReadOnlySpan codeA = _context.MemoryAccessor.GetSpan(gpuVaA, MaxProgramSize); + ReadOnlySpan codeB = _context.MemoryAccessor.GetSpan(gpuVa, MaxProgramSize); program = Translator.Translate(codeA, codeB, callbacks, DefaultFlags); @@ -340,7 +340,7 @@ namespace Ryujinx.Graphics.Gpu.Shader } else { - Span code = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize); + ReadOnlySpan code = _context.MemoryAccessor.GetSpan(gpuVa, MaxProgramSize); program = Translator.Translate(code, callbacks, DefaultFlags); diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderDumper.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderDumper.cs index 3be75564bf..0e22b07e3a 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderDumper.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderDumper.cs @@ -27,7 +27,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// True for compute shader code, false for graphics shader code /// Output path for the shader code with header included /// Output path for the shader code without header - public void Dump(Span code, bool compute, out string fullPath, out string codePath) + public void Dump(ReadOnlySpan code, bool compute, out string fullPath, out string codePath) { _dumpPath = GraphicsConfig.ShadersDumpPath; diff --git a/Ryujinx.Graphics.OpenGL/Buffer.cs b/Ryujinx.Graphics.OpenGL/Buffer.cs index b86719ceb4..db3e94ba59 100644 --- a/Ryujinx.Graphics.OpenGL/Buffer.cs +++ b/Ryujinx.Graphics.OpenGL/Buffer.cs @@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.OpenGL return data; } - public void SetData(Span data) + public void SetData(ReadOnlySpan data) { unsafe { @@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.OpenGL } } - public void SetData(int offset, Span data) + public void SetData(int offset, ReadOnlySpan data) { GL.BindBuffer(BufferTarget.CopyWriteBuffer, Handle); diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs index 669cfe3e99..e308becfe6 100644 --- a/Ryujinx.Graphics.OpenGL/Pipeline.cs +++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs @@ -37,6 +37,11 @@ namespace Ryujinx.Graphics.OpenGL _clipDepthMode = ClipDepthMode.NegativeOneToOne; } + public void Barrier() + { + GL.MemoryBarrier(MemoryBarrierFlags.AllBarrierBits); + } + public void ClearRenderTargetColor(int index, uint componentMask, ColorF color) { GL.ColorMask( @@ -165,26 +170,35 @@ namespace Ryujinx.Graphics.OpenGL int firstVertex, int firstInstance) { - // TODO: Instanced rendering. int quadsCount = (vertexCount - 2) / 2; - int[] firsts = new int[quadsCount]; - int[] counts = new int[quadsCount]; - - firsts[0] = firstVertex; - counts[0] = 4; - - for (int quadIndex = 1; quadIndex < quadsCount; quadIndex++) + if (firstInstance != 0 || instanceCount != 1) { - firsts[quadIndex] = firstVertex + quadIndex * 2; - counts[quadIndex] = 4; + for (int quadIndex = 0; quadIndex < quadsCount; quadIndex++) + { + GL.DrawArraysInstancedBaseInstance(PrimitiveType.TriangleFan, firstVertex + quadIndex * 2, 4, instanceCount, firstInstance); + } } + else + { + int[] firsts = new int[quadsCount]; + int[] counts = new int[quadsCount]; - GL.MultiDrawArrays( - PrimitiveType.TriangleFan, - firsts, - counts, - quadsCount); + firsts[0] = firstVertex; + counts[0] = 4; + + for (int quadIndex = 1; quadIndex < quadsCount; quadIndex++) + { + firsts[quadIndex] = firstVertex + quadIndex * 2; + counts[quadIndex] = 4; + } + + GL.MultiDrawArrays( + PrimitiveType.TriangleFan, + firsts, + counts, + quadsCount); + } } private void DrawImpl( @@ -277,31 +291,75 @@ namespace Ryujinx.Graphics.OpenGL int firstVertex, int firstInstance) { - // TODO: Instanced rendering. int quadsCount = indexCount / 4; - IntPtr[] indices = new IntPtr[quadsCount]; - - int[] counts = new int[quadsCount]; - - int[] baseVertices = new int[quadsCount]; - - for (int quadIndex = 0; quadIndex < quadsCount; quadIndex++) + if (firstInstance != 0 || instanceCount != 1) { - indices[quadIndex] = indexBaseOffset + quadIndex * 4 * indexElemSize; - - counts[quadIndex] = 4; - - baseVertices[quadIndex] = firstVertex; + if (firstVertex != 0 && firstInstance != 0) + { + for (int quadIndex = 0; quadIndex < quadsCount; quadIndex++) + { + GL.DrawElementsInstancedBaseVertexBaseInstance( + PrimitiveType.TriangleFan, + 4, + _elementsType, + indexBaseOffset + quadIndex * 4 * indexElemSize, + instanceCount, + firstVertex, + firstInstance); + } + } + else if (firstInstance != 0) + { + for (int quadIndex = 0; quadIndex < quadsCount; quadIndex++) + { + GL.DrawElementsInstancedBaseInstance( + PrimitiveType.TriangleFan, + 4, + _elementsType, + indexBaseOffset + quadIndex * 4 * indexElemSize, + instanceCount, + firstInstance); + } + } + else + { + for (int quadIndex = 0; quadIndex < quadsCount; quadIndex++) + { + GL.DrawElementsInstanced( + PrimitiveType.TriangleFan, + 4, + _elementsType, + indexBaseOffset + quadIndex * 4 * indexElemSize, + instanceCount); + } + } } + else + { + IntPtr[] indices = new IntPtr[quadsCount]; - GL.MultiDrawElementsBaseVertex( - PrimitiveType.TriangleFan, - counts, - _elementsType, - indices, - quadsCount, - baseVertices); + int[] counts = new int[quadsCount]; + + int[] baseVertices = new int[quadsCount]; + + for (int quadIndex = 0; quadIndex < quadsCount; quadIndex++) + { + indices[quadIndex] = indexBaseOffset + quadIndex * 4 * indexElemSize; + + counts[quadIndex] = 4; + + baseVertices[quadIndex] = firstVertex; + } + + GL.MultiDrawElementsBaseVertex( + PrimitiveType.TriangleFan, + counts, + _elementsType, + indices, + quadsCount, + baseVertices); + } } private void DrawQuadStripIndexedImpl( diff --git a/Ryujinx.Graphics.OpenGL/Renderer.cs b/Ryujinx.Graphics.OpenGL/Renderer.cs index 29a0ea2954..ccb53397d1 100644 --- a/Ryujinx.Graphics.OpenGL/Renderer.cs +++ b/Ryujinx.Graphics.OpenGL/Renderer.cs @@ -55,11 +55,6 @@ namespace Ryujinx.Graphics.OpenGL return new TextureStorage(this, info).CreateDefaultView(); } - public void FlushPipelines() - { - GL.Finish(); - } - public Capabilities GetCapabilities() { return new Capabilities( diff --git a/Ryujinx.Graphics.OpenGL/TextureView.cs b/Ryujinx.Graphics.OpenGL/TextureView.cs index 91f1865d32..2efaf7c0a1 100644 --- a/Ryujinx.Graphics.OpenGL/TextureView.cs +++ b/Ryujinx.Graphics.OpenGL/TextureView.cs @@ -217,7 +217,7 @@ namespace Ryujinx.Graphics.OpenGL } } - public void SetData(Span data) + public void SetData(ReadOnlySpan data) { unsafe { diff --git a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs index db63712bff..8a502e3c6c 100644 --- a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs +++ b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs @@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Shader.Decoders _opActivators = new ConcurrentDictionary(); } - public static Block[] Decode(Span code, ulong headerSize) + public static Block[] Decode(ReadOnlySpan code, ulong headerSize) { List blocks = new List(); @@ -214,10 +214,10 @@ namespace Ryujinx.Graphics.Shader.Decoders } private static void FillBlock( - Span code, - Block block, - ulong limitAddress, - ulong startAddress) + ReadOnlySpan code, + Block block, + ulong limitAddress, + ulong startAddress) { ulong address = block.Address; diff --git a/Ryujinx.Graphics.Shader/Translation/ShaderHeader.cs b/Ryujinx.Graphics.Shader/Translation/ShaderHeader.cs index 0c56132d95..42701fbdca 100644 --- a/Ryujinx.Graphics.Shader/Translation/ShaderHeader.cs +++ b/Ryujinx.Graphics.Shader/Translation/ShaderHeader.cs @@ -76,9 +76,9 @@ namespace Ryujinx.Graphics.Shader.Translation public bool OmapSampleMask { get; } public bool OmapDepth { get; } - public ShaderHeader(Span code) + public ShaderHeader(ReadOnlySpan code) { - Span header = MemoryMarshal.Cast(code); + ReadOnlySpan header = MemoryMarshal.Cast(code); int commonWord0 = header[0]; int commonWord1 = header[1]; diff --git a/Ryujinx.Graphics.Shader/Translation/Translator.cs b/Ryujinx.Graphics.Shader/Translation/Translator.cs index 760d616f63..a333db9529 100644 --- a/Ryujinx.Graphics.Shader/Translation/Translator.cs +++ b/Ryujinx.Graphics.Shader/Translation/Translator.cs @@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Shader.Translation { private const int HeaderSize = 0x50; - public static Span ExtractCode(Span code, bool compute, out int headerSize) + public static ReadOnlySpan ExtractCode(ReadOnlySpan code, bool compute, out int headerSize) { headerSize = compute ? 0 : HeaderSize; @@ -38,14 +38,14 @@ namespace Ryujinx.Graphics.Shader.Translation return code.Slice(0, headerSize + (int)endAddress); } - public static ShaderProgram Translate(Span code, TranslatorCallbacks callbacks, TranslationFlags flags) + public static ShaderProgram Translate(ReadOnlySpan code, TranslatorCallbacks callbacks, TranslationFlags flags) { Operation[] ops = DecodeShader(code, callbacks, flags, out ShaderConfig config, out int size); return Translate(ops, config, size); } - public static ShaderProgram Translate(Span vpACode, Span vpBCode, TranslatorCallbacks callbacks, TranslationFlags flags) + public static ShaderProgram Translate(ReadOnlySpan vpACode, ReadOnlySpan vpBCode, TranslatorCallbacks callbacks, TranslationFlags flags) { Operation[] vpAOps = DecodeShader(vpACode, callbacks, flags, out _, out _); Operation[] vpBOps = DecodeShader(vpBCode, callbacks, flags, out ShaderConfig config, out int sizeB); @@ -88,7 +88,7 @@ namespace Ryujinx.Graphics.Shader.Translation } private static Operation[] DecodeShader( - Span code, + ReadOnlySpan code, TranslatorCallbacks callbacks, TranslationFlags flags, out ShaderConfig config, diff --git a/Ryujinx.HLE/FileSystem/Content/ContentManager.cs b/Ryujinx.HLE/FileSystem/Content/ContentManager.cs index b83ae44064..680ebd522e 100644 --- a/Ryujinx.HLE/FileSystem/Content/ContentManager.cs +++ b/Ryujinx.HLE/FileSystem/Content/ContentManager.cs @@ -28,6 +28,8 @@ namespace Ryujinx.HLE.FileSystem.Content private Switch _device; + private readonly object _lock = new object(); + public ContentManager(Switch device) { _contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>(); @@ -58,139 +60,151 @@ namespace Ryujinx.HLE.FileSystem.Content public void LoadEntries(bool ignoreMissingFonts = false) { - _contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>(); - _locationEntries = new Dictionary>(); - - foreach (StorageId storageId in Enum.GetValues(typeof(StorageId))) + lock (_lock) { - string contentDirectory = null; - string contentPathString = null; - string registeredDirectory = null; + _contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>(); + _locationEntries = new Dictionary>(); - try + foreach (StorageId storageId in Enum.GetValues(typeof(StorageId))) { - contentPathString = LocationHelper.GetContentRoot(storageId); - contentDirectory = LocationHelper.GetRealPath(_device.FileSystem, contentPathString); - registeredDirectory = Path.Combine(contentDirectory, "registered"); - } - catch (NotSupportedException) - { - continue; - } + string contentDirectory = null; + string contentPathString = null; + string registeredDirectory = null; - Directory.CreateDirectory(registeredDirectory); - - LinkedList locationList = new LinkedList(); - - void AddEntry(LocationEntry entry) - { - locationList.AddLast(entry); - } - - foreach (string directoryPath in Directory.EnumerateDirectories(registeredDirectory)) - { - if (Directory.GetFiles(directoryPath).Length > 0) + try { - string ncaName = new DirectoryInfo(directoryPath).Name.Replace(".nca", string.Empty); + contentPathString = LocationHelper.GetContentRoot(storageId); + contentDirectory = LocationHelper.GetRealPath(_device.FileSystem, contentPathString); + registeredDirectory = Path.Combine(contentDirectory, "registered"); + } + catch (NotSupportedException) + { + continue; + } - using (FileStream ncaFile = new FileStream(Directory.GetFiles(directoryPath)[0], FileMode.Open, FileAccess.Read)) + Directory.CreateDirectory(registeredDirectory); + + LinkedList locationList = new LinkedList(); + + void AddEntry(LocationEntry entry) + { + locationList.AddLast(entry); + } + + foreach (string directoryPath in Directory.EnumerateDirectories(registeredDirectory)) + { + if (Directory.GetFiles(directoryPath).Length > 0) { - Nca nca = new Nca(_device.System.KeySet, ncaFile.AsStorage()); + string ncaName = new DirectoryInfo(directoryPath).Name.Replace(".nca", string.Empty); - string switchPath = contentPathString + ":/" + ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar); + using (FileStream ncaFile = File.OpenRead(Directory.GetFiles(directoryPath)[0])) + { + Nca nca = new Nca(_device.System.KeySet, ncaFile.AsStorage()); - // Change path format to switch's - switchPath = switchPath.Replace('\\', '/'); + string switchPath = contentPathString + ":/" + ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar); - LocationEntry entry = new LocationEntry(switchPath, - 0, - (long)nca.Header.TitleId, - nca.Header.ContentType); + // Change path format to switch's + switchPath = switchPath.Replace('\\', '/'); - AddEntry(entry); + LocationEntry entry = new LocationEntry(switchPath, + 0, + (long)nca.Header.TitleId, + nca.Header.ContentType); - _contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); + AddEntry(entry); + + _contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); + } } } + + foreach (string filePath in Directory.EnumerateFiles(contentDirectory)) + { + if (Path.GetExtension(filePath) == ".nca") + { + string ncaName = Path.GetFileNameWithoutExtension(filePath); + + using (FileStream ncaFile = new FileStream(filePath, FileMode.Open, FileAccess.Read)) + { + Nca nca = new Nca(_device.System.KeySet, ncaFile.AsStorage()); + + string switchPath = contentPathString + ":/" + filePath.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar); + + // Change path format to switch's + switchPath = switchPath.Replace('\\', '/'); + + LocationEntry entry = new LocationEntry(switchPath, + 0, + (long)nca.Header.TitleId, + nca.Header.ContentType); + + AddEntry(entry); + + _contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); + } + } + } + + if (_locationEntries.ContainsKey(storageId) && _locationEntries[storageId]?.Count == 0) + { + _locationEntries.Remove(storageId); + } + + if (!_locationEntries.ContainsKey(storageId)) + { + _locationEntries.Add(storageId, locationList); + } } - foreach (string filePath in Directory.EnumerateFiles(contentDirectory)) - { - if (Path.GetExtension(filePath) == ".nca") - { - string ncaName = Path.GetFileNameWithoutExtension(filePath); + TimeManager.Instance.InitializeTimeZone(_device); - using (FileStream ncaFile = new FileStream(filePath, FileMode.Open, FileAccess.Read)) - { - Nca nca = new Nca(_device.System.KeySet, ncaFile.AsStorage()); - - string switchPath = contentPathString + ":/" + filePath.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar); - - // Change path format to switch's - switchPath = switchPath.Replace('\\', '/'); - - LocationEntry entry = new LocationEntry(switchPath, - 0, - (long)nca.Header.TitleId, - nca.Header.ContentType); - - AddEntry(entry); - - _contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); - } - } - } - - if (_locationEntries.ContainsKey(storageId) && _locationEntries[storageId]?.Count == 0) - { - _locationEntries.Remove(storageId); - } - - if (!_locationEntries.ContainsKey(storageId)) - { - _locationEntries.Add(storageId, locationList); - } + _device.System.Font.Initialize(this, ignoreMissingFonts); } - - TimeManager.Instance.InitializeTimeZone(_device); - - _device.System.Font.Initialize(this, ignoreMissingFonts); } public void ClearEntry(long titleId, NcaContentType contentType, StorageId storageId) { - RemoveLocationEntry(titleId, contentType, storageId); + lock (_lock) + { + RemoveLocationEntry(titleId, contentType, storageId); + } } public void RefreshEntries(StorageId storageId, int flag) { - LinkedList locationList = _locationEntries[storageId]; - LinkedListNode locationEntry = locationList.First; - - while (locationEntry != null) + lock (_lock) { - LinkedListNode nextLocationEntry = locationEntry.Next; + LinkedList locationList = _locationEntries[storageId]; + LinkedListNode locationEntry = locationList.First; - if (locationEntry.Value.Flag == flag) + while (locationEntry != null) { - locationList.Remove(locationEntry.Value); - } + LinkedListNode nextLocationEntry = locationEntry.Next; - locationEntry = nextLocationEntry; + if (locationEntry.Value.Flag == flag) + { + locationList.Remove(locationEntry.Value); + } + + locationEntry = nextLocationEntry; + } } } public bool HasNca(string ncaId, StorageId storageId) { - if (_contentDictionary.ContainsValue(ncaId)) + lock (_lock) { - var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId); - long titleId = (long)content.Key.Item1; + if (_contentDictionary.ContainsValue(ncaId)) + { + var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId); + long titleId = (long)content.Key.Item1; - NcaContentType contentType = content.Key.type; - StorageId storage = GetInstalledStorage(titleId, contentType, storageId); + NcaContentType contentType = content.Key.type; + StorageId storage = GetInstalledStorage(titleId, contentType, storageId); - return storage == storageId; + return storage == storageId; + } } return false; @@ -198,9 +212,12 @@ namespace Ryujinx.HLE.FileSystem.Content public UInt128 GetInstalledNcaId(long titleId, NcaContentType contentType) { - if (_contentDictionary.ContainsKey(((ulong)titleId, contentType))) + lock (_lock) { - return new UInt128(_contentDictionary[((ulong)titleId, contentType)]); + if (_contentDictionary.ContainsKey(((ulong)titleId, contentType))) + { + return new UInt128(_contentDictionary[((ulong)titleId, contentType)]); + } } return new UInt128(); @@ -208,19 +225,25 @@ namespace Ryujinx.HLE.FileSystem.Content public StorageId GetInstalledStorage(long titleId, NcaContentType contentType, StorageId storageId) { - LocationEntry locationEntry = GetLocation(titleId, contentType, storageId); + lock (_lock) + { + LocationEntry locationEntry = GetLocation(titleId, contentType, storageId); - return locationEntry.ContentPath != null ? - LocationHelper.GetStorageId(locationEntry.ContentPath) : StorageId.None; + return locationEntry.ContentPath != null ? + LocationHelper.GetStorageId(locationEntry.ContentPath) : StorageId.None; + } } public string GetInstalledContentPath(long titleId, StorageId storageId, NcaContentType contentType) { - LocationEntry locationEntry = GetLocation(titleId, contentType, storageId); - - if (VerifyContentType(locationEntry, contentType)) + lock (_lock) { - return locationEntry.ContentPath; + LocationEntry locationEntry = GetLocation(titleId, contentType, storageId); + + if (VerifyContentType(locationEntry, contentType)) + { + return locationEntry.ContentPath; + } } return string.Empty; @@ -228,14 +251,17 @@ namespace Ryujinx.HLE.FileSystem.Content public void RedirectLocation(LocationEntry newEntry, StorageId storageId) { - LocationEntry locationEntry = GetLocation(newEntry.TitleId, newEntry.ContentType, storageId); - - if (locationEntry.ContentPath != null) + lock (_lock) { - RemoveLocationEntry(newEntry.TitleId, newEntry.ContentType, storageId); - } + LocationEntry locationEntry = GetLocation(newEntry.TitleId, newEntry.ContentType, storageId); - AddLocationEntry(newEntry, storageId); + if (locationEntry.ContentPath != null) + { + RemoveLocationEntry(newEntry.TitleId, newEntry.ContentType, storageId); + } + + AddLocationEntry(newEntry, storageId); + } } private bool VerifyContentType(LocationEntry locationEntry, NcaContentType contentType) @@ -827,28 +853,31 @@ namespace Ryujinx.HLE.FileSystem.Content { LoadEntries(true); - var locationEnties = _locationEntries[StorageId.NandSystem]; - - foreach (var entry in locationEnties) + lock (_lock) { - if (entry.ContentType == NcaContentType.Data) + var locationEnties = _locationEntries[StorageId.NandSystem]; + + foreach (var entry in locationEnties) { - var path = _device.FileSystem.SwitchPathToSystemPath(entry.ContentPath); - - using (IStorage ncaStorage = File.Open(path, FileMode.Open).AsStorage()) + if (entry.ContentType == NcaContentType.Data) { - Nca nca = new Nca(_device.System.KeySet, ncaStorage); + var path = _device.FileSystem.SwitchPathToSystemPath(entry.ContentPath); - if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data) + using (FileStream fileStream = File.OpenRead(path)) { - var romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel); + Nca nca = new Nca(_device.System.KeySet, fileStream.AsStorage()); - if (romfs.OpenFile(out IFile systemVersionFile, "/file", OpenMode.Read).IsSuccess()) + if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data) { - return new SystemVersion(systemVersionFile.AsStream()); - } - } + var romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel); + if (romfs.OpenFile(out IFile systemVersionFile, "/file", OpenMode.Read).IsSuccess()) + { + return new SystemVersion(systemVersionFile.AsStream()); + } + } + + } } } } diff --git a/Ryujinx.HLE/HOS/Kernel/Common/KTimeManager.cs b/Ryujinx.HLE/HOS/Kernel/Common/KTimeManager.cs index f6a9e6f9d1..8273520fd1 100644 --- a/Ryujinx.HLE/HOS/Kernel/Common/KTimeManager.cs +++ b/Ryujinx.HLE/HOS/Kernel/Common/KTimeManager.cs @@ -33,7 +33,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Common _keepRunning = true; - Thread work = new Thread(WaitAndCheckScheduledObjects); + Thread work = new Thread(WaitAndCheckScheduledObjects) + { + Name = "HLE.TimeManager" + }; work.Start(); } diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/HleScheduler.cs b/Ryujinx.HLE/HOS/Kernel/Threading/HleScheduler.cs index 0b95113481..1a213b924f 100644 --- a/Ryujinx.HLE/HOS/Kernel/Threading/HleScheduler.cs +++ b/Ryujinx.HLE/HOS/Kernel/Threading/HleScheduler.cs @@ -17,7 +17,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading public void StartAutoPreemptionThread() { - Thread preemptionThread = new Thread(PreemptCurrentThread); + Thread preemptionThread = new Thread(PreemptCurrentThread) + { + Name = "HLE.PreemptionThread" + }; _keepPreempting = true; diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs index e1a49a561a..c4bd781d4e 100644 --- a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs +++ b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs @@ -159,7 +159,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading is64Bits = true; } - HostThread = new Thread(customHostThreadStart == null ? () => ThreadStart(entrypoint) : customHostThreadStart); + HostThread = new Thread(customHostThreadStart ?? (() => ThreadStart(entrypoint))); Context = new ARMeilleure.State.ExecutionContext(); @@ -185,7 +185,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading ThreadUid = System.GetThreadUid(); - HostThread.Name = $"Host Thread (thread id {ThreadUid})"; + HostThread.Name = $"HLE.HostThread.{ThreadUid}"; _hasBeenInitialized = true; diff --git a/Ryujinx.Profiler/InternalProfile.cs b/Ryujinx.Profiler/InternalProfile.cs index 46984601b5..0346244423 100644 --- a/Ryujinx.Profiler/InternalProfile.cs +++ b/Ryujinx.Profiler/InternalProfile.cs @@ -55,7 +55,10 @@ namespace Ryujinx.Profiler _cleanupRunning = true; // Create cleanup thread. - _cleanupThread = new Thread(CleanupLoop); + _cleanupThread = new Thread(CleanupLoop) + { + Name = "Profiler.CleanupThread" + }; _cleanupThread.Start(); } diff --git a/Ryujinx.Profiler/UI/ProfileWindowManager.cs b/Ryujinx.Profiler/UI/ProfileWindowManager.cs index c6a65a317c..1360302933 100644 --- a/Ryujinx.Profiler/UI/ProfileWindowManager.cs +++ b/Ryujinx.Profiler/UI/ProfileWindowManager.cs @@ -21,7 +21,10 @@ namespace Ryujinx.Profiler.UI { _profilerRunning = true; _prevTime = 0; - _profileThread = new Thread(ProfileLoop); + _profileThread = new Thread(ProfileLoop) + { + Name = "Profiler.ProfileThread" + }; _profileThread.Start(); } } @@ -60,7 +63,10 @@ namespace Ryujinx.Profiler.UI using (_window = new ProfileWindow()) { // Create thread for render loop - _renderThread = new Thread(RenderLoop); + _renderThread = new Thread(RenderLoop) + { + Name = "Profiler.RenderThread" + }; _renderThread.Start(); while (_profilerRunning) diff --git a/Ryujinx/Ui/AboutInfo.cs b/Ryujinx/Ui/AboutInfo.cs deleted file mode 100644 index 01e0d81b57..0000000000 --- a/Ryujinx/Ui/AboutInfo.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Ryujinx.Ui -{ - internal struct AboutInfo - { - public string InstallVersion; - public string InstallCommit; - public string InstallBranch; - } -} \ No newline at end of file diff --git a/Ryujinx/Ui/AboutWindow.cs b/Ryujinx/Ui/AboutWindow.cs index 0332d7a48b..122dcaae1f 100644 --- a/Ryujinx/Ui/AboutWindow.cs +++ b/Ryujinx/Ui/AboutWindow.cs @@ -13,8 +13,6 @@ namespace Ryujinx.Ui { public class AboutWindow : Window { - private static AboutInfo AboutInformation { get; set; } - #pragma warning disable CS0649 #pragma warning disable IDE0044 [GUI] Window _aboutWin; diff --git a/Ryujinx/Ui/GLScreen.cs b/Ryujinx/Ui/GLScreen.cs index 8e39126224..d32ddb5ca5 100644 --- a/Ryujinx/Ui/GLScreen.cs +++ b/Ryujinx/Ui/GLScreen.cs @@ -120,7 +120,10 @@ namespace Ryujinx.Ui Context.MakeCurrent(null); // OpenTK doesn't like sleeps in its thread, to avoid this a renderer thread is created - _renderThread = new Thread(RenderLoop); + _renderThread = new Thread(RenderLoop) + { + Name = "GUI.RenderThread" + }; _renderThread.Start(); diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs index 9cca6158ca..2696907e8f 100644 --- a/Ryujinx/Ui/MainWindow.cs +++ b/Ryujinx/Ui/MainWindow.cs @@ -656,6 +656,7 @@ namespace Ryujinx.Ui } }); + thread.Name = "GUI.FirmwareInstallerThread"; thread.Start(); } else