From e72fd3f7a7cf770283f4cbd4b082677a83daf515 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 1 Sep 2018 18:44:19 -0300 Subject: [PATCH] Shaders: Handle Ipa PASS argument as needed in Fragment Shaders (#392) --- 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 104fd723..ac34400e 100644 --- a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs +++ b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs @@ -1026,7 +1026,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 5eb761da..afff7e9b 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 00000000..b3713fa4 --- /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 00000000..3b884621 --- /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