Ryujinx.Graphics.OpenGL: update ITexture and Texture-like types with SetData() methods to take IMemoryOwner<byte> instead of SpanOrArray<byte>

This commit is contained in:
Jim Horvath 2024-02-22 20:27:54 -05:00 committed by jhorv
commit 692757ccfc
4 changed files with 69 additions and 57 deletions

View file

@ -33,7 +33,8 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
public int Quality public int Quality
{ {
get => _quality; set get => _quality;
set
{ {
_quality = Math.Clamp(value, 0, _qualities.Length - 1); _quality = Math.Clamp(value, 0, _qualities.Length - 1);
} }
@ -150,8 +151,8 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
_areaTexture = new TextureStorage(_renderer, areaInfo); _areaTexture = new TextureStorage(_renderer, areaInfo);
_searchTexture = new TextureStorage(_renderer, searchInfo); _searchTexture = new TextureStorage(_renderer, searchInfo);
var areaTexture = EmbeddedResources.Read("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaAreaTexture.bin"); var areaTexture = EmbeddedResources.ReadRentedMemory("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaAreaTexture.bin");
var searchTexture = EmbeddedResources.Read("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaSearchTexture.bin"); var searchTexture = EmbeddedResources.ReadRentedMemory("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaSearchTexture.bin");
var areaView = _areaTexture.CreateDefaultView(); var areaView = _areaTexture.CreateDefaultView();
var searchView = _searchTexture.CreateDefaultView(); var searchView = _searchTexture.CreateDefaultView();

View file

@ -1,4 +1,6 @@
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;
@ -8,9 +10,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
static class FormatConverter static class FormatConverter
{ {
public unsafe static byte[] ConvertS8D24ToD24S8(ReadOnlySpan<byte> data) public unsafe static IMemoryOwner<byte> ConvertS8D24ToD24S8(ReadOnlySpan<byte> data)
{ {
byte[] output = new byte[data.Length]; IMemoryOwner<byte> outputMemory = ByteMemoryPool.Rent(data.Length);
Span<byte> output = outputMemory.Memory.Span;
int start = 0; int start = 0;
@ -74,7 +78,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
outSpan[i] = BitOperations.RotateLeft(dataSpan[i], 8); outSpan[i] = BitOperations.RotateLeft(dataSpan[i], 8);
} }
return output; return outputMemory;
} }
public unsafe static byte[] ConvertD24S8ToS8D24(ReadOnlySpan<byte> data) public unsafe static byte[] ConvertD24S8ToS8D24(ReadOnlySpan<byte> data)

View file

@ -1,7 +1,7 @@
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Ryujinx.Common.Memory;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using System; using System;
using System.Buffers;
namespace Ryujinx.Graphics.OpenGL.Image namespace Ryujinx.Graphics.OpenGL.Image
{ {
@ -54,19 +54,24 @@ namespace Ryujinx.Graphics.OpenGL.Image
throw new NotImplementedException(); throw new NotImplementedException();
} }
public void SetData(SpanOrArray<byte> data) /// <inheritdoc/>
public void SetData(IMemoryOwner<byte> data)
{ {
var dataSpan = data.AsSpan(); var dataSpan = data.Memory.Span;
Buffer.SetData(_buffer, _bufferOffset, dataSpan[..Math.Min(dataSpan.Length, _bufferSize)]); Buffer.SetData(_buffer, _bufferOffset, dataSpan[..Math.Min(dataSpan.Length, _bufferSize)]);
data.Dispose();
} }
public void SetData(SpanOrArray<byte> data, int layer, int level) /// <inheritdoc/>
public void SetData(IMemoryOwner<byte> data, int layer, int level)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
public void SetData(SpanOrArray<byte> data, int layer, int level, Rectangle<int> region) /// <inheritdoc/>
public void SetData(IMemoryOwner<byte> data, int layer, int level, Rectangle<int> region)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }

View file

@ -1,8 +1,8 @@
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Memory;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using System; using System;
using System.Buffers;
using System.Diagnostics; using System.Diagnostics;
namespace Ryujinx.Graphics.OpenGL.Image namespace Ryujinx.Graphics.OpenGL.Image
@ -448,70 +448,59 @@ namespace Ryujinx.Graphics.OpenGL.Image
} }
} }
public void SetData(SpanOrArray<byte> data) public void SetData(IMemoryOwner<byte> data)
{ {
var dataSpan = data.AsSpan(); using (data = EnsureDataFormat(data))
if (Format == Format.S8UintD24Unorm)
{ {
dataSpan = FormatConverter.ConvertS8D24ToD24S8(dataSpan); unsafe
}
unsafe
{
fixed (byte* ptr = dataSpan)
{ {
ReadFrom((IntPtr)ptr, dataSpan.Length); var dataSpan = data.Memory.Span;
fixed (byte* ptr = dataSpan)
{
ReadFrom((IntPtr)ptr, dataSpan.Length);
}
} }
} }
} }
public void SetData(SpanOrArray<byte> data, int layer, int level) public void SetData(IMemoryOwner<byte> data, int layer, int level)
{ {
var dataSpan = data.AsSpan(); using (data = EnsureDataFormat(data))
if (Format == Format.S8UintD24Unorm)
{ {
dataSpan = FormatConverter.ConvertS8D24ToD24S8(dataSpan); unsafe
}
unsafe
{
fixed (byte* ptr = dataSpan)
{ {
int width = Math.Max(Info.Width >> level, 1); fixed (byte* ptr = data.Memory.Span)
int height = Math.Max(Info.Height >> level, 1); {
int width = Math.Max(Info.Width >> level, 1);
int height = Math.Max(Info.Height >> level, 1);
ReadFrom2D((IntPtr)ptr, layer, level, 0, 0, width, height); ReadFrom2D((IntPtr)ptr, layer, level, 0, 0, width, height);
}
} }
} }
} }
public void SetData(SpanOrArray<byte> data, int layer, int level, Rectangle<int> region) public void SetData(IMemoryOwner<byte> data, int layer, int level, Rectangle<int> region)
{ {
var dataSpan = data.AsSpan(); using (data = EnsureDataFormat(data))
if (Format == Format.S8UintD24Unorm)
{ {
dataSpan = FormatConverter.ConvertS8D24ToD24S8(dataSpan); int wInBlocks = BitUtils.DivRoundUp(region.Width, Info.BlockWidth);
} int hInBlocks = BitUtils.DivRoundUp(region.Height, Info.BlockHeight);
int wInBlocks = BitUtils.DivRoundUp(region.Width, Info.BlockWidth); unsafe
int hInBlocks = BitUtils.DivRoundUp(region.Height, Info.BlockHeight);
unsafe
{
fixed (byte* ptr = dataSpan)
{ {
ReadFrom2D( fixed (byte* ptr = data.Memory.Span)
(IntPtr)ptr, {
layer, ReadFrom2D(
level, (IntPtr)ptr,
region.X, layer,
region.Y, level,
region.Width, region.X,
region.Height, region.Y,
BitUtils.AlignUp(wInBlocks * Info.BytesPerPixel, 4) * hInBlocks); region.Width,
region.Height,
BitUtils.AlignUp(wInBlocks * Info.BytesPerPixel, 4) * hInBlocks);
}
} }
} }
} }
@ -533,6 +522,19 @@ namespace Ryujinx.Graphics.OpenGL.Image
ReadFrom2D(data, layer, level, x, y, width, height, mipSize); ReadFrom2D(data, layer, level, x, y, width, height, mipSize);
} }
private IMemoryOwner<byte> EnsureDataFormat(IMemoryOwner<byte> data)
{
if (Format == Format.S8UintD24Unorm)
{
using (data)
{
return FormatConverter.ConvertS8D24ToD24S8(data.Memory.Span);
}
}
return data;
}
private void ReadFrom2D(IntPtr data, int layer, int level, int x, int y, int width, int height, int mipSize) private void ReadFrom2D(IntPtr data, int layer, int level, int x, int y, int width, int height, int mipSize)
{ {
TextureTarget target = Target.Convert(); TextureTarget target = Target.Convert();