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
This commit is contained in:
parent
808803d97a
commit
3e6e0e4afa
83 changed files with 3263 additions and 955 deletions
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue