aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-04-08 16:17:35 -0300
committergdkchan <gab.dark.100@gmail.com>2018-04-08 16:41:38 -0300
commitb9aa3966c00b4bb3ff0292dc28ed53ad26cf284b (patch)
treecd2ab3d65c61ac6c6ceb312116e5d138868a3e18 /Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs
parent7acd0e01226d64d05b2675f6ae07507039a31835 (diff)
Merge shader branch, adding support for GLSL decompilation, a macro
interpreter, and a rewrite of the GPU code.
Diffstat (limited to 'Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs')
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs97
1 files changed, 97 insertions, 0 deletions
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs b/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs
new file mode 100644
index 00000000..48c3b2ee
--- /dev/null
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs
@@ -0,0 +1,97 @@
+using System;
+
+namespace Ryujinx.Graphics.Gal.Shader
+{
+ static class ShaderOpCodeTable
+ {
+ private const int EncodingBits = 14;
+
+ private static ShaderDecodeFunc[] OpCodes;
+
+ static ShaderOpCodeTable()
+ {
+ OpCodes = new ShaderDecodeFunc[1 << EncodingBits];
+
+#region Instructions
+ Set("111000110000xx", ShaderDecode.Exit);
+ Set("0100110001011x", ShaderDecode.Fadd_C);
+ Set("0011100x01011x", ShaderDecode.Fadd_I);
+ Set("0101110001011x", ShaderDecode.Fadd_R);
+ Set("010010011xxxxx", ShaderDecode.Ffma_CR);
+ Set("001100101xxxxx", ShaderDecode.Ffma_I);
+ Set("010100011xxxxx", ShaderDecode.Ffma_RC);
+ Set("010110011xxxxx", ShaderDecode.Ffma_RR);
+ Set("0100110001101x", ShaderDecode.Fmul_C);
+ Set("0011100x01101x", ShaderDecode.Fmul_I);
+ Set("0101110001101x", ShaderDecode.Fmul_R);
+ Set("010010111011xx", ShaderDecode.Fsetp_C);
+ Set("0011011x1011xx", ShaderDecode.Fsetp_I);
+ Set("010110111011xx", ShaderDecode.Fsetp_R);
+ Set("0100110010111x", ShaderDecode.I2f_C);
+ Set("0011100x10111x", ShaderDecode.I2f_I);
+ Set("0101110010111x", ShaderDecode.I2f_R);
+ Set("11100000xxxxxx", ShaderDecode.Ipa);
+ Set("111000110011xx", ShaderDecode.Kil);
+ Set("1110111111011x", ShaderDecode.Ld_A);
+ Set("000001xxxxxxxx", ShaderDecode.Lop32i);
+ Set("000000010000xx", ShaderDecode.Mov32i);
+ Set("0101000010000x", ShaderDecode.Mufu);
+ Set("0100110000101x", ShaderDecode.Shr_C);
+ Set("0011100x00101x", ShaderDecode.Shr_I);
+ Set("0101110000101x", ShaderDecode.Shr_R);
+ Set("1110111111110x", ShaderDecode.St_A);
+ Set("1101100xxxxxxx", ShaderDecode.Texs);
+#endregion
+ }
+
+ private static void Set(string Encoding, ShaderDecodeFunc Func)
+ {
+ if (Encoding.Length != EncodingBits)
+ {
+ throw new ArgumentException(nameof(Encoding));
+ }
+
+ int Bit = Encoding.Length - 1;
+ int Value = 0;
+ int XMask = 0;
+ int XBits = 0;
+
+ int[] XPos = new int[Encoding.Length];
+
+ for (int Index = 0; Index < Encoding.Length; Index++, Bit--)
+ {
+ char Chr = Encoding[Index];
+
+ if (Chr == '1')
+ {
+ Value |= 1 << Bit;
+ }
+ else if (Chr == 'x')
+ {
+ XMask |= 1 << Bit;
+
+ XPos[XBits++] = Bit;
+ }
+ }
+
+ XMask = ~XMask;
+
+ for (int Index = 0; Index < (1 << XBits); Index++)
+ {
+ Value &= XMask;
+
+ for (int X = 0; X < XBits; X++)
+ {
+ Value |= ((Index >> X) & 1) << XPos[X];
+ }
+
+ OpCodes[Value] = Func;
+ }
+ }
+
+ public static ShaderDecodeFunc GetDecoder(long OpCode)
+ {
+ return OpCodes[(ulong)OpCode >> (64 - EncodingBits)];
+ }
+ }
+} \ No newline at end of file