diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2020-03-25 11:49:10 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-03-25 15:49:10 +0100 |
| commit | 1586450a38caabdfe62c10391c28f52f0c88372e (patch) | |
| tree | 969876251e1ddc452494badab1e477f301c170cb /Ryujinx.Graphics.Shader/Decoders | |
| parent | 56374c8633b68bccba774b85140241a8a4173f68 (diff) | |
Implement VMNMX shader instruction (#1032)
* Implement VMNMX shader instruction
* No need for the gap on the enum
* Fix typo
Diffstat (limited to 'Ryujinx.Graphics.Shader/Decoders')
| -rw-r--r-- | Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs | 1 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/Decoders/OpCodeVideo.cs | 85 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/Decoders/VideoPostOp.cs | 14 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/Decoders/VideoType.cs | 15 |
4 files changed, 112 insertions, 3 deletions
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs index 3878dd87..4579d650 100644 --- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs +++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs @@ -205,6 +205,7 @@ namespace Ryujinx.Graphics.Shader.Decoders Set("1101111101001x", InstEmit.Txq, typeof(OpCodeTex)); Set("1101111101010x", InstEmit.TxqB, typeof(OpCodeTex)); Set("01011111xxxxxx", InstEmit.Vmad, typeof(OpCodeVideo)); + Set("0011101xxxxxxx", InstEmit.Vmnmx, typeof(OpCodeVideo)); Set("0101000011011x", InstEmit.Vote, typeof(OpCodeVote)); Set("0100111xxxxxxx", InstEmit.Xmad, typeof(OpCodeAluCbuf)); Set("0011011x00xxxx", InstEmit.Xmad, typeof(OpCodeAluImm)); diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeVideo.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeVideo.cs index 15dcfa98..c2bdc22f 100644 --- a/Ryujinx.Graphics.Shader/Decoders/OpCodeVideo.cs +++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeVideo.cs @@ -6,19 +6,98 @@ namespace Ryujinx.Graphics.Shader.Decoders { public Register Rd { get; } public Register Ra { get; } + public Register Rb { get; } public Register Rc { get; } - public bool SetCondCode { get; protected set; } - public bool Saturate { get; protected set; } + public int Immediate { get; } + + public int RaSelection { get; } + public int RbSelection { get; } + + public bool SetCondCode { get; } + + public bool HasRb { get; } + + public VideoType RaType { get; } + public VideoType RbType { get; } + + public VideoPostOp PostOp { get; } + + public bool DstSigned { get; } + public bool Saturate { get; } public OpCodeVideo(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) { Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr); Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr); + Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr); Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr); + RaSelection = opCode.Extract(36, 2); + RbSelection = opCode.Extract(28, 2); + + RaType = opCode.Extract(37, 2) switch + { + 2 => VideoType.U16, + 3 => VideoType.U32, + _ => VideoType.U8 + }; + + RbType = opCode.Extract(29, 2) switch + { + 2 => VideoType.U16, + 3 => VideoType.U32, + _ => VideoType.U8 + }; + + if (opCode.Extract(48)) + { + RaType |= VideoType.Signed; + } + + if (!opCode.Extract(50)) + { + // Immediate variant. + Immediate = opCode.Extract(16, 20); + + RbType = opCode.Extract(49) ? VideoType.S16 : VideoType.U16; + + if (RbType == VideoType.S16) + { + Immediate = (Immediate << 12) >> 12; + } + } + else if (opCode.Extract(49)) + { + RbType |= VideoType.Signed; + } + + if (RaType == VideoType.U16) + { + RaSelection &= 1; + } + else if (RaType == VideoType.U32) + { + RaSelection = 0; + } + + if (RbType == VideoType.U16) + { + RbSelection &= 1; + } + else if (RbType == VideoType.U32) + { + RbSelection = 0; + } + SetCondCode = opCode.Extract(47); - Saturate = opCode.Extract(55); + + HasRb = opCode.Extract(50); + + PostOp = (VideoPostOp)opCode.Extract(51, 3); + + DstSigned = opCode.Extract(54); + Saturate = opCode.Extract(55); } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/Decoders/VideoPostOp.cs b/Ryujinx.Graphics.Shader/Decoders/VideoPostOp.cs new file mode 100644 index 00000000..65891789 --- /dev/null +++ b/Ryujinx.Graphics.Shader/Decoders/VideoPostOp.cs @@ -0,0 +1,14 @@ +namespace Ryujinx.Graphics.Shader.Decoders +{ + enum VideoPostOp + { + Mrg16h, + Mrg16l, + Mrg8b0, + Mrg8b2, + Acc, + Min, + Max, + Pass + } +} diff --git a/Ryujinx.Graphics.Shader/Decoders/VideoType.cs b/Ryujinx.Graphics.Shader/Decoders/VideoType.cs new file mode 100644 index 00000000..7186e7c3 --- /dev/null +++ b/Ryujinx.Graphics.Shader/Decoders/VideoType.cs @@ -0,0 +1,15 @@ +namespace Ryujinx.Graphics.Shader.Decoders +{ + enum VideoType + { + U8 = 0, + U16 = 1, + U32 = 2, + + Signed = 1 << 2, + + S8 = Signed | U8, + S16 = Signed | U16, + S32 = Signed | U32 + } +} |
