From fa5b40441d279812bb23e89cd8ae415f92844850 Mon Sep 17 00:00:00 2001 From: Gabriel A Date: Sun, 31 Mar 2024 07:58:49 -0300 Subject: [PATCH] Backport some fixes from part 2 --- .../Image/TextureBindingsArrayCache.cs | 6 ++-- src/Ryujinx.Graphics.Shader/SamplerType.cs | 30 ++++++++++++++++ .../Translation/ResourceManager.cs | 12 +++++-- .../DescriptorSetUpdater.cs | 34 +++++++++++++++++-- src/Ryujinx.Graphics.Vulkan/ImageArray.cs | 12 ++++++- src/Ryujinx.Graphics.Vulkan/PipelineBase.cs | 10 ++++++ src/Ryujinx.Graphics.Vulkan/TextureArray.cs | 12 +++++-- src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs | 4 +-- 8 files changed, 107 insertions(+), 13 deletions(-) diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs index d2274e7618..eebf9ebc62 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs @@ -463,7 +463,7 @@ namespace Ryujinx.Graphics.Gpu.Image bindingInfo, isImage, ref textureBufferBounds, - out bool isNewEnry); + out bool isNewEntry); bool poolsModified = entry.PoolsModified(); bool isStore = bindingInfo.Flags.HasFlag(TextureUsageFlags.ImageStore); @@ -471,7 +471,7 @@ namespace Ryujinx.Graphics.Gpu.Image ReadOnlySpan cachedTextureBuffer; ReadOnlySpan cachedSamplerBuffer; - if (!poolsModified && !isNewEnry && entry.ValidateTextures()) + if (!poolsModified && !isNewEntry && entry.ValidateTextures()) { if (entry.MatchesSequenceNumber(_context.SequenceNumber)) { @@ -532,7 +532,7 @@ namespace Ryujinx.Graphics.Gpu.Image } } - if (!isNewEnry) + if (!isNewEntry) { entry.Reset(); } diff --git a/src/Ryujinx.Graphics.Shader/SamplerType.cs b/src/Ryujinx.Graphics.Shader/SamplerType.cs index 2185004859..66c748bf3a 100644 --- a/src/Ryujinx.Graphics.Shader/SamplerType.cs +++ b/src/Ryujinx.Graphics.Shader/SamplerType.cs @@ -35,6 +35,36 @@ namespace Ryujinx.Graphics.Shader }; } + public static string ToShortSamplerType(this SamplerType type) + { + string typeName = (type & SamplerType.Mask) switch + { + SamplerType.Texture1D => "1d", + SamplerType.TextureBuffer => "b", + SamplerType.Texture2D => "2d", + SamplerType.Texture3D => "3d", + SamplerType.TextureCube => "cube", + _ => throw new ArgumentException($"Invalid sampler type \"{type}\"."), + }; + + if ((type & SamplerType.Multisample) != 0) + { + typeName += "ms"; + } + + if ((type & SamplerType.Array) != 0) + { + typeName += "a"; + } + + if ((type & SamplerType.Shadow) != 0) + { + typeName += "s"; + } + + return typeName; + } + public static string ToGlslSamplerType(this SamplerType type) { string typeName = (type & SamplerType.Mask) switch diff --git a/src/Ryujinx.Graphics.Shader/Translation/ResourceManager.cs b/src/Ryujinx.Graphics.Shader/Translation/ResourceManager.cs index b831c012ec..e9fe0b1ee5 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/ResourceManager.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/ResourceManager.cs @@ -319,16 +319,22 @@ namespace Ryujinx.Graphics.Shader.Translation } string nameSuffix; + string prefix = isImage ? "i" : "t"; + + if (arrayLength != 1 && type != SamplerType.None) + { + prefix += type.ToShortSamplerType(); + } if (isImage) { nameSuffix = cbufSlot < 0 - ? $"i_tcb_{handle:X}_{format.ToGlslFormat()}" - : $"i_cb{cbufSlot}_{handle:X}_{format.ToGlslFormat()}"; + ? $"{prefix}_tcb_{handle:X}_{format.ToGlslFormat()}" + : $"{prefix}_cb{cbufSlot}_{handle:X}_{format.ToGlslFormat()}"; } else { - nameSuffix = cbufSlot < 0 ? $"t_tcb_{handle:X}" : $"t_cb{cbufSlot}_{handle:X}"; + nameSuffix = cbufSlot < 0 ? $"{prefix}_tcb_{handle:X}" : $"{prefix}_cb{cbufSlot}_{handle:X}"; } var definition = new TextureDefinition( diff --git a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs index 0933aec3da..a0299a3720 100644 --- a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs +++ b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs @@ -501,8 +501,18 @@ namespace Ryujinx.Graphics.Vulkan if (_textureArrayRefs[binding].Stage != stage || _textureArrayRefs[binding].Array != array) { + if (_textureArrayRefs[binding].Array != null) + { + _textureArrayRefs[binding].Array.Bound = false; + } + + if (array is TextureArray textureArray) + { + textureArray.Bound = true; + textureArray.QueueWriteToReadBarriers(cbs, stage.ConvertToPipelineStageFlags()); + } + _textureArrayRefs[binding] = new ArrayRef(stage, array as TextureArray); - _textureArrayRefs[binding].Array?.QueueWriteToReadBarriers(cbs, stage.ConvertToPipelineStageFlags()); SignalDirty(DirtyFlags.Texture); } @@ -517,8 +527,18 @@ namespace Ryujinx.Graphics.Vulkan if (_imageArrayRefs[binding].Stage != stage || _imageArrayRefs[binding].Array != array) { + if (_imageArrayRefs[binding].Array != null) + { + _imageArrayRefs[binding].Array.Bound = false; + } + + if (array is ImageArray imageArray) + { + imageArray.Bound = true; + imageArray.QueueWriteToReadBarriers(cbs, stage.ConvertToPipelineStageFlags()); + } + _imageArrayRefs[binding] = new ArrayRef(stage, array as ImageArray); - _imageArrayRefs[binding].Array?.QueueWriteToReadBarriers(cbs, stage.ConvertToPipelineStageFlags()); SignalDirty(DirtyFlags.Image); } @@ -922,6 +942,16 @@ namespace Ryujinx.Graphics.Vulkan AdvancePdSequence(); } + public void ForceTextureDirty() + { + SignalDirty(DirtyFlags.Texture); + } + + public void ForceImageDirty() + { + SignalDirty(DirtyFlags.Image); + } + private static void SwapBuffer(BufferRef[] list, Auto from, Auto to) { for (int i = 0; i < list.Length; i++) diff --git a/src/Ryujinx.Graphics.Vulkan/ImageArray.cs b/src/Ryujinx.Graphics.Vulkan/ImageArray.cs index c0358f38eb..9cc6ba0890 100644 --- a/src/Ryujinx.Graphics.Vulkan/ImageArray.cs +++ b/src/Ryujinx.Graphics.Vulkan/ImageArray.cs @@ -7,6 +7,8 @@ namespace Ryujinx.Graphics.Vulkan { class ImageArray : IImageArray { + private readonly VulkanRenderer _gd; + private record struct TextureRef { public TextureStorage Storage; @@ -27,8 +29,14 @@ namespace Ryujinx.Graphics.Vulkan private readonly bool _isBuffer; - public ImageArray(int size, bool isBuffer) + public bool Bound; + + public bool IsDirty => _storages == null; + + public ImageArray(VulkanRenderer gd, int size, bool isBuffer) { + _gd = gd; + if (isBuffer) { _bufferTextureRefs = new TextureBuffer[size]; @@ -91,6 +99,8 @@ namespace Ryujinx.Graphics.Vulkan { _cachedCommandBufferIndex = -1; _storages = null; + + _gd.PipelineInternal.ForceImageDirty(); } public void QueueWriteToReadBarriers(CommandBufferScoped cbs, PipelineStageFlags stageFlags) diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index d2fcbee0ed..41ab84d941 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -1385,6 +1385,16 @@ namespace Ryujinx.Graphics.Vulkan SignalCommandBufferChange(); } + public void ForceTextureDirty() + { + _descriptorSetUpdater.ForceTextureDirty(); + } + + public void ForceImageDirty() + { + _descriptorSetUpdater.ForceImageDirty(); + } + public unsafe void TextureBarrier() { MemoryBarrier memoryBarrier = new() diff --git a/src/Ryujinx.Graphics.Vulkan/TextureArray.cs b/src/Ryujinx.Graphics.Vulkan/TextureArray.cs index f1e8a67913..6ef9087bcd 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureArray.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureArray.cs @@ -7,7 +7,9 @@ namespace Ryujinx.Graphics.Vulkan { class TextureArray : ITextureArray { - private record struct TextureRef + private readonly VulkanRenderer _gd; + + private struct TextureRef { public TextureStorage Storage; public Auto View; @@ -27,8 +29,12 @@ namespace Ryujinx.Graphics.Vulkan private readonly bool _isBuffer; - public TextureArray(int size, bool isBuffer) + public bool Bound; + + public TextureArray(VulkanRenderer gd, int size, bool isBuffer) { + _gd = gd; + if (isBuffer) { _bufferTextureRefs = new TextureBuffer[size]; @@ -100,6 +106,8 @@ namespace Ryujinx.Graphics.Vulkan { _cachedCommandBufferIndex = -1; _storages = null; + + _gd.PipelineInternal.ForceTextureDirty(); } public void QueueWriteToReadBarriers(CommandBufferScoped cbs, PipelineStageFlags stageFlags) diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs index cd5e0dc935..e75e7f4b4c 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs @@ -506,7 +506,7 @@ namespace Ryujinx.Graphics.Vulkan public IImageArray CreateImageArray(int size, bool isBuffer) { - return new ImageArray(size, isBuffer); + return new ImageArray(this, size, isBuffer); } public IProgram CreateProgram(ShaderSource[] sources, ShaderInfo info) @@ -543,7 +543,7 @@ namespace Ryujinx.Graphics.Vulkan public ITextureArray CreateTextureArray(int size, bool isBuffer) { - return new TextureArray(size, isBuffer); + return new TextureArray(this, size, isBuffer); } internal TextureView CreateTextureView(TextureCreateInfo info)