Răsfoiți Sursa

Fix image units bindings and shader dump in the presence of NOPs

gdk 6 ani în urmă
părinte
comite
d274328c31

+ 24 - 4
Ryujinx.Graphics.Gpu/Engine/ShaderCache.cs

@@ -117,7 +117,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
 
             program = Translator.Translate(code, translationConfig);
 
-            _dumper.Dump(gpuVa, compute : true);
+            _dumper.Dump(code, compute : true, out string fullPath, out string codePath);
+
+            if (fullPath != null && codePath != null)
+            {
+                program.Prepend("// " + codePath);
+                program.Prepend("// " + fullPath);
+            }
 
             return program;
         }
@@ -144,8 +150,16 @@ namespace Ryujinx.Graphics.Gpu.Engine
 
                 program = Translator.Translate(codeA, codeB, translationConfig);
 
-                _dumper.Dump(gpuVaA, compute: false);
-                _dumper.Dump(gpuVa,  compute: false);
+                _dumper.Dump(codeA, compute: false, out string fullPathA, out string codePathA);
+                _dumper.Dump(codeB, compute: false, out string fullPathB, out string codePathB);
+
+                if (fullPathA != null && fullPathB != null && codePathA != null && codePathB != null)
+                {
+                    program.Prepend("// " + codePathB);
+                    program.Prepend("// " + fullPathB);
+                    program.Prepend("// " + codePathA);
+                    program.Prepend("// " + fullPathA);
+                }
             }
             else
             {
@@ -153,7 +167,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
 
                 program = Translator.Translate(code, translationConfig);
 
-                _dumper.Dump(gpuVa, compute: false);
+                _dumper.Dump(code, compute: false, out string fullPath, out string codePath);
+
+                if (fullPath != null && codePath != null)
+                {
+                    program.Prepend("// " + codePath);
+                    program.Prepend("// " + fullPath);
+                }
             }
 
             if (program.Stage == ShaderStage.Geometry)

+ 22 - 40
Ryujinx.Graphics.Gpu/Engine/ShaderDumper.cs

@@ -1,11 +1,11 @@
+using Ryujinx.Graphics.Shader.Translation;
+using System;
 using System.IO;
 
 namespace Ryujinx.Graphics.Gpu.Engine
 {
     class ShaderDumper
     {
-        private const int ShaderHeaderSize = 0x50;
-
         private GpuContext _context;
 
         private string _runtimeDir;
@@ -21,67 +21,49 @@ namespace Ryujinx.Graphics.Gpu.Engine
             _dumpIndex = 1;
         }
 
-        public void Dump(ulong gpuVa, bool compute)
+        public void Dump(Span<byte> code, bool compute, out string fullPath, out string codePath)
         {
             _dumpPath = GraphicsConfig.ShadersDumpPath;
 
             if (string.IsNullOrWhiteSpace(_dumpPath))
             {
+                fullPath = null;
+                codePath = null;
+
                 return;
             }
 
             string fileName = "Shader" + _dumpIndex.ToString("d4") + ".bin";
 
-            string fullPath = Path.Combine(FullDir(), fileName);
-            string codePath = Path.Combine(CodeDir(), fileName);
+            fullPath = Path.Combine(FullDir(), fileName);
+            codePath = Path.Combine(CodeDir(), fileName);
 
             _dumpIndex++;
 
-            ulong headerSize = compute ? 0UL : ShaderHeaderSize;
+            code = Translator.ExtractCode(code, compute, out int headerSize);
 
-            using (FileStream fullFile = File.Create(fullPath))
-            using (FileStream codeFile = File.Create(codePath))
+            using (MemoryStream stream = new MemoryStream(code.ToArray()))
             {
-                BinaryWriter fullWriter = new BinaryWriter(fullFile);
-                BinaryWriter codeWriter = new BinaryWriter(codeFile);
+                BinaryReader codeReader = new BinaryReader(stream);
 
-                for (ulong i = 0; i < headerSize; i += 4)
+                using (FileStream fullFile = File.Create(fullPath))
+                using (FileStream codeFile = File.Create(codePath))
                 {
-                    fullWriter.Write(_context.MemoryAccessor.ReadInt32(gpuVa + i));
-                }
+                    BinaryWriter fullWriter = new BinaryWriter(fullFile);
+                    BinaryWriter codeWriter = new BinaryWriter(codeFile);
 
-                ulong offset = 0;
+                    fullWriter.Write(codeReader.ReadBytes(headerSize));
 
-                ulong instruction = 0;
+                    byte[] temp = codeReader.ReadBytes(code.Length - headerSize);
 
-                // Dump until a NOP instruction is found.
-                while ((instruction >> 48 & 0xfff8) != 0x50b0)
-                {
-                    uint word0 = (uint)_context.MemoryAccessor.ReadInt32(gpuVa + headerSize + offset + 0);
-                    uint word1 = (uint)_context.MemoryAccessor.ReadInt32(gpuVa + headerSize + offset + 4);
-
-                    instruction = word0 | (ulong)word1 << 32;
+                    fullWriter.Write(temp);
+                    codeWriter.Write(temp);
 
-                    // Zero instructions (other kind of NOP) stop immediately,
-                    // this is to avoid two rows of zeroes.
-                    if (instruction == 0)
+                    // Align to meet nvdisasm requirements.
+                    while (codeFile.Length % 0x20 != 0)
                     {
-                        break;
+                        codeWriter.Write(0);
                     }
-
-                    fullWriter.Write(instruction);
-                    codeWriter.Write(instruction);
-
-                    offset += 8;
-                }
-
-                // Align to meet nvdisasm requirements.
-                while (offset % 0x20 != 0)
-                {
-                    fullWriter.Write(0);
-                    codeWriter.Write(0);
-
-                    offset += 4;
                 }
             }
         }

+ 5 - 4
Ryujinx.Graphics.OpenGL/Program.cs

@@ -79,6 +79,7 @@ namespace Ryujinx.Graphics.OpenGL
             int ubBindingPoint = 1;
             int sbBindingPoint = 0;
             int textureUnit    = 0;
+            int imageUnit      = 0;
 
             for (int index = 0; index < shaders.Length; index++)
             {
@@ -151,13 +152,13 @@ namespace Ryujinx.Graphics.OpenGL
                         continue;
                     }
 
-                    GL.Uniform1(location, textureUnit);
+                    GL.Uniform1(location, imageUnit);
 
                     int uIndex = (int)shader.Stage << ImgStageShift | imageIndex++;
 
-                    _textureUnits[uIndex] = textureUnit;
+                    _imageUnits[uIndex] = imageUnit;
 
-                    textureUnit++;
+                    imageUnit++;
                 }
             }
         }
@@ -184,7 +185,7 @@ namespace Ryujinx.Graphics.OpenGL
 
         public int GetImageUnit(ShaderStage stage, int index)
         {
-            return _textureUnits[(int)stage << ImgStageShift | index];
+            return _imageUnits[(int)stage << ImgStageShift | index];
         }
 
         private void CheckProgramLink()