aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Texture
diff options
context:
space:
mode:
authorjhorv <38920027+jhorv@users.noreply.github.com>2024-04-14 16:06:14 -0400
committerGitHub <noreply@github.com>2024-04-14 17:06:14 -0300
commit268c9aecf8e9181bb7114cf1dd826f00b2237714 (patch)
tree7e14ab6cde7c7edaf99bd2151abfb73d5b00f103 /src/Ryujinx.Graphics.Texture
parente916662b0f17b93d8987d481784cd45073335990 (diff)
Texture loading: reduce memory allocations (#6623)
* rebase * add methods Ryyjinx.Common EmbeddedResources and SteamUtils * GAL changes - change SetData() methods and ThreadedTexture commands to use IMemoryOwner<byte> instead of SpanOrArray<byte> * Ryujinx.Graphics.Texture: change texture conversion methods to return IMemoryOwner<byte> and allocate from ByteMemoryPool * Ryujinx.Graphics.OpenGL: update ITexture and Texture-like types with SetData() methods to take IMemoryOwner<byte> instead of SpanOrArray<byte> * Ryujinx.Graphics.Vulkan: update ITexture and Texture-like types with SetData() methods to take IMemoryOwner<byte> instead of SpanOrArray<byte> * Ryujinx.Graphics.Gpu: update ITexture and Texture-like types with SetData() methods to take IMemoryOwner<byte> instead of SpanOrArray<byte> * Remove now-unused SpanOrArray<T> * post-rebase cleanup * PixelConverter: remove unsafe modifier on safe methods, and remove one unnecessary cast * use ByteMemoryPool.Rent() in GetWritableRegion() impls * fix formatting, rename `ReadRentedMemory()` to `ReadFileToRentedMemory()`` * Texture.ConvertToHostCompatibleFormat(): dispose of `result` in Astc decode branch
Diffstat (limited to 'src/Ryujinx.Graphics.Texture')
-rw-r--r--src/Ryujinx.Graphics.Texture/Astc/AstcDecoder.cs10
-rw-r--r--src/Ryujinx.Graphics.Texture/BCnDecoder.cs46
-rw-r--r--src/Ryujinx.Graphics.Texture/BCnEncoder.cs11
-rw-r--r--src/Ryujinx.Graphics.Texture/ETC2Decoder.cs20
-rw-r--r--src/Ryujinx.Graphics.Texture/LayoutConverter.cs15
-rw-r--r--src/Ryujinx.Graphics.Texture/PixelConverter.cs36
6 files changed, 76 insertions, 62 deletions
diff --git a/src/Ryujinx.Graphics.Texture/Astc/AstcDecoder.cs b/src/Ryujinx.Graphics.Texture/Astc/AstcDecoder.cs
index edf699dc..3f65e122 100644
--- a/src/Ryujinx.Graphics.Texture/Astc/AstcDecoder.cs
+++ b/src/Ryujinx.Graphics.Texture/Astc/AstcDecoder.cs
@@ -1,5 +1,7 @@
+using Ryujinx.Common.Memory;
using Ryujinx.Common.Utilities;
using System;
+using System.Buffers;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
@@ -291,16 +293,14 @@ namespace Ryujinx.Graphics.Texture.Astc
int depth,
int levels,
int layers,
- out byte[] decoded)
+ out IMemoryOwner<byte> decoded)
{
- byte[] output = new byte[QueryDecompressedSize(width, height, depth, levels, layers)];
+ decoded = ByteMemoryPool.Rent(QueryDecompressedSize(width, height, depth, levels, layers));
- AstcDecoder decoder = new(data, output, blockWidth, blockHeight, width, height, depth, levels, layers);
+ AstcDecoder decoder = new(data, decoded.Memory, blockWidth, blockHeight, width, height, depth, levels, layers);
Enumerable.Range(0, decoder.TotalBlockCount).AsParallel().ForAll(x => decoder.ProcessBlock(x));
- decoded = output;
-
return decoder.Success;
}
diff --git a/src/Ryujinx.Graphics.Texture/BCnDecoder.cs b/src/Ryujinx.Graphics.Texture/BCnDecoder.cs
index 2d68ca34..eb85334a 100644
--- a/src/Ryujinx.Graphics.Texture/BCnDecoder.cs
+++ b/src/Ryujinx.Graphics.Texture/BCnDecoder.cs
@@ -1,5 +1,7 @@
using Ryujinx.Common;
+using Ryujinx.Common.Memory;
using System;
+using System.Buffers;
using System.Buffers.Binary;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@@ -12,7 +14,7 @@ namespace Ryujinx.Graphics.Texture
private const int BlockWidth = 4;
private const int BlockHeight = 4;
- public static byte[] DecodeBC1(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
+ public static IMemoryOwner<byte> DecodeBC1(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
{
int size = 0;
@@ -21,12 +23,12 @@ namespace Ryujinx.Graphics.Texture
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 4;
}
- byte[] output = new byte[size];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
Span<byte> tile = stackalloc byte[BlockWidth * BlockHeight * 4];
Span<uint> tileAsUint = MemoryMarshal.Cast<byte, uint>(tile);
- Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output);
+ Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
@@ -100,7 +102,7 @@ namespace Ryujinx.Graphics.Texture
return output;
}
- public static byte[] DecodeBC2(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
+ public static IMemoryOwner<byte> DecodeBC2(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
{
int size = 0;
@@ -109,12 +111,12 @@ namespace Ryujinx.Graphics.Texture
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 4;
}
- byte[] output = new byte[size];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
Span<byte> tile = stackalloc byte[BlockWidth * BlockHeight * 4];
Span<uint> tileAsUint = MemoryMarshal.Cast<byte, uint>(tile);
- Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output);
+ Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
@@ -195,7 +197,7 @@ namespace Ryujinx.Graphics.Texture
return output;
}
- public static byte[] DecodeBC3(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
+ public static IMemoryOwner<byte> DecodeBC3(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
{
int size = 0;
@@ -204,13 +206,13 @@ namespace Ryujinx.Graphics.Texture
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 4;
}
- byte[] output = new byte[size];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
Span<byte> tile = stackalloc byte[BlockWidth * BlockHeight * 4];
Span<byte> rPal = stackalloc byte[8];
Span<uint> tileAsUint = MemoryMarshal.Cast<byte, uint>(tile);
- Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output);
+ Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
@@ -292,7 +294,7 @@ namespace Ryujinx.Graphics.Texture
return output;
}
- public static byte[] DecodeBC4(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers, bool signed)
+ public static IMemoryOwner<byte> DecodeBC4(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers, bool signed)
{
int size = 0;
@@ -304,8 +306,8 @@ namespace Ryujinx.Graphics.Texture
// Backends currently expect a stride alignment of 4 bytes, so output width must be aligned.
int alignedWidth = BitUtils.AlignUp(width, 4);
- byte[] output = new byte[size];
- Span<byte> outputSpan = new(output);
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
+ Span<byte> outputSpan = output.Memory.Span;
ReadOnlySpan<ulong> data64 = MemoryMarshal.Cast<byte, ulong>(data);
@@ -400,7 +402,7 @@ namespace Ryujinx.Graphics.Texture
return output;
}
- public static byte[] DecodeBC5(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers, bool signed)
+ public static IMemoryOwner<byte> DecodeBC5(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers, bool signed)
{
int size = 0;
@@ -412,7 +414,7 @@ namespace Ryujinx.Graphics.Texture
// Backends currently expect a stride alignment of 4 bytes, so output width must be aligned.
int alignedWidth = BitUtils.AlignUp(width, 2);
- byte[] output = new byte[size];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
ReadOnlySpan<ulong> data64 = MemoryMarshal.Cast<byte, ulong>(data);
@@ -421,7 +423,7 @@ namespace Ryujinx.Graphics.Texture
Span<byte> rPal = stackalloc byte[8];
Span<byte> gPal = stackalloc byte[8];
- Span<ushort> outputAsUshort = MemoryMarshal.Cast<byte, ushort>(output);
+ Span<ushort> outputAsUshort = MemoryMarshal.Cast<byte, ushort>(output.Memory.Span);
Span<uint> rTileAsUint = MemoryMarshal.Cast<byte, uint>(rTile);
Span<uint> gTileAsUint = MemoryMarshal.Cast<byte, uint>(gTile);
@@ -525,7 +527,7 @@ namespace Ryujinx.Graphics.Texture
return output;
}
- public static byte[] DecodeBC6(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers, bool signed)
+ public static IMemoryOwner<byte> DecodeBC6(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers, bool signed)
{
int size = 0;
@@ -534,7 +536,8 @@ namespace Ryujinx.Graphics.Texture
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 8;
}
- byte[] output = new byte[size];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
+ Span<byte> outputSpan = output.Memory.Span;
int inputOffset = 0;
int outputOffset = 0;
@@ -548,7 +551,7 @@ namespace Ryujinx.Graphics.Texture
{
for (int z = 0; z < depth; z++)
{
- BC6Decoder.Decode(output.AsSpan()[outputOffset..], data[inputOffset..], width, height, signed);
+ BC6Decoder.Decode(outputSpan[outputOffset..], data[inputOffset..], width, height, signed);
inputOffset += w * h * 16;
outputOffset += width * height * 8;
@@ -563,7 +566,7 @@ namespace Ryujinx.Graphics.Texture
return output;
}
- public static byte[] DecodeBC7(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
+ public static IMemoryOwner<byte> DecodeBC7(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
{
int size = 0;
@@ -572,7 +575,8 @@ namespace Ryujinx.Graphics.Texture
size += Math.Max(1, width >> l) * Math.Max(1, height >> l) * Math.Max(1, depth >> l) * layers * 4;
}
- byte[] output = new byte[size];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
+ Span<byte> outputSpan = output.Memory.Span;
int inputOffset = 0;
int outputOffset = 0;
@@ -586,7 +590,7 @@ namespace Ryujinx.Graphics.Texture
{
for (int z = 0; z < depth; z++)
{
- BC7Decoder.Decode(output.AsSpan()[outputOffset..], data[inputOffset..], width, height);
+ BC7Decoder.Decode(outputSpan[outputOffset..], data[inputOffset..], width, height);
inputOffset += w * h * 16;
outputOffset += width * height * 4;
diff --git a/src/Ryujinx.Graphics.Texture/BCnEncoder.cs b/src/Ryujinx.Graphics.Texture/BCnEncoder.cs
index 8103990f..253ba305 100644
--- a/src/Ryujinx.Graphics.Texture/BCnEncoder.cs
+++ b/src/Ryujinx.Graphics.Texture/BCnEncoder.cs
@@ -1,6 +1,8 @@
using Ryujinx.Common;
+using Ryujinx.Common.Memory;
using Ryujinx.Graphics.Texture.Encoders;
using System;
+using System.Buffers;
namespace Ryujinx.Graphics.Texture
{
@@ -9,7 +11,7 @@ namespace Ryujinx.Graphics.Texture
private const int BlockWidth = 4;
private const int BlockHeight = 4;
- public static byte[] EncodeBC7(byte[] data, int width, int height, int depth, int levels, int layers)
+ public static IMemoryOwner<byte> EncodeBC7(Memory<byte> data, int width, int height, int depth, int levels, int layers)
{
int size = 0;
@@ -21,7 +23,8 @@ namespace Ryujinx.Graphics.Texture
size += w * h * 16 * Math.Max(1, depth >> l) * layers;
}
- byte[] output = new byte[size];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
+ Memory<byte> outputMemory = output.Memory;
int imageBaseIOffs = 0;
int imageBaseOOffs = 0;
@@ -36,8 +39,8 @@ namespace Ryujinx.Graphics.Texture
for (int z = 0; z < depth; z++)
{
BC7Encoder.Encode(
- output.AsMemory()[imageBaseOOffs..],
- data.AsMemory()[imageBaseIOffs..],
+ outputMemory[imageBaseOOffs..],
+ data[imageBaseIOffs..],
width,
height,
EncodeMode.Fast | EncodeMode.Multithreaded);
diff --git a/src/Ryujinx.Graphics.Texture/ETC2Decoder.cs b/src/Ryujinx.Graphics.Texture/ETC2Decoder.cs
index 57f2e98d..52801ff4 100644
--- a/src/Ryujinx.Graphics.Texture/ETC2Decoder.cs
+++ b/src/Ryujinx.Graphics.Texture/ETC2Decoder.cs
@@ -1,5 +1,7 @@
using Ryujinx.Common;
+using Ryujinx.Common.Memory;
using System;
+using System.Buffers;
using System.Buffers.Binary;
using System.Runtime.InteropServices;
@@ -49,15 +51,15 @@ namespace Ryujinx.Graphics.Texture
new int[] { -3, -5, -7, -9, 2, 4, 6, 8 },
};
- public static byte[] DecodeRgb(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
+ public static IMemoryOwner<byte> DecodeRgb(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
{
ReadOnlySpan<ulong> dataUlong = MemoryMarshal.Cast<byte, ulong>(data);
int inputOffset = 0;
- byte[] output = new byte[CalculateOutputSize(width, height, depth, levels, layers)];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(CalculateOutputSize(width, height, depth, levels, layers));
- Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output);
+ Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
Span<uint> tile = stackalloc uint[BlockWidth * BlockHeight];
int imageBaseOOffs = 0;
@@ -111,15 +113,15 @@ namespace Ryujinx.Graphics.Texture
return output;
}
- public static byte[] DecodePta(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
+ public static IMemoryOwner<byte> DecodePta(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
{
ReadOnlySpan<ulong> dataUlong = MemoryMarshal.Cast<byte, ulong>(data);
int inputOffset = 0;
- byte[] output = new byte[CalculateOutputSize(width, height, depth, levels, layers)];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(CalculateOutputSize(width, height, depth, levels, layers));
- Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output);
+ Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
Span<uint> tile = stackalloc uint[BlockWidth * BlockHeight];
int imageBaseOOffs = 0;
@@ -168,15 +170,15 @@ namespace Ryujinx.Graphics.Texture
return output;
}
- public static byte[] DecodeRgba(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
+ public static IMemoryOwner<byte> DecodeRgba(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)
{
ReadOnlySpan<ulong> dataUlong = MemoryMarshal.Cast<byte, ulong>(data);
int inputOffset = 0;
- byte[] output = new byte[CalculateOutputSize(width, height, depth, levels, layers)];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(CalculateOutputSize(width, height, depth, levels, layers));
- Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output);
+ Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
Span<uint> tile = stackalloc uint[BlockWidth * BlockHeight];
int imageBaseOOffs = 0;
diff --git a/src/Ryujinx.Graphics.Texture/LayoutConverter.cs b/src/Ryujinx.Graphics.Texture/LayoutConverter.cs
index d9a666c3..d6732674 100644
--- a/src/Ryujinx.Graphics.Texture/LayoutConverter.cs
+++ b/src/Ryujinx.Graphics.Texture/LayoutConverter.cs
@@ -1,5 +1,7 @@
using Ryujinx.Common;
+using Ryujinx.Common.Memory;
using System;
+using System.Buffers;
using System.Runtime.Intrinsics;
using static Ryujinx.Graphics.Texture.BlockLinearConstants;
@@ -93,7 +95,7 @@ namespace Ryujinx.Graphics.Texture
};
}
- public static byte[] ConvertBlockLinearToLinear(
+ public static IMemoryOwner<byte> ConvertBlockLinearToLinear(
int width,
int height,
int depth,
@@ -119,7 +121,8 @@ namespace Ryujinx.Graphics.Texture
blockHeight,
bytesPerPixel);
- byte[] output = new byte[outSize];
+ IMemoryOwner<byte> outputOwner = ByteMemoryPool.Rent(outSize);
+ Span<byte> output = outputOwner.Memory.Span;
int outOffs = 0;
@@ -243,10 +246,10 @@ namespace Ryujinx.Graphics.Texture
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format."),
};
}
- return output;
+ return outputOwner;
}
- public static byte[] ConvertLinearStridedToLinear(
+ public static IMemoryOwner<byte> ConvertLinearStridedToLinear(
int width,
int height,
int blockWidth,
@@ -262,8 +265,8 @@ namespace Ryujinx.Graphics.Texture
int outStride = BitUtils.AlignUp(w * bytesPerPixel, HostStrideAlignment);
lineSize = Math.Min(lineSize, outStride);
- byte[] output = new byte[h * outStride];
- Span<byte> outSpan = output;
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(h * outStride);
+ Span<byte> outSpan = output.Memory.Span;
int outOffs = 0;
int inOffs = 0;
diff --git a/src/Ryujinx.Graphics.Texture/PixelConverter.cs b/src/Ryujinx.Graphics.Texture/PixelConverter.cs
index 7955aed3..4475cc98 100644
--- a/src/Ryujinx.Graphics.Texture/PixelConverter.cs
+++ b/src/Ryujinx.Graphics.Texture/PixelConverter.cs
@@ -1,5 +1,7 @@
using Ryujinx.Common;
+using Ryujinx.Common.Memory;
using System;
+using System.Buffers;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
@@ -19,13 +21,13 @@ namespace Ryujinx.Graphics.Texture
return (remainder, outRemainder, length / stride);
}
- public unsafe static byte[] ConvertR4G4ToR4G4B4A4(ReadOnlySpan<byte> data, int width)
+ public unsafe static IMemoryOwner<byte> ConvertR4G4ToR4G4B4A4(ReadOnlySpan<byte> data, int width)
{
- byte[] output = new byte[data.Length * 2];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(data.Length * 2);
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 1, 2);
- Span<ushort> outputSpan = MemoryMarshal.Cast<byte, ushort>(output);
+ Span<ushort> outputSpan = MemoryMarshal.Cast<byte, ushort>(output.Memory.Span);
if (remainder == 0)
{
@@ -36,7 +38,7 @@ namespace Ryujinx.Graphics.Texture
int sizeTrunc = data.Length & ~7;
start = sizeTrunc;
- fixed (byte* inputPtr = data, outputPtr = output)
+ fixed (byte* inputPtr = data, outputPtr = output.Memory.Span)
{
for (ulong offset = 0; offset < (ulong)sizeTrunc; offset += 8)
{
@@ -47,7 +49,7 @@ namespace Ryujinx.Graphics.Texture
for (int i = start; i < data.Length; i++)
{
- outputSpan[i] = (ushort)data[i];
+ outputSpan[i] = data[i];
}
}
else
@@ -70,16 +72,16 @@ namespace Ryujinx.Graphics.Texture
return output;
}
- public unsafe static byte[] ConvertR5G6B5ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
+ public static IMemoryOwner<byte> ConvertR5G6B5ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
{
- byte[] output = new byte[data.Length * 2];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(data.Length * 2);
int offset = 0;
int outOffset = 0;
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
- Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output);
+ Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
for (int y = 0; y < height; y++)
{
@@ -107,16 +109,16 @@ namespace Ryujinx.Graphics.Texture
return output;
}
- public unsafe static byte[] ConvertR5G5B5ToR8G8B8A8(ReadOnlySpan<byte> data, int width, bool forceAlpha)
+ public static IMemoryOwner<byte> ConvertR5G5B5ToR8G8B8A8(ReadOnlySpan<byte> data, int width, bool forceAlpha)
{
- byte[] output = new byte[data.Length * 2];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(data.Length * 2);
int offset = 0;
int outOffset = 0;
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
- Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output);
+ Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
for (int y = 0; y < height; y++)
{
@@ -144,16 +146,16 @@ namespace Ryujinx.Graphics.Texture
return output;
}
- public unsafe static byte[] ConvertA1B5G5R5ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
+ public static IMemoryOwner<byte> ConvertA1B5G5R5ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
{
- byte[] output = new byte[data.Length * 2];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(data.Length * 2);
int offset = 0;
int outOffset = 0;
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
- Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output);
+ Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
for (int y = 0; y < height; y++)
{
@@ -181,16 +183,16 @@ namespace Ryujinx.Graphics.Texture
return output;
}
- public unsafe static byte[] ConvertR4G4B4A4ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
+ public static IMemoryOwner<byte> ConvertR4G4B4A4ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
{
- byte[] output = new byte[data.Length * 2];
+ IMemoryOwner<byte> output = ByteMemoryPool.Rent(data.Length * 2);
int offset = 0;
int outOffset = 0;
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
- Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output);
+ Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
for (int y = 0; y < height; y++)
{