Merge branch 'master' into aot
This commit is contained in:
commit
7d0d9703a1
41 changed files with 402 additions and 255 deletions
|
@ -1,6 +1,7 @@
|
||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
|
@ -552,6 +553,50 @@ namespace ARMeilleure.Memory
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReadOnlySpan<byte> GetSpan(ulong address, ulong size)
|
||||||
|
{
|
||||||
|
if (IsContiguous(address, size))
|
||||||
|
{
|
||||||
|
return new ReadOnlySpan<byte>((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)
|
public void WriteSByte(long position, sbyte value)
|
||||||
{
|
{
|
||||||
WriteByte(position, (byte)value);
|
WriteByte(position, (byte)value);
|
||||||
|
|
|
@ -78,9 +78,12 @@ namespace ARMeilleure.Translation
|
||||||
{
|
{
|
||||||
if (Interlocked.Increment(ref _threadCount) == 1)
|
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();
|
backgroundTranslatorThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,10 @@ namespace Ryujinx.Audio
|
||||||
_context = new AudioContext();
|
_context = new AudioContext();
|
||||||
_tracks = new ConcurrentDictionary<int, OpenALAudioTrack>();
|
_tracks = new ConcurrentDictionary<int, OpenALAudioTrack>();
|
||||||
_keepPolling = true;
|
_keepPolling = true;
|
||||||
_audioPollerThread = new Thread(AudioPollerWork);
|
_audioPollerThread = new Thread(AudioPollerWork)
|
||||||
|
{
|
||||||
|
Name = "Audio.PollerThread"
|
||||||
|
};
|
||||||
|
|
||||||
_audioPollerThread.Start();
|
_audioPollerThread.Start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,13 @@ namespace Ryujinx.Common.Logging
|
||||||
|
|
||||||
sb.AppendFormat(@"{0:hh\:mm\:ss\.fff}", args.Time);
|
sb.AppendFormat(@"{0:hh\:mm\:ss\.fff}", args.Time);
|
||||||
sb.Append(" | ");
|
sb.Append(" | ");
|
||||||
sb.AppendFormat("{0:d4}", args.ThreadId);
|
|
||||||
|
if (args.ThreadName != null)
|
||||||
|
{
|
||||||
|
sb.Append(args.ThreadName);
|
||||||
sb.Append(' ');
|
sb.Append(' ');
|
||||||
|
}
|
||||||
|
|
||||||
sb.Append(args.Message);
|
sb.Append(args.Message);
|
||||||
|
|
||||||
if (args.Data != null)
|
if (args.Data != null)
|
||||||
|
|
|
@ -6,24 +6,24 @@ namespace Ryujinx.Common.Logging
|
||||||
{
|
{
|
||||||
public LogLevel Level { get; private set; }
|
public LogLevel Level { get; private set; }
|
||||||
public TimeSpan Time { get; private set; }
|
public TimeSpan Time { get; private set; }
|
||||||
public int ThreadId { get; private set; }
|
public string ThreadName { get; private set; }
|
||||||
|
|
||||||
public string Message { get; private set; }
|
public string Message { get; private set; }
|
||||||
public object Data { 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;
|
Level = level;
|
||||||
Time = time;
|
Time = time;
|
||||||
ThreadId = threadId;
|
ThreadName = threadName;
|
||||||
Message = message;
|
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;
|
Level = level;
|
||||||
Time = time;
|
Time = time;
|
||||||
ThreadId = threadId;
|
ThreadName = threadName;
|
||||||
Message = message;
|
Message = message;
|
||||||
Data = data;
|
Data = data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,7 @@ namespace Ryujinx.Common.Logging
|
||||||
{
|
{
|
||||||
if (m_EnabledLevels[(int)logLevel] && m_EnabledClasses[(int)logClass])
|
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])
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ namespace Ryujinx.Common.Logging
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_messageThread.Name = "Logger.MessageThread";
|
||||||
_messageThread.IsBackground = true;
|
_messageThread.IsBackground = true;
|
||||||
_messageThread.Start();
|
_messageThread.Start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ namespace Ryujinx.Graphics.GAL
|
||||||
|
|
||||||
byte[] GetData(int offset, int size);
|
byte[] GetData(int offset, int size);
|
||||||
|
|
||||||
void SetData(Span<byte> data);
|
void SetData(ReadOnlySpan<byte> data);
|
||||||
|
|
||||||
void SetData(int offset, Span<byte> data);
|
void SetData(int offset, ReadOnlySpan<byte> data);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,6 +4,8 @@ namespace Ryujinx.Graphics.GAL
|
||||||
{
|
{
|
||||||
public interface IPipeline
|
public interface IPipeline
|
||||||
{
|
{
|
||||||
|
void Barrier();
|
||||||
|
|
||||||
void ClearRenderTargetColor(int index, uint componentMask, ColorF color);
|
void ClearRenderTargetColor(int index, uint componentMask, ColorF color);
|
||||||
|
|
||||||
void ClearRenderTargetDepthStencil(
|
void ClearRenderTargetDepthStencil(
|
||||||
|
|
|
@ -18,8 +18,6 @@ namespace Ryujinx.Graphics.GAL
|
||||||
ISampler CreateSampler(SamplerCreateInfo info);
|
ISampler CreateSampler(SamplerCreateInfo info);
|
||||||
ITexture CreateTexture(TextureCreateInfo info);
|
ITexture CreateTexture(TextureCreateInfo info);
|
||||||
|
|
||||||
void FlushPipelines();
|
|
||||||
|
|
||||||
Capabilities GetCapabilities();
|
Capabilities GetCapabilities();
|
||||||
|
|
||||||
ulong GetCounter(CounterType type);
|
ulong GetCounter(CounterType type);
|
||||||
|
|
|
@ -11,6 +11,6 @@ namespace Ryujinx.Graphics.GAL
|
||||||
|
|
||||||
byte[] GetData();
|
byte[] GetData();
|
||||||
|
|
||||||
void SetData(Span<byte> data);
|
void SetData(ReadOnlySpan<byte> data);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -77,7 +77,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
sbDescAddress += (ulong)sbDescOffset;
|
sbDescAddress += (ulong)sbDescOffset;
|
||||||
|
|
||||||
Span<byte> sbDescriptorData = _context.PhysicalMemory.Read(sbDescAddress, 0x10);
|
ReadOnlySpan<byte> sbDescriptorData = _context.PhysicalMemory.GetSpan(sbDescAddress, 0x10);
|
||||||
|
|
||||||
SbDescriptor sbDescriptor = MemoryMarshal.Cast<byte, SbDescriptor>(sbDescriptorData)[0];
|
SbDescriptor sbDescriptor = MemoryMarshal.Cast<byte, SbDescriptor>(sbDescriptorData)[0];
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
ulong srcAddress = srcBaseAddress + (ulong)srcOffset;
|
ulong srcAddress = srcBaseAddress + (ulong)srcOffset;
|
||||||
ulong dstAddress = dstBaseAddress + (ulong)dstOffset;
|
ulong dstAddress = dstBaseAddress + (ulong)dstOffset;
|
||||||
|
|
||||||
Span<byte> pixel = _context.PhysicalMemory.Read(srcAddress, (ulong)srcBpp);
|
ReadOnlySpan<byte> pixel = _context.PhysicalMemory.GetSpan(srcAddress, (ulong)srcBpp);
|
||||||
|
|
||||||
_context.PhysicalMemory.Write(dstAddress, pixel);
|
_context.PhysicalMemory.Write(dstAddress, pixel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,7 +235,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
sbDescAddress += (ulong)sbDescOffset;
|
sbDescAddress += (ulong)sbDescOffset;
|
||||||
|
|
||||||
Span<byte> sbDescriptorData = _context.PhysicalMemory.Read(sbDescAddress, 0x10);
|
ReadOnlySpan<byte> sbDescriptorData = _context.PhysicalMemory.GetSpan(sbDescAddress, 0x10);
|
||||||
|
|
||||||
SbDescriptor sbDescriptor = MemoryMarshal.Cast<byte, SbDescriptor>(sbDescriptorData)[0];
|
SbDescriptor sbDescriptor = MemoryMarshal.Cast<byte, SbDescriptor>(sbDescriptorData)[0];
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
{
|
{
|
||||||
ulong address = Address + (ulong)(uint)id * DescriptorSize;
|
ulong address = Address + (ulong)(uint)id * DescriptorSize;
|
||||||
|
|
||||||
Span<byte> data = Context.PhysicalMemory.Read(address, DescriptorSize);
|
ReadOnlySpan<byte> data = Context.PhysicalMemory.GetSpan(address, DescriptorSize);
|
||||||
|
|
||||||
SamplerDescriptor descriptor = MemoryMarshal.Cast<byte, SamplerDescriptor>(data)[0];
|
SamplerDescriptor descriptor = MemoryMarshal.Cast<byte, SamplerDescriptor>(data)[0];
|
||||||
|
|
||||||
|
|
|
@ -304,7 +304,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Span<byte> data = _context.PhysicalMemory.Read(Address, Size);
|
ReadOnlySpan<byte> data = _context.PhysicalMemory.GetSpan(Address, Size);
|
||||||
|
|
||||||
if (Info.IsLinear)
|
if (Info.IsLinear)
|
||||||
{
|
{
|
||||||
|
|
|
@ -197,7 +197,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
address = bufferManager.GetGraphicsUniformBufferAddress(stageIndex, binding.CbufSlot);
|
address = bufferManager.GetGraphicsUniformBufferAddress(stageIndex, binding.CbufSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
packedId = MemoryMarshal.Cast<byte, int>(_context.PhysicalMemory.Read(address + (ulong)binding.CbufOffset * 4, 4))[0];
|
packedId = MemoryMarshal.Cast<byte, int>(_context.PhysicalMemory.GetSpan(address + (ulong)binding.CbufOffset * 4, 4))[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -321,7 +321,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
address += (uint)wordOffset * 4;
|
address += (uint)wordOffset * 4;
|
||||||
|
|
||||||
return BitConverter.ToInt32(_context.PhysicalMemory.Read(address, 4));
|
return BitConverter.ToInt32(_context.PhysicalMemory.GetSpan(address, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -85,7 +85,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
{
|
{
|
||||||
ulong address = Address + (ulong)(uint)id * DescriptorSize;
|
ulong address = Address + (ulong)(uint)id * DescriptorSize;
|
||||||
|
|
||||||
Span<byte> data = Context.PhysicalMemory.Read(address, DescriptorSize);
|
ReadOnlySpan<byte> data = Context.PhysicalMemory.GetSpan(address, DescriptorSize);
|
||||||
|
|
||||||
return MemoryMarshal.Cast<byte, TextureDescriptor>(data)[0];
|
return MemoryMarshal.Cast<byte, TextureDescriptor>(data)[0];
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
if (texture != null)
|
if (texture != null)
|
||||||
{
|
{
|
||||||
Span<byte> data = Context.PhysicalMemory.Read(address, DescriptorSize);
|
ReadOnlySpan<byte> data = Context.PhysicalMemory.GetSpan(address, DescriptorSize);
|
||||||
|
|
||||||
TextureDescriptor descriptor = MemoryMarshal.Cast<byte, TextureDescriptor>(data)[0];
|
TextureDescriptor descriptor = MemoryMarshal.Cast<byte, TextureDescriptor>(data)[0];
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
|
|
||||||
int offset = (int)(mAddress - Address);
|
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
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Invalidate()
|
public void Invalidate()
|
||||||
{
|
{
|
||||||
HostBuffer.SetData(0, _context.PhysicalMemory.Read(Address, Size));
|
HostBuffer.SetData(0, _context.PhysicalMemory.GetSpan(Address, Size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -27,23 +27,23 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
/// <returns>Byte array with the data</returns>
|
/// <returns>Byte array with the data</returns>
|
||||||
public byte[] ReadBytes(ulong gpuVa, ulong size)
|
public byte[] ReadBytes(ulong gpuVa, ulong size)
|
||||||
{
|
{
|
||||||
return Read(gpuVa, size).ToArray();
|
return GetSpan(gpuVa, size).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 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.
|
/// This reads as much data as possible, up to the specified maximum size.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="gpuVa">GPU virtual address where the data is located</param>
|
/// <param name="gpuVa">GPU virtual address where the data is located</param>
|
||||||
/// <param name="maxSize">Maximum size of the data</param>
|
/// <param name="maxSize">Maximum size of the data</param>
|
||||||
/// <returns>The data at the specified memory location</returns>
|
/// <returns>The span of the data at the specified memory location</returns>
|
||||||
public Span<byte> Read(ulong gpuVa, ulong maxSize)
|
public ReadOnlySpan<byte> GetSpan(ulong gpuVa, ulong maxSize)
|
||||||
{
|
{
|
||||||
ulong processVa = _context.MemoryManager.Translate(gpuVa);
|
ulong processVa = _context.MemoryManager.Translate(gpuVa);
|
||||||
|
|
||||||
ulong size = Math.Min(_context.MemoryManager.GetSubSize(gpuVa), maxSize);
|
ulong size = Math.Min(_context.MemoryManager.GetSubSize(gpuVa), maxSize);
|
||||||
|
|
||||||
return _context.PhysicalMemory.Read(processVa, size);
|
return _context.PhysicalMemory.GetSpan(processVa, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
|
|
||||||
ulong size = (uint)Marshal.SizeOf<T>();
|
ulong size = (uint)Marshal.SizeOf<T>();
|
||||||
|
|
||||||
return MemoryMarshal.Cast<byte, T>(_context.PhysicalMemory.Read(processVa, size))[0];
|
return MemoryMarshal.Cast<byte, T>(_context.PhysicalMemory.GetSpan(processVa, size))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -70,7 +70,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
{
|
{
|
||||||
ulong processVa = _context.MemoryManager.Translate(gpuVa);
|
ulong processVa = _context.MemoryManager.Translate(gpuVa);
|
||||||
|
|
||||||
return BitConverter.ToInt32(_context.PhysicalMemory.Read(processVa, 4));
|
return BitConverter.ToInt32(_context.PhysicalMemory.GetSpan(processVa, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -82,7 +82,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
{
|
{
|
||||||
ulong processVa = _context.MemoryManager.Translate(gpuVa);
|
ulong processVa = _context.MemoryManager.Translate(gpuVa);
|
||||||
|
|
||||||
return BitConverter.ToUInt64(_context.PhysicalMemory.Read(processVa, 8));
|
return BitConverter.ToUInt64(_context.PhysicalMemory.GetSpan(processVa, 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -22,14 +22,14 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads data from the application process.
|
/// Gets a span of data from the application process.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="address">Address to be read</param>
|
/// <param name="address">Start address of the range</param>
|
||||||
/// <param name="size">Size in bytes to be read</param>
|
/// <param name="size">Size in bytes to be range</param>
|
||||||
/// <returns>The data at the specified memory location</returns>
|
/// <returns>A read only span of the data at the specified memory location</returns>
|
||||||
public Span<byte> Read(ulong address, ulong size)
|
public ReadOnlySpan<byte> GetSpan(ulong address, ulong size)
|
||||||
{
|
{
|
||||||
return _cpuMemory.ReadBytes((long)address, (long)size);
|
return _cpuMemory.GetSpan(address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="address">Address to write into</param>
|
/// <param name="address">Address to write into</param>
|
||||||
/// <param name="data">Data to be written</param>
|
/// <param name="data">Data to be written</param>
|
||||||
public void Write(ulong address, Span<byte> data)
|
public void Write(ulong address, ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
_cpuMemory.WriteBytes((long)address, data.ToArray());
|
_cpuMemory.WriteBytes((long)address, data.ToArray());
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,7 +154,7 @@ namespace Ryujinx.Graphics.Gpu
|
||||||
{
|
{
|
||||||
_context.Methods.PerformDeferredDraws();
|
_context.Methods.PerformDeferredDraws();
|
||||||
|
|
||||||
_context.Renderer.FlushPipelines();
|
_context.Renderer.Pipeline.Barrier();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,7 +265,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
|
|
||||||
ShaderProgram program;
|
ShaderProgram program;
|
||||||
|
|
||||||
Span<byte> code = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize);
|
ReadOnlySpan<byte> code = _context.MemoryAccessor.GetSpan(gpuVa, MaxProgramSize);
|
||||||
|
|
||||||
program = Translator.Translate(code, callbacks, DefaultFlags | TranslationFlags.Compute);
|
program = Translator.Translate(code, callbacks, DefaultFlags | TranslationFlags.Compute);
|
||||||
|
|
||||||
|
@ -319,8 +319,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
|
|
||||||
if (gpuVaA != 0)
|
if (gpuVaA != 0)
|
||||||
{
|
{
|
||||||
Span<byte> codeA = _context.MemoryAccessor.Read(gpuVaA, MaxProgramSize);
|
ReadOnlySpan<byte> codeA = _context.MemoryAccessor.GetSpan(gpuVaA, MaxProgramSize);
|
||||||
Span<byte> codeB = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize);
|
ReadOnlySpan<byte> codeB = _context.MemoryAccessor.GetSpan(gpuVa, MaxProgramSize);
|
||||||
|
|
||||||
program = Translator.Translate(codeA, codeB, callbacks, DefaultFlags);
|
program = Translator.Translate(codeA, codeB, callbacks, DefaultFlags);
|
||||||
|
|
||||||
|
@ -340,7 +340,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Span<byte> code = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize);
|
ReadOnlySpan<byte> code = _context.MemoryAccessor.GetSpan(gpuVa, MaxProgramSize);
|
||||||
|
|
||||||
program = Translator.Translate(code, callbacks, DefaultFlags);
|
program = Translator.Translate(code, callbacks, DefaultFlags);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// <param name="compute">True for compute shader code, false for graphics shader code</param>
|
/// <param name="compute">True for compute shader code, false for graphics shader code</param>
|
||||||
/// <param name="fullPath">Output path for the shader code with header included</param>
|
/// <param name="fullPath">Output path for the shader code with header included</param>
|
||||||
/// <param name="codePath">Output path for the shader code without header</param>
|
/// <param name="codePath">Output path for the shader code without header</param>
|
||||||
public void Dump(Span<byte> code, bool compute, out string fullPath, out string codePath)
|
public void Dump(ReadOnlySpan<byte> code, bool compute, out string fullPath, out string codePath)
|
||||||
{
|
{
|
||||||
_dumpPath = GraphicsConfig.ShadersDumpPath;
|
_dumpPath = GraphicsConfig.ShadersDumpPath;
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetData(Span<byte> data)
|
public void SetData(ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
|
@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetData(int offset, Span<byte> data)
|
public void SetData(int offset, ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
GL.BindBuffer(BufferTarget.CopyWriteBuffer, Handle);
|
GL.BindBuffer(BufferTarget.CopyWriteBuffer, Handle);
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,11 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
_clipDepthMode = ClipDepthMode.NegativeOneToOne;
|
_clipDepthMode = ClipDepthMode.NegativeOneToOne;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Barrier()
|
||||||
|
{
|
||||||
|
GL.MemoryBarrier(MemoryBarrierFlags.AllBarrierBits);
|
||||||
|
}
|
||||||
|
|
||||||
public void ClearRenderTargetColor(int index, uint componentMask, ColorF color)
|
public void ClearRenderTargetColor(int index, uint componentMask, ColorF color)
|
||||||
{
|
{
|
||||||
GL.ColorMask(
|
GL.ColorMask(
|
||||||
|
@ -165,9 +170,17 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
int firstVertex,
|
int firstVertex,
|
||||||
int firstInstance)
|
int firstInstance)
|
||||||
{
|
{
|
||||||
// TODO: Instanced rendering.
|
|
||||||
int quadsCount = (vertexCount - 2) / 2;
|
int quadsCount = (vertexCount - 2) / 2;
|
||||||
|
|
||||||
|
if (firstInstance != 0 || instanceCount != 1)
|
||||||
|
{
|
||||||
|
for (int quadIndex = 0; quadIndex < quadsCount; quadIndex++)
|
||||||
|
{
|
||||||
|
GL.DrawArraysInstancedBaseInstance(PrimitiveType.TriangleFan, firstVertex + quadIndex * 2, 4, instanceCount, firstInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
int[] firsts = new int[quadsCount];
|
int[] firsts = new int[quadsCount];
|
||||||
int[] counts = new int[quadsCount];
|
int[] counts = new int[quadsCount];
|
||||||
|
|
||||||
|
@ -186,6 +199,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
counts,
|
counts,
|
||||||
quadsCount);
|
quadsCount);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawImpl(
|
private void DrawImpl(
|
||||||
int vertexCount,
|
int vertexCount,
|
||||||
|
@ -277,9 +291,52 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
int firstVertex,
|
int firstVertex,
|
||||||
int firstInstance)
|
int firstInstance)
|
||||||
{
|
{
|
||||||
// TODO: Instanced rendering.
|
|
||||||
int quadsCount = indexCount / 4;
|
int quadsCount = indexCount / 4;
|
||||||
|
|
||||||
|
if (firstInstance != 0 || instanceCount != 1)
|
||||||
|
{
|
||||||
|
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];
|
IntPtr[] indices = new IntPtr[quadsCount];
|
||||||
|
|
||||||
int[] counts = new int[quadsCount];
|
int[] counts = new int[quadsCount];
|
||||||
|
@ -303,6 +360,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
quadsCount,
|
quadsCount,
|
||||||
baseVertices);
|
baseVertices);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawQuadStripIndexedImpl(
|
private void DrawQuadStripIndexedImpl(
|
||||||
int indexCount,
|
int indexCount,
|
||||||
|
|
|
@ -55,11 +55,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
return new TextureStorage(this, info).CreateDefaultView();
|
return new TextureStorage(this, info).CreateDefaultView();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FlushPipelines()
|
|
||||||
{
|
|
||||||
GL.Finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Capabilities GetCapabilities()
|
public Capabilities GetCapabilities()
|
||||||
{
|
{
|
||||||
return new Capabilities(
|
return new Capabilities(
|
||||||
|
|
|
@ -217,7 +217,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetData(Span<byte> data)
|
public void SetData(ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
_opActivators = new ConcurrentDictionary<Type, OpActivator>();
|
_opActivators = new ConcurrentDictionary<Type, OpActivator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Block[] Decode(Span<byte> code, ulong headerSize)
|
public static Block[] Decode(ReadOnlySpan<byte> code, ulong headerSize)
|
||||||
{
|
{
|
||||||
List<Block> blocks = new List<Block>();
|
List<Block> blocks = new List<Block>();
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void FillBlock(
|
private static void FillBlock(
|
||||||
Span<byte> code,
|
ReadOnlySpan<byte> code,
|
||||||
Block block,
|
Block block,
|
||||||
ulong limitAddress,
|
ulong limitAddress,
|
||||||
ulong startAddress)
|
ulong startAddress)
|
||||||
|
|
|
@ -76,9 +76,9 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
public bool OmapSampleMask { get; }
|
public bool OmapSampleMask { get; }
|
||||||
public bool OmapDepth { get; }
|
public bool OmapDepth { get; }
|
||||||
|
|
||||||
public ShaderHeader(Span<byte> code)
|
public ShaderHeader(ReadOnlySpan<byte> code)
|
||||||
{
|
{
|
||||||
Span<int> header = MemoryMarshal.Cast<byte, int>(code);
|
ReadOnlySpan<int> header = MemoryMarshal.Cast<byte, int>(code);
|
||||||
|
|
||||||
int commonWord0 = header[0];
|
int commonWord0 = header[0];
|
||||||
int commonWord1 = header[1];
|
int commonWord1 = header[1];
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
{
|
{
|
||||||
private const int HeaderSize = 0x50;
|
private const int HeaderSize = 0x50;
|
||||||
|
|
||||||
public static Span<byte> ExtractCode(Span<byte> code, bool compute, out int headerSize)
|
public static ReadOnlySpan<byte> ExtractCode(ReadOnlySpan<byte> code, bool compute, out int headerSize)
|
||||||
{
|
{
|
||||||
headerSize = compute ? 0 : HeaderSize;
|
headerSize = compute ? 0 : HeaderSize;
|
||||||
|
|
||||||
|
@ -38,14 +38,14 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
return code.Slice(0, headerSize + (int)endAddress);
|
return code.Slice(0, headerSize + (int)endAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ShaderProgram Translate(Span<byte> code, TranslatorCallbacks callbacks, TranslationFlags flags)
|
public static ShaderProgram Translate(ReadOnlySpan<byte> code, TranslatorCallbacks callbacks, TranslationFlags flags)
|
||||||
{
|
{
|
||||||
Operation[] ops = DecodeShader(code, callbacks, flags, out ShaderConfig config, out int size);
|
Operation[] ops = DecodeShader(code, callbacks, flags, out ShaderConfig config, out int size);
|
||||||
|
|
||||||
return Translate(ops, config, size);
|
return Translate(ops, config, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ShaderProgram Translate(Span<byte> vpACode, Span<byte> vpBCode, TranslatorCallbacks callbacks, TranslationFlags flags)
|
public static ShaderProgram Translate(ReadOnlySpan<byte> vpACode, ReadOnlySpan<byte> vpBCode, TranslatorCallbacks callbacks, TranslationFlags flags)
|
||||||
{
|
{
|
||||||
Operation[] vpAOps = DecodeShader(vpACode, callbacks, flags, out _, out _);
|
Operation[] vpAOps = DecodeShader(vpACode, callbacks, flags, out _, out _);
|
||||||
Operation[] vpBOps = DecodeShader(vpBCode, callbacks, flags, out ShaderConfig config, out int sizeB);
|
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(
|
private static Operation[] DecodeShader(
|
||||||
Span<byte> code,
|
ReadOnlySpan<byte> code,
|
||||||
TranslatorCallbacks callbacks,
|
TranslatorCallbacks callbacks,
|
||||||
TranslationFlags flags,
|
TranslationFlags flags,
|
||||||
out ShaderConfig config,
|
out ShaderConfig config,
|
||||||
|
|
|
@ -28,6 +28,8 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||||
|
|
||||||
private Switch _device;
|
private Switch _device;
|
||||||
|
|
||||||
|
private readonly object _lock = new object();
|
||||||
|
|
||||||
public ContentManager(Switch device)
|
public ContentManager(Switch device)
|
||||||
{
|
{
|
||||||
_contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>();
|
_contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>();
|
||||||
|
@ -57,6 +59,8 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadEntries(bool ignoreMissingFonts = false)
|
public void LoadEntries(bool ignoreMissingFonts = false)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
_contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>();
|
_contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>();
|
||||||
_locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
|
_locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
|
||||||
|
@ -93,7 +97,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||||
{
|
{
|
||||||
string ncaName = new DirectoryInfo(directoryPath).Name.Replace(".nca", string.Empty);
|
string ncaName = new DirectoryInfo(directoryPath).Name.Replace(".nca", string.Empty);
|
||||||
|
|
||||||
using (FileStream ncaFile = new FileStream(Directory.GetFiles(directoryPath)[0], FileMode.Open, FileAccess.Read))
|
using (FileStream ncaFile = File.OpenRead(Directory.GetFiles(directoryPath)[0]))
|
||||||
{
|
{
|
||||||
Nca nca = new Nca(_device.System.KeySet, ncaFile.AsStorage());
|
Nca nca = new Nca(_device.System.KeySet, ncaFile.AsStorage());
|
||||||
|
|
||||||
|
@ -156,13 +160,19 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||||
|
|
||||||
_device.System.Font.Initialize(this, ignoreMissingFonts);
|
_device.System.Font.Initialize(this, ignoreMissingFonts);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void ClearEntry(long titleId, NcaContentType contentType, StorageId storageId)
|
public void ClearEntry(long titleId, NcaContentType contentType, StorageId storageId)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
RemoveLocationEntry(titleId, contentType, storageId);
|
RemoveLocationEntry(titleId, contentType, storageId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void RefreshEntries(StorageId storageId, int flag)
|
public void RefreshEntries(StorageId storageId, int flag)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
LinkedList<LocationEntry> locationList = _locationEntries[storageId];
|
LinkedList<LocationEntry> locationList = _locationEntries[storageId];
|
||||||
LinkedListNode<LocationEntry> locationEntry = locationList.First;
|
LinkedListNode<LocationEntry> locationEntry = locationList.First;
|
||||||
|
@ -179,8 +189,11 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||||
locationEntry = nextLocationEntry;
|
locationEntry = nextLocationEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool HasNca(string ncaId, StorageId storageId)
|
public bool HasNca(string ncaId, StorageId storageId)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
if (_contentDictionary.ContainsValue(ncaId))
|
if (_contentDictionary.ContainsValue(ncaId))
|
||||||
{
|
{
|
||||||
|
@ -192,29 +205,38 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||||
|
|
||||||
return storage == storageId;
|
return storage == storageId;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UInt128 GetInstalledNcaId(long titleId, NcaContentType contentType)
|
public UInt128 GetInstalledNcaId(long titleId, NcaContentType contentType)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
if (_contentDictionary.ContainsKey(((ulong)titleId, contentType)))
|
if (_contentDictionary.ContainsKey(((ulong)titleId, contentType)))
|
||||||
{
|
{
|
||||||
return new UInt128(_contentDictionary[((ulong)titleId, contentType)]);
|
return new UInt128(_contentDictionary[((ulong)titleId, contentType)]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new UInt128();
|
return new UInt128();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StorageId GetInstalledStorage(long titleId, NcaContentType contentType, StorageId storageId)
|
public StorageId GetInstalledStorage(long titleId, NcaContentType contentType, StorageId storageId)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId);
|
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId);
|
||||||
|
|
||||||
return locationEntry.ContentPath != null ?
|
return locationEntry.ContentPath != null ?
|
||||||
LocationHelper.GetStorageId(locationEntry.ContentPath) : StorageId.None;
|
LocationHelper.GetStorageId(locationEntry.ContentPath) : StorageId.None;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string GetInstalledContentPath(long titleId, StorageId storageId, NcaContentType contentType)
|
public string GetInstalledContentPath(long titleId, StorageId storageId, NcaContentType contentType)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId);
|
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId);
|
||||||
|
|
||||||
|
@ -222,11 +244,14 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||||
{
|
{
|
||||||
return locationEntry.ContentPath;
|
return locationEntry.ContentPath;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RedirectLocation(LocationEntry newEntry, StorageId storageId)
|
public void RedirectLocation(LocationEntry newEntry, StorageId storageId)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
LocationEntry locationEntry = GetLocation(newEntry.TitleId, newEntry.ContentType, storageId);
|
LocationEntry locationEntry = GetLocation(newEntry.TitleId, newEntry.ContentType, storageId);
|
||||||
|
|
||||||
|
@ -237,6 +262,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||||
|
|
||||||
AddLocationEntry(newEntry, storageId);
|
AddLocationEntry(newEntry, storageId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool VerifyContentType(LocationEntry locationEntry, NcaContentType contentType)
|
private bool VerifyContentType(LocationEntry locationEntry, NcaContentType contentType)
|
||||||
{
|
{
|
||||||
|
@ -827,6 +853,8 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||||
{
|
{
|
||||||
LoadEntries(true);
|
LoadEntries(true);
|
||||||
|
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
var locationEnties = _locationEntries[StorageId.NandSystem];
|
var locationEnties = _locationEntries[StorageId.NandSystem];
|
||||||
|
|
||||||
foreach (var entry in locationEnties)
|
foreach (var entry in locationEnties)
|
||||||
|
@ -835,9 +863,9 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||||
{
|
{
|
||||||
var path = _device.FileSystem.SwitchPathToSystemPath(entry.ContentPath);
|
var path = _device.FileSystem.SwitchPathToSystemPath(entry.ContentPath);
|
||||||
|
|
||||||
using (IStorage ncaStorage = File.Open(path, FileMode.Open).AsStorage())
|
using (FileStream fileStream = File.OpenRead(path))
|
||||||
{
|
{
|
||||||
Nca nca = new Nca(_device.System.KeySet, ncaStorage);
|
Nca nca = new Nca(_device.System.KeySet, fileStream.AsStorage());
|
||||||
|
|
||||||
if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data)
|
if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data)
|
||||||
{
|
{
|
||||||
|
@ -852,6 +880,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
|
||||||
|
|
||||||
_keepRunning = true;
|
_keepRunning = true;
|
||||||
|
|
||||||
Thread work = new Thread(WaitAndCheckScheduledObjects);
|
Thread work = new Thread(WaitAndCheckScheduledObjects)
|
||||||
|
{
|
||||||
|
Name = "HLE.TimeManager"
|
||||||
|
};
|
||||||
|
|
||||||
work.Start();
|
work.Start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||||
|
|
||||||
public void StartAutoPreemptionThread()
|
public void StartAutoPreemptionThread()
|
||||||
{
|
{
|
||||||
Thread preemptionThread = new Thread(PreemptCurrentThread);
|
Thread preemptionThread = new Thread(PreemptCurrentThread)
|
||||||
|
{
|
||||||
|
Name = "HLE.PreemptionThread"
|
||||||
|
};
|
||||||
|
|
||||||
_keepPreempting = true;
|
_keepPreempting = true;
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||||
is64Bits = true;
|
is64Bits = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
HostThread = new Thread(customHostThreadStart == null ? () => ThreadStart(entrypoint) : customHostThreadStart);
|
HostThread = new Thread(customHostThreadStart ?? (() => ThreadStart(entrypoint)));
|
||||||
|
|
||||||
Context = new ARMeilleure.State.ExecutionContext();
|
Context = new ARMeilleure.State.ExecutionContext();
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||||
|
|
||||||
ThreadUid = System.GetThreadUid();
|
ThreadUid = System.GetThreadUid();
|
||||||
|
|
||||||
HostThread.Name = $"Host Thread (thread id {ThreadUid})";
|
HostThread.Name = $"HLE.HostThread.{ThreadUid}";
|
||||||
|
|
||||||
_hasBeenInitialized = true;
|
_hasBeenInitialized = true;
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,10 @@ namespace Ryujinx.Profiler
|
||||||
_cleanupRunning = true;
|
_cleanupRunning = true;
|
||||||
|
|
||||||
// Create cleanup thread.
|
// Create cleanup thread.
|
||||||
_cleanupThread = new Thread(CleanupLoop);
|
_cleanupThread = new Thread(CleanupLoop)
|
||||||
|
{
|
||||||
|
Name = "Profiler.CleanupThread"
|
||||||
|
};
|
||||||
_cleanupThread.Start();
|
_cleanupThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,10 @@ namespace Ryujinx.Profiler.UI
|
||||||
{
|
{
|
||||||
_profilerRunning = true;
|
_profilerRunning = true;
|
||||||
_prevTime = 0;
|
_prevTime = 0;
|
||||||
_profileThread = new Thread(ProfileLoop);
|
_profileThread = new Thread(ProfileLoop)
|
||||||
|
{
|
||||||
|
Name = "Profiler.ProfileThread"
|
||||||
|
};
|
||||||
_profileThread.Start();
|
_profileThread.Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +63,10 @@ namespace Ryujinx.Profiler.UI
|
||||||
using (_window = new ProfileWindow())
|
using (_window = new ProfileWindow())
|
||||||
{
|
{
|
||||||
// Create thread for render loop
|
// Create thread for render loop
|
||||||
_renderThread = new Thread(RenderLoop);
|
_renderThread = new Thread(RenderLoop)
|
||||||
|
{
|
||||||
|
Name = "Profiler.RenderThread"
|
||||||
|
};
|
||||||
_renderThread.Start();
|
_renderThread.Start();
|
||||||
|
|
||||||
while (_profilerRunning)
|
while (_profilerRunning)
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
namespace Ryujinx.Ui
|
|
||||||
{
|
|
||||||
internal struct AboutInfo
|
|
||||||
{
|
|
||||||
public string InstallVersion;
|
|
||||||
public string InstallCommit;
|
|
||||||
public string InstallBranch;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,8 +13,6 @@ namespace Ryujinx.Ui
|
||||||
{
|
{
|
||||||
public class AboutWindow : Window
|
public class AboutWindow : Window
|
||||||
{
|
{
|
||||||
private static AboutInfo AboutInformation { get; set; }
|
|
||||||
|
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
#pragma warning disable IDE0044
|
#pragma warning disable IDE0044
|
||||||
[GUI] Window _aboutWin;
|
[GUI] Window _aboutWin;
|
||||||
|
|
|
@ -120,7 +120,10 @@ namespace Ryujinx.Ui
|
||||||
Context.MakeCurrent(null);
|
Context.MakeCurrent(null);
|
||||||
|
|
||||||
// OpenTK doesn't like sleeps in its thread, to avoid this a renderer thread is created
|
// 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();
|
_renderThread.Start();
|
||||||
|
|
||||||
|
|
|
@ -656,6 +656,7 @@ namespace Ryujinx.Ui
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
thread.Name = "GUI.FirmwareInstallerThread";
|
||||||
thread.Start();
|
thread.Start();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue