diff --git a/Ryujinx.Graphics.GAL/Capabilities.cs b/Ryujinx.Graphics.GAL/Capabilities.cs index 60f93bc4c5..c4428f175c 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 d76879eb4a..a6bb57419e 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 617e47652d..5c1b638b73 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 9648298e9d..33f06b6e92 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 63c96fa23b..9e008b33eb 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 cc690eedd1..337bd314a0 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 640717f919..bdd9b791ba 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 45e614e21f..e947206724 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,