aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.OpenGL/Image
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.OpenGL/Image
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.OpenGL/Image')
-rw-r--r--src/Ryujinx.Graphics.OpenGL/Image/FormatConverter.cs10
-rw-r--r--src/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs15
-rw-r--r--src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs94
3 files changed, 65 insertions, 54 deletions
diff --git a/src/Ryujinx.Graphics.OpenGL/Image/FormatConverter.cs b/src/Ryujinx.Graphics.OpenGL/Image/FormatConverter.cs
index c4bbf745..434f2590 100644
--- a/src/Ryujinx.Graphics.OpenGL/Image/FormatConverter.cs
+++ b/src/Ryujinx.Graphics.OpenGL/Image/FormatConverter.cs
@@ -1,4 +1,6 @@
+using Ryujinx.Common.Memory;
using System;
+using System.Buffers;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@@ -8,9 +10,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
{
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;
@@ -74,7 +78,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
outSpan[i] = BitOperations.RotateLeft(dataSpan[i], 8);
}
- return output;
+ return outputMemory;
}
public unsafe static byte[] ConvertD24S8ToS8D24(ReadOnlySpan<byte> data)
diff --git a/src/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs b/src/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs
index f140b276..a8196541 100644
--- a/src/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs
+++ b/src/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs
@@ -1,7 +1,7 @@
using OpenTK.Graphics.OpenGL;
-using Ryujinx.Common.Memory;
using Ryujinx.Graphics.GAL;
using System;
+using System.Buffers;
namespace Ryujinx.Graphics.OpenGL.Image
{
@@ -54,19 +54,24 @@ namespace Ryujinx.Graphics.OpenGL.Image
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)]);
+
+ 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();
}
- 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();
}
diff --git a/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs b/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs
index 7f1b1c38..8a18e613 100644
--- a/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs
+++ b/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs
@@ -1,8 +1,8 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Common;
-using Ryujinx.Common.Memory;
using Ryujinx.Graphics.GAL;
using System;
+using System.Buffers;
using System.Diagnostics;
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();
-
- if (Format == Format.S8UintD24Unorm)
- {
- dataSpan = FormatConverter.ConvertS8D24ToD24S8(dataSpan);
- }
-
- unsafe
+ using (data = EnsureDataFormat(data))
{
- fixed (byte* ptr = dataSpan)
+ unsafe
{
- 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();
-
- if (Format == Format.S8UintD24Unorm)
- {
- dataSpan = FormatConverter.ConvertS8D24ToD24S8(dataSpan);
- }
-
- unsafe
+ using (data = EnsureDataFormat(data))
{
- fixed (byte* ptr = dataSpan)
+ unsafe
{
- int width = Math.Max(Info.Width >> level, 1);
- int height = Math.Max(Info.Height >> level, 1);
+ fixed (byte* ptr = data.Memory.Span)
+ {
+ 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();
-
- if (Format == Format.S8UintD24Unorm)
+ using (data = EnsureDataFormat(data))
{
- 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);
+ int hInBlocks = BitUtils.DivRoundUp(region.Height, Info.BlockHeight);
- unsafe
- {
- fixed (byte* ptr = dataSpan)
+ unsafe
{
- ReadFrom2D(
- (IntPtr)ptr,
- layer,
- level,
- region.X,
- region.Y,
- region.Width,
- region.Height,
- BitUtils.AlignUp(wInBlocks * Info.BytesPerPixel, 4) * hInBlocks);
+ fixed (byte* ptr = data.Memory.Span)
+ {
+ ReadFrom2D(
+ (IntPtr)ptr,
+ layer,
+ level,
+ region.X,
+ region.Y,
+ 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);
}
+ 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)
{
TextureTarget target = Target.Convert();