aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-04-25 23:11:26 -0300
committergdkchan <gab.dark.100@gmail.com>2018-04-25 23:12:26 -0300
commita38a72b0622f89897bdcd01b6d00ea6bc142c34f (patch)
tree2025cdddaa7ef6769ac69c51eeede0924ffcba5f /Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs
parent211f7f69db4d84b82caa3ee62d4ecdfbbd95604d (diff)
Some small sync primitive fixes, logging fixes, started to implement the 2D engine on the GPU, fixed DrawArrays, implemented a few more shader instructions, made a start on nvdrv refactor, etc...
Diffstat (limited to 'Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs')
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs92
1 files changed, 91 insertions, 1 deletions
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs
index 6d30cfed..b9cf02f1 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs
@@ -70,6 +70,21 @@ namespace Ryujinx.Graphics.Gal.Shader
EmitI2f(Block, OpCode, ShaderOper.RR);
}
+ public static void I2i_C(ShaderIrBlock Block, long OpCode)
+ {
+ EmitI2i(Block, OpCode, ShaderOper.CR);
+ }
+
+ public static void I2i_I(ShaderIrBlock Block, long OpCode)
+ {
+ EmitI2i(Block, OpCode, ShaderOper.Imm);
+ }
+
+ public static void I2i_R(ShaderIrBlock Block, long OpCode)
+ {
+ EmitI2i(Block, OpCode, ShaderOper.RR);
+ }
+
public static void Mov_C(ShaderIrBlock Block, long OpCode)
{
ShaderIrOperCbuf Cbuf = GetOperCbuf34(OpCode);
@@ -183,7 +198,7 @@ namespace Ryujinx.Graphics.Gal.Shader
ShaderIrOperImmf IMin = new ShaderIrOperImmf(CMin);
ShaderIrOperImmf IMax = new ShaderIrOperImmf(CMax);
- OperA = new ShaderIrOp(ShaderIrInst.Clamp, OperA, IMin, IMax);
+ OperA = new ShaderIrOp(ShaderIrInst.Fclamp, OperA, IMin, IMax);
}
ShaderIrInst Inst = Signed
@@ -252,6 +267,81 @@ namespace Ryujinx.Graphics.Gal.Shader
Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
}
+ private static void EmitI2i(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
+ {
+ IntType Type = GetIntType(OpCode);
+
+ if (Type == IntType.U64 ||
+ Type == IntType.S64)
+ {
+ //TODO: 64-bits support.
+ //Note: GLSL doesn't support 64-bits integers.
+ throw new NotImplementedException();
+ }
+
+ int Sel = (int)(OpCode >> 41) & 3;
+
+ bool NegA = ((OpCode >> 45) & 1) != 0;
+ bool AbsA = ((OpCode >> 49) & 1) != 0;
+ bool SatA = ((OpCode >> 50) & 1) != 0;
+
+ ShaderIrNode OperA;
+
+ switch (Oper)
+ {
+ case ShaderOper.CR: OperA = GetOperCbuf34 (OpCode); break;
+ case ShaderOper.Immf: OperA = GetOperImmf19_20(OpCode); break;
+ case ShaderOper.RR: OperA = GetOperGpr20 (OpCode); break;
+
+ default: throw new ArgumentException(nameof(Oper));
+ }
+
+ OperA = GetAluAbsNeg(OperA, AbsA, NegA);
+
+ bool Signed = Type >= IntType.S8;
+
+ int Shift = Sel * 8;
+
+ int Size = 8 << ((int)Type & 3);
+
+ if (Shift != 0)
+ {
+ OperA = new ShaderIrOp(ShaderIrInst.Asr, OperA, new ShaderIrOperImm(Shift));
+ }
+
+ if (Size < 32)
+ {
+ uint Mask = uint.MaxValue >> (32 - Size);
+
+ if (SatA)
+ {
+ uint CMin = 0;
+ uint CMax = Mask;
+
+ if (Signed)
+ {
+ uint HalfMask = Mask >> 1;
+
+ CMin -= HalfMask + 1;
+ CMax = HalfMask;
+ }
+
+ ShaderIrOperImm IMin = new ShaderIrOperImm((int)CMin);
+ ShaderIrOperImm IMax = new ShaderIrOperImm((int)CMax);
+
+ OperA = new ShaderIrOp(Signed
+ ? ShaderIrInst.Clamps
+ : ShaderIrInst.Clampu, OperA, IMin, IMax);
+ }
+ else
+ {
+ OperA = new ShaderIrOp(ShaderIrInst.And, OperA, new ShaderIrOperImm((int)Mask));
+ }
+ }
+
+ Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), OperA), OpCode));
+ }
+
private static IntType GetIntType(long OpCode)
{
bool Signed = ((OpCode >> 13) & 1) != 0;