diff --git a/Ryujinx.Graphics/Gal/IGalRenderer.cs b/Ryujinx.Graphics/Gal/IGalRenderer.cs index 9f3310d23b..79d35efcb6 100644 --- a/Ryujinx.Graphics/Gal/IGalRenderer.cs +++ b/Ryujinx.Graphics/Gal/IGalRenderer.cs @@ -23,7 +23,7 @@ namespace Ryujinx.Graphics.Gal //Shader void CreateShader(long Tag, byte[] Data, GalShaderType Type); - void SetShaderCb(int Cbuf, byte[] Data); + void SetShaderCb(long Tag, int Cbuf, byte[] Data); void BindShader(long Tag); void SendVertexBuffer(int Index, byte[] Buffer, int Stride, GalVertexAttrib[] Attribs); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs index 0b0d997661..b286db667c 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs @@ -3,6 +3,7 @@ using Ryujinx.Graphics.Gal.Shader; using System; using System.Collections.Generic; using System.IO; +using System.Linq; namespace Ryujinx.Graphics.Gal.OpenGL { @@ -14,11 +15,19 @@ namespace Ryujinx.Graphics.Gal.OpenGL public GalShaderType Type { get; private set; } - public ShaderStage(GalShaderType Type) + public ICollection TextureUsage { get; private set; } + public ICollection UniformUsage { get; private set; } + + public ShaderStage( + GalShaderType Type, + ICollection TextureUsage, + ICollection UniformUsage) { Handle = GL.CreateShader(OGLEnumConverter.GetShaderType(Type)); - this.Type = Type; + this.Type = Type; + this.TextureUsage = TextureUsage; + this.UniformUsage = UniformUsage; } public void Dispose() @@ -63,21 +72,30 @@ namespace Ryujinx.Graphics.Gal.OpenGL { if (!Stages.ContainsKey(Tag)) { - string Glsl = GetGlslCode(Data, Type); + GlslProgram Program = GetGlslProgram(Data, Type); - System.Console.WriteLine(Glsl); + System.Console.WriteLine(Program.Code); - ShaderStage Stage = new ShaderStage(Type); + ShaderStage Stage = new ShaderStage( + Type, + Program.Textures, + Program.Uniforms); Stages.Add(Tag, Stage); - CompileAndCheck(Stage.Handle, Glsl); + CompileAndCheck(Stage.Handle, Program.Code); } } - public void SetConstBuffer(int Cbuf, byte[] Data) + public void SetConstBuffer(long Tag, int Cbuf, byte[] Data) { - + if (Stages.TryGetValue(Tag, out ShaderStage Stage)) + { + foreach (ShaderDeclInfo DeclInfo in Stage.UniformUsage.Where(x => x.Cbuf == Cbuf)) + { + float Value = BitConverter.ToSingle(Data, DeclInfo.Index * 4); + } + } } public void Bind(long Tag) @@ -138,7 +156,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL } } - private string GetGlslCode(byte[] Data, GalShaderType Type) + private GlslProgram GetGlslProgram(byte[] Data, GalShaderType Type) { int[] Code = new int[(Data.Length - 0x50) >> 2]; @@ -156,7 +174,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL GlslDecompiler Decompiler = new GlslDecompiler(); - return Decompiler.Decompile(Code, Type).Code; + return Decompiler.Decompile(Code, Type); } private static void CompileAndCheck(int Handle, string Code) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs b/Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs index 72661571b5..1a385ebc7d 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OpenGLRenderer.cs @@ -197,7 +197,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL case GalVertexAttribType.Sint: case GalVertexAttribType.Uint: case GalVertexAttribType.Uscaled: - case GalVertexAttribType.Sscaled: + case GalVertexAttribType.Sscaled: { switch (Attrib.Size) { @@ -287,7 +287,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL { GL.ActiveTexture(TextureUnit.Texture0 + Index); - GL.BindTexture(TextureTarget.Texture2D, Textures[Index].Handle); + GL.BindTexture(TextureTarget.Texture2D, Textures[Index].Handle); } public void CreateShader(long Tag, byte[] Data, GalShaderType Type) @@ -300,14 +300,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL ActionsQueue.Enqueue(() => Shader.Create(Tag, Data, Type)); } - public void SetShaderCb(int Cbuf, byte[] Data) + public void SetShaderCb(long Tag, int Cbuf, byte[] Data) { if (Data == null) { throw new ArgumentNullException(nameof(Data)); } - ActionsQueue.Enqueue(() => Shader.SetConstBuffer(Cbuf, Data)); + ActionsQueue.Enqueue(() => Shader.SetConstBuffer(Tag, Cbuf, Data)); } public void BindShader(long Tag) diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs index aa7d9d711d..0fa5d3a151 100644 --- a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs +++ b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs @@ -16,15 +16,15 @@ namespace Ryujinx.Graphics.Gal.Shader private static string[] ElemTypes = new string[] { "float", "vec2", "vec3", "vec4" }; - private Dictionary Textures; + private Dictionary Textures; - private Dictionary<(int, int), GlslDeclInfo> Uniforms; + private Dictionary<(int, int), ShaderDeclInfo> Uniforms; - private Dictionary InputAttributes; - private Dictionary OutputAttributes; + private Dictionary InAttributes; + private Dictionary OutAttributes; - private Dictionary Gprs; - private Dictionary Preds; + private Dictionary Gprs; + private Dictionary Preds; private const int AttrStartIndex = 8; private const int TexStartIndex = 8; @@ -74,26 +74,26 @@ namespace Ryujinx.Graphics.Gal.Shader public GlslProgram Decompile(int[] Code, GalShaderType Type) { - Uniforms = new Dictionary<(int, int), GlslDeclInfo>(); + Uniforms = new Dictionary<(int, int), ShaderDeclInfo>(); - Textures = new Dictionary(); + Textures = new Dictionary(); - InputAttributes = new Dictionary(); - OutputAttributes = new Dictionary(); + InAttributes = new Dictionary(); + OutAttributes = new Dictionary(); - Gprs = new Dictionary(); - Preds = new Dictionary(); + Gprs = new Dictionary(); + Preds = new Dictionary(); SB = new StringBuilder(); //FIXME: Only valid for vertex shaders. if (Type == GalShaderType.Fragment) { - Gprs.Add(0, new GlslDeclInfo("FragColor", 0, 0, 4)); + Gprs.Add(0, new ShaderDeclInfo("FragColor", 0, 0, 4)); } else { - OutputAttributes.Add(7, new GlslDeclInfo("gl_Position", -1, 0, 4)); + OutAttributes.Add(7, new ShaderDeclInfo("gl_Position", -1, 0, 4)); } ShaderIrBlock Block = ShaderDecoder.DecodeBasicBlock(Code, 0, Type); @@ -116,15 +116,12 @@ namespace Ryujinx.Graphics.Gal.Shader PrintBlockScope("void main()", 1, Nodes); - GlslProgram Program = new GlslProgram(); + string GlslCode = SB.ToString(); - Program.Code = SB.ToString(); - - Program.Attributes = InputAttributes.Values.ToArray(); - - SB.Clear(); - - return Program; + return new GlslProgram( + GlslCode, + Textures.Values, + Uniforms.Values); } private void Traverse(ShaderIrNode Parent, ShaderIrNode Node) @@ -164,7 +161,7 @@ namespace Ryujinx.Graphics.Gal.Shader string Name = $"{TextureName}{Index}"; - Textures.TryAdd(Handle, new GlslDeclInfo(Name, Index)); + Textures.TryAdd(Handle, new ShaderDeclInfo(Name, Index)); } break; } @@ -173,7 +170,7 @@ namespace Ryujinx.Graphics.Gal.Shader { string Name = $"{UniformName}{Cbuf.Index}_{Cbuf.Offs}"; - GlslDeclInfo DeclInfo = new GlslDeclInfo(Name, Cbuf.Offs, Cbuf.Index); + ShaderDeclInfo DeclInfo = new ShaderDeclInfo(Name, Cbuf.Offs, Cbuf.Index); Uniforms.TryAdd((Cbuf.Index, Cbuf.Offs), DeclInfo); @@ -187,24 +184,24 @@ namespace Ryujinx.Graphics.Gal.Shader int GlslIndex = Index - AttrStartIndex; - GlslDeclInfo DeclInfo; + ShaderDeclInfo DeclInfo; if (Parent is ShaderIrAsg Asg && Asg.Dst == Node) { - if (!OutputAttributes.TryGetValue(Index, out DeclInfo)) + if (!OutAttributes.TryGetValue(Index, out DeclInfo)) { - DeclInfo = new GlslDeclInfo(OutputName + GlslIndex, GlslIndex); + DeclInfo = new ShaderDeclInfo(OutputName + GlslIndex, GlslIndex); - OutputAttributes.Add(Index, DeclInfo); + OutAttributes.Add(Index, DeclInfo); } } else { - if (!InputAttributes.TryGetValue(Index, out DeclInfo)) + if (!InAttributes.TryGetValue(Index, out DeclInfo)) { - DeclInfo = new GlslDeclInfo(InputAttrName + GlslIndex, GlslIndex); + DeclInfo = new ShaderDeclInfo(InputAttrName + GlslIndex, GlslIndex); - InputAttributes.Add(Index, DeclInfo); + InAttributes.Add(Index, DeclInfo); } } @@ -219,7 +216,7 @@ namespace Ryujinx.Graphics.Gal.Shader { string Name = $"{GprName}{Gpr.Index}"; - Gprs.TryAdd(Gpr.Index, new GlslDeclInfo(Name, Gpr.Index)); + Gprs.TryAdd(Gpr.Index, new ShaderDeclInfo(Name, Gpr.Index)); } break; } @@ -230,7 +227,7 @@ namespace Ryujinx.Graphics.Gal.Shader { string Name = $"{PredName}{Pred.Index}"; - Preds.TryAdd(Pred.Index, new GlslDeclInfo(Name, Pred.Index)); + Preds.TryAdd(Pred.Index, new ShaderDeclInfo(Name, Pred.Index)); } break; } @@ -244,7 +241,7 @@ namespace Ryujinx.Graphics.Gal.Shader private void PrintDeclUniforms() { - foreach (GlslDeclInfo DeclInfo in Uniforms.Values.OrderBy(DeclKeySelector)) + foreach (ShaderDeclInfo DeclInfo in Uniforms.Values.OrderBy(DeclKeySelector)) { SB.AppendLine($"uniform {GetDecl(DeclInfo)};"); } @@ -257,19 +254,19 @@ namespace Ryujinx.Graphics.Gal.Shader private void PrintDeclInAttributes() { - PrintDeclAttributes(InputAttributes.Values, "in"); + PrintDeclAttributes(InAttributes.Values, "in"); } private void PrintDeclOutAttributes() { - PrintDeclAttributes(OutputAttributes.Values, "out"); + PrintDeclAttributes(OutAttributes.Values, "out"); } - private void PrintDeclAttributes(ICollection Decls, string InOut) + private void PrintDeclAttributes(ICollection Decls, string InOut) { bool PrintNl = false; - foreach (GlslDeclInfo DeclInfo in Decls.OrderBy(DeclKeySelector)) + foreach (ShaderDeclInfo DeclInfo in Decls.OrderBy(DeclKeySelector)) { if (DeclInfo.Index >= 0) { @@ -295,9 +292,9 @@ namespace Ryujinx.Graphics.Gal.Shader PrintDecls(Preds.Values, "bool"); } - private void PrintDecls(ICollection Decls, string CustomType = null) + private void PrintDecls(ICollection Decls, string CustomType = null) { - foreach (GlslDeclInfo DeclInfo in Decls.OrderBy(DeclKeySelector)) + foreach (ShaderDeclInfo DeclInfo in Decls.OrderBy(DeclKeySelector)) { string Name; @@ -319,12 +316,12 @@ namespace Ryujinx.Graphics.Gal.Shader } } - private int DeclKeySelector(GlslDeclInfo DeclInfo) + private int DeclKeySelector(ShaderDeclInfo DeclInfo) { return DeclInfo.Cbuf << 24 | DeclInfo.Index; } - private string GetDecl(GlslDeclInfo DeclInfo) + private string GetDecl(ShaderDeclInfo DeclInfo) { return $"{ElemTypes[DeclInfo.Size - 1]} {DeclInfo.Name}"; } @@ -362,14 +359,9 @@ namespace Ryujinx.Graphics.Gal.Shader PrintBlockScope(SubScopeName, IdentationLevel + 1, Cond.Child); } - else if (Node is ShaderIrAsg Asg) + else if (Node is ShaderIrAsg Asg && IsValidOutOper(Asg.Dst)) { - if (IsValidOutOper(Asg.Dst)) - { - SB.AppendLine(Identation + - $"{GetOutOperName(Asg.Dst)} = " + - $"{GetInOperName (Asg.Src, true)};"); - } + SB.AppendLine($"{Identation}{GetOutOperName(Asg.Dst)} = {GetInOperName(Asg.Src, true)};"); } else if (Node is ShaderIrOp Op) { @@ -469,7 +461,7 @@ namespace Ryujinx.Graphics.Gal.Shader private string GetName(ShaderIrOperCbuf Cbuf) { - if (!Uniforms.TryGetValue((Cbuf.Index, Cbuf.Offs), out GlslDeclInfo DeclInfo)) + if (!Uniforms.TryGetValue((Cbuf.Index, Cbuf.Offs), out ShaderDeclInfo DeclInfo)) { throw new InvalidOperationException(); } @@ -479,20 +471,20 @@ namespace Ryujinx.Graphics.Gal.Shader private string GetOutAbufName(ShaderIrOperAbuf Abuf) { - return GetName(OutputAttributes, Abuf, Swizzle: true); + return GetName(OutAttributes, Abuf, Swizzle: true); } private string GetName(ShaderIrOperAbuf Abuf, bool Swizzle = true) { - return GetName(InputAttributes, Abuf, Swizzle); + return GetName(InAttributes, Abuf, Swizzle); } - private string GetName(Dictionary Decls, ShaderIrOperAbuf Abuf, bool Swizzle) + private string GetName(Dictionary Decls, ShaderIrOperAbuf Abuf, bool Swizzle) { int Index = Abuf.Offs >> 4; int Elem = (Abuf.Offs >> 2) & 3; - if (!Decls.TryGetValue(Index, out GlslDeclInfo DeclInfo)) + if (!Decls.TryGetValue(Index, out ShaderDeclInfo DeclInfo)) { throw new InvalidOperationException(); } @@ -517,11 +509,11 @@ namespace Ryujinx.Graphics.Gal.Shader return Pred.IsConst ? "true" : GetNameWithSwizzle(Preds, Pred.Index); } - private string GetNameWithSwizzle(Dictionary Decls, int Index) + private string GetNameWithSwizzle(Dictionary Decls, int Index) { int VecIndex = Index >> 2; - if (Decls.TryGetValue(VecIndex, out GlslDeclInfo DeclInfo)) + if (Decls.TryGetValue(VecIndex, out ShaderDeclInfo DeclInfo)) { if (DeclInfo.Size > 1 && Index < VecIndex + DeclInfo.Size) { @@ -674,7 +666,7 @@ namespace Ryujinx.Graphics.Gal.Shader int Handle = ((ShaderIrOperImm)Op.OperandC).Imm; - if (!Textures.TryGetValue(Handle, out GlslDeclInfo DeclInfo)) + if (!Textures.TryGetValue(Handle, out ShaderDeclInfo DeclInfo)) { throw new InvalidOperationException(); } diff --git a/Ryujinx.Graphics/Gal/Shader/GlslProgram.cs b/Ryujinx.Graphics/Gal/Shader/GlslProgram.cs index 4be9299cdf..8a77694832 100644 --- a/Ryujinx.Graphics/Gal/Shader/GlslProgram.cs +++ b/Ryujinx.Graphics/Gal/Shader/GlslProgram.cs @@ -1,10 +1,22 @@ +using System.Collections.Generic; + namespace Ryujinx.Graphics.Gal.Shader { struct GlslProgram { - public string Code; + public string Code { get; private set; } - public GlslDeclInfo[] ConstBuffers; - public GlslDeclInfo[] Attributes; + public ICollection Textures { get; private set; } + public ICollection Uniforms { get; private set; } + + public GlslProgram( + string Code, + ICollection Textures, + ICollection Uniforms) + { + this.Code = Code; + this.Textures = Textures; + this.Uniforms = Uniforms; + } } } \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDeclInfo.cs b/Ryujinx.Graphics/Gal/ShaderDeclInfo.cs similarity index 71% rename from Ryujinx.Graphics/Gal/Shader/GlslDeclInfo.cs rename to Ryujinx.Graphics/Gal/ShaderDeclInfo.cs index 19a54d1bb3..d400850c86 100644 --- a/Ryujinx.Graphics/Gal/Shader/GlslDeclInfo.cs +++ b/Ryujinx.Graphics/Gal/ShaderDeclInfo.cs @@ -1,6 +1,6 @@ -namespace Ryujinx.Graphics.Gal.Shader +namespace Ryujinx.Graphics.Gal { - public class GlslDeclInfo + public class ShaderDeclInfo { public string Name { get; private set; } @@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Gal.Shader public int Cbuf { get; private set; } public int Size { get; private set; } - public GlslDeclInfo(string Name, int Index, int Cbuf = 0, int Size = 1) + public ShaderDeclInfo(string Name, int Index, int Cbuf = 0, int Size = 1) { this.Name = Name; this.Index = Index; @@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Gal.Shader this.Size = Size; } - public void Enlarge(int NewSize) + internal void Enlarge(int NewSize) { if (Size < NewSize) { diff --git a/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs b/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs index 2814b65e6e..95d8e537f7 100644 --- a/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs +++ b/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs @@ -89,7 +89,23 @@ namespace Ryujinx.Graphics.Gpu byte[] Code = AMemoryHelper.ReadBytes(Memory, Position, (uint)Size); - Gpu.Renderer.CreateShader(Position, Code, GetTypeFromProgram(Index)); + GalShaderType ShaderType = GetTypeFromProgram(Index); + + Gpu.Renderer.CreateShader(Position, Code, ShaderType); + + for (int Cbuf = 0; Cbuf < Cbs.Length; Cbuf++) + { + ConstBuffer Cb = Cbs[Cbuf]; + + if (Cb.Enabled) + { + long CbPosition = Cb.Position + (int)ShaderType * Cb.Size; + + byte[] Data = AMemoryHelper.ReadBytes(Memory, CbPosition, (uint)Cb.Size); + + Gpu.Renderer.SetShaderCb(Position, Cbuf, Data); + } + } } } @@ -155,10 +171,9 @@ namespace Ryujinx.Graphics.Gpu if (TryGetCpuAddr(NvGpuEngine3dReg.CbAddress, out long Position)) { Cbs[Index].Position = Position; + Cbs[Index].Enabled = Enabled; + Cbs[Index].Size = ReadRegister(NvGpuEngine3dReg.CbSize); } - - Cbs[Index].Enabled = Enabled; - Cbs[Index].Size = ReadRegister(NvGpuEngine3dReg.CbSize); } private int ReadCb(AMemory Memory, int Cbuf, int Offset) diff --git a/Ryujinx.Graphics/Gpu/NvGpuFifo.cs b/Ryujinx.Graphics/Gpu/NvGpuFifo.cs index c2be18cba2..df765895c4 100644 --- a/Ryujinx.Graphics/Gpu/NvGpuFifo.cs +++ b/Ryujinx.Graphics/Gpu/NvGpuFifo.cs @@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Gpu { public class NvGpuFifo { - private const int MacrosCount = 32; + private const int MacrosCount = 0x80; private const int MacroIndexMask = MacrosCount - 1; private NsGpu Gpu;