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/OpCodeVideo.cs | |
| 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/OpCodeVideo.cs')
| -rw-r--r-- | Ryujinx.Graphics.Shader/Decoders/OpCodeVideo.cs | 85 |
1 files changed, 82 insertions, 3 deletions
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 |
