mirror of
https://github.com/ryujinx-mirror/ryujinx.git
synced 2024-11-25 03:25:13 +00:00
replace ByteMemoryPool usage in Ryujinx.Graphics (#7129)
* chore: replace `ByteMemoryPool` usage with `MemoryOwner<byte>` * refactor: `PixelConverter.ConvertR4G4ToR4G4B4A4()` - rename old `outputSpan` to `outputSpanUInt16`, reuse same output `Span<byte>` as newly-freed name `outputSpan` * eliminate temporary buffer allocations * chore, perf: use MemoryOwner<byte> instead of IMemoryOwner<byte>
This commit is contained in:
parent
83fda10f6e
commit
59ddb26628
13 changed files with 73 additions and 80 deletions
|
@ -1,7 +1,6 @@
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
@ -145,9 +144,9 @@ namespace Ryujinx.Graphics.Device
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IMemoryOwner<byte> memoryOwner = ByteMemoryPool.Rent(size);
|
MemoryOwner<byte> memoryOwner = MemoryOwner<byte>.Rent(size);
|
||||||
|
|
||||||
GetSpan(va, size).CopyTo(memoryOwner.Memory.Span);
|
ReadImpl(va, memoryOwner.Span);
|
||||||
|
|
||||||
return new WritableRegion(this, va, memoryOwner, tracked: true);
|
return new WritableRegion(this, va, memoryOwner, tracked: true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,7 +199,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
||||||
if (target != null)
|
if (target != null)
|
||||||
{
|
{
|
||||||
target.SynchronizeMemory();
|
target.SynchronizeMemory();
|
||||||
var dataCopy = ByteMemoryPool.RentCopy(data);
|
var dataCopy = MemoryOwner<byte>.RentCopy(data);
|
||||||
target.SetData(dataCopy, 0, 0, new GAL.Rectangle<int>(_dstX, _dstY, _lineLengthIn / target.Info.FormatInfo.BytesPerPixel, _lineCount));
|
target.SetData(dataCopy, 0, 0, new GAL.Rectangle<int>(_dstX, _dstY, _lineLengthIn / target.Info.FormatInfo.BytesPerPixel, _lineCount));
|
||||||
target.SignalModified();
|
target.SignalModified();
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Gpu.Memory;
|
using Ryujinx.Graphics.Gpu.Memory;
|
||||||
using Ryujinx.Graphics.Texture;
|
using Ryujinx.Graphics.Texture;
|
||||||
|
@ -805,7 +806,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
sliceDepth,
|
sliceDepth,
|
||||||
levels,
|
levels,
|
||||||
layers,
|
layers,
|
||||||
out IMemoryOwner<byte> decoded))
|
out MemoryOwner<byte> decoded))
|
||||||
{
|
{
|
||||||
string texInfo = $"{Info.Target} {Info.FormatInfo.Format} {Info.Width}x{Info.Height}x{Info.DepthOrLayers} levels {Info.Levels}";
|
string texInfo = $"{Info.Target} {Info.FormatInfo.Format} {Info.Width}x{Info.Height}x{Info.DepthOrLayers} levels {Info.Levels}";
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using Ryujinx.Memory.Range;
|
using Ryujinx.Memory.Range;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
@ -242,9 +241,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IMemoryOwner<byte> memoryOwner = ByteMemoryPool.Rent(size);
|
MemoryOwner<byte> memoryOwner = MemoryOwner<byte>.Rent(size);
|
||||||
|
|
||||||
GetSpan(va, size).CopyTo(memoryOwner.Memory.Span);
|
ReadImpl(va, memoryOwner.Span, tracked);
|
||||||
|
|
||||||
return new WritableRegion(this, va, memoryOwner, tracked);
|
return new WritableRegion(this, va, memoryOwner, tracked);
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,9 +192,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IMemoryOwner<byte> memoryOwner = ByteMemoryPool.Rent(range.GetSize());
|
MemoryOwner<byte> memoryOwner = MemoryOwner<byte>.Rent(checked((int)range.GetSize()));
|
||||||
|
|
||||||
Memory<byte> memory = memoryOwner.Memory;
|
Span<byte> memorySpan = memoryOwner.Span;
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for (int i = 0; i < range.Count; i++)
|
for (int i = 0; i < range.Count; i++)
|
||||||
|
@ -203,7 +203,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
int size = (int)currentRange.Size;
|
int size = (int)currentRange.Size;
|
||||||
if (currentRange.Address != MemoryManager.PteUnmapped)
|
if (currentRange.Address != MemoryManager.PteUnmapped)
|
||||||
{
|
{
|
||||||
GetSpan(currentRange.Address, size).CopyTo(memory.Span.Slice(offset, size));
|
GetSpan(currentRange.Address, size).CopyTo(memorySpan.Slice(offset, size));
|
||||||
}
|
}
|
||||||
offset += size;
|
offset += size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Intrinsics;
|
using System.Runtime.Intrinsics;
|
||||||
|
@ -10,11 +9,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||||
{
|
{
|
||||||
static class FormatConverter
|
static class FormatConverter
|
||||||
{
|
{
|
||||||
public unsafe static IMemoryOwner<byte> ConvertS8D24ToD24S8(ReadOnlySpan<byte> data)
|
public unsafe static MemoryOwner<byte> ConvertS8D24ToD24S8(ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
IMemoryOwner<byte> outputMemory = ByteMemoryPool.Rent(data.Length);
|
MemoryOwner<byte> outputMemory = MemoryOwner<byte>.Rent(data.Length);
|
||||||
|
|
||||||
Span<byte> output = outputMemory.Memory.Span;
|
Span<byte> output = outputMemory.Span;
|
||||||
|
|
||||||
int start = 0;
|
int start = 0;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
@ -293,9 +292,9 @@ namespace Ryujinx.Graphics.Texture.Astc
|
||||||
int depth,
|
int depth,
|
||||||
int levels,
|
int levels,
|
||||||
int layers,
|
int layers,
|
||||||
out IMemoryOwner<byte> decoded)
|
out MemoryOwner<byte> decoded)
|
||||||
{
|
{
|
||||||
decoded = ByteMemoryPool.Rent(QueryDecompressedSize(width, height, depth, levels, layers));
|
decoded = MemoryOwner<byte>.Rent(QueryDecompressedSize(width, height, depth, levels, layers));
|
||||||
|
|
||||||
AstcDecoder decoder = new(data, decoded.Memory, blockWidth, blockHeight, width, height, depth, levels, layers);
|
AstcDecoder decoder = new(data, decoded.Memory, blockWidth, blockHeight, width, height, depth, levels, layers);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Buffers.Binary;
|
using System.Buffers.Binary;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Intrinsics;
|
using System.Runtime.Intrinsics;
|
||||||
|
@ -14,7 +13,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
private const int BlockWidth = 4;
|
private const int BlockWidth = 4;
|
||||||
private const int BlockHeight = 4;
|
private const int BlockHeight = 4;
|
||||||
|
|
||||||
public static IMemoryOwner<byte> DecodeBC1(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
public static MemoryOwner<byte> DecodeBC1(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
|
@ -23,12 +22,12 @@ namespace Ryujinx.Graphics.Texture
|
||||||
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 4;
|
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(size);
|
||||||
|
|
||||||
Span<byte> tile = stackalloc byte[BlockWidth * BlockHeight * 4];
|
Span<byte> tile = stackalloc byte[BlockWidth * BlockHeight * 4];
|
||||||
|
|
||||||
Span<uint> tileAsUint = MemoryMarshal.Cast<byte, uint>(tile);
|
Span<uint> tileAsUint = MemoryMarshal.Cast<byte, uint>(tile);
|
||||||
Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output.Span);
|
||||||
|
|
||||||
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
|
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
|
||||||
|
|
||||||
|
@ -102,7 +101,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> DecodeBC2(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
public static MemoryOwner<byte> DecodeBC2(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
|
@ -111,12 +110,12 @@ namespace Ryujinx.Graphics.Texture
|
||||||
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 4;
|
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(size);
|
||||||
|
|
||||||
Span<byte> tile = stackalloc byte[BlockWidth * BlockHeight * 4];
|
Span<byte> tile = stackalloc byte[BlockWidth * BlockHeight * 4];
|
||||||
|
|
||||||
Span<uint> tileAsUint = MemoryMarshal.Cast<byte, uint>(tile);
|
Span<uint> tileAsUint = MemoryMarshal.Cast<byte, uint>(tile);
|
||||||
Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output.Span);
|
||||||
|
|
||||||
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
|
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
|
||||||
|
|
||||||
|
@ -197,7 +196,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> DecodeBC3(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
public static MemoryOwner<byte> DecodeBC3(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
|
@ -206,13 +205,13 @@ namespace Ryujinx.Graphics.Texture
|
||||||
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 4;
|
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(size);
|
||||||
|
|
||||||
Span<byte> tile = stackalloc byte[BlockWidth * BlockHeight * 4];
|
Span<byte> tile = stackalloc byte[BlockWidth * BlockHeight * 4];
|
||||||
Span<byte> rPal = stackalloc byte[8];
|
Span<byte> rPal = stackalloc byte[8];
|
||||||
|
|
||||||
Span<uint> tileAsUint = MemoryMarshal.Cast<byte, uint>(tile);
|
Span<uint> tileAsUint = MemoryMarshal.Cast<byte, uint>(tile);
|
||||||
Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output.Span);
|
||||||
|
|
||||||
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
|
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
|
||||||
|
|
||||||
|
@ -294,7 +293,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> DecodeBC4(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers, bool signed)
|
public static MemoryOwner<byte> DecodeBC4(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers, bool signed)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
|
@ -306,8 +305,8 @@ namespace Ryujinx.Graphics.Texture
|
||||||
// Backends currently expect a stride alignment of 4 bytes, so output width must be aligned.
|
// Backends currently expect a stride alignment of 4 bytes, so output width must be aligned.
|
||||||
int alignedWidth = BitUtils.AlignUp(width, 4);
|
int alignedWidth = BitUtils.AlignUp(width, 4);
|
||||||
|
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(size);
|
||||||
Span<byte> outputSpan = output.Memory.Span;
|
Span<byte> outputSpan = output.Span;
|
||||||
|
|
||||||
ReadOnlySpan<ulong> data64 = MemoryMarshal.Cast<byte, ulong>(data);
|
ReadOnlySpan<ulong> data64 = MemoryMarshal.Cast<byte, ulong>(data);
|
||||||
|
|
||||||
|
@ -402,7 +401,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> DecodeBC5(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers, bool signed)
|
public static MemoryOwner<byte> DecodeBC5(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers, bool signed)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
|
@ -414,7 +413,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
// Backends currently expect a stride alignment of 4 bytes, so output width must be aligned.
|
// Backends currently expect a stride alignment of 4 bytes, so output width must be aligned.
|
||||||
int alignedWidth = BitUtils.AlignUp(width, 2);
|
int alignedWidth = BitUtils.AlignUp(width, 2);
|
||||||
|
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(size);
|
||||||
|
|
||||||
ReadOnlySpan<ulong> data64 = MemoryMarshal.Cast<byte, ulong>(data);
|
ReadOnlySpan<ulong> data64 = MemoryMarshal.Cast<byte, ulong>(data);
|
||||||
|
|
||||||
|
@ -423,7 +422,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
Span<byte> rPal = stackalloc byte[8];
|
Span<byte> rPal = stackalloc byte[8];
|
||||||
Span<byte> gPal = stackalloc byte[8];
|
Span<byte> gPal = stackalloc byte[8];
|
||||||
|
|
||||||
Span<ushort> outputAsUshort = MemoryMarshal.Cast<byte, ushort>(output.Memory.Span);
|
Span<ushort> outputAsUshort = MemoryMarshal.Cast<byte, ushort>(output.Span);
|
||||||
|
|
||||||
Span<uint> rTileAsUint = MemoryMarshal.Cast<byte, uint>(rTile);
|
Span<uint> rTileAsUint = MemoryMarshal.Cast<byte, uint>(rTile);
|
||||||
Span<uint> gTileAsUint = MemoryMarshal.Cast<byte, uint>(gTile);
|
Span<uint> gTileAsUint = MemoryMarshal.Cast<byte, uint>(gTile);
|
||||||
|
@ -527,7 +526,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> DecodeBC6(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers, bool signed)
|
public static MemoryOwner<byte> DecodeBC6(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers, bool signed)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
|
@ -536,8 +535,8 @@ namespace Ryujinx.Graphics.Texture
|
||||||
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 8;
|
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(size);
|
||||||
Span<byte> outputSpan = output.Memory.Span;
|
Span<byte> outputSpan = output.Span;
|
||||||
|
|
||||||
int inputOffset = 0;
|
int inputOffset = 0;
|
||||||
int outputOffset = 0;
|
int outputOffset = 0;
|
||||||
|
@ -566,7 +565,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> DecodeBC7(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
public static MemoryOwner<byte> DecodeBC7(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
|
@ -575,8 +574,8 @@ namespace Ryujinx.Graphics.Texture
|
||||||
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 4;
|
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(size);
|
||||||
Span<byte> outputSpan = output.Memory.Span;
|
Span<byte> outputSpan = output.Span;
|
||||||
|
|
||||||
int inputOffset = 0;
|
int inputOffset = 0;
|
||||||
int outputOffset = 0;
|
int outputOffset = 0;
|
||||||
|
|
|
@ -2,7 +2,6 @@ using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Graphics.Texture.Encoders;
|
using Ryujinx.Graphics.Texture.Encoders;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Texture
|
namespace Ryujinx.Graphics.Texture
|
||||||
{
|
{
|
||||||
|
@ -11,7 +10,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
private const int BlockWidth = 4;
|
private const int BlockWidth = 4;
|
||||||
private const int BlockHeight = 4;
|
private const int BlockHeight = 4;
|
||||||
|
|
||||||
public static IMemoryOwner<byte> EncodeBC7(Memory<byte> data, int width, int height, int depth, int levels, int layers)
|
public static MemoryOwner<byte> EncodeBC7(Memory<byte> data, int width, int height, int depth, int levels, int layers)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
|
@ -23,7 +22,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
size += w * h * 16 * Math.Max(1, depth >> l) * layers;
|
size += w * h * 16 * Math.Max(1, depth >> l) * layers;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(size);
|
||||||
Memory<byte> outputMemory = output.Memory;
|
Memory<byte> outputMemory = output.Memory;
|
||||||
|
|
||||||
int imageBaseIOffs = 0;
|
int imageBaseIOffs = 0;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Buffers.Binary;
|
using System.Buffers.Binary;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
@ -51,15 +50,15 @@ namespace Ryujinx.Graphics.Texture
|
||||||
new int[] { -3, -5, -7, -9, 2, 4, 6, 8 },
|
new int[] { -3, -5, -7, -9, 2, 4, 6, 8 },
|
||||||
};
|
};
|
||||||
|
|
||||||
public static IMemoryOwner<byte> DecodeRgb(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
public static MemoryOwner<byte> DecodeRgb(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
||||||
{
|
{
|
||||||
ReadOnlySpan<ulong> dataUlong = MemoryMarshal.Cast<byte, ulong>(data);
|
ReadOnlySpan<ulong> dataUlong = MemoryMarshal.Cast<byte, ulong>(data);
|
||||||
|
|
||||||
int inputOffset = 0;
|
int inputOffset = 0;
|
||||||
|
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(CalculateOutputSize(width, height, depth, levels, layers));
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(CalculateOutputSize(width, height, depth, levels, layers));
|
||||||
|
|
||||||
Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output.Span);
|
||||||
Span<uint> tile = stackalloc uint[BlockWidth * BlockHeight];
|
Span<uint> tile = stackalloc uint[BlockWidth * BlockHeight];
|
||||||
|
|
||||||
int imageBaseOOffs = 0;
|
int imageBaseOOffs = 0;
|
||||||
|
@ -113,15 +112,15 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> DecodePta(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
public static MemoryOwner<byte> DecodePta(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
||||||
{
|
{
|
||||||
ReadOnlySpan<ulong> dataUlong = MemoryMarshal.Cast<byte, ulong>(data);
|
ReadOnlySpan<ulong> dataUlong = MemoryMarshal.Cast<byte, ulong>(data);
|
||||||
|
|
||||||
int inputOffset = 0;
|
int inputOffset = 0;
|
||||||
|
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(CalculateOutputSize(width, height, depth, levels, layers));
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(CalculateOutputSize(width, height, depth, levels, layers));
|
||||||
|
|
||||||
Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output.Span);
|
||||||
Span<uint> tile = stackalloc uint[BlockWidth * BlockHeight];
|
Span<uint> tile = stackalloc uint[BlockWidth * BlockHeight];
|
||||||
|
|
||||||
int imageBaseOOffs = 0;
|
int imageBaseOOffs = 0;
|
||||||
|
@ -170,15 +169,15 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> DecodeRgba(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
public static MemoryOwner<byte> DecodeRgba(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
|
||||||
{
|
{
|
||||||
ReadOnlySpan<ulong> dataUlong = MemoryMarshal.Cast<byte, ulong>(data);
|
ReadOnlySpan<ulong> dataUlong = MemoryMarshal.Cast<byte, ulong>(data);
|
||||||
|
|
||||||
int inputOffset = 0;
|
int inputOffset = 0;
|
||||||
|
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(CalculateOutputSize(width, height, depth, levels, layers));
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(CalculateOutputSize(width, height, depth, levels, layers));
|
||||||
|
|
||||||
Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output.Span);
|
||||||
Span<uint> tile = stackalloc uint[BlockWidth * BlockHeight];
|
Span<uint> tile = stackalloc uint[BlockWidth * BlockHeight];
|
||||||
|
|
||||||
int imageBaseOOffs = 0;
|
int imageBaseOOffs = 0;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Runtime.Intrinsics;
|
using System.Runtime.Intrinsics;
|
||||||
using static Ryujinx.Graphics.Texture.BlockLinearConstants;
|
using static Ryujinx.Graphics.Texture.BlockLinearConstants;
|
||||||
|
|
||||||
|
@ -95,7 +94,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> ConvertBlockLinearToLinear(
|
public static MemoryOwner<byte> ConvertBlockLinearToLinear(
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int depth,
|
int depth,
|
||||||
|
@ -121,8 +120,8 @@ namespace Ryujinx.Graphics.Texture
|
||||||
blockHeight,
|
blockHeight,
|
||||||
bytesPerPixel);
|
bytesPerPixel);
|
||||||
|
|
||||||
IMemoryOwner<byte> outputOwner = ByteMemoryPool.Rent(outSize);
|
MemoryOwner<byte> outputOwner = MemoryOwner<byte>.Rent(outSize);
|
||||||
Span<byte> output = outputOwner.Memory.Span;
|
Span<byte> output = outputOwner.Span;
|
||||||
|
|
||||||
int outOffs = 0;
|
int outOffs = 0;
|
||||||
|
|
||||||
|
@ -249,7 +248,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return outputOwner;
|
return outputOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> ConvertLinearStridedToLinear(
|
public static MemoryOwner<byte> ConvertLinearStridedToLinear(
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int blockWidth,
|
int blockWidth,
|
||||||
|
@ -265,8 +264,8 @@ namespace Ryujinx.Graphics.Texture
|
||||||
int outStride = BitUtils.AlignUp(w * bytesPerPixel, HostStrideAlignment);
|
int outStride = BitUtils.AlignUp(w * bytesPerPixel, HostStrideAlignment);
|
||||||
lineSize = Math.Min(lineSize, outStride);
|
lineSize = Math.Min(lineSize, outStride);
|
||||||
|
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(h * outStride);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(h * outStride);
|
||||||
Span<byte> outSpan = output.Memory.Span;
|
Span<byte> outSpan = output.Span;
|
||||||
|
|
||||||
int outOffs = 0;
|
int outOffs = 0;
|
||||||
int inOffs = 0;
|
int inOffs = 0;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Intrinsics;
|
using System.Runtime.Intrinsics;
|
||||||
using System.Runtime.Intrinsics.X86;
|
using System.Runtime.Intrinsics.X86;
|
||||||
|
@ -21,13 +20,14 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return (remainder, outRemainder, length / stride);
|
return (remainder, outRemainder, length / stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe static IMemoryOwner<byte> ConvertR4G4ToR4G4B4A4(ReadOnlySpan<byte> data, int width)
|
public unsafe static MemoryOwner<byte> ConvertR4G4ToR4G4B4A4(ReadOnlySpan<byte> data, int width)
|
||||||
{
|
{
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(data.Length * 2);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(data.Length * 2);
|
||||||
|
Span<byte> outputSpan = output.Span;
|
||||||
|
|
||||||
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 1, 2);
|
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 1, 2);
|
||||||
|
|
||||||
Span<ushort> outputSpan = MemoryMarshal.Cast<byte, ushort>(output.Memory.Span);
|
Span<ushort> outputSpanUInt16 = MemoryMarshal.Cast<byte, ushort>(outputSpan);
|
||||||
|
|
||||||
if (remainder == 0)
|
if (remainder == 0)
|
||||||
{
|
{
|
||||||
|
@ -38,7 +38,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
int sizeTrunc = data.Length & ~7;
|
int sizeTrunc = data.Length & ~7;
|
||||||
start = sizeTrunc;
|
start = sizeTrunc;
|
||||||
|
|
||||||
fixed (byte* inputPtr = data, outputPtr = output.Memory.Span)
|
fixed (byte* inputPtr = data, outputPtr = outputSpan)
|
||||||
{
|
{
|
||||||
for (ulong offset = 0; offset < (ulong)sizeTrunc; offset += 8)
|
for (ulong offset = 0; offset < (ulong)sizeTrunc; offset += 8)
|
||||||
{
|
{
|
||||||
|
@ -49,7 +49,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
|
|
||||||
for (int i = start; i < data.Length; i++)
|
for (int i = start; i < data.Length; i++)
|
||||||
{
|
{
|
||||||
outputSpan[i] = data[i];
|
outputSpanUInt16[i] = data[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -61,7 +61,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
{
|
{
|
||||||
for (int x = 0; x < width; x++)
|
for (int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
outputSpan[outOffset++] = data[offset++];
|
outputSpanUInt16[outOffset++] = data[offset++];
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += remainder;
|
offset += remainder;
|
||||||
|
@ -72,16 +72,16 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> ConvertR5G6B5ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
|
public static MemoryOwner<byte> ConvertR5G6B5ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
|
||||||
{
|
{
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(data.Length * 2);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(data.Length * 2);
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int outOffset = 0;
|
int outOffset = 0;
|
||||||
|
|
||||||
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
|
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
|
||||||
|
|
||||||
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
|
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
|
||||||
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Span);
|
||||||
|
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
|
@ -109,16 +109,16 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> ConvertR5G5B5ToR8G8B8A8(ReadOnlySpan<byte> data, int width, bool forceAlpha)
|
public static MemoryOwner<byte> ConvertR5G5B5ToR8G8B8A8(ReadOnlySpan<byte> data, int width, bool forceAlpha)
|
||||||
{
|
{
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(data.Length * 2);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(data.Length * 2);
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int outOffset = 0;
|
int outOffset = 0;
|
||||||
|
|
||||||
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
|
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
|
||||||
|
|
||||||
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
|
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
|
||||||
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Span);
|
||||||
|
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
|
@ -146,16 +146,16 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> ConvertA1B5G5R5ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
|
public static MemoryOwner<byte> ConvertA1B5G5R5ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
|
||||||
{
|
{
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(data.Length * 2);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(data.Length * 2);
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int outOffset = 0;
|
int outOffset = 0;
|
||||||
|
|
||||||
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
|
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
|
||||||
|
|
||||||
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
|
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
|
||||||
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Span);
|
||||||
|
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
|
@ -183,16 +183,16 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> ConvertR4G4B4A4ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
|
public static MemoryOwner<byte> ConvertR4G4B4A4ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
|
||||||
{
|
{
|
||||||
IMemoryOwner<byte> output = ByteMemoryPool.Rent(data.Length * 2);
|
MemoryOwner<byte> output = MemoryOwner<byte>.Rent(data.Length * 2);
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int outOffset = 0;
|
int outOffset = 0;
|
||||||
|
|
||||||
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
|
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
|
||||||
|
|
||||||
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
|
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
|
||||||
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Span);
|
||||||
|
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -211,7 +211,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
IMemoryOwner<byte> dummyTextureData = ByteMemoryPool.RentCleared(4);
|
MemoryOwner<byte> dummyTextureData = MemoryOwner<byte>.RentCleared(4);
|
||||||
_dummyTexture.SetData(dummyTextureData);
|
_dummyTexture.SetData(dummyTextureData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue