Add a GetSpan method to the memory manager and use it on GPU (#877)

This commit is contained in:
gdkchan 2020-01-12 20:27:50 -03:00 committed by jduncanator
parent 8b90924c1e
commit b8e3909d80
20 changed files with 93 additions and 48 deletions

View file

@ -77,7 +77,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
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];

View file

@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
ulong srcAddress = srcBaseAddress + (ulong)srcOffset;
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);
}

View file

@ -235,7 +235,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
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];

View file

@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{
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];

View file

@ -304,7 +304,7 @@ namespace Ryujinx.Graphics.Gpu.Image
return;
}
Span<byte> data = _context.PhysicalMemory.Read(Address, Size);
ReadOnlySpan<byte> data = _context.PhysicalMemory.GetSpan(Address, Size);
if (Info.IsLinear)
{

View file

@ -197,7 +197,7 @@ namespace Ryujinx.Graphics.Gpu.Image
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
{
@ -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));
}
/// <summary>

View file

@ -85,7 +85,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{
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];
}
@ -107,7 +107,7 @@ namespace Ryujinx.Graphics.Gpu.Image
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];

View file

@ -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
/// </summary>
public void Invalidate()
{
HostBuffer.SetData(0, _context.PhysicalMemory.Read(Address, Size));
HostBuffer.SetData(0, _context.PhysicalMemory.GetSpan(Address, Size));
}
/// <summary>

View file

@ -27,23 +27,23 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// <returns>Byte array with the data</returns>
public byte[] ReadBytes(ulong gpuVa, ulong size)
{
return Read(gpuVa, size).ToArray();
return GetSpan(gpuVa, size).ToArray();
}
/// <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.
/// </summary>
/// <param name="gpuVa">GPU virtual address where the data is located</param>
/// <param name="maxSize">Maximum size of the data</param>
/// <returns>The data at the specified memory location</returns>
public Span<byte> Read(ulong gpuVa, ulong maxSize)
/// <returns>The span of the data at the specified memory location</returns>
public ReadOnlySpan<byte> 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);
}
/// <summary>
@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
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>
@ -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));
}
/// <summary>
@ -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));
}
/// <summary>

View file

@ -22,14 +22,14 @@ namespace Ryujinx.Graphics.Gpu.Memory
}
/// <summary>
/// Reads data from the application process.
/// Gets a span of data from the application process.
/// </summary>
/// <param name="address">Address to be read</param>
/// <param name="size">Size in bytes to be read</param>
/// <returns>The data at the specified memory location</returns>
public Span<byte> Read(ulong address, ulong size)
/// <param name="address">Start address of the range</param>
/// <param name="size">Size in bytes to be range</param>
/// <returns>A read only span of the data at the specified memory location</returns>
public ReadOnlySpan<byte> GetSpan(ulong address, ulong size)
{
return _cpuMemory.ReadBytes((long)address, (long)size);
return _cpuMemory.GetSpan(address, size);
}
/// <summary>
@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// </summary>
/// <param name="address">Address to write into</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());
}

View file

@ -265,7 +265,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
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);
@ -319,8 +319,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
if (gpuVaA != 0)
{
Span<byte> codeA = _context.MemoryAccessor.Read(gpuVaA, MaxProgramSize);
Span<byte> codeB = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize);
ReadOnlySpan<byte> codeA = _context.MemoryAccessor.GetSpan(gpuVaA, MaxProgramSize);
ReadOnlySpan<byte> codeB = _context.MemoryAccessor.GetSpan(gpuVa, MaxProgramSize);
program = Translator.Translate(codeA, codeB, callbacks, DefaultFlags);
@ -340,7 +340,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
}
else
{
Span<byte> code = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize);
ReadOnlySpan<byte> code = _context.MemoryAccessor.GetSpan(gpuVa, MaxProgramSize);
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="fullPath">Output path for the shader code with header included</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;