Просмотр исходного кода

Do not attempt to normalize SNORM image buffers on shaders (#2317)

* Do not attempt to normalize SNORM image buffers on shaders

* Shader cache version bump
gdkchan 4 лет назад
Родитель
Сommit
79b3243f54

+ 1 - 1
Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs

@@ -365,7 +365,7 @@ namespace Ryujinx.Graphics.Gpu.Image
                     }
                     }
 
 
                     _context.Methods.BufferManager.SetBufferTextureStorage(hostTexture, texture.Range.GetSubRange(0).Address, texture.Size, bindingInfo, format, true);
                     _context.Methods.BufferManager.SetBufferTextureStorage(hostTexture, texture.Range.GetSubRange(0).Address, texture.Size, bindingInfo, format, true);
-                } 
+                }
                 else if (isStore)
                 else if (isStore)
                 {
                 {
                     texture?.SignalModified();
                     texture?.SignalModified();

+ 1 - 1
Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs

@@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
         /// <summary>
         /// <summary>
         /// Version of the codegen (to be changed when codegen or guest format change).
         /// Version of the codegen (to be changed when codegen or guest format change).
         /// </summary>
         /// </summary>
-        private const ulong ShaderCodeGenVersion = 2301;
+        private const ulong ShaderCodeGenVersion = 2317;
 
 
         // Progress reporting helpers
         // Progress reporting helpers
         private volatile int _shaderCount;
         private volatile int _shaderCount;

+ 21 - 11
Ryujinx.Graphics.Shader/Translation/Rewriter.cs

@@ -18,7 +18,7 @@ namespace Ryujinx.Graphics.Shader.Translation
 
 
                 for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
                 for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
                 {
                 {
-                    if (!(node.Value is Operation operation))
+                    if (node.Value is not Operation operation)
                     {
                     {
                         continue;
                         continue;
                     }
                     }
@@ -33,11 +33,11 @@ namespace Ryujinx.Graphics.Shader.Translation
                         if (texOp.Inst == Instruction.TextureSample)
                         if (texOp.Inst == Instruction.TextureSample)
                         {
                         {
                             node = RewriteTextureSample(node, config);
                             node = RewriteTextureSample(node, config);
-                        }
 
 
-                        if (texOp.Type == SamplerType.TextureBuffer)
-                        {
-                            node = InsertSnormNormalization(node, config);
+                            if (texOp.Type == SamplerType.TextureBuffer)
+                            {
+                                node = InsertSnormNormalization(node, config);
+                            }
                         }
                         }
                     }
                     }
                 }
                 }
@@ -147,14 +147,15 @@ namespace Ryujinx.Graphics.Shader.Translation
 
 
             bool hasInvalidOffset = (hasOffset || hasOffsets) && !config.GpuAccessor.QuerySupportsNonConstantTextureOffset();
             bool hasInvalidOffset = (hasOffset || hasOffsets) && !config.GpuAccessor.QuerySupportsNonConstantTextureOffset();
 
 
-            bool isRect = config.GpuAccessor.QueryIsTextureRectangle(texOp.Handle, texOp.CbufSlot);
+            bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
+
+            bool isRect = !isBindless && config.GpuAccessor.QueryIsTextureRectangle(texOp.Handle, texOp.CbufSlot);
 
 
             if (!(hasInvalidOffset || isRect))
             if (!(hasInvalidOffset || isRect))
             {
             {
                 return node;
                 return node;
             }
             }
-
-            bool isBindless     = (texOp.Flags & TextureFlags.Bindless)    != 0;
+            
             bool isGather       = (texOp.Flags & TextureFlags.Gather)      != 0;
             bool isGather       = (texOp.Flags & TextureFlags.Gather)      != 0;
             bool hasDerivatives = (texOp.Flags & TextureFlags.Derivatives) != 0;
             bool hasDerivatives = (texOp.Flags & TextureFlags.Derivatives) != 0;
             bool intCoords      = (texOp.Flags & TextureFlags.IntCoords)   != 0;
             bool intCoords      = (texOp.Flags & TextureFlags.IntCoords)   != 0;
@@ -442,6 +443,13 @@ namespace Ryujinx.Graphics.Shader.Translation
         {
         {
             TextureOperation texOp = (TextureOperation)node.Value;
             TextureOperation texOp = (TextureOperation)node.Value;
 
 
+            // We can't query the format of a bindless texture,
+            // because the handle is unknown, it can have any format.
+            if (texOp.Flags.HasFlag(TextureFlags.Bindless))
+            {
+                return node;
+            }
+
             TextureFormat format = config.GpuAccessor.QueryTextureFormat(texOp.Handle, texOp.CbufSlot);
             TextureFormat format = config.GpuAccessor.QueryTextureFormat(texOp.Handle, texOp.CbufSlot);
 
 
             int maxPositive = format switch
             int maxPositive = format switch
@@ -455,13 +463,15 @@ namespace Ryujinx.Graphics.Shader.Translation
                 _                               => 0
                 _                               => 0
             };
             };
 
 
-            // The value being 0 means that the format is not a SNORM format, so there's nothing to do here.
+            // The value being 0 means that the format is not a SNORM format,
+            // so there's nothing to do here.
             if (maxPositive == 0)
             if (maxPositive == 0)
             {
             {
                 return node;
                 return node;
             }
             }
 
 
-            // Do normalization. We assume SINT formats are being used as replacement for SNORM (that is not supported).
+            // Do normalization. We assume SINT formats are being used
+            // as replacement for SNORM (which is not supported).
             INode[] uses = texOp.Dest.UseOps.ToArray();
             INode[] uses = texOp.Dest.UseOps.ToArray();
 
 
             Operation convOp = new Operation(Instruction.ConvertS32ToFP, Local(), texOp.Dest);
             Operation convOp = new Operation(Instruction.ConvertS32ToFP, Local(), texOp.Dest);
@@ -472,7 +482,7 @@ namespace Ryujinx.Graphics.Shader.Translation
 
 
             foreach (INode useOp in uses)
             foreach (INode useOp in uses)
             {
             {
-                if (!(useOp is Operation op))
+                if (useOp is not Operation op)
                 {
                 {
                     continue;
                     continue;
                 }
                 }