From 15489c57c3523c8507d0aafcfe0a7ad8f7ec0081 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 28 Aug 2018 22:03:00 -0300 Subject: [PATCH] Shaders: Handle Ipa PASS argument as needed in Fragment Shaders --- Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs | 26 ++++++++++++++++++- .../Gal/Shader/ShaderDecodeAlu.cs | 6 ++++- Ryujinx.Graphics/Gal/Shader/ShaderIpaMode.cs | 10 +++++++ .../Gal/Shader/ShaderIrMetaIpa.cs | 12 +++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 Ryujinx.Graphics/Gal/Shader/ShaderIpaMode.cs create mode 100644 Ryujinx.Graphics/Gal/Shader/ShaderIrMetaIpa.cs diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs index 984684f16b..35dd1291e6 100644 --- a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs +++ b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs @@ -1038,7 +1038,31 @@ namespace Ryujinx.Graphics.Gal.Shader return "int(uint(" + GetOperExpr(Op, Op.OperandA) + "))"; } - private string GetIpaExpr(ShaderIrOp Op) => GetSrcExpr(Op.OperandA); + private string GetIpaExpr(ShaderIrOp Op) + { + ShaderIrMetaIpa Meta = (ShaderIrMetaIpa)Op.MetaData; + + ShaderIrOperAbuf Abuf = (ShaderIrOperAbuf)Op.OperandA; + + if (Meta.Mode == ShaderIpaMode.Pass) + { + int Index = Abuf.Offs >> 4; + int Elem = (Abuf.Offs >> 2) & 3; + + if (Decl.ShaderType == GalShaderType.Fragment && Index == GlslDecl.GlPositionVec4Index) + { + switch (Elem) + { + case 0: return "gl_FragCoord.x"; + case 1: return "gl_FragCoord.y"; + case 2: return "gl_FragCoord.z"; + case 3: return "1"; + } + } + } + + return GetSrcExpr(Op.OperandA); + } private string GetKilExpr(ShaderIrOp Op) => "discard"; diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs index b60da7c1c3..3c9cbe9cc4 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs @@ -208,7 +208,11 @@ namespace Ryujinx.Graphics.Gal.Shader ShaderIrNode OperA = GetOperAbuf28(OpCode); ShaderIrNode OperB = GetOperGpr20 (OpCode); - ShaderIrOp Op = new ShaderIrOp(ShaderIrInst.Ipa, OperA, OperB); + ShaderIpaMode Mode = (ShaderIpaMode)((OpCode >> 54) & 3); + + ShaderIrMetaIpa Meta = new ShaderIrMetaIpa(Mode); + + ShaderIrOp Op = new ShaderIrOp(ShaderIrInst.Ipa, OperA, OperB, null, Meta); Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode)); } diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIpaMode.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIpaMode.cs new file mode 100644 index 0000000000..b3713fa483 --- /dev/null +++ b/Ryujinx.Graphics/Gal/Shader/ShaderIpaMode.cs @@ -0,0 +1,10 @@ +namespace Ryujinx.Graphics.Gal.Shader +{ + enum ShaderIpaMode + { + Pass = 0, + None = 1, + Constant = 2, + Sc = 3 + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrMetaIpa.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrMetaIpa.cs new file mode 100644 index 0000000000..3b884621b0 --- /dev/null +++ b/Ryujinx.Graphics/Gal/Shader/ShaderIrMetaIpa.cs @@ -0,0 +1,12 @@ +namespace Ryujinx.Graphics.Gal.Shader +{ + class ShaderIrMetaIpa : ShaderIrMeta + { + public ShaderIpaMode Mode { get; private set; } + + public ShaderIrMetaIpa(ShaderIpaMode Mode) + { + this.Mode = Mode; + } + } +} \ No newline at end of file