From a8076aaa2f6114c221a70becde5d4421ab57eff6 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 8 Apr 2018 16:06:47 -0300 Subject: [PATCH] [GPU] Fix casting on shader, support reading gl_Position.w on fragment shader --- Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs | 16 +++--- Ryujinx.Graphics/Gal/Shader/GlslDecl.cs | 3 +- Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs | 52 +++++++++++++++---- Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs | 2 - Ryujinx/Ui/Program.cs | 2 + 5 files changed, 55 insertions(+), 20 deletions(-) diff --git a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs index b7c30d2a44..3b3fa1c037 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs @@ -244,12 +244,16 @@ namespace Ryujinx.Core.OsHle.Services.Android { int Slot = ParcelReader.ReadInt32(); - int BufferCount = ParcelReader.ReadInt32(); - long BufferSize = ParcelReader.ReadInt64(); + int BufferCount = ParcelReader.ReadInt32(); - BufferQueue[Slot].State = BufferState.Free; + if (BufferCount > 0) + { + long BufferSize = ParcelReader.ReadInt64(); - BufferQueue[Slot].Data = new GbpBuffer(ParcelReader); + BufferQueue[Slot].State = BufferState.Free; + + BufferQueue[Slot].Data = new GbpBuffer(ParcelReader); + } return MakeReplyParcel(Context, 0); } @@ -429,7 +433,7 @@ namespace Ryujinx.Core.OsHle.Services.Android break; } - Logging.Debug("Waiting for a free BufferQueue slot..."); + Logging.Info("Waiting for a free BufferQueue slot..."); if (!KeepRunning) { @@ -443,7 +447,7 @@ namespace Ryujinx.Core.OsHle.Services.Android } while (KeepRunning); - Logging.Debug($"Found free BufferQueue slot {Slot}!"); + Logging.Info($"Found free BufferQueue slot {Slot}!"); return Slot; } diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs index a6c3b88b1c..898b90b51f 100644 --- a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs +++ b/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs @@ -4,7 +4,8 @@ namespace Ryujinx.Graphics.Gal.Shader { class GlslDecl { - public const int VertexIdAttr = 0x2fc; + public const int VertexIdAttr = 0x2fc; + public const int GlPositionWAttr = 0x7c; private const int AttrStartIndex = 8; private const int TexStartIndex = 8; diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs index 80090137a0..eda70cefa6 100644 --- a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs +++ b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs @@ -302,8 +302,7 @@ namespace Ryujinx.Graphics.Gal.Shader throw new NotImplementedException(Op.Inst.ToString()); } - if (!Entry && (Op.OperandB != null || - Op.OperandC != null)) + if (!Entry && NeedsParentheses(Op)) { Expr = "(" + Expr + ")"; } @@ -314,6 +313,25 @@ namespace Ryujinx.Graphics.Gal.Shader } } + private static bool NeedsParentheses(ShaderIrOp Op) + { + switch (Op.Inst) + { + case ShaderIrInst.Frcp: + return true; + + case ShaderIrInst.Ipa: + case ShaderIrInst.Texr: + case ShaderIrInst.Texg: + case ShaderIrInst.Texb: + case ShaderIrInst.Texa: + return false; + } + + return Op.OperandB != null || + Op.OperandC != null; + } + private string GetName(ShaderIrOperCbuf Cbuf) { if (!Decl.Uniforms.TryGetValue((Cbuf.Index, Cbuf.Offs), out ShaderDeclInfo DeclInfo)) @@ -331,16 +349,21 @@ namespace Ryujinx.Graphics.Gal.Shader private string GetName(ShaderIrOperAbuf Abuf) { - return GetName(Decl.InAttributes, Abuf); - } + if (Abuf.Offs == GlslDecl.GlPositionWAttr && Decl.ShaderType == GalShaderType.Fragment) + { + return "(1f / gl_FragCoord.w)"; + } - private string GetName(IReadOnlyDictionary Dict, ShaderIrOperAbuf Abuf) - { if (Abuf.Offs == GlslDecl.VertexIdAttr) { return "gl_VertexID"; } + return GetName(Decl.InAttributes, Abuf); + } + + private string GetName(IReadOnlyDictionary Dict, ShaderIrOperAbuf Abuf) + { int Index = Abuf.Offs >> 4; int Elem = (Abuf.Offs >> 2) & 3; @@ -439,7 +462,7 @@ namespace Ryujinx.Graphics.Gal.Shader private string GetFnegExpr(ShaderIrOp Op) => GetUnaryExpr(Op, "-"); - private string GetFrcpExpr(ShaderIrOp Op) => GetUnaryExpr(Op, "1 / "); + private string GetFrcpExpr(ShaderIrOp Op) => GetUnaryExpr(Op, "1f / "); private string GetFrsqExpr(ShaderIrOp Op) => GetUnaryCall(Op, "inversesqrt"); @@ -451,16 +474,23 @@ namespace Ryujinx.Graphics.Gal.Shader private string GetLsrExpr(ShaderIrOp Op) { - return "(int)((uint)" + GetOperExpr(Op, Op.OperandA) + " >> " + - GetOperExpr(Op, Op.OperandB) + ")"; + return "int(uint(" + GetOperExpr(Op, Op.OperandA) + ") >> " + + GetOperExpr(Op, Op.OperandB) + ")"; } private string GetNotExpr(ShaderIrOp Op) => GetUnaryExpr(Op, "~"); private string GetOrExpr(ShaderIrOp Op) => GetBinaryExpr(Op, "|"); - private string GetStofExpr(ShaderIrOp Op) => GetUnaryExpr(Op, "(float)"); - private string GetUtofExpr(ShaderIrOp Op) => GetUnaryExpr(Op, "(float)(uint)"); + private string GetStofExpr(ShaderIrOp Op) + { + return "float(" + GetOperExpr(Op, Op.OperandA) + ")"; + } + + private string GetUtofExpr(ShaderIrOp Op) + { + return "float(uint(" + GetOperExpr(Op, Op.OperandA) + "))"; + } private string GetXorExpr(ShaderIrOp Op) => GetBinaryExpr(Op, "^"); diff --git a/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs b/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs index f856e9fa37..f4486f46cf 100644 --- a/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs +++ b/Ryujinx.Graphics/Gpu/NvGpuEngine3d.cs @@ -63,8 +63,6 @@ namespace Ryujinx.Graphics.Gpu } } - private const long GoodFbAddress = 0x1615b2a00; - private void VertexEndGl(AMemory Memory, NsGpuPBEntry PBEntry) { SetFrameBuffer(0); diff --git a/Ryujinx/Ui/Program.cs b/Ryujinx/Ui/Program.cs index bfd07433cc..31f7d4ac5d 100644 --- a/Ryujinx/Ui/Program.cs +++ b/Ryujinx/Ui/Program.cs @@ -12,6 +12,8 @@ namespace Ryujinx { static void Main(string[] args) { + //Ryujinx.Graphics.Gal.Shader.ShaderTest.PrintGlslProgram(File.ReadAllBytes("D:\\shbh_000000000048ba30.bin")); + Config.Read(); AOptimizations.DisableMemoryChecks = !Config.EnableMemoryChecks;