aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.GAL
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2024-04-07 18:25:55 -0300
committerGitHub <noreply@github.com>2024-04-07 18:25:55 -0300
commit3e6e0e4afaa3c3ffb118cb17b61feb16966a7eeb (patch)
treea4652499c089b0853e39c382cad82a9db4d6ad08 /src/Ryujinx.Graphics.GAL
parent808803d97a0c06809bf000687c252f960048fcf0 (diff)
Add support for large sampler arrays on Vulkan (#6489)
* Add support for large sampler arrays on Vulkan * Shader cache version bump * Format whitespace * Move DescriptorSetManager to PipelineLayoutCacheEntry to allow different pool sizes per layout * Handle array textures with different types on the same buffer * Somewhat better caching system * Avoid useless buffer data modification checks * Move redundant bindings update checking to the backend * Fix an issue where texture arrays would get the same bindings across stages on Vulkan * Backport some fixes from part 2 * Fix typo * PR feedback * Format whitespace * Add some missing XML docs
Diffstat (limited to 'src/Ryujinx.Graphics.GAL')
-rw-r--r--src/Ryujinx.Graphics.GAL/IImageArray.cs8
-rw-r--r--src/Ryujinx.Graphics.GAL/IPipeline.cs2
-rw-r--r--src/Ryujinx.Graphics.GAL/IRenderer.cs4
-rw-r--r--src/Ryujinx.Graphics.GAL/ITextureArray.cs8
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs12
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs10
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Commands/ImageArray/ImageArraySetFormatsCommand.cs26
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Commands/ImageArray/ImageArraySetImagesCommand.cs27
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateImageArrayCommand.cs25
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateTextureArrayCommand.cs25
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetImageArrayCommand.cs26
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureArrayCommand.cs26
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureAndSamplerArray/TextureArraySetSamplersCommand.cs27
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureAndSamplerArray/TextureArraySetTexturesCommand.cs27
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedImageArray.cs36
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTextureArray.cs37
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs12
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs17
-rw-r--r--src/Ryujinx.Graphics.GAL/ResourceLayout.cs8
19 files changed, 360 insertions, 3 deletions
diff --git a/src/Ryujinx.Graphics.GAL/IImageArray.cs b/src/Ryujinx.Graphics.GAL/IImageArray.cs
new file mode 100644
index 00000000..30cff50b
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/IImageArray.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.Graphics.GAL
+{
+ public interface IImageArray
+ {
+ void SetFormats(int index, Format[] imageFormats);
+ void SetImages(int index, ITexture[] images);
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/IPipeline.cs b/src/Ryujinx.Graphics.GAL/IPipeline.cs
index 3ba084aa..9efb9e3e 100644
--- a/src/Ryujinx.Graphics.GAL/IPipeline.cs
+++ b/src/Ryujinx.Graphics.GAL/IPipeline.cs
@@ -59,6 +59,7 @@ namespace Ryujinx.Graphics.GAL
void SetIndexBuffer(BufferRange buffer, IndexType type);
void SetImage(ShaderStage stage, int binding, ITexture texture, Format imageFormat);
+ void SetImageArray(ShaderStage stage, int binding, IImageArray array);
void SetLineParameters(float width, bool smooth);
@@ -89,6 +90,7 @@ namespace Ryujinx.Graphics.GAL
void SetStorageBuffers(ReadOnlySpan<BufferAssignment> buffers);
void SetTextureAndSampler(ShaderStage stage, int binding, ITexture texture, ISampler sampler);
+ void SetTextureArray(ShaderStage stage, int binding, ITextureArray array);
void SetTransformFeedbackBuffers(ReadOnlySpan<BufferRange> buffers);
void SetUniformBuffers(ReadOnlySpan<BufferAssignment> buffers);
diff --git a/src/Ryujinx.Graphics.GAL/IRenderer.cs b/src/Ryujinx.Graphics.GAL/IRenderer.cs
index 3bf56465..a3466e39 100644
--- a/src/Ryujinx.Graphics.GAL/IRenderer.cs
+++ b/src/Ryujinx.Graphics.GAL/IRenderer.cs
@@ -21,10 +21,14 @@ namespace Ryujinx.Graphics.GAL
BufferHandle CreateBuffer(nint pointer, int size);
BufferHandle CreateBufferSparse(ReadOnlySpan<BufferRange> storageBuffers);
+ IImageArray CreateImageArray(int size, bool isBuffer);
+
IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info);
ISampler CreateSampler(SamplerCreateInfo info);
ITexture CreateTexture(TextureCreateInfo info);
+ ITextureArray CreateTextureArray(int size, bool isBuffer);
+
bool PrepareHostMapping(nint address, ulong size);
void CreateSync(ulong id, bool strict);
diff --git a/src/Ryujinx.Graphics.GAL/ITextureArray.cs b/src/Ryujinx.Graphics.GAL/ITextureArray.cs
new file mode 100644
index 00000000..35c2116b
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/ITextureArray.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.Graphics.GAL
+{
+ public interface ITextureArray
+ {
+ void SetSamplers(int index, ISampler[] samplers);
+ void SetTextures(int index, ITexture[] textures);
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs b/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs
index 5bf3d328..fd2919be 100644
--- a/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs
@@ -1,10 +1,12 @@
using Ryujinx.Graphics.GAL.Multithreading.Commands;
using Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer;
using Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent;
+using Ryujinx.Graphics.GAL.Multithreading.Commands.ImageArray;
using Ryujinx.Graphics.GAL.Multithreading.Commands.Program;
using Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer;
using Ryujinx.Graphics.GAL.Multithreading.Commands.Sampler;
using Ryujinx.Graphics.GAL.Multithreading.Commands.Texture;
+using Ryujinx.Graphics.GAL.Multithreading.Commands.TextureArray;
using Ryujinx.Graphics.GAL.Multithreading.Commands.Window;
using System;
using System.Linq;
@@ -46,10 +48,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading
Register<CreateBufferAccessCommand>(CommandType.CreateBufferAccess);
Register<CreateBufferSparseCommand>(CommandType.CreateBufferSparse);
Register<CreateHostBufferCommand>(CommandType.CreateHostBuffer);
+ Register<CreateImageArrayCommand>(CommandType.CreateImageArray);
Register<CreateProgramCommand>(CommandType.CreateProgram);
Register<CreateSamplerCommand>(CommandType.CreateSampler);
Register<CreateSyncCommand>(CommandType.CreateSync);
Register<CreateTextureCommand>(CommandType.CreateTexture);
+ Register<CreateTextureArrayCommand>(CommandType.CreateTextureArray);
Register<GetCapabilitiesCommand>(CommandType.GetCapabilities);
Register<PreFrameCommand>(CommandType.PreFrame);
Register<ReportCounterCommand>(CommandType.ReportCounter);
@@ -63,6 +67,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading
Register<CounterEventDisposeCommand>(CommandType.CounterEventDispose);
Register<CounterEventFlushCommand>(CommandType.CounterEventFlush);
+ Register<ImageArraySetFormatsCommand>(CommandType.ImageArraySetFormats);
+ Register<ImageArraySetImagesCommand>(CommandType.ImageArraySetImages);
+
Register<ProgramDisposeCommand>(CommandType.ProgramDispose);
Register<ProgramGetBinaryCommand>(CommandType.ProgramGetBinary);
Register<ProgramCheckLinkCommand>(CommandType.ProgramCheckLink);
@@ -82,6 +89,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading
Register<TextureSetDataSliceRegionCommand>(CommandType.TextureSetDataSliceRegion);
Register<TextureSetStorageCommand>(CommandType.TextureSetStorage);
+ Register<TextureArraySetSamplersCommand>(CommandType.TextureArraySetSamplers);
+ Register<TextureArraySetTexturesCommand>(CommandType.TextureArraySetTextures);
+
Register<WindowPresentCommand>(CommandType.WindowPresent);
Register<BarrierCommand>(CommandType.Barrier);
@@ -114,6 +124,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
Register<SetTransformFeedbackBuffersCommand>(CommandType.SetTransformFeedbackBuffers);
Register<SetUniformBuffersCommand>(CommandType.SetUniformBuffers);
Register<SetImageCommand>(CommandType.SetImage);
+ Register<SetImageArrayCommand>(CommandType.SetImageArray);
Register<SetIndexBufferCommand>(CommandType.SetIndexBuffer);
Register<SetLineParametersCommand>(CommandType.SetLineParameters);
Register<SetLogicOpStateCommand>(CommandType.SetLogicOpState);
@@ -130,6 +141,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
Register<SetScissorsCommand>(CommandType.SetScissor);
Register<SetStencilTestCommand>(CommandType.SetStencilTest);
Register<SetTextureAndSamplerCommand>(CommandType.SetTextureAndSampler);
+ Register<SetTextureArrayCommand>(CommandType.SetTextureArray);
Register<SetUserClipDistanceCommand>(CommandType.SetUserClipDistance);
Register<SetVertexAttribsCommand>(CommandType.SetVertexAttribs);
Register<SetVertexBuffersCommand>(CommandType.SetVertexBuffers);
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs b/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs
index 6be63925..a5e7336c 100644
--- a/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs
@@ -7,10 +7,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading
CreateBufferAccess,
CreateBufferSparse,
CreateHostBuffer,
+ CreateImageArray,
CreateProgram,
CreateSampler,
CreateSync,
CreateTexture,
+ CreateTextureArray,
GetCapabilities,
Unused,
PreFrame,
@@ -25,6 +27,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading
CounterEventDispose,
CounterEventFlush,
+ ImageArraySetFormats,
+ ImageArraySetImages,
+
ProgramDispose,
ProgramGetBinary,
ProgramCheckLink,
@@ -44,6 +49,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading
TextureSetDataSliceRegion,
TextureSetStorage,
+ TextureArraySetSamplers,
+ TextureArraySetTextures,
+
WindowPresent,
Barrier,
@@ -76,6 +84,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
SetTransformFeedbackBuffers,
SetUniformBuffers,
SetImage,
+ SetImageArray,
SetIndexBuffer,
SetLineParameters,
SetLogicOpState,
@@ -92,6 +101,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
SetScissor,
SetStencilTest,
SetTextureAndSampler,
+ SetTextureArray,
SetUserClipDistance,
SetVertexAttribs,
SetVertexBuffers,
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ImageArray/ImageArraySetFormatsCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ImageArray/ImageArraySetFormatsCommand.cs
new file mode 100644
index 00000000..8e3ba88a
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ImageArray/ImageArraySetFormatsCommand.cs
@@ -0,0 +1,26 @@
+using Ryujinx.Graphics.GAL.Multithreading.Model;
+using Ryujinx.Graphics.GAL.Multithreading.Resources;
+
+namespace Ryujinx.Graphics.GAL.Multithreading.Commands.ImageArray
+{
+ struct ImageArraySetFormatsCommand : IGALCommand, IGALCommand<ImageArraySetFormatsCommand>
+ {
+ public readonly CommandType CommandType => CommandType.ImageArraySetFormats;
+ private TableRef<ThreadedImageArray> _imageArray;
+ private int _index;
+ private TableRef<Format[]> _imageFormats;
+
+ public void Set(TableRef<ThreadedImageArray> imageArray, int index, TableRef<Format[]> imageFormats)
+ {
+ _imageArray = imageArray;
+ _index = index;
+ _imageFormats = imageFormats;
+ }
+
+ public static void Run(ref ImageArraySetFormatsCommand command, ThreadedRenderer threaded, IRenderer renderer)
+ {
+ ThreadedImageArray imageArray = command._imageArray.Get(threaded);
+ imageArray.Base.SetFormats(command._index, command._imageFormats.Get(threaded));
+ }
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ImageArray/ImageArraySetImagesCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ImageArray/ImageArraySetImagesCommand.cs
new file mode 100644
index 00000000..cc28d585
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/ImageArray/ImageArraySetImagesCommand.cs
@@ -0,0 +1,27 @@
+using Ryujinx.Graphics.GAL.Multithreading.Model;
+using Ryujinx.Graphics.GAL.Multithreading.Resources;
+using System.Linq;
+
+namespace Ryujinx.Graphics.GAL.Multithreading.Commands.ImageArray
+{
+ struct ImageArraySetImagesCommand : IGALCommand, IGALCommand<ImageArraySetImagesCommand>
+ {
+ public readonly CommandType CommandType => CommandType.ImageArraySetImages;
+ private TableRef<ThreadedImageArray> _imageArray;
+ private int _index;
+ private TableRef<ITexture[]> _images;
+
+ public void Set(TableRef<ThreadedImageArray> imageArray, int index, TableRef<ITexture[]> images)
+ {
+ _imageArray = imageArray;
+ _index = index;
+ _images = images;
+ }
+
+ public static void Run(ref ImageArraySetImagesCommand command, ThreadedRenderer threaded, IRenderer renderer)
+ {
+ ThreadedImageArray imageArray = command._imageArray.Get(threaded);
+ imageArray.Base.SetImages(command._index, command._images.Get(threaded).Select(texture => ((ThreadedTexture)texture)?.Base).ToArray());
+ }
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateImageArrayCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateImageArrayCommand.cs
new file mode 100644
index 00000000..1c3fb812
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateImageArrayCommand.cs
@@ -0,0 +1,25 @@
+using Ryujinx.Graphics.GAL.Multithreading.Model;
+using Ryujinx.Graphics.GAL.Multithreading.Resources;
+
+namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
+{
+ struct CreateImageArrayCommand : IGALCommand, IGALCommand<CreateImageArrayCommand>
+ {
+ public readonly CommandType CommandType => CommandType.CreateImageArray;
+ private TableRef<ThreadedImageArray> _imageArray;
+ private int _size;
+ private bool _isBuffer;
+
+ public void Set(TableRef<ThreadedImageArray> imageArray, int size, bool isBuffer)
+ {
+ _imageArray = imageArray;
+ _size = size;
+ _isBuffer = isBuffer;
+ }
+
+ public static void Run(ref CreateImageArrayCommand command, ThreadedRenderer threaded, IRenderer renderer)
+ {
+ command._imageArray.Get(threaded).Base = renderer.CreateImageArray(command._size, command._isBuffer);
+ }
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateTextureArrayCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateTextureArrayCommand.cs
new file mode 100644
index 00000000..9bd891e6
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateTextureArrayCommand.cs
@@ -0,0 +1,25 @@
+using Ryujinx.Graphics.GAL.Multithreading.Model;
+using Ryujinx.Graphics.GAL.Multithreading.Resources;
+
+namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
+{
+ struct CreateTextureArrayCommand : IGALCommand, IGALCommand<CreateTextureArrayCommand>
+ {
+ public readonly CommandType CommandType => CommandType.CreateTextureArray;
+ private TableRef<ThreadedTextureArray> _textureArray;
+ private int _size;
+ private bool _isBuffer;
+
+ public void Set(TableRef<ThreadedTextureArray> textureArray, int size, bool isBuffer)
+ {
+ _textureArray = textureArray;
+ _size = size;
+ _isBuffer = isBuffer;
+ }
+
+ public static void Run(ref CreateTextureArrayCommand command, ThreadedRenderer threaded, IRenderer renderer)
+ {
+ command._textureArray.Get(threaded).Base = renderer.CreateTextureArray(command._size, command._isBuffer);
+ }
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetImageArrayCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetImageArrayCommand.cs
new file mode 100644
index 00000000..b8d3c7ac
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetImageArrayCommand.cs
@@ -0,0 +1,26 @@
+using Ryujinx.Graphics.GAL.Multithreading.Model;
+using Ryujinx.Graphics.GAL.Multithreading.Resources;
+using Ryujinx.Graphics.Shader;
+
+namespace Ryujinx.Graphics.GAL.Multithreading.Commands
+{
+ struct SetImageArrayCommand : IGALCommand, IGALCommand<SetImageArrayCommand>
+ {
+ public readonly CommandType CommandType => CommandType.SetImageArray;
+ private ShaderStage _stage;
+ private int _binding;
+ private TableRef<IImageArray> _array;
+
+ public void Set(ShaderStage stage, int binding, TableRef<IImageArray> array)
+ {
+ _stage = stage;
+ _binding = binding;
+ _array = array;
+ }
+
+ public static void Run(ref SetImageArrayCommand command, ThreadedRenderer threaded, IRenderer renderer)
+ {
+ renderer.Pipeline.SetImageArray(command._stage, command._binding, command._array.GetAs<ThreadedImageArray>(threaded)?.Base);
+ }
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureArrayCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureArrayCommand.cs
new file mode 100644
index 00000000..45e28aa6
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetTextureArrayCommand.cs
@@ -0,0 +1,26 @@
+using Ryujinx.Graphics.GAL.Multithreading.Model;
+using Ryujinx.Graphics.GAL.Multithreading.Resources;
+using Ryujinx.Graphics.Shader;
+
+namespace Ryujinx.Graphics.GAL.Multithreading.Commands
+{
+ struct SetTextureArrayCommand : IGALCommand, IGALCommand<SetTextureArrayCommand>
+ {
+ public readonly CommandType CommandType => CommandType.SetTextureArray;
+ private ShaderStage _stage;
+ private int _binding;
+ private TableRef<ITextureArray> _array;
+
+ public void Set(ShaderStage stage, int binding, TableRef<ITextureArray> array)
+ {
+ _stage = stage;
+ _binding = binding;
+ _array = array;
+ }
+
+ public static void Run(ref SetTextureArrayCommand command, ThreadedRenderer threaded, IRenderer renderer)
+ {
+ renderer.Pipeline.SetTextureArray(command._stage, command._binding, command._array.GetAs<ThreadedTextureArray>(threaded)?.Base);
+ }
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureAndSamplerArray/TextureArraySetSamplersCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureAndSamplerArray/TextureArraySetSamplersCommand.cs
new file mode 100644
index 00000000..204ee32d
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureAndSamplerArray/TextureArraySetSamplersCommand.cs
@@ -0,0 +1,27 @@
+using Ryujinx.Graphics.GAL.Multithreading.Model;
+using Ryujinx.Graphics.GAL.Multithreading.Resources;
+using System.Linq;
+
+namespace Ryujinx.Graphics.GAL.Multithreading.Commands.TextureArray
+{
+ struct TextureArraySetSamplersCommand : IGALCommand, IGALCommand<TextureArraySetSamplersCommand>
+ {
+ public readonly CommandType CommandType => CommandType.TextureArraySetSamplers;
+ private TableRef<ThreadedTextureArray> _textureArray;
+ private int _index;
+ private TableRef<ISampler[]> _samplers;
+
+ public void Set(TableRef<ThreadedTextureArray> textureArray, int index, TableRef<ISampler[]> samplers)
+ {
+ _textureArray = textureArray;
+ _index = index;
+ _samplers = samplers;
+ }
+
+ public static void Run(ref TextureArraySetSamplersCommand command, ThreadedRenderer threaded, IRenderer renderer)
+ {
+ ThreadedTextureArray textureArray = command._textureArray.Get(threaded);
+ textureArray.Base.SetSamplers(command._index, command._samplers.Get(threaded).Select(sampler => ((ThreadedSampler)sampler)?.Base).ToArray());
+ }
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureAndSamplerArray/TextureArraySetTexturesCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureAndSamplerArray/TextureArraySetTexturesCommand.cs
new file mode 100644
index 00000000..cc94d1b6
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/TextureAndSamplerArray/TextureArraySetTexturesCommand.cs
@@ -0,0 +1,27 @@
+using Ryujinx.Graphics.GAL.Multithreading.Model;
+using Ryujinx.Graphics.GAL.Multithreading.Resources;
+using System.Linq;
+
+namespace Ryujinx.Graphics.GAL.Multithreading.Commands.TextureArray
+{
+ struct TextureArraySetTexturesCommand : IGALCommand, IGALCommand<TextureArraySetTexturesCommand>
+ {
+ public readonly CommandType CommandType => CommandType.TextureArraySetTextures;
+ private TableRef<ThreadedTextureArray> _textureArray;
+ private int _index;
+ private TableRef<ITexture[]> _textures;
+
+ public void Set(TableRef<ThreadedTextureArray> textureArray, int index, TableRef<ITexture[]> textures)
+ {
+ _textureArray = textureArray;
+ _index = index;
+ _textures = textures;
+ }
+
+ public static void Run(ref TextureArraySetTexturesCommand command, ThreadedRenderer threaded, IRenderer renderer)
+ {
+ ThreadedTextureArray textureArray = command._textureArray.Get(threaded);
+ textureArray.Base.SetTextures(command._index, command._textures.Get(threaded).Select(texture => ((ThreadedTexture)texture)?.Base).ToArray());
+ }
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedImageArray.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedImageArray.cs
new file mode 100644
index 00000000..d26ee1fb
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedImageArray.cs
@@ -0,0 +1,36 @@
+using Ryujinx.Graphics.GAL.Multithreading.Commands.ImageArray;
+using Ryujinx.Graphics.GAL.Multithreading.Model;
+
+namespace Ryujinx.Graphics.GAL.Multithreading.Resources
+{
+ /// <summary>
+ /// Threaded representation of a image array.
+ /// </summary>
+ class ThreadedImageArray : IImageArray
+ {
+ private readonly ThreadedRenderer _renderer;
+ public IImageArray Base;
+
+ public ThreadedImageArray(ThreadedRenderer renderer)
+ {
+ _renderer = renderer;
+ }
+
+ private TableRef<T> Ref<T>(T reference)
+ {
+ return new TableRef<T>(_renderer, reference);
+ }
+
+ public void SetFormats(int index, Format[] imageFormats)
+ {
+ _renderer.New<ImageArraySetFormatsCommand>().Set(Ref(this), index, Ref(imageFormats));
+ _renderer.QueueCommand();
+ }
+
+ public void SetImages(int index, ITexture[] images)
+ {
+ _renderer.New<ImageArraySetImagesCommand>().Set(Ref(this), index, Ref(images));
+ _renderer.QueueCommand();
+ }
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTextureArray.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTextureArray.cs
new file mode 100644
index 00000000..82405a1f
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTextureArray.cs
@@ -0,0 +1,37 @@
+using Ryujinx.Graphics.GAL.Multithreading.Commands.TextureArray;
+using Ryujinx.Graphics.GAL.Multithreading.Model;
+using System.Linq;
+
+namespace Ryujinx.Graphics.GAL.Multithreading.Resources
+{
+ /// <summary>
+ /// Threaded representation of a texture and sampler array.
+ /// </summary>
+ class ThreadedTextureArray : ITextureArray
+ {
+ private readonly ThreadedRenderer _renderer;
+ public ITextureArray Base;
+
+ public ThreadedTextureArray(ThreadedRenderer renderer)
+ {
+ _renderer = renderer;
+ }
+
+ private TableRef<T> Ref<T>(T reference)
+ {
+ return new TableRef<T>(_renderer, reference);
+ }
+
+ public void SetSamplers(int index, ISampler[] samplers)
+ {
+ _renderer.New<TextureArraySetSamplersCommand>().Set(Ref(this), index, Ref(samplers.ToArray()));
+ _renderer.QueueCommand();
+ }
+
+ public void SetTextures(int index, ITexture[] textures)
+ {
+ _renderer.New<TextureArraySetTexturesCommand>().Set(Ref(this), index, Ref(textures.ToArray()));
+ _renderer.QueueCommand();
+ }
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs
index ad50bddf..697894eb 100644
--- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs
@@ -183,6 +183,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading
_renderer.QueueCommand();
}
+ public void SetImageArray(ShaderStage stage, int binding, IImageArray array)
+ {
+ _renderer.New<SetImageArrayCommand>().Set(stage, binding, Ref(array));
+ _renderer.QueueCommand();
+ }
+
public void SetIndexBuffer(BufferRange buffer, IndexType type)
{
_renderer.New<SetIndexBufferCommand>().Set(buffer, type);
@@ -285,6 +291,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading
_renderer.QueueCommand();
}
+ public void SetTextureArray(ShaderStage stage, int binding, ITextureArray array)
+ {
+ _renderer.New<SetTextureArrayCommand>().Set(stage, binding, Ref(array));
+ _renderer.QueueCommand();
+ }
+
public void SetTransformFeedbackBuffers(ReadOnlySpan<BufferRange> buffers)
{
_renderer.New<SetTransformFeedbackBuffersCommand>().Set(_renderer.CopySpan(buffers));
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs
index 830fbf2d..5e17bcd2 100644
--- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs
@@ -299,6 +299,15 @@ namespace Ryujinx.Graphics.GAL.Multithreading
return handle;
}
+ public IImageArray CreateImageArray(int size, bool isBuffer)
+ {
+ var imageArray = new ThreadedImageArray(this);
+ New<CreateImageArrayCommand>().Set(Ref(imageArray), size, isBuffer);
+ QueueCommand();
+
+ return imageArray;
+ }
+
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
{
var program = new ThreadedProgram(this);
@@ -349,6 +358,14 @@ namespace Ryujinx.Graphics.GAL.Multithreading
return texture;
}
}
+ public ITextureArray CreateTextureArray(int size, bool isBuffer)
+ {
+ var textureArray = new ThreadedTextureArray(this);
+ New<CreateTextureArrayCommand>().Set(Ref(textureArray), size, isBuffer);
+ QueueCommand();
+
+ return textureArray;
+ }
public void DeleteBuffer(BufferHandle buffer)
{
diff --git a/src/Ryujinx.Graphics.GAL/ResourceLayout.cs b/src/Ryujinx.Graphics.GAL/ResourceLayout.cs
index 84bca5b4..998c046f 100644
--- a/src/Ryujinx.Graphics.GAL/ResourceLayout.cs
+++ b/src/Ryujinx.Graphics.GAL/ResourceLayout.cs
@@ -71,19 +71,21 @@ namespace Ryujinx.Graphics.GAL
public readonly struct ResourceUsage : IEquatable<ResourceUsage>
{
public int Binding { get; }
+ public int ArrayLength { get; }
public ResourceType Type { get; }
public ResourceStages Stages { get; }
- public ResourceUsage(int binding, ResourceType type, ResourceStages stages)
+ public ResourceUsage(int binding, int arrayLength, ResourceType type, ResourceStages stages)
{
Binding = binding;
+ ArrayLength = arrayLength;
Type = type;
Stages = stages;
}
public override int GetHashCode()
{
- return HashCode.Combine(Binding, Type, Stages);
+ return HashCode.Combine(Binding, ArrayLength, Type, Stages);
}
public override bool Equals(object obj)
@@ -93,7 +95,7 @@ namespace Ryujinx.Graphics.GAL
public bool Equals(ResourceUsage other)
{
- return Binding == other.Binding && Type == other.Type && Stages == other.Stages;
+ return Binding == other.Binding && ArrayLength == other.ArrayLength && Type == other.Type && Stages == other.Stages;
}
public static bool operator ==(ResourceUsage left, ResourceUsage right)