diff options
| author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-08-20 23:31:10 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-08-20 23:31:10 -0300 |
| commit | afc44850be37f57d96e981925229964771a3e9e0 (patch) | |
| tree | 3536a255668499945942c6347e91b7dc8517a05d | |
| parent | afdeee2b866bd5e41dd629553939d9b5d8bc1d50 (diff) | |
Avoid gpr overwritting on Ld_C instruction (#371)
* Avoid gpr overwritting on LD_C instruction
* Address feedback
* Ignore invalid registers
| -rw-r--r-- | Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs | 7 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs | 18 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs | 7 |
3 files changed, 22 insertions, 10 deletions
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs index 7d7b2f6c..2093f070 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs @@ -35,13 +35,6 @@ namespace Ryujinx.Graphics.Gal.Shader (int)(OpCode >> 20) & 0x3fff); } - public static ShaderIrOperCbuf GetOperCbuf36(long OpCode) - { - return new ShaderIrOperCbuf( - (int)(OpCode >> 36) & 0x1f, - (int)(OpCode >> 22) & 0x3fff, GetOperGpr8(OpCode)); - } - public static ShaderIrOperGpr GetOperGpr8(long OpCode) { return new ShaderIrOperGpr((int)(OpCode >> 8) & 0xff); diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs index e794e1f8..a183b0c6 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs @@ -52,23 +52,35 @@ namespace Ryujinx.Graphics.Gal.Shader public static void Ld_C(ShaderIrBlock Block, long OpCode) { - int Type = (int)(OpCode >> 48) & 7; + int CbufPos = (int)(OpCode >> 22) & 0x3fff; + int CbufIndex = (int)(OpCode >> 36) & 0x1f; + int Type = (int)(OpCode >> 48) & 7; if (Type > 5) { throw new InvalidOperationException(); } + ShaderIrOperGpr Temp = ShaderIrOperGpr.MakeTemporary(); + + Block.AddNode(new ShaderIrAsg(Temp, GetOperGpr8(OpCode))); + int Count = Type == 5 ? 2 : 1; for (int Index = 0; Index < Count; Index++) { - ShaderIrOperCbuf OperA = GetOperCbuf36(OpCode); - ShaderIrOperGpr OperD = GetOperGpr0 (OpCode); + ShaderIrOperCbuf OperA = new ShaderIrOperCbuf(CbufIndex, CbufPos, Temp); + + ShaderIrOperGpr OperD = GetOperGpr0(OpCode); OperA.Pos += Index; OperD.Index += Index; + if (!OperD.IsValidRegister) + { + break; + } + ShaderIrNode Node = OperA; if (Type < 4) diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs index 5c69d6a6..9dd196e6 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderIrOperGpr.cs @@ -6,11 +6,18 @@ namespace Ryujinx.Graphics.Gal.Shader public bool IsConst => Index == ZRIndex; + public bool IsValidRegister => (Index <= ZRIndex); + public int Index { get; set; } public ShaderIrOperGpr(int Index) { this.Index = Index; } + + public static ShaderIrOperGpr MakeTemporary(int Index = 0) + { + return new ShaderIrOperGpr(0x100 + Index); + } } }
\ No newline at end of file |
