Merge branch 'master' into aot

This commit is contained in:
LDj3SNuD 2020-01-13 01:47:46 +01:00
commit 7d0d9703a1
41 changed files with 402 additions and 255 deletions

View file

@ -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);

View file

@ -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();
} }

View file

@ -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();
} }

View file

@ -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)

View file

@ -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;
} }

View file

@ -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));
} }
} }

View file

@ -57,6 +57,7 @@ namespace Ryujinx.Common.Logging
} }
}); });
_messageThread.Name = "Logger.MessageThread";
_messageThread.IsBackground = true; _messageThread.IsBackground = true;
_messageThread.Start(); _messageThread.Start();
} }

View file

@ -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);
} }
} }

View file

@ -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(

View file

@ -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);

View file

@ -11,6 +11,6 @@ namespace Ryujinx.Graphics.GAL
byte[] GetData(); byte[] GetData();
void SetData(Span<byte> data); void SetData(ReadOnlySpan<byte> data);
} }
} }

View file

@ -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];

View file

@ -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);
} }

View file

@ -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];

View file

@ -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];

View file

@ -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)
{ {

View file

@ -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>

View file

@ -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];

View file

@ -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>

View file

@ -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>

View file

@ -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());
} }

View file

@ -154,7 +154,7 @@ namespace Ryujinx.Graphics.Gpu
{ {
_context.Methods.PerformDeferredDraws(); _context.Methods.PerformDeferredDraws();
_context.Renderer.FlushPipelines(); _context.Renderer.Pipeline.Barrier();
break; break;
} }

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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,

View file

@ -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(

View file

@ -217,7 +217,7 @@ namespace Ryujinx.Graphics.OpenGL
} }
} }
public void SetData(Span<byte> data) public void SetData(ReadOnlySpan<byte> data)
{ {
unsafe unsafe
{ {

View file

@ -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)

View file

@ -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];

View file

@ -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,

View file

@ -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;
} }

View file

@ -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();
} }

View file

@ -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;

View file

@ -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;

View file

@ -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();
} }

View file

@ -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)

View file

@ -1,9 +0,0 @@
namespace Ryujinx.Ui
{
internal struct AboutInfo
{
public string InstallVersion;
public string InstallCommit;
public string InstallBranch;
}
}

View file

@ -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;

View file

@ -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();

View file

@ -656,6 +656,7 @@ namespace Ryujinx.Ui
} }
}); });
thread.Name = "GUI.FirmwareInstallerThread";
thread.Start(); thread.Start();
} }
else else