Ryujinx.Graphics.Texture: change texture conversion methods to return IMemoryOwner<byte> and allocate from ByteMemoryPool
This commit is contained in:
parent
73799c120f
commit
61d7c5a094
6 changed files with 75 additions and 61 deletions
|
@ -1,5 +1,7 @@
|
||||||
|
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;
|
||||||
|
@ -291,16 +293,14 @@ namespace Ryujinx.Graphics.Texture.Astc
|
||||||
int depth,
|
int depth,
|
||||||
int levels,
|
int levels,
|
||||||
int layers,
|
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));
|
Enumerable.Range(0, decoder.TotalBlockCount).AsParallel().ForAll(x => decoder.ProcessBlock(x));
|
||||||
|
|
||||||
decoded = output;
|
|
||||||
|
|
||||||
return decoder.Success;
|
return decoder.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
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;
|
||||||
|
@ -12,7 +14,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 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;
|
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;
|
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> 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);
|
Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
||||||
|
|
||||||
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
|
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
|
||||||
|
|
||||||
|
@ -100,7 +102,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
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;
|
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;
|
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> 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);
|
Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
||||||
|
|
||||||
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
|
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
|
||||||
|
|
||||||
|
@ -195,7 +197,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
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;
|
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;
|
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> 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);
|
Span<uint> outputAsUint = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
||||||
|
|
||||||
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
|
Span<Vector128<byte>> tileAsVector128 = MemoryMarshal.Cast<byte, Vector128<byte>>(tile);
|
||||||
|
|
||||||
|
@ -292,7 +294,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
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;
|
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.
|
// 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);
|
||||||
|
|
||||||
byte[] output = new byte[size];
|
IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
|
||||||
Span<byte> outputSpan = new(output);
|
Span<byte> outputSpan = output.Memory.Span;
|
||||||
|
|
||||||
ReadOnlySpan<ulong> data64 = MemoryMarshal.Cast<byte, ulong>(data);
|
ReadOnlySpan<ulong> data64 = MemoryMarshal.Cast<byte, ulong>(data);
|
||||||
|
|
||||||
|
@ -400,7 +402,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
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;
|
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.
|
// 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);
|
||||||
|
|
||||||
byte[] output = new byte[size];
|
IMemoryOwner<byte> output = ByteMemoryPool.Rent(size);
|
||||||
|
|
||||||
ReadOnlySpan<ulong> data64 = MemoryMarshal.Cast<byte, ulong>(data);
|
ReadOnlySpan<ulong> data64 = MemoryMarshal.Cast<byte, ulong>(data);
|
||||||
|
|
||||||
|
@ -421,7 +423,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);
|
Span<ushort> outputAsUshort = MemoryMarshal.Cast<byte, ushort>(output.Memory.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);
|
||||||
|
@ -525,7 +527,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
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;
|
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;
|
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 inputOffset = 0;
|
||||||
int outputOffset = 0;
|
int outputOffset = 0;
|
||||||
|
@ -548,7 +551,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
{
|
{
|
||||||
for (int z = 0; z < depth; z++)
|
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;
|
inputOffset += w * h * 16;
|
||||||
outputOffset += width * height * 8;
|
outputOffset += width * height * 8;
|
||||||
|
@ -563,7 +566,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
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;
|
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;
|
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 inputOffset = 0;
|
||||||
int outputOffset = 0;
|
int outputOffset = 0;
|
||||||
|
@ -586,7 +590,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
{
|
{
|
||||||
for (int z = 0; z < depth; z++)
|
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;
|
inputOffset += w * h * 16;
|
||||||
outputOffset += width * height * 4;
|
outputOffset += width * height * 4;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
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
|
||||||
{
|
{
|
||||||
|
@ -9,7 +11,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 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;
|
int size = 0;
|
||||||
|
|
||||||
|
@ -21,7 +23,8 @@ namespace Ryujinx.Graphics.Texture
|
||||||
size += w * h * 16 * Math.Max(1, depth >> l) * layers;
|
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 imageBaseIOffs = 0;
|
||||||
int imageBaseOOffs = 0;
|
int imageBaseOOffs = 0;
|
||||||
|
@ -36,8 +39,8 @@ namespace Ryujinx.Graphics.Texture
|
||||||
for (int z = 0; z < depth; z++)
|
for (int z = 0; z < depth; z++)
|
||||||
{
|
{
|
||||||
BC7Encoder.Encode(
|
BC7Encoder.Encode(
|
||||||
output.AsMemory()[imageBaseOOffs..],
|
outputMemory[imageBaseOOffs..],
|
||||||
data.AsMemory()[imageBaseIOffs..],
|
data[imageBaseIOffs..],
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
EncodeMode.Fast | EncodeMode.Multithreaded);
|
EncodeMode.Fast | EncodeMode.Multithreaded);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@ -49,15 +51,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 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);
|
ReadOnlySpan<ulong> dataUlong = MemoryMarshal.Cast<byte, ulong>(data);
|
||||||
|
|
||||||
int inputOffset = 0;
|
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];
|
Span<uint> tile = stackalloc uint[BlockWidth * BlockHeight];
|
||||||
|
|
||||||
int imageBaseOOffs = 0;
|
int imageBaseOOffs = 0;
|
||||||
|
@ -111,15 +113,15 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
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);
|
ReadOnlySpan<ulong> dataUlong = MemoryMarshal.Cast<byte, ulong>(data);
|
||||||
|
|
||||||
int inputOffset = 0;
|
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];
|
Span<uint> tile = stackalloc uint[BlockWidth * BlockHeight];
|
||||||
|
|
||||||
int imageBaseOOffs = 0;
|
int imageBaseOOffs = 0;
|
||||||
|
@ -168,15 +170,15 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
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);
|
ReadOnlySpan<ulong> dataUlong = MemoryMarshal.Cast<byte, ulong>(data);
|
||||||
|
|
||||||
int inputOffset = 0;
|
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];
|
Span<uint> tile = stackalloc uint[BlockWidth * BlockHeight];
|
||||||
|
|
||||||
int imageBaseOOffs = 0;
|
int imageBaseOOffs = 0;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@ -93,7 +95,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] ConvertBlockLinearToLinear(
|
public static IMemoryOwner<byte> ConvertBlockLinearToLinear(
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int depth,
|
int depth,
|
||||||
|
@ -119,7 +121,8 @@ namespace Ryujinx.Graphics.Texture
|
||||||
blockHeight,
|
blockHeight,
|
||||||
bytesPerPixel);
|
bytesPerPixel);
|
||||||
|
|
||||||
byte[] output = new byte[outSize];
|
IMemoryOwner<byte> outputOwner = ByteMemoryPool.Rent(outSize);
|
||||||
|
Span<byte> output = outputOwner.Memory.Span;
|
||||||
|
|
||||||
int outOffs = 0;
|
int outOffs = 0;
|
||||||
|
|
||||||
|
@ -243,10 +246,10 @@ namespace Ryujinx.Graphics.Texture
|
||||||
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format."),
|
_ => 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 width,
|
||||||
int height,
|
int height,
|
||||||
int blockWidth,
|
int blockWidth,
|
||||||
|
@ -262,8 +265,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);
|
||||||
|
|
||||||
byte[] output = new byte[h * outStride];
|
IMemoryOwner<byte> output = ByteMemoryPool.Rent(h * outStride);
|
||||||
Span<byte> outSpan = output;
|
Span<byte> outSpan = output.Memory.Span;
|
||||||
|
|
||||||
int outOffs = 0;
|
int outOffs = 0;
|
||||||
int inOffs = 0;
|
int inOffs = 0;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
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;
|
||||||
|
@ -19,13 +21,13 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return (remainder, outRemainder, length / stride);
|
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);
|
(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)
|
if (remainder == 0)
|
||||||
{
|
{
|
||||||
|
@ -36,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)
|
fixed (byte* inputPtr = data, outputPtr = output.Memory.Span)
|
||||||
{
|
{
|
||||||
for (ulong offset = 0; offset < (ulong)sizeTrunc; offset += 8)
|
for (ulong offset = 0; offset < (ulong)sizeTrunc; offset += 8)
|
||||||
{
|
{
|
||||||
|
@ -70,16 +72,16 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe static byte[] ConvertR5G6B5ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
|
public unsafe 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 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);
|
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
||||||
|
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
|
@ -107,16 +109,16 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe static byte[] ConvertR5G5B5ToR8G8B8A8(ReadOnlySpan<byte> data, int width, bool forceAlpha)
|
public unsafe 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 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);
|
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
||||||
|
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
|
@ -144,16 +146,16 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe static byte[] ConvertA1B5G5R5ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
|
public unsafe 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 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);
|
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
||||||
|
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
|
@ -181,16 +183,16 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe static byte[] ConvertR4G4B4A4ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
|
public unsafe 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 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);
|
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output.Memory.Span);
|
||||||
|
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue