From 17a1cab5d29787f3b41f40a69b530dae4e3cb25f Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 4 Dec 2022 15:36:03 -0300 Subject: [PATCH] Allow SNorm buffer texture formats on Vulkan (#3957) * Allow SNorm buffer texture formats on Vulkan * Shader cache version bump --- Ryujinx.Graphics.GAL/Capabilities.cs | 3 +++ Ryujinx.Graphics.Gpu/Image/TextureCache.cs | 5 ++--- .../Shader/DiskCache/DiskCacheHostStorage.cs | 2 +- Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs | 2 ++ Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs | 1 + Ryujinx.Graphics.Shader/IGpuAccessor.cs | 9 +++++++++ Ryujinx.Graphics.Shader/Translation/Rewriter.cs | 3 ++- Ryujinx.Graphics.Vulkan/VulkanRenderer.cs | 1 + 8 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Ryujinx.Graphics.GAL/Capabilities.cs b/Ryujinx.Graphics.GAL/Capabilities.cs index 60f93bc4..c4428f17 100644 --- a/Ryujinx.Graphics.GAL/Capabilities.cs +++ b/Ryujinx.Graphics.GAL/Capabilities.cs @@ -17,6 +17,7 @@ namespace Ryujinx.Graphics.GAL public readonly bool Supports3DTextureCompression; public readonly bool SupportsBgraFormat; public readonly bool SupportsR4G4Format; + public readonly bool SupportsSnormBufferTextureFormat; public readonly bool SupportsFragmentShaderInterlock; public readonly bool SupportsFragmentShaderOrderingIntel; public readonly bool SupportsGeometryShaderPassthrough; @@ -52,6 +53,7 @@ namespace Ryujinx.Graphics.GAL bool supports3DTextureCompression, bool supportsBgraFormat, bool supportsR4G4Format, + bool supportsSnormBufferTextureFormat, bool supportsFragmentShaderInterlock, bool supportsFragmentShaderOrderingIntel, bool supportsGeometryShaderPassthrough, @@ -84,6 +86,7 @@ namespace Ryujinx.Graphics.GAL Supports3DTextureCompression = supports3DTextureCompression; SupportsBgraFormat = supportsBgraFormat; SupportsR4G4Format = supportsR4G4Format; + SupportsSnormBufferTextureFormat = supportsSnormBufferTextureFormat; SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock; SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel; SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough; diff --git a/Ryujinx.Graphics.Gpu/Image/TextureCache.cs b/Ryujinx.Graphics.Gpu/Image/TextureCache.cs index d76879eb..a6bb5741 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureCache.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureCache.cs @@ -1088,10 +1088,9 @@ namespace Ryujinx.Graphics.Gpu.Image { FormatInfo formatInfo = TextureCompatibility.ToHostCompatibleFormat(info, caps); - if (info.Target == Target.TextureBuffer) + if (info.Target == Target.TextureBuffer && !caps.SupportsSnormBufferTextureFormat) { - // We assume that the host does not support signed normalized format - // (as is the case with OpenGL), so we just use a unsigned format. + // If the host does not support signed normalized formats, we use a signed integer format instead. // The shader will need the appropriate conversion code to compensate. switch (formatInfo.Format) { diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs index 617e4765..5c1b638b 100644 --- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs +++ b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs @@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMinor = 2; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; - private const uint CodeGenVersion = 3943; + private const uint CodeGenVersion = 3957; private const string SharedTocFileName = "shared.toc"; private const string SharedDataFileName = "shared.data"; diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs b/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs index 9648298e..33f06b6e 100644 --- a/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs +++ b/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs @@ -134,6 +134,8 @@ namespace Ryujinx.Graphics.Gpu.Shader public bool QueryHostSupportsShaderBallot() => _context.Capabilities.SupportsShaderBallot; + public bool QueryHostSupportsSnormBufferTextureFormat() => _context.Capabilities.SupportsSnormBufferTextureFormat; + public bool QueryHostSupportsTextureShadowLod() => _context.Capabilities.SupportsTextureShadowLod; public bool QueryHostSupportsViewportIndex() => _context.Capabilities.SupportsViewportIndex; diff --git a/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs b/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs index 63c96fa2..9e008b33 100644 --- a/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs +++ b/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs @@ -113,6 +113,7 @@ namespace Ryujinx.Graphics.OpenGL supports3DTextureCompression: false, supportsBgraFormat: false, supportsR4G4Format: false, + supportsSnormBufferTextureFormat: false, supportsFragmentShaderInterlock: HwCapabilities.SupportsFragmentShaderInterlock, supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering, supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough, diff --git a/Ryujinx.Graphics.Shader/IGpuAccessor.cs b/Ryujinx.Graphics.Shader/IGpuAccessor.cs index cc690eed..337bd314 100644 --- a/Ryujinx.Graphics.Shader/IGpuAccessor.cs +++ b/Ryujinx.Graphics.Shader/IGpuAccessor.cs @@ -285,6 +285,15 @@ namespace Ryujinx.Graphics.Shader return true; } + /// + /// Queries host GPU support for signed normalized buffer texture formats. + /// + /// True if the GPU and driver supports the formats, false otherwise + bool QueryHostSupportsSnormBufferTextureFormat() + { + return true; + } + /// /// Queries host GPU texture shadow LOD support. /// diff --git a/Ryujinx.Graphics.Shader/Translation/Rewriter.cs b/Ryujinx.Graphics.Shader/Translation/Rewriter.cs index 640717f9..bdd9b791 100644 --- a/Ryujinx.Graphics.Shader/Translation/Rewriter.cs +++ b/Ryujinx.Graphics.Shader/Translation/Rewriter.cs @@ -14,6 +14,7 @@ namespace Ryujinx.Graphics.Shader.Translation { bool isVertexShader = config.Stage == ShaderStage.Vertex; bool hasConstantBufferDrawParameters = config.GpuAccessor.QueryHasConstantBufferDrawParameters(); + bool supportsSnormBufferTextureFormat = config.GpuAccessor.QueryHostSupportsSnormBufferTextureFormat(); for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) { @@ -52,7 +53,7 @@ namespace Ryujinx.Graphics.Shader.Translation { node = RewriteTextureSample(node, config); - if (texOp.Type == SamplerType.TextureBuffer) + if (texOp.Type == SamplerType.TextureBuffer && !supportsSnormBufferTextureFormat) { node = InsertSnormNormalization(node, config); } diff --git a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs index 45e614e2..e9472067 100644 --- a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs +++ b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs @@ -402,6 +402,7 @@ namespace Ryujinx.Graphics.Vulkan supports3DTextureCompression: true, supportsBgraFormat: true, supportsR4G4Format: false, + supportsSnormBufferTextureFormat: true, supportsFragmentShaderInterlock: Capabilities.SupportsFragmentShaderInterlock, supportsFragmentShaderOrderingIntel: false, supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,