Преглед изворни кода

Improve shader sending method to GAL, use a memory interface instead of reading a fixed array size and sending every time

gdkchan пре 8 година
родитељ
комит
79e0070363

+ 1 - 6
Ryujinx.Core/Gpu/NvGpuEngine3d.cs

@@ -138,16 +138,11 @@ namespace Ryujinx.Core.Gpu
 
 
                 long Tag = BasePosition + (uint)Offset;
                 long Tag = BasePosition + (uint)Offset;
 
 
-                //TODO: Find a better way to calculate the size.
-                int Size = 0x20000;
-
-                byte[] Code = Vmm.ReadBytes(Tag, Size);
-
                 GalShaderType ShaderType = GetTypeFromProgram(Index);
                 GalShaderType ShaderType = GetTypeFromProgram(Index);
 
 
                 Tags[(int)ShaderType] = Tag;
                 Tags[(int)ShaderType] = Tag;
 
 
-                Gpu.Renderer.CreateShader(Tag, ShaderType, Code);
+                Gpu.Renderer.CreateShader(Vmm, Tag, ShaderType);
                 Gpu.Renderer.BindShader(Tag);
                 Gpu.Renderer.BindShader(Tag);
             }
             }
 
 

+ 3 - 1
Ryujinx.Core/Gpu/NvGpuVmm.cs

@@ -1,9 +1,11 @@
 using ChocolArm64.Memory;
 using ChocolArm64.Memory;
 using System.Collections.Concurrent;
 using System.Collections.Concurrent;
 
 
+using Ryujinx.Graphics.Gal;
+
 namespace Ryujinx.Core.Gpu
 namespace Ryujinx.Core.Gpu
 {
 {
-    public class NvGpuVmm : IAMemory
+    public class NvGpuVmm : IAMemory, IGalMemory
     {
     {
         public const long AddrSize = 1L << 40;
         public const long AddrSize = 1L << 40;
 
 

+ 7 - 0
Ryujinx.Graphics/Gal/IGalMemory.cs

@@ -0,0 +1,7 @@
+namespace Ryujinx.Graphics.Gal
+{
+    public unsafe interface IGalMemory
+    {
+        int ReadInt32(long Position);
+    }
+}

+ 1 - 1
Ryujinx.Graphics/Gal/IGalRenderer.cs

@@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Gal
         void DrawElements(int VbIndex, int First, GalPrimitiveType PrimType);
         void DrawElements(int VbIndex, int First, GalPrimitiveType PrimType);
 
 
         //Shader
         //Shader
-        void CreateShader(long Tag, GalShaderType Type, byte[] Data);
+        void CreateShader(IGalMemory Memory, long Tag, GalShaderType Type);
 
 
         IEnumerable<ShaderDeclInfo> GetTextureUsage(long Tag);
         IEnumerable<ShaderDeclInfo> GetTextureUsage(long Tag);
 
 

+ 6 - 21
Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs

@@ -3,7 +3,6 @@ using Ryujinx.Graphics.Gal.Shader;
 using System;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.IO;
 using System.Linq;
 using System.Linq;
 
 
 namespace Ryujinx.Graphics.Gal.OpenGL
 namespace Ryujinx.Graphics.Gal.OpenGL
@@ -85,14 +84,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
             Programs = new Dictionary<ShaderProgram, int>();
             Programs = new Dictionary<ShaderProgram, int>();
         }
         }
 
 
-        public void Create(long Tag, GalShaderType Type, byte[] Data)
+        public void Create(IGalMemory Memory, long Tag, GalShaderType Type)
         {
         {
-            Stages.GetOrAdd(Tag, (Key) => ShaderStageFactory(Type, Tag, Data));
+            Stages.GetOrAdd(Tag, (Key) => ShaderStageFactory(Memory, Tag, Type));
         }
         }
 
 
-        private ShaderStage ShaderStageFactory(GalShaderType Type, long Tag, byte[] Data)
+        private ShaderStage ShaderStageFactory(IGalMemory Memory, long Position, GalShaderType Type)
         {
         {
-            GlslProgram Program = GetGlslProgram(Data, Type);
+            GlslProgram Program = GetGlslProgram(Memory, Position,  Type);
 
 
             return new ShaderStage(
             return new ShaderStage(
                 Type,
                 Type,
@@ -101,25 +100,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
                 Program.Uniforms);
                 Program.Uniforms);
         }
         }
 
 
-        private GlslProgram GetGlslProgram(byte[] Data, GalShaderType Type)
+        private GlslProgram GetGlslProgram(IGalMemory Memory, long Position, GalShaderType Type)
         {
         {
-            int[] Code = new int[(Data.Length - 0x50) >> 2];
-
-            using (MemoryStream MS = new MemoryStream(Data))
-            {
-                MS.Seek(0x50, SeekOrigin.Begin);
-
-                BinaryReader Reader = new BinaryReader(MS);
-
-                for (int Index = 0; Index < Code.Length; Index++)
-                {
-                    Code[Index] = Reader.ReadInt32();
-                }
-            }
-
             GlslDecompiler Decompiler = new GlslDecompiler();
             GlslDecompiler Decompiler = new GlslDecompiler();
 
 
-            return Decompiler.Decompile(Code, Type);
+            return Decompiler.Decompile(Memory, Position + 0x50, Type);
         }
         }
 
 
         public IEnumerable<ShaderDeclInfo> GetTextureUsage(long Tag)
         public IEnumerable<ShaderDeclInfo> GetTextureUsage(long Tag)

+ 4 - 4
Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs

@@ -198,14 +198,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
             ActionsQueue.Enqueue(() => Rasterizer.DrawElements(VbIndex, First, PrimType));
             ActionsQueue.Enqueue(() => Rasterizer.DrawElements(VbIndex, First, PrimType));
         }
         }
 
 
-        public void CreateShader(long Tag, GalShaderType Type, byte[] Data)
+        public void CreateShader(IGalMemory Memory, long Tag, GalShaderType Type)
         {
         {
-            if (Data == null)
+            if (Memory == null)
             {
             {
-                throw new ArgumentNullException(nameof(Data));
+                throw new ArgumentNullException(nameof(Memory));
             }
             }
 
 
-            Shader.Create(Tag, Type, Data);
+            Shader.Create(Memory, Tag, Type);
         }
         }
 
 
         public void SetConstBuffer(long Tag, int Cbuf, byte[] Data)
         public void SetConstBuffer(long Tag, int Cbuf, byte[] Data)

+ 2 - 2
Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs

@@ -89,9 +89,9 @@ namespace Ryujinx.Graphics.Gal.Shader
             };
             };
         }
         }
 
 
-        public GlslProgram Decompile(int[] Code, GalShaderType ShaderType)
+        public GlslProgram Decompile(IGalMemory Memory, long Position, GalShaderType ShaderType)
         {
         {
-            ShaderIrBlock Block = ShaderDecoder.DecodeBasicBlock(Code, 0);
+            ShaderIrBlock Block = ShaderDecoder.DecodeBasicBlock(Memory, Position);
 
 
             ShaderIrNode[] Nodes = Block.GetNodes();
             ShaderIrNode[] Nodes = Block.GetNodes();
 
 

+ 1 - 1
Ryujinx.Graphics/Gal/Shader/ShaderDecodeFlow.cs

@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Gal.Shader
                 throw new NotImplementedException();
                 throw new NotImplementedException();
             }
             }
 
 
-            int Target = ((int)(OpCode >> 20) << 8) >> 8;
+            long Target = ((int)(OpCode >> 20) << 8) >> 8;
 
 
             Target += Block.Position + 8;
             Target += Block.Position + 8;
 
 

+ 11 - 11
Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs

