diff options
| author | jhorv <38920027+jhorv@users.noreply.github.com> | 2024-04-14 16:06:14 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-14 17:06:14 -0300 |
| commit | 268c9aecf8e9181bb7114cf1dd826f00b2237714 (patch) | |
| tree | 7e14ab6cde7c7edaf99bd2151abfb73d5b00f103 /src/Ryujinx.Graphics.Texture/PixelConverter.cs | |
| parent | e916662b0f17b93d8987d481784cd45073335990 (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/PixelConverter.cs')
| -rw-r--r-- | src/Ryujinx.Graphics.Texture/PixelConverter.cs | 36 |
1 files changed, 19 insertions, 17 deletions
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++) { |