@@ -4,28 +4,28 @@ namespace Ryujinx.Graphics.Gal.Shader
     {
     {
         private const bool AddDbgComments = true;
         private const bool AddDbgComments = true;
 
 
-        public static ShaderIrBlock DecodeBasicBlock(int[] Code, int Offset)
+        public static ShaderIrBlock DecodeBasicBlock(IGalMemory Memory, long Position)
         {
         {
             ShaderIrBlock Block = new ShaderIrBlock();
             ShaderIrBlock Block = new ShaderIrBlock();
 
 
-            while (Offset + 2 <= Code.Length)
+            while (true)
             {
             {
-                int InstPos = Offset * 4;
+                Block.Position = Position;
 
 
-                Block.Position = InstPos;
-
-                Block.MarkLabel(InstPos);
+                Block.MarkLabel(Position);
 
 
                 //Ignore scheduling instructions, which are written every 32 bytes.
                 //Ignore scheduling instructions, which are written every 32 bytes.
-                if ((Offset & 7) == 0)
+                if ((Position & 0x1f) == 0)
                 {
                 {
-                    Offset += 2;
+                    Position += 8;
 
 
                     continue;
                     continue;
                 }
                 }
 
 
-                uint Word0 = (uint)Code[Offset++];
-                uint Word1 = (uint)Code[Offset++];
+                uint Word0 = (uint)Memory.ReadInt32(Position + 0);
+                uint Word1 = (uint)Memory.ReadInt32(Position + 4);
+
+                Position += 8;
 
 
                 long OpCode = Word0 | (long)Word1 << 32;
                 long OpCode = Word0 | (long)Word1 << 32;
 
 
@@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Gal.Shader
 
 
                 if (AddDbgComments)
                 if (AddDbgComments)
                 {
                 {
-                    string DbgOpCode = $"0x{InstPos:x8}: 0x{OpCode:x16} ";
+                    string DbgOpCode = $"0x{Position:x16}: 0x{OpCode:x16} ";
 
 
                     Block.AddNode(new ShaderIrCmnt(DbgOpCode + (Decode?.Method.Name ?? "???")));
                     Block.AddNode(new ShaderIrCmnt(DbgOpCode + (Decode?.Method.Name ?? "???")));
                 }
                 }

+ 5 - 5
Ryujinx.Graphics/Gal/Shader/ShaderIrBlock.cs

@@ -6,15 +6,15 @@ namespace Ryujinx.Graphics.Gal.Shader
     {
     {
         private List<ShaderIrNode> Nodes;
         private List<ShaderIrNode> Nodes;
 
 
-        private Dictionary<int, ShaderIrLabel> LabelsToInsert;
+        private Dictionary<long, ShaderIrLabel> LabelsToInsert;
 
 
-        public int Position;
+        public long Position;
 
 
         public ShaderIrBlock()
         public ShaderIrBlock()
         {
         {
             Nodes = new List<ShaderIrNode>();
             Nodes = new List<ShaderIrNode>();
 
 
-            LabelsToInsert = new Dictionary<int, ShaderIrLabel>();
+            LabelsToInsert = new Dictionary<long, ShaderIrLabel>();
         }
         }
 
 
         public void AddNode(ShaderIrNode Node)
         public void AddNode(ShaderIrNode Node)
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gal.Shader
             Nodes.Add(Node);
             Nodes.Add(Node);
         }
         }
 
 
-        public ShaderIrLabel GetLabel(int Position)
+        public ShaderIrLabel GetLabel(long Position)
         {
         {
             if (LabelsToInsert.TryGetValue(Position, out ShaderIrLabel Label))
             if (LabelsToInsert.TryGetValue(Position, out ShaderIrLabel Label))
             {
             {
@@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.Gal.Shader
             return Label;
             return Label;
         }
         }
 
 
-        public void MarkLabel(int Position)
+        public void MarkLabel(long Position)
         {
         {
             if (LabelsToInsert.TryGetValue(Position, out ShaderIrLabel Label))
             if (LabelsToInsert.TryGetValue(Position, out ShaderIrLabel Label))
             {
             {

+ 26 - 0
Ryushader/Memory.cs

@@ -0,0 +1,26 @@
+using Ryujinx.Graphics.Gal;
+using System.IO;
+
+namespace Ryushader
+{
+    class Memory : IGalMemory
+    {
+        private Stream BaseStream;
+
+        private BinaryReader Reader;
+
+        public Memory(Stream BaseStream)
+        {
+            this.BaseStream = BaseStream;
+
+            Reader = new BinaryReader(BaseStream);
+        }
+
+        public int ReadInt32(long Position)
+        {
+            BaseStream.Seek(Position, SeekOrigin.Begin);
+
+            return Reader.ReadInt32();
+        }
+    }
+}

+ 5 - 11
Ryushader/Program.cs

@@ -24,20 +24,14 @@ namespace Ryushader
                     case "f":  ShaderType = GalShaderType.Fragment;       break;
                     case "f":  ShaderType = GalShaderType.Fragment;       break;
                 }
                 }
 
 
-                byte[] Data = File.ReadAllBytes(args[1]);
-
-                int[] Code = new int[Data.Length / 4];
-
-                for (int Offset = 0; Offset + 4 <= Data.Length; Offset += 4)
+                using (FileStream FS = new FileStream(args[1], FileMode.Open, FileAccess.Read))
                 {
                 {
-                    int Value = BitConverter.ToInt32(Data, Offset);
+                    Memory Mem = new Memory(FS);
 
 
-                    Code[Offset >> 2] = Value;
-                }
+                    GlslProgram Program = Decompiler.Decompile(Mem, 0, ShaderType);
 
 
-                GlslProgram Program = Decompiler.Decompile(Code, ShaderType);
-
-                Console.WriteLine(Program.Code);
+                    Console.WriteLine(Program.Code);
+                }
             }
             }
             else
             else
             {
             {