aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Shader/Instructions
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2019-10-13 03:02:07 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commit1876b346fea647e8284a66bb6d62c38801035cff (patch)
tree6eeff094298cda84d1613dc5ec0691e51d7b35f1 /Ryujinx.Graphics/Shader/Instructions
parentf617fb542a0e3d36012d77a4b5acbde7b08902f2 (diff)
Initial work
Diffstat (limited to 'Ryujinx.Graphics/Shader/Instructions')
-rw-r--r--Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs684
-rw-r--r--Ryujinx.Graphics/Shader/Instructions/InstEmitAluHelper.cs88
-rw-r--r--Ryujinx.Graphics/Shader/Instructions/InstEmitConversion.cs213
-rw-r--r--Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs370
-rw-r--r--Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs107
-rw-r--r--Ryujinx.Graphics/Shader/Instructions/InstEmitHelper.cs267
-rw-r--r--Ryujinx.Graphics/Shader/Instructions/InstEmitMemory.cs138
-rw-r--r--Ryujinx.Graphics/Shader/Instructions/InstEmitMove.cs32
-rw-r--r--Ryujinx.Graphics/Shader/Instructions/InstEmitTexture.cs776
-rw-r--r--Ryujinx.Graphics/Shader/Instructions/InstEmitter.cs6
-rw-r--r--Ryujinx.Graphics/Shader/Instructions/Lop3Expression.cs149
11 files changed, 0 insertions, 2830 deletions
diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs
deleted file mode 100644
index 8e2b39bf..00000000
--- a/Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs
+++ /dev/null
@@ -1,684 +0,0 @@
-using Ryujinx.Graphics.Shader.Decoders;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-using System;
-
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
-using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
- static partial class InstEmit
- {
- public static void Bfe(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool isReverse = op.RawOpCode.Extract(40);
- bool isSigned = op.RawOpCode.Extract(48);
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
-
- if (isReverse)
- {
- srcA = context.BitfieldReverse(srcA);
- }
-
- Operand position = context.BitwiseAnd(srcB, Const(0xff));
-
- Operand size = context.BitfieldExtractU32(srcB, Const(8), Const(8));
-
- Operand res = isSigned
- ? context.BitfieldExtractS32(srcA, position, size)
- : context.BitfieldExtractU32(srcA, position, size);
-
- context.Copy(GetDest(context), res);
-
- // TODO: CC, X, corner cases
- }
-
- public static void Iadd(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool negateA = false, negateB = false;
-
- if (!(op is OpCodeAluImm32))
- {
- negateB = op.RawOpCode.Extract(48);
- negateA = op.RawOpCode.Extract(49);
- }
-
- Operand srcA = context.INegate(GetSrcA(context), negateA);
- Operand srcB = context.INegate(GetSrcB(context), negateB);
-
- Operand res = context.IAdd(srcA, srcB);
-
- bool isSubtraction = negateA || negateB;
-
- if (op.Extended)
- {
- // Add carry, or subtract borrow.
- res = context.IAdd(res, isSubtraction
- ? context.BitwiseNot(GetCF(context))
- : context.BitwiseAnd(GetCF(context), Const(1)));
- }
-
- SetIaddFlags(context, res, srcA, srcB, op.SetCondCode, op.Extended, isSubtraction);
-
- context.Copy(GetDest(context), res);
- }
-
- public static void Iadd3(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- IntegerHalfPart partC = (IntegerHalfPart)op.RawOpCode.Extract(31, 2);
- IntegerHalfPart partB = (IntegerHalfPart)op.RawOpCode.Extract(33, 2);
- IntegerHalfPart partA = (IntegerHalfPart)op.RawOpCode.Extract(35, 2);
-
- IntegerShift mode = (IntegerShift)op.RawOpCode.Extract(37, 2);
-
- bool negateC = op.RawOpCode.Extract(49);
- bool negateB = op.RawOpCode.Extract(50);
- bool negateA = op.RawOpCode.Extract(51);
-
- Operand Extend(Operand src, IntegerHalfPart part)
- {
- if (!(op is OpCodeAluReg) || part == IntegerHalfPart.B32)
- {
- return src;
- }
-
- if (part == IntegerHalfPart.H0)
- {
- return context.BitwiseAnd(src, Const(0xffff));
- }
- else if (part == IntegerHalfPart.H1)
- {
- return context.ShiftRightU32(src, Const(16));
- }
- else
- {
- // TODO: Warning.
- }
-
- return src;
- }
-
- Operand srcA = context.INegate(Extend(GetSrcA(context), partA), negateA);
- Operand srcB = context.INegate(Extend(GetSrcB(context), partB), negateB);
- Operand srcC = context.INegate(Extend(GetSrcC(context), partC), negateC);
-
- Operand res = context.IAdd(srcA, srcB);
-
- if (op is OpCodeAluReg && mode != IntegerShift.NoShift)
- {
- if (mode == IntegerShift.ShiftLeft)
- {
- res = context.ShiftLeft(res, Const(16));
- }
- else if (mode == IntegerShift.ShiftRight)
- {
- res = context.ShiftRightU32(res, Const(16));
- }
- else
- {
- // TODO: Warning.
- }
- }
-
- res = context.IAdd(res, srcC);
-
- context.Copy(GetDest(context), res);
-
- // TODO: CC, X, corner cases
- }
-
- public static void Imnmx(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool isSignedInt = op.RawOpCode.Extract(48);
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
-
- Operand resMin = isSignedInt
- ? context.IMinimumS32(srcA, srcB)
- : context.IMinimumU32(srcA, srcB);
-
- Operand resMax = isSignedInt
- ? context.IMaximumS32(srcA, srcB)
- : context.IMaximumU32(srcA, srcB);
-
- Operand pred = GetPredicate39(context);
-
- Operand dest = GetDest(context);
-
- context.Copy(dest, context.ConditionalSelect(pred, resMin, resMax));
-
- SetZnFlags(context, dest, op.SetCondCode);
-
- // TODO: X flags.
- }
-
- public static void Iscadd(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool negateA = false, negateB = false;
-
- if (!(op is OpCodeAluImm32))
- {
- negateB = op.RawOpCode.Extract(48);
- negateA = op.RawOpCode.Extract(49);
- }
-
- int shift = op is OpCodeAluImm32
- ? op.RawOpCode.Extract(53, 5)
- : op.RawOpCode.Extract(39, 5);
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
-
- srcA = context.ShiftLeft(srcA, Const(shift));
-
- srcA = context.INegate(srcA, negateA);
- srcB = context.INegate(srcB, negateB);
-
- Operand res = context.IAdd(srcA, srcB);
-
- context.Copy(GetDest(context), res);
-
- // TODO: CC, X
- }
-
- public static void Iset(EmitterContext context)
- {
- OpCodeSet op = (OpCodeSet)context.CurrOp;
-
- bool boolFloat = op.RawOpCode.Extract(44);
- bool isSigned = op.RawOpCode.Extract(48);
-
- IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3);
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
-
- Operand res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned);
-
- Operand pred = GetPredicate39(context);
-
- res = GetPredLogicalOp(context, op.LogicalOp, res, pred);
-
- Operand dest = GetDest(context);
-
- if (boolFloat)
- {
- context.Copy(dest, context.ConditionalSelect(res, ConstF(1), Const(0)));
- }
- else
- {
- context.Copy(dest, res);
- }
-
- // TODO: CC, X
- }
-
- public static void Isetp(EmitterContext context)
- {
- OpCodeSet op = (OpCodeSet)context.CurrOp;
-
- bool isSigned = op.RawOpCode.Extract(48);
-
- IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3);
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
-
- Operand p0Res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned);
-
- Operand p1Res = context.BitwiseNot(p0Res);
-
- Operand pred = GetPredicate39(context);
-
- p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred);
- p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred);
-
- context.Copy(Register(op.Predicate3), p0Res);
- context.Copy(Register(op.Predicate0), p1Res);
- }
-
- public static void Lop(EmitterContext context)
- {
- IOpCodeLop op = (IOpCodeLop)context.CurrOp;
-
- Operand srcA = context.BitwiseNot(GetSrcA(context), op.InvertA);
- Operand srcB = context.BitwiseNot(GetSrcB(context), op.InvertB);
-
- Operand res = srcB;
-
- switch (op.LogicalOp)
- {
- case LogicalOperation.And: res = context.BitwiseAnd (srcA, srcB); break;
- case LogicalOperation.Or: res = context.BitwiseOr (srcA, srcB); break;
- case LogicalOperation.ExclusiveOr: res = context.BitwiseExclusiveOr(srcA, srcB); break;
- }
-
- EmitLopPredWrite(context, op, res);
-
- Operand dest = GetDest(context);
-
- context.Copy(dest, res);
-
- SetZnFlags(context, dest, op.SetCondCode, op.Extended);
- }
-
- public static void Lop3(EmitterContext context)
- {
- IOpCodeLop op = (IOpCodeLop)context.CurrOp;
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
- Operand srcC = GetSrcC(context);
-
- bool regVariant = op is OpCodeLopReg;
-
- int truthTable = regVariant
- ? op.RawOpCode.Extract(28, 8)
- : op.RawOpCode.Extract(48, 8);
-
- Operand res = Lop3Expression.GetFromTruthTable(context, srcA, srcB, srcC, truthTable);
-
- if (regVariant)
- {
- EmitLopPredWrite(context, op, res);
- }
-
- Operand dest = GetDest(context);
-
- context.Copy(dest, res);
-
- SetZnFlags(context, dest, op.SetCondCode, op.Extended);
- }
-
- public static void Psetp(EmitterContext context)
- {
- OpCodePsetp op = (OpCodePsetp)context.CurrOp;
-
- bool invertA = op.RawOpCode.Extract(15);
- bool invertB = op.RawOpCode.Extract(32);
-
- Operand srcA = context.BitwiseNot(Register(op.Predicate12), invertA);
- Operand srcB = context.BitwiseNot(Register(op.Predicate29), invertB);
-
- Operand p0Res = GetPredLogicalOp(context, op.LogicalOpAB, srcA, srcB);
-
- Operand p1Res = context.BitwiseNot(p0Res);
-
- Operand pred = GetPredicate39(context);
-
- p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred);
- p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred);
-
- context.Copy(Register(op.Predicate3), p0Res);
- context.Copy(Register(op.Predicate0), p1Res);
- }
-
- public static void Rro(EmitterContext context)
- {
- // This is the range reduction operator,
- // we translate it as a simple move, as it
- // should be always followed by a matching
- // MUFU instruction.
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool negateB = op.RawOpCode.Extract(45);
- bool absoluteB = op.RawOpCode.Extract(49);
-
- Operand srcB = GetSrcB(context);
-
- srcB = context.FPAbsNeg(srcB, absoluteB, negateB);
-
- context.Copy(GetDest(context), srcB);
- }
-
- public static void Shl(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool isMasked = op.RawOpCode.Extract(39);
-
- Operand srcB = GetSrcB(context);
-
- if (isMasked)
- {
- srcB = context.BitwiseAnd(srcB, Const(0x1f));
- }
-
- Operand res = context.ShiftLeft(GetSrcA(context), srcB);
-
- if (!isMasked)
- {
- // Clamped shift value.
- Operand isLessThan32 = context.ICompareLessUnsigned(srcB, Const(32));
-
- res = context.ConditionalSelect(isLessThan32, res, Const(0));
- }
-
- // TODO: X, CC
-
- context.Copy(GetDest(context), res);
- }
-
- public static void Shr(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool isMasked = op.RawOpCode.Extract(39);
- bool isReverse = op.RawOpCode.Extract(40);
- bool isSigned = op.RawOpCode.Extract(48);
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
-
- if (isReverse)
- {
- srcA = context.BitfieldReverse(srcA);
- }
-
- if (isMasked)
- {
- srcB = context.BitwiseAnd(srcB, Const(0x1f));
- }
-
- Operand res = isSigned
- ? context.ShiftRightS32(srcA, srcB)
- : context.ShiftRightU32(srcA, srcB);
-
- if (!isMasked)
- {
- // Clamped shift value.
- Operand resShiftBy32;
-
- if (isSigned)
- {
- resShiftBy32 = context.ShiftRightS32(srcA, Const(31));
- }
- else
- {
- resShiftBy32 = Const(0);
- }
-
- Operand isLessThan32 = context.ICompareLessUnsigned(srcB, Const(32));
-
- res = context.ConditionalSelect(isLessThan32, res, resShiftBy32);
- }
-
- // TODO: X, CC
-
- context.Copy(GetDest(context), res);
- }
-
- public static void Xmad(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- bool signedA = context.CurrOp.RawOpCode.Extract(48);
- bool signedB = context.CurrOp.RawOpCode.Extract(49);
- bool highA = context.CurrOp.RawOpCode.Extract(53);
- bool highB = false;
-
- XmadCMode mode;
-
- if (op is OpCodeAluReg)
- {
- highB = context.CurrOp.RawOpCode.Extract(35);
-
- mode = (XmadCMode)context.CurrOp.RawOpCode.Extract(50, 3);
- }
- else
- {
- mode = (XmadCMode)context.CurrOp.RawOpCode.Extract(50, 2);
-
- if (!(op is OpCodeAluImm))
- {
- highB = context.CurrOp.RawOpCode.Extract(52);
- }
- }
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
- Operand srcC = GetSrcC(context);
-
- // XMAD immediates are 16-bits unsigned integers.
- if (srcB.Type == OperandType.Constant)
- {
- srcB = Const(srcB.Value & 0xffff);
- }
-
- Operand Extend16To32(Operand src, bool high, bool signed)
- {
- if (signed && high)
- {
- return context.ShiftRightS32(src, Const(16));
- }
- else if (signed)
- {
- return context.BitfieldExtractS32(src, Const(0), Const(16));
- }
- else if (high)
- {
- return context.ShiftRightU32(src, Const(16));
- }
- else
- {
- return context.BitwiseAnd(src, Const(0xffff));
- }
- }
-
- srcA = Extend16To32(srcA, highA, signedA);
- srcB = Extend16To32(srcB, highB, signedB);
-
- bool productShiftLeft = false;
- bool merge = false;
-
- if (!(op is OpCodeAluRegCbuf))
- {
- productShiftLeft = context.CurrOp.RawOpCode.Extract(36);
- merge = context.CurrOp.RawOpCode.Extract(37);
- }
-
- bool extended;
-
- if ((op is OpCodeAluReg) || (op is OpCodeAluImm))
- {
- extended = context.CurrOp.RawOpCode.Extract(38);
- }
- else
- {
- extended = context.CurrOp.RawOpCode.Extract(54);
- }
-
- Operand res = context.IMultiply(srcA, srcB);
-
- if (productShiftLeft)
- {
- res = context.ShiftLeft(res, Const(16));
- }
-
- switch (mode)
- {
- case XmadCMode.Cfull: break;
-
- case XmadCMode.Clo: srcC = Extend16To32(srcC, high: false, signed: false); break;
- case XmadCMode.Chi: srcC = Extend16To32(srcC, high: true, signed: false); break;
-
- case XmadCMode.Cbcc:
- {
- srcC = context.IAdd(srcC, context.ShiftLeft(GetSrcB(context), Const(16)));
-
- break;
- }
-
- case XmadCMode.Csfu:
- {
- Operand signAdjustA = context.ShiftLeft(context.ShiftRightU32(srcA, Const(31)), Const(16));
- Operand signAdjustB = context.ShiftLeft(context.ShiftRightU32(srcB, Const(31)), Const(16));
-
- srcC = context.ISubtract(srcC, context.IAdd(signAdjustA, signAdjustB));
-
- break;
- }
-
- default: /* TODO: Warning */ break;
- }
-
- Operand product = res;
-
- if (extended)
- {
- // Add with carry.
- res = context.IAdd(res, context.BitwiseAnd(GetCF(context), Const(1)));
- }
- else
- {
- // Add (no carry in).
- res = context.IAdd(res, srcC);
- }
-
- SetIaddFlags(context, res, product, srcC, op.SetCondCode, extended);
-
- if (merge)
- {
- res = context.BitwiseAnd(res, Const(0xffff));
- res = context.BitwiseOr(res, context.ShiftLeft(GetSrcB(context), Const(16)));
- }
-
- context.Copy(GetDest(context), res);
- }
-
- private static Operand GetIntComparison(
- EmitterContext context,
- IntegerCondition cond,
- Operand srcA,
- Operand srcB,
- bool isSigned)
- {
- Operand res;
-
- if (cond == IntegerCondition.Always)
- {
- res = Const(IrConsts.True);
- }
- else if (cond == IntegerCondition.Never)
- {
- res = Const(IrConsts.False);
- }
- else
- {
- Instruction inst;
-
- switch (cond)
- {
- case IntegerCondition.Less: inst = Instruction.CompareLessU32; break;
- case IntegerCondition.Equal: inst = Instruction.CompareEqual; break;
- case IntegerCondition.LessOrEqual: inst = Instruction.CompareLessOrEqualU32; break;
- case IntegerCondition.Greater: inst = Instruction.CompareGreaterU32; break;
- case IntegerCondition.NotEqual: inst = Instruction.CompareNotEqual; break;
- case IntegerCondition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqualU32; break;
-
- default: throw new InvalidOperationException($"Unexpected condition \"{cond}\".");
- }
-
- if (isSigned)
- {
- switch (cond)
- {
- case IntegerCondition.Less: inst = Instruction.CompareLess; break;
- case IntegerCondition.LessOrEqual: inst = Instruction.CompareLessOrEqual; break;
- case IntegerCondition.Greater: inst = Instruction.CompareGreater; break;
- case IntegerCondition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqual; break;
- }
- }
-
- res = context.Add(inst, Local(), srcA, srcB);
- }
-
- return res;
- }
-
- private static void EmitLopPredWrite(EmitterContext context, IOpCodeLop op, Operand result)
- {
- if (op is OpCodeLop opLop && !opLop.Predicate48.IsPT)
- {
- Operand pRes;
-
- if (opLop.CondOp == ConditionalOperation.False)
- {
- pRes = Const(IrConsts.False);
- }
- else if (opLop.CondOp == ConditionalOperation.True)
- {
- pRes = Const(IrConsts.True);
- }
- else if (opLop.CondOp == ConditionalOperation.Zero)
- {
- pRes = context.ICompareEqual(result, Const(0));
- }
- else /* if (opLop.CondOp == ConditionalOperation.NotZero) */
- {
- pRes = context.ICompareNotEqual(result, Const(0));
- }
-
- context.Copy(Register(opLop.Predicate48), pRes);
- }
- }
-
- private static void SetIaddFlags(
- EmitterContext context,
- Operand res,
- Operand srcA,
- Operand srcB,
- bool setCC,
- bool extended,
- bool isSubtraction = false)
- {
- if (!setCC)
- {
- return;
- }
-
- if (!extended || isSubtraction)
- {
- // C = d < a
- context.Copy(GetCF(context), context.ICompareLessUnsigned(res, srcA));
- }
- else
- {
- // C = (d == a && CIn) || d < a
- Operand tempC0 = context.ICompareEqual (res, srcA);
- Operand tempC1 = context.ICompareLessUnsigned(res, srcA);
-
- tempC0 = context.BitwiseAnd(tempC0, GetCF(context));
-
- context.Copy(GetCF(context), context.BitwiseOr(tempC0, tempC1));
- }
-
- // V = (d ^ a) & ~(a ^ b) < 0
- Operand tempV0 = context.BitwiseExclusiveOr(res, srcA);
- Operand tempV1 = context.BitwiseExclusiveOr(srcA, srcB);
-
- tempV1 = context.BitwiseNot(tempV1);
-
- Operand tempV = context.BitwiseAnd(tempV0, tempV1);
-
- context.Copy(GetVF(context), context.ICompareLess(tempV, Const(0)));
-
- SetZnFlags(context, res, setCC: true, extended: extended);
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitAluHelper.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitAluHelper.cs
deleted file mode 100644
index 5c4f5398..00000000
--- a/Ryujinx.Graphics/Shader/Instructions/InstEmitAluHelper.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using Ryujinx.Graphics.Shader.Decoders;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-using System;
-
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
-using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
- static class InstEmitAluHelper
- {
- public static int GetIntMin(IntegerType type)
- {
- switch (type)
- {
- case IntegerType.U8: return byte.MinValue;
- case IntegerType.S8: return sbyte.MinValue;
- case IntegerType.U16: return ushort.MinValue;
- case IntegerType.S16: return short.MinValue;
- case IntegerType.U32: return (int)uint.MinValue;
- case IntegerType.S32: return int.MinValue;
- }
-
- throw new ArgumentException($"The type \"{type}\" is not a supported int type.");
- }
-
- public static int GetIntMax(IntegerType type)
- {
- switch (type)
- {
- case IntegerType.U8: return byte.MaxValue;
- case IntegerType.S8: return sbyte.MaxValue;
- case IntegerType.U16: return ushort.MaxValue;
- case IntegerType.S16: return short.MaxValue;
- case IntegerType.U32: return unchecked((int)uint.MaxValue);
- case IntegerType.S32: return int.MaxValue;
- }
-
- throw new ArgumentException($"The type \"{type}\" is not a supported int type.");
- }
-
- public static Operand GetPredLogicalOp(
- EmitterContext context,
- LogicalOperation logicalOp,
- Operand input,
- Operand pred)
- {
- switch (logicalOp)
- {
- case LogicalOperation.And: return context.BitwiseAnd (input, pred);
- case LogicalOperation.Or: return context.BitwiseOr (input, pred);
- case LogicalOperation.ExclusiveOr: return context.BitwiseExclusiveOr(input, pred);
- }
-
- return input;
- }
-
- public static void SetZnFlags(EmitterContext context, Operand dest, bool setCC, bool extended = false)
- {
- if (!setCC)
- {
- return;
- }
-
- if (extended)
- {
- // When the operation is extended, it means we are doing
- // the operation on a long word with any number of bits,
- // so we need to AND the zero flag from result with the
- // previous result when extended is specified, to ensure
- // we have ZF set only if all words are zero, and not just
- // the last one.
- Operand oldZF = GetZF(context);
-
- Operand res = context.BitwiseAnd(context.ICompareEqual(dest, Const(0)), oldZF);
-
- context.Copy(GetZF(context), res);
- }
- else
- {
- context.Copy(GetZF(context), context.ICompareEqual(dest, Const(0)));
- }
-
- context.Copy(GetNF(context), context.ICompareLess(dest, Const(0)));
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitConversion.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitConversion.cs
deleted file mode 100644
index c4de1750..00000000
--- a/Ryujinx.Graphics/Shader/Instructions/InstEmitConversion.cs
+++ /dev/null
@@ -1,213 +0,0 @@
-using Ryujinx.Graphics.Shader.Decoders;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
-using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
- static partial class InstEmit
- {
- public static void F2F(EmitterContext context)
- {
- OpCodeFArith op = (OpCodeFArith)context.CurrOp;
-
- FPType srcType = (FPType)op.RawOpCode.Extract(8, 2);
- FPType dstType = (FPType)op.RawOpCode.Extract(10, 2);
-
- bool pass = op.RawOpCode.Extract(40);
- bool negateB = op.RawOpCode.Extract(45);
- bool absoluteB = op.RawOpCode.Extract(49);
-
- pass &= op.RoundingMode == RoundingMode.TowardsNegativeInfinity;
-
- Operand srcB = context.FPAbsNeg(GetSrcB(context, srcType), absoluteB, negateB);
-
- if (!pass)
- {
- switch (op.RoundingMode)
- {
- case RoundingMode.TowardsNegativeInfinity:
- srcB = context.FPFloor(srcB);
- break;
-
- case RoundingMode.TowardsPositiveInfinity:
- srcB = context.FPCeiling(srcB);
- break;
-
- case RoundingMode.TowardsZero:
- srcB = context.FPTruncate(srcB);
- break;
- }
- }
-
- srcB = context.FPSaturate(srcB, op.Saturate);
-
- WriteFP(context, dstType, srcB);
-
- // TODO: CC.
- }
-
- public static void F2I(EmitterContext context)
- {
- OpCodeFArith op = (OpCodeFArith)context.CurrOp;
-
- IntegerType intType = (IntegerType)op.RawOpCode.Extract(8, 2);
-
- bool isSmallInt = intType <= IntegerType.U16;
-
- FPType floatType = (FPType)op.RawOpCode.Extract(10, 2);
-
- bool isSignedInt = op.RawOpCode.Extract(12);
- bool negateB = op.RawOpCode.Extract(45);
- bool absoluteB = op.RawOpCode.Extract(49);
-
- if (isSignedInt)
- {
- intType |= IntegerType.S8;
- }
-
- Operand srcB = context.FPAbsNeg(GetSrcB(context, floatType), absoluteB, negateB);
-
- switch (op.RoundingMode)
- {
- case RoundingMode.TowardsNegativeInfinity:
- srcB = context.FPFloor(srcB);
- break;
-
- case RoundingMode.TowardsPositiveInfinity:
- srcB = context.FPCeiling(srcB);
- break;
-
- case RoundingMode.TowardsZero:
- srcB = context.FPTruncate(srcB);
- break;
- }
-
- srcB = context.FPConvertToS32(srcB);
-
- // TODO: S/U64, conversion overflow handling.
- if (intType != IntegerType.S32)
- {
- int min = GetIntMin(intType);
- int max = GetIntMax(intType);
-
- srcB = isSignedInt
- ? context.IClampS32(srcB, Const(min), Const(max))
- : context.IClampU32(srcB, Const(min), Const(max));
- }
-
- Operand dest = GetDest(context);
-
- context.Copy(dest, srcB);
-
- // TODO: CC.
- }
-
- public static void I2F(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- FPType dstType = (FPType)op.RawOpCode.Extract(8, 2);
-
- IntegerType srcType = (IntegerType)op.RawOpCode.Extract(10, 2);
-
- bool isSmallInt = srcType <= IntegerType.U16;
-
- bool isSignedInt = op.RawOpCode.Extract(13);
- bool negateB = op.RawOpCode.Extract(45);
- bool absoluteB = op.RawOpCode.Extract(49);
-
- Operand srcB = context.IAbsNeg(GetSrcB(context), absoluteB, negateB);
-
- if (isSmallInt)
- {
- int size = srcType == IntegerType.U16 ? 16 : 8;
-
- srcB = isSignedInt
- ? context.BitfieldExtractS32(srcB, Const(op.ByteSelection * 8), Const(size))
- : context.BitfieldExtractU32(srcB, Const(op.ByteSelection * 8), Const(size));
- }
-
- srcB = isSignedInt
- ? context.IConvertS32ToFP(srcB)
- : context.IConvertU32ToFP(srcB);
-
- WriteFP(context, dstType, srcB);
-
- // TODO: CC.
- }
-
- public static void I2I(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- IntegerType dstType = (IntegerType)op.RawOpCode.Extract(8, 2);
- IntegerType srcType = (IntegerType)op.RawOpCode.Extract(10, 2);
-
- if (srcType == IntegerType.U64 || dstType == IntegerType.U64)
- {
- // TODO: Warning. This instruction doesn't support 64-bits integers
- }
-
- bool srcIsSmallInt = srcType <= IntegerType.U16;
-
- bool dstIsSignedInt = op.RawOpCode.Extract(12);
- bool srcIsSignedInt = op.RawOpCode.Extract(13);
- bool negateB = op.RawOpCode.Extract(45);
- bool absoluteB = op.RawOpCode.Extract(49);
-
- Operand srcB = GetSrcB(context);
-
- if (srcIsSmallInt)
- {
- int size = srcType == IntegerType.U16 ? 16 : 8;
-
- srcB = srcIsSignedInt
- ? context.BitfieldExtractS32(srcB, Const(op.ByteSelection * 8), Const(size))
- : context.BitfieldExtractU32(srcB, Const(op.ByteSelection * 8), Const(size));
- }
-
- srcB = context.IAbsNeg(srcB, absoluteB, negateB);
-
- if (op.Saturate)
- {
- if (dstIsSignedInt)
- {
- dstType |= IntegerType.S8;
- }
-
- int min = GetIntMin(dstType);
- int max = GetIntMax(dstType);
-
- srcB = dstIsSignedInt
- ? context.IClampS32(srcB, Const(min), Const(max))
- : context.IClampU32(srcB, Const(min), Const(max));
- }
-
- context.Copy(GetDest(context), srcB);
-
- // TODO: CC.
- }
-
- private static void WriteFP(EmitterContext context, FPType type, Operand srcB)
- {
- Operand dest = GetDest(context);
-
- if (type == FPType.FP32)
- {
- context.Copy(dest, srcB);
- }
- else if (type == FPType.FP16)
- {
- context.Copy(dest, context.PackHalf2x16(srcB, ConstF(0)));
- }
- else
- {
- // TODO.
- }
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs
deleted file mode 100644
index b22639de..00000000
--- a/Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs
+++ /dev/null
@@ -1,370 +0,0 @@
-using Ryujinx.Graphics.Shader.Decoders;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-using System;
-
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
-using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
- static partial class InstEmit
- {
- public static void Fadd(EmitterContext context)
- {
- IOpCodeFArith op = (IOpCodeFArith)context.CurrOp;
-
- bool absoluteA = op.AbsoluteA, absoluteB, negateA, negateB;
-
- if (op is OpCodeFArithImm32)
- {
- negateB = op.RawOpCode.Extract(53);
- negateA = op.RawOpCode.Extract(56);
- absoluteB = op.RawOpCode.Extract(57);
- }
- else
- {
- negateB = op.RawOpCode.Extract(45);
- negateA = op.RawOpCode.Extract(48);
- absoluteB = op.RawOpCode.Extract(49);
- }
-
- Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA);
- Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB);
-
- Operand dest = GetDest(context);
-
- context.Copy(dest, context.FPSaturate(context.FPAdd(srcA, srcB), op.Saturate));
-
- SetFPZnFlags(context, dest, op.SetCondCode);
- }
-
- public static void Ffma(EmitterContext context)
- {
- IOpCodeFArith op = (IOpCodeFArith)context.CurrOp;
-
- bool negateB = op.RawOpCode.Extract(48);
- bool negateC = op.RawOpCode.Extract(49);
-
- Operand srcA = GetSrcA(context);
-
- Operand srcB = context.FPNegate(GetSrcB(context), negateB);
- Operand srcC = context.FPNegate(GetSrcC(context), negateC);
-
- Operand dest = GetDest(context);
-
- context.Copy(dest, context.FPSaturate(context.FPFusedMultiplyAdd(srcA, srcB, srcC), op.Saturate));
-
- SetFPZnFlags(context, dest, op.SetCondCode);
- }
-
- public static void Fmnmx(EmitterContext context)
- {
- IOpCodeFArith op = (IOpCodeFArith)context.CurrOp;
-
- bool absoluteA = op.AbsoluteA;
- bool negateB = op.RawOpCode.Extract(45);
- bool negateA = op.RawOpCode.Extract(48);
- bool absoluteB = op.RawOpCode.Extract(49);
-
- Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA);
- Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB);
-
- Operand resMin = context.FPMinimum(srcA, srcB);
- Operand resMax = context.FPMaximum(srcA, srcB);
-
- Operand pred = GetPredicate39(context);
-
- Operand dest = GetDest(context);
-
- context.Copy(dest, context.ConditionalSelect(pred, resMin, resMax));
-
- SetFPZnFlags(context, dest, op.SetCondCode);
- }
-
- public static void Fmul(EmitterContext context)
- {
- IOpCodeFArith op = (IOpCodeFArith)context.CurrOp;
-
- bool negateB = !(op is OpCodeFArithImm32) && op.RawOpCode.Extract(48);
-
- Operand srcA = GetSrcA(context);
-
- Operand srcB = context.FPNegate(GetSrcB(context), negateB);
-
- switch (op.Scale)
- {
- case FmulScale.None: break;
-
- case FmulScale.Divide2: srcA = context.FPDivide (srcA, ConstF(2)); break;
- case FmulScale.Divide4: srcA = context.FPDivide (srcA, ConstF(4)); break;
- case FmulScale.Divide8: srcA = context.FPDivide (srcA, ConstF(8)); break;
- case FmulScale.Multiply2: srcA = context.FPMultiply(srcA, ConstF(2)); break;
- case FmulScale.Multiply4: srcA = context.FPMultiply(srcA, ConstF(4)); break;
- case FmulScale.Multiply8: srcA = context.FPMultiply(srcA, ConstF(8)); break;
-
- default: break; //TODO: Warning.
- }
-
- Operand dest = GetDest(context);
-
- context.Copy(dest, context.FPSaturate(context.FPMultiply(srcA, srcB), op.Saturate));
-
- SetFPZnFlags(context, dest, op.SetCondCode);
- }
-
- public static void Fset(EmitterContext context)
- {
- OpCodeSet op = (OpCodeSet)context.CurrOp;
-
- Condition cmpOp = (Condition)op.RawOpCode.Extract(48, 4);
-
- bool negateA = op.RawOpCode.Extract(43);
- bool absoluteB = op.RawOpCode.Extract(44);
- bool boolFloat = op.RawOpCode.Extract(52);
- bool negateB = op.RawOpCode.Extract(53);
- bool absoluteA = op.RawOpCode.Extract(54);
-
- Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA);
- Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB);
-
- Operand res = GetFPComparison(context, cmpOp, srcA, srcB);
-
- Operand pred = GetPredicate39(context);
-
- res = GetPredLogicalOp(context, op.LogicalOp, res, pred);
-
- Operand dest = GetDest(context);
-
- if (boolFloat)
- {
- context.Copy(dest, context.ConditionalSelect(res, ConstF(1), Const(0)));
- }
- else
- {
- context.Copy(dest, res);
- }
-
- // TODO: CC, X
- }
-
- public static void Fsetp(EmitterContext context)
- {
- OpCodeSet op = (OpCodeSet)context.CurrOp;
-
- Condition cmpOp = (Condition)op.RawOpCode.Extract(48, 4);
-
- bool absoluteA = op.RawOpCode.Extract(7);
- bool negateA = op.RawOpCode.Extract(43);
- bool absoluteB = op.RawOpCode.Extract(44);
- bool negateB = op.RawOpCode.Extract(6);
-
- Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA);
- Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB);
-
- Operand p0Res = GetFPComparison(context, cmpOp, srcA, srcB);
-
- Operand p1Res = context.BitwiseNot(p0Res);
-
- Operand pred = GetPredicate39(context);
-
- p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred);
- p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred);
-
- context.Copy(Register(op.Predicate3), p0Res);
- context.Copy(Register(op.Predicate0), p1Res);
- }
-
- public static void Hadd2(EmitterContext context)
- {
- Hadd2Hmul2Impl(context, isAdd: true);
- }
-
- public static void Hfma2(EmitterContext context)
- {
- IOpCodeHfma op = (IOpCodeHfma)context.CurrOp;
-
- Operand[] srcA = GetHfmaSrcA(context);
- Operand[] srcB = GetHfmaSrcB(context);
- Operand[] srcC = GetHfmaSrcC(context);
-
- Operand[] res = new Operand[2];
-
- for (int index = 0; index < res.Length; index++)
- {
- res[index] = context.FPFusedMultiplyAdd(srcA[index], srcB[index], srcC[index]);
-
- res[index] = context.FPSaturate(res[index], op.Saturate);
- }
-
- context.Copy(GetDest(context), GetHalfPacked(context, res));
- }
-
- public static void Hmul2(EmitterContext context)
- {
- Hadd2Hmul2Impl(context, isAdd: false);
- }
-
- private static void Hadd2Hmul2Impl(EmitterContext context, bool isAdd)
- {
- OpCode op = context.CurrOp;
-
- bool saturate = op.RawOpCode.Extract(op is OpCodeAluImm32 ? 52 : 32);
-
- Operand[] srcA = GetHalfSrcA(context);
- Operand[] srcB = GetHalfSrcB(context);
-
- Operand[] res = new Operand[2];
-
- for (int index = 0; index < res.Length; index++)
- {
- if (isAdd)
- {
- res[index] = context.FPAdd(srcA[index], srcB[index]);
- }
- else
- {
- res[index] = context.FPMultiply(srcA[index], srcB[index]);
- }
-
- res[index] = context.FPSaturate(res[index], saturate);
- }
-
- context.Copy(GetDest(context), GetHalfPacked(context, res));
- }
-
- public static void Mufu(EmitterContext context)
- {
- IOpCodeFArith op = (IOpCodeFArith)context.CurrOp;
-
- bool negateB = op.RawOpCode.Extract(48);
-
- Operand res = context.FPAbsNeg(GetSrcA(context), op.AbsoluteA, negateB);
-
- MufuOperation subOp = (MufuOperation)context.CurrOp.RawOpCode.Extract(20, 4);
-
- switch (subOp)
- {
- case MufuOperation.Cosine:
- res = context.FPCosine(res);
- break;
-
- case MufuOperation.Sine:
- res = context.FPSine(res);
- break;
-
- case MufuOperation.ExponentB2:
- res = context.FPExponentB2(res);
- break;
-
- case MufuOperation.LogarithmB2:
- res = context.FPLogarithmB2(res);
- break;
-
- case MufuOperation.Reciprocal:
- res = context.FPReciprocal(res);
- break;
-
- case MufuOperation.ReciprocalSquareRoot:
- res = context.FPReciprocalSquareRoot(res);
- break;
-
- case MufuOperation.SquareRoot:
- res = context.FPSquareRoot(res);
- break;
-
- default: /* TODO */ break;
- }
-
- context.Copy(GetDest(context), context.FPSaturate(res, op.Saturate));
- }
-
- private static Operand GetFPComparison(
- EmitterContext context,
- Condition cond,
- Operand srcA,
- Operand srcB)
- {
- Operand res;
-
- if (cond == Condition.Always)
- {
- res = Const(IrConsts.True);
- }
- else if (cond == Condition.Never)
- {
- res = Const(IrConsts.False);
- }
- else if (cond == Condition.Nan || cond == Condition.Number)
- {
- res = context.BitwiseOr(context.IsNan(srcA), context.IsNan(srcB));
-
- if (cond == Condition.Number)
- {
- res = context.BitwiseNot(res);
- }
- }
- else
- {
- Instruction inst;
-
- switch (cond & ~Condition.Nan)
- {
- case Condition.Less: inst = Instruction.CompareLess; break;
- case Condition.Equal: inst = Instruction.CompareEqual; break;
- case Condition.LessOrEqual: inst = Instruction.CompareLessOrEqual; break;
- case Condition.Greater: inst = Instruction.CompareGreater; break;
- case Condition.NotEqual: inst = Instruction.CompareNotEqual; break;
- case Condition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqual; break;
-
- default: throw new InvalidOperationException($"Unexpected condition \"{cond}\".");
- }
-
- res = context.Add(inst | Instruction.FP, Local(), srcA, srcB);
-
- if ((cond & Condition.Nan) != 0)
- {
- res = context.BitwiseOr(res, context.IsNan(srcA));
- res = context.BitwiseOr(res, context.IsNan(srcB));
- }
- }
-
- return res;
- }
-
- private static void SetFPZnFlags(EmitterContext context, Operand dest, bool setCC)
- {
- if (setCC)
- {
- context.Copy(GetZF(context), context.FPCompareEqual(dest, ConstF(0)));
- context.Copy(GetNF(context), context.FPCompareLess (dest, ConstF(0)));
- }
- }
-
- private static Operand[] GetHfmaSrcA(EmitterContext context)
- {
- IOpCodeHfma op = (IOpCodeHfma)context.CurrOp;
-
- return GetHalfSources(context, GetSrcA(context), op.SwizzleA);
- }
-
- private static Operand[] GetHfmaSrcB(EmitterContext context)
- {
- IOpCodeHfma op = (IOpCodeHfma)context.CurrOp;
-
- Operand[] operands = GetHalfSources(context, GetSrcB(context), op.SwizzleB);
-
- return FPAbsNeg(context, operands, false, op.NegateB);
- }
-
- private static Operand[] GetHfmaSrcC(EmitterContext context)
- {
- IOpCodeHfma op = (IOpCodeHfma)context.CurrOp;
-
- Operand[] operands = GetHalfSources(context, GetSrcC(context), op.SwizzleC);
-
- return FPAbsNeg(context, operands, false, op.NegateC);
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs
deleted file mode 100644
index fb76e06a..00000000
--- a/Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-using Ryujinx.Graphics.Shader.Decoders;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-using System.Collections.Generic;
-using System.Linq;
-
-using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
- static partial class InstEmit
- {
- public static void Bra(EmitterContext context)
- {
- EmitBranch(context, context.CurrBlock.Branch.Address);
- }
-
- public static void Exit(EmitterContext context)
- {
- OpCodeExit op = (OpCodeExit)context.CurrOp;
-
- // TODO: Figure out how this is supposed to work in the
- // presence of other condition codes.
- if (op.Condition == Condition.Always)
- {
- context.Return();
- }
- }
-
- public static void Kil(EmitterContext context)
- {
- context.Discard();
- }
-
- public static void Ssy(EmitterContext context)
- {
- OpCodeSsy op = (OpCodeSsy)context.CurrOp;
-
- foreach (KeyValuePair<OpCodeSync, Operand> kv in op.Syncs)
- {
- OpCodeSync opSync = kv.Key;
-
- Operand local = kv.Value;
-
- int ssyIndex = opSync.Targets[op];
-
- context.Copy(local, Const(ssyIndex));
- }
- }
-
- public static void Sync(EmitterContext context)
- {
- OpCodeSync op = (OpCodeSync)context.CurrOp;
-
- if (op.Targets.Count == 1)
- {
- // If we have only one target, then the SSY is basically
- // a branch, we can produce better codegen for this case.
- OpCodeSsy opSsy = op.Targets.Keys.First();
-
- EmitBranch(context, opSsy.GetAbsoluteAddress());
- }
- else
- {
- foreach (KeyValuePair<OpCodeSsy, int> kv in op.Targets)
- {
- OpCodeSsy opSsy = kv.Key;
-
- Operand label = context.GetLabel(opSsy.GetAbsoluteAddress());
-
- Operand local = opSsy.Syncs[op];
-
- int ssyIndex = kv.Value;
-
- context.BranchIfTrue(label, context.ICompareEqual(local, Const(ssyIndex)));
- }
- }
- }
-
- private static void EmitBranch(EmitterContext context, ulong address)
- {
- // If we're branching to the next instruction, then the branch
- // is useless and we can ignore it.
- if (address == context.CurrOp.Address + 8)
- {
- return;
- }
-
- Operand label = context.GetLabel(address);
-
- Operand pred = Register(context.CurrOp.Predicate);
-
- if (context.CurrOp.Predicate.IsPT)
- {
- context.Branch(label);
- }
- else if (context.CurrOp.InvertPredicate)
- {
- context.BranchIfFalse(label, pred);
- }
- else
- {
- context.BranchIfTrue(label, pred);
- }
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitHelper.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitHelper.cs
deleted file mode 100644
index c87e1789..00000000
--- a/Ryujinx.Graphics/Shader/Instructions/InstEmitHelper.cs
+++ /dev/null
@@ -1,267 +0,0 @@
-using Ryujinx.Graphics.Shader.Decoders;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-using System;
-
-using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
- static class InstEmitHelper
- {
- public static Operand GetZF(EmitterContext context)
- {
- return Register(0, RegisterType.Flag);
- }
-
- public static Operand GetNF(EmitterContext context)
- {
- return Register(1, RegisterType.Flag);
- }
-
- public static Operand GetCF(EmitterContext context)
- {
- return Register(2, RegisterType.Flag);
- }
-
- public static Operand GetVF(EmitterContext context)
- {
- return Register(3, RegisterType.Flag);
- }
-
- public static Operand GetDest(EmitterContext context)
- {
- return Register(((IOpCodeRd)context.CurrOp).Rd);
- }
-
- public static Operand GetSrcA(EmitterContext context)
- {
- return Register(((IOpCodeRa)context.CurrOp).Ra);
- }
-
- public static Operand GetSrcB(EmitterContext context, FPType floatType)
- {
- if (floatType == FPType.FP32)
- {
- return GetSrcB(context);
- }
- else if (floatType == FPType.FP16)
- {
- int h = context.CurrOp.RawOpCode.Extract(41, 1);
-
- return GetHalfSources(context, GetSrcB(context), FPHalfSwizzle.FP16)[h];
- }
- else if (floatType == FPType.FP64)
- {
- // TODO.
- }
-
- throw new ArgumentException($"Invalid floating point type \"{floatType}\".");
- }
-
- public static Operand GetSrcB(EmitterContext context)
- {
- switch (context.CurrOp)
- {
- case IOpCodeCbuf op:
- return Cbuf(op.Slot, op.Offset);
-
- case IOpCodeImm op:
- return Const(op.Immediate);
-
- case IOpCodeImmF op:
- return ConstF(op.Immediate);
-
- case IOpCodeReg op:
- return Register(op.Rb);
-
- case IOpCodeRegCbuf op:
- return Register(op.Rc);
- }
-
- throw new InvalidOperationException($"Unexpected opcode type \"{context.CurrOp.GetType().Name}\".");
- }
-
- public static Operand GetSrcC(EmitterContext context)
- {
- switch (context.CurrOp)
- {
- case IOpCodeRegCbuf op:
- return Cbuf(op.Slot, op.Offset);
-
- case IOpCodeRc op:
- return Register(op.Rc);
- }
-
- throw new InvalidOperationException($"Unexpected opcode type \"{context.CurrOp.GetType().Name}\".");
- }
-
- public static Operand[] GetHalfSrcA(EmitterContext context)
- {
- OpCode op = context.CurrOp;
-
- bool absoluteA = false, negateA = false;
-
- if (op is IOpCodeCbuf || op is IOpCodeImm)
- {
- negateA = op.RawOpCode.Extract(43);
- absoluteA = op.RawOpCode.Extract(44);
- }
- else if (op is IOpCodeReg)
- {
- absoluteA = op.RawOpCode.Extract(44);
- }
- else if (op is OpCodeAluImm32 && op.Emitter == InstEmit.Hadd2)
- {
- negateA = op.RawOpCode.Extract(56);
- }
-
- FPHalfSwizzle swizzle = (FPHalfSwizzle)op.RawOpCode.Extract(47, 2);
-
- Operand[] operands = GetHalfSources(context, GetSrcA(context), swizzle);
-
- return FPAbsNeg(context, operands, absoluteA, negateA);
- }
-
- public static Operand[] GetHalfSrcB(EmitterContext context)
- {
- OpCode op = context.CurrOp;
-
- FPHalfSwizzle swizzle = FPHalfSwizzle.FP16;
-
- bool absoluteB = false, negateB = false;
-
- if (op is IOpCodeReg)
- {
- swizzle = (FPHalfSwizzle)op.RawOpCode.Extract(28, 2);
-
- absoluteB = op.RawOpCode.Extract(30);
- negateB = op.RawOpCode.Extract(31);
- }
- else if (op is IOpCodeCbuf)
- {
- swizzle = FPHalfSwizzle.FP32;
-
- absoluteB = op.RawOpCode.Extract(54);
- }
-
- Operand[] operands = GetHalfSources(context, GetSrcB(context), swizzle);
-
- return FPAbsNeg(context, operands, absoluteB, negateB);
- }
-
- public static Operand[] FPAbsNeg(EmitterContext context, Operand[] operands, bool abs, bool neg)
- {
- for (int index = 0; index < operands.Length; index++)
- {
- operands[index] = context.FPAbsNeg(operands[index], abs, neg);
- }
-
- return operands;
- }
-
- public static Operand[] GetHalfSources(EmitterContext context, Operand src, FPHalfSwizzle swizzle)
- {
- switch (swizzle)
- {
- case FPHalfSwizzle.FP16:
- return new Operand[]
- {
- context.UnpackHalf2x16Low (src),
- context.UnpackHalf2x16High(src)
- };
-
- case FPHalfSwizzle.FP32: return new Operand[] { src, src };
-
- case FPHalfSwizzle.DupH0:
- return new Operand[]
- {
- context.UnpackHalf2x16Low(src),
- context.UnpackHalf2x16Low(src)
- };
-
- case FPHalfSwizzle.DupH1:
- return new Operand[]
- {
- context.UnpackHalf2x16High(src),
- context.UnpackHalf2x16High(src)
- };
- }
-
- throw new ArgumentException($"Invalid swizzle \"{swizzle}\".");
- }
-
- public static Operand GetHalfPacked(EmitterContext context, Operand[] results)
- {
- OpCode op = context.CurrOp;
-
- FPHalfSwizzle swizzle = FPHalfSwizzle.FP16;
-
- if (!(op is OpCodeAluImm32))
- {
- swizzle = (FPHalfSwizzle)context.CurrOp.RawOpCode.Extract(49, 2);
- }
-
- switch (swizzle)
- {
- case FPHalfSwizzle.FP16: return context.PackHalf2x16(results[0], results[1]);
-
- case FPHalfSwizzle.FP32: return results[0];
-
- case FPHalfSwizzle.DupH0:
- {
- Operand h1 = GetHalfDest(context, isHigh: true);
-
- return context.PackHalf2x16(results[0], h1);
- }
-
- case FPHalfSwizzle.DupH1:
- {
- Operand h0 = GetHalfDest(context, isHigh: false);
-
- return context.PackHalf2x16(h0, results[1]);
- }
- }
-
- throw new ArgumentException($"Invalid swizzle \"{swizzle}\".");
- }
-
- public static Operand GetHalfDest(EmitterContext context, bool isHigh)
- {
- if (isHigh)
- {
- return context.UnpackHalf2x16High(GetDest(context));
- }
- else
- {
- return context.UnpackHalf2x16Low(GetDest(context));
- }
- }
-
- public static Operand GetPredicate39(EmitterContext context)
- {
- IOpCodeAlu op = (IOpCodeAlu)context.CurrOp;
-
- Operand local = Register(op.Predicate39);
-
- if (op.InvertP)
- {
- local = context.BitwiseNot(local);
- }
-
- return local;
- }
-
- public static Operand SignExtendTo32(EmitterContext context, Operand src, int srcBits)
- {
- return context.BitfieldExtractS32(src, Const(0), Const(srcBits));
- }
-
- public static Operand ZeroExtendTo32(EmitterContext context, Operand src, int srcBits)
- {
- int mask = (int)(0xffffffffu >> (32 - srcBits));
-
- return context.BitwiseAnd(src, Const(mask));
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitMemory.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitMemory.cs
deleted file mode 100644
index a2a50fce..00000000
--- a/Ryujinx.Graphics/Shader/Instructions/InstEmitMemory.cs
+++ /dev/null
@@ -1,138 +0,0 @@
-using Ryujinx.Graphics.Shader.Decoders;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
-using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
- static partial class InstEmit
- {
- public static void Ald(EmitterContext context)
- {
- OpCodeAttribute op = (OpCodeAttribute)context.CurrOp;
-
- Operand[] elems = new Operand[op.Count];
-
- for (int index = 0; index < op.Count; index++)
- {
- Operand src = Attribute(op.AttributeOffset + index * 4);
-
- context.Copy(elems[index] = Local(), src);
- }
-
- for (int index = 0; index < op.Count; index++)
- {
- Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);
-
- if (rd.IsRZ)
- {
- break;
- }
-
- context.Copy(Register(rd), elems[index]);
- }
- }
-
- public static void Ast(EmitterContext context)
- {
- OpCodeAttribute op = (OpCodeAttribute)context.CurrOp;
-
- for (int index = 0; index < op.Count; index++)
- {
- if (op.Rd.Index + index > RegisterConsts.RegisterZeroIndex)
- {
- break;
- }
-
- Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);
-
- Operand dest = Attribute(op.AttributeOffset + index * 4);
-
- context.Copy(dest, Register(rd));
- }
- }
-
- public static void Ipa(EmitterContext context)
- {
- OpCodeIpa op = (OpCodeIpa)context.CurrOp;
-
- Operand srcA = new Operand(OperandType.Attribute, op.AttributeOffset);
-
- Operand srcB = GetSrcB(context);
-
- context.Copy(GetDest(context), srcA);
- }
-
- public static void Ldc(EmitterContext context)
- {
- OpCodeLdc op = (OpCodeLdc)context.CurrOp;
-
- if (op.Size > IntegerSize.B64)
- {
- // TODO: Warning.
- }
-
- bool isSmallInt = op.Size < IntegerSize.B32;
-
- int count = op.Size == IntegerSize.B64 ? 2 : 1;
-
- Operand baseOffset = context.Copy(GetSrcA(context));
-
- for (int index = 0; index < count; index++)
- {
- Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);
-
- if (rd.IsRZ)
- {
- break;
- }
-
- Operand offset = context.IAdd(baseOffset, Const((op.Offset + index) * 4));
-
- Operand value = context.LoadConstant(Const(op.Slot), offset);
-
- if (isSmallInt)
- {
- Operand shift = context.BitwiseAnd(baseOffset, Const(3));
-
- value = context.ShiftRightU32(value, shift);
-
- switch (op.Size)
- {
- case IntegerSize.U8: value = ZeroExtendTo32(context, value, 8); break;
- case IntegerSize.U16: value = ZeroExtendTo32(context, value, 16); break;
- case IntegerSize.S8: value = SignExtendTo32(context, value, 8); break;
- case IntegerSize.S16: value = SignExtendTo32(context, value, 16); break;
- }
- }
-
- context.Copy(Register(rd), value);
- }
- }
-
- public static void Out(EmitterContext context)
- {
- OpCode op = context.CurrOp;
-
- bool emit = op.RawOpCode.Extract(39);
- bool cut = op.RawOpCode.Extract(40);
-
- if (!(emit || cut))
- {
- // TODO: Warning.
- }
-
- if (emit)
- {
- context.EmitVertex();
- }
-
- if (cut)
- {
- context.EndPrimitive();
- }
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitMove.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitMove.cs
deleted file mode 100644
index b74dbfd7..00000000
--- a/Ryujinx.Graphics/Shader/Instructions/InstEmitMove.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using Ryujinx.Graphics.Shader.Decoders;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
- static partial class InstEmit
- {
- public static void Mov(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- context.Copy(GetDest(context), GetSrcB(context));
- }
-
- public static void Sel(EmitterContext context)
- {
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
- Operand pred = GetPredicate39(context);
-
- Operand srcA = GetSrcA(context);
- Operand srcB = GetSrcB(context);
-
- Operand res = context.ConditionalSelect(pred, srcA, srcB);
-
- context.Copy(GetDest(context), res);
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitTexture.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitTexture.cs
deleted file mode 100644
index a9b29f40..00000000
--- a/Ryujinx.Graphics/Shader/Instructions/InstEmitTexture.cs
+++ /dev/null
@@ -1,776 +0,0 @@
-using Ryujinx.Graphics.Shader.Decoders;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-using System;
-using System.Collections.Generic;
-
-using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
- static partial class InstEmit
- {
- public static void Tex(EmitterContext context)
- {
- Tex(context, TextureFlags.None);
- }
-
- public static void Tex_B(EmitterContext context)
- {
- Tex(context, TextureFlags.Bindless);
- }
-
- public static void Tld(EmitterContext context)
- {
- Tex(context, TextureFlags.IntCoords);
- }
-
- public static void Tld_B(EmitterContext context)
- {
- Tex(context, TextureFlags.IntCoords | TextureFlags.Bindless);
- }
-
- public static void Texs(EmitterContext context)
- {
- OpCodeTextureScalar op = (OpCodeTextureScalar)context.CurrOp;
-
- if (op.Rd0.IsRZ && op.Rd1.IsRZ)
- {
- return;
- }
-
- List<Operand> sourcesList = new List<Operand>();
-
- int raIndex = op.Ra.Index;
- int rbIndex = op.Rb.Index;
-
- Operand Ra()
- {
- if (raIndex > RegisterConsts.RegisterZeroIndex)
- {
- return Const(0);
- }
-
- return context.Copy(Register(raIndex++, RegisterType.Gpr));
- }
-
- Operand Rb()
- {
- if (rbIndex > RegisterConsts.RegisterZeroIndex)
- {
- return Const(0);
- }
-
- return context.Copy(Register(rbIndex++, RegisterType.Gpr));
- }
-
- void AddTextureOffset(int coordsCount, int stride, int size)
- {
- Operand packedOffs = Rb();
-
- for (int index = 0; index < coordsCount; index++)
- {
- sourcesList.Add(context.BitfieldExtractS32(packedOffs, Const(index * stride), Const(size)));
- }
- }
-
- TextureType type;
- TextureFlags flags;
-
- if (op is OpCodeTexs texsOp)
- {
- type = GetTextureType (texsOp.Type);
- flags = GetTextureFlags(texsOp.Type);
-
- if ((type & TextureType.Array) != 0)
- {
- Operand arrayIndex = Ra();
-
- sourcesList.Add(Ra());
- sourcesList.Add(Rb());
-
- sourcesList.Add(arrayIndex);
-
- if ((type & TextureType.Shadow) != 0)
- {
- sourcesList.Add(Rb());
- }
-
- if ((flags & TextureFlags.LodLevel) != 0)
- {
- sourcesList.Add(ConstF(0));
- }
- }
- else
- {
- switch (texsOp.Type)
- {
- case TextureScalarType.Texture1DLodZero:
- sourcesList.Add(Ra());
- break;
-
- case TextureScalarType.Texture2D:
- sourcesList.Add(Ra());
- sourcesList.Add(Rb());
- break;
-
- case TextureScalarType.Texture2DLodZero:
- sourcesList.Add(Ra());
- sourcesList.Add(Rb());
- sourcesList.Add(ConstF(0));
- break;
-
- case TextureScalarType.Texture2DLodLevel:
- case TextureScalarType.Texture2DDepthCompare:
- case TextureScalarType.Texture3D:
- case TextureScalarType.TextureCube:
- sourcesList.Add(Ra());
- sourcesList.Add(Ra());
- sourcesList.Add(Rb());
- break;
-
- case TextureScalarType.Texture2DLodZeroDepthCompare:
- case TextureScalarType.Texture3DLodZero:
- sourcesList.Add(Ra());
- sourcesList.Add(Ra());
- sourcesList.Add(Rb());
- sourcesList.Add(ConstF(0));
- break;
-
- case TextureScalarType.Texture2DLodLevelDepthCompare:
- case TextureScalarType.TextureCubeLodLevel:
- sourcesList.Add(Ra());
- sourcesList.Add(Ra());
- sourcesList.Add(Rb());
- sourcesList.Add(Rb());
- break;
- }
- }
- }
- else if (op is OpCodeTlds tldsOp)
- {
- type = GetTextureType (tldsOp.Type);
- flags = GetTextureFlags(tldsOp.Type) | TextureFlags.IntCoords;
-
- switch (tldsOp.Type)
- {
- case TexelLoadScalarType.Texture1DLodZero:
- sourcesList.Add(Ra());
- sourcesList.Add(Const(0));
- break;
-
- case TexelLoadScalarType.Texture1DLodLevel:
- sourcesList.Add(Ra());
- sourcesList.Add(Rb());
- break;
-
- case TexelLoadScalarType.Texture2DLodZero:
- sourcesList.Add(Ra());
- sourcesList.Add(Rb());
- sourcesList.Add(Const(0));
- break;
-
- case TexelLoadScalarType.Texture2DLodZeroOffset:
- sourcesList.Add(Ra());
- sourcesList.Add(Ra());
- sourcesList.Add(Const(0));
- break;
-
- case TexelLoadScalarType.Texture2DLodZeroMultisample:
- case TexelLoadScalarType.Texture2DLodLevel:
- case TexelLoadScalarType.Texture2DLodLevelOffset:
- sourcesList.Add(Ra());
- sourcesList.Add(Ra());
- sourcesList.Add(Rb());
- break;
-
- case TexelLoadScalarType.Texture3DLodZero:
- sourcesList.Add(Ra());
- sourcesList.Add(Ra());
- sourcesList.Add(Rb());
- sourcesList.Add(Const(0));
- break;
-
- case TexelLoadScalarType.Texture2DArrayLodZero:
- sourcesList.Add(Rb());
- sourcesList.Add(Rb());
- sourcesList.Add(Ra());
- sourcesList.Add(Const(0));
- break;
- }
-
- if ((flags & TextureFlags.Offset) != 0)
- {
- AddTextureOffset(type.GetCoordsCount(), 4, 4);
- }
- }
- else if (op is OpCodeTld4s tld4sOp)
- {
- if (!(tld4sOp.HasDepthCompare || tld4sOp.HasOffset))
- {
- sourcesList.Add(Ra());
- sourcesList.Add(Rb());
- }
- else
- {
- sourcesList.Add(Ra());
- sourcesList.Add(Ra());
- }
-
- type = TextureType.Texture2D;
- flags = TextureFlags.Gather;
-
- if (tld4sOp.HasDepthCompare)
- {
- sourcesList.Add(Rb());
-
- type |= TextureType.Shadow;
- }
-
- if (tld4sOp.HasOffset)
- {
- AddTextureOffset(type.GetCoordsCount(), 8, 6);
-
- flags |= TextureFlags.Offset;
- }
-
- sourcesList.Add(Const(tld4sOp.GatherCompIndex));
- }
- else
- {
- throw new InvalidOperationException($"Invalid opcode type \"{op.GetType().Name}\".");
- }
-
- Operand[] sources = sourcesList.ToArray();
-
- Operand[] rd0 = new Operand[2] { ConstF(0), ConstF(0) };
- Operand[] rd1 = new Operand[2] { ConstF(0), ConstF(0) };
-
- int destIncrement = 0;
-
- Operand GetDest()
- {
- int high = destIncrement >> 1;
- int low = destIncrement & 1;
-
- destIncrement++;
-
- if (op.IsFp16)
- {
- return high != 0
- ? (rd1[low] = Local())
- : (rd0[low] = Local());
- }
- else
- {
- int rdIndex = high != 0 ? op.Rd1.Index : op.Rd0.Index;
-
- if (rdIndex < RegisterConsts.RegisterZeroIndex)
- {
- rdIndex += low;
- }
-
- return Register(rdIndex, RegisterType.Gpr);
- }
- }
-
- int handle = op.Immediate;
-
- for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
- {
- if ((compMask & 1) != 0)
- {
- Operand dest = GetDest();
-
- TextureOperation operation = new TextureOperation(
- Instruction.TextureSample,
- type,
- flags,
- handle,
- compIndex,
- dest,
- sources);
-
- context.Add(operation);
- }
- }
-
- if (op.IsFp16)
- {
- context.Copy(Register(op.Rd0), context.PackHalf2x16(rd0[0], rd0[1]));
- context.Copy(Register(op.Rd1), context.PackHalf2x16(rd1[0], rd1[1]));
- }
- }
-
- public static void Tld4(EmitterContext context)
- {
- OpCodeTld4 op = (OpCodeTld4)context.CurrOp;
-
- if (op.Rd.IsRZ)
- {
- return;
- }
-
- int raIndex = op.Ra.Index;
- int rbIndex = op.Rb.Index;
-
- Operand Ra()
- {
- if (raIndex > RegisterConsts.RegisterZeroIndex)
- {
- return Const(0);
- }
-
- return context.Copy(Register(raIndex++, RegisterType.Gpr));
- }
-
- Operand Rb()
- {
- if (rbIndex > RegisterConsts.RegisterZeroIndex)
- {
- return Const(0);
- }
-
- return context.Copy(Register(rbIndex++, RegisterType.Gpr));
- }
-
- Operand arrayIndex = op.IsArray ? Ra() : null;
-
- List<Operand> sourcesList = new List<Operand>();
-
- TextureType type = GetTextureType(op.Dimensions);
-
- TextureFlags flags = TextureFlags.Gather;
-
- int coordsCount = type.GetCoordsCount();
-
- for (int index = 0; index < coordsCount; index++)
- {
- sourcesList.Add(Ra());
- }
-
- if (op.IsArray)
- {
- sourcesList.Add(arrayIndex);
-
- type |= TextureType.Array;
- }
-
- Operand[] packedOffs = new Operand[2];
-
- packedOffs[0] = op.Offset != TextureGatherOffset.None ? Rb() : null;
- packedOffs[1] = op.Offset == TextureGatherOffset.Offsets ? Rb() : null;
-
- if (op.HasDepthCompare)
- {
- sourcesList.Add(Rb());
-
- type |= TextureType.Shadow;
- }
-
- if (op.Offset != TextureGatherOffset.None)
- {
- int offsetTexelsCount = op.Offset == TextureGatherOffset.Offsets ? 4 : 1;
-
- for (int index = 0; index < coordsCount * offsetTexelsCount; index++)
- {
- Operand packed = packedOffs[(index >> 2) & 1];
-
- sourcesList.Add(context.BitfieldExtractS32(packed, Const((index & 3) * 8), Const(6)));
- }
-
- flags |= op.Offset == TextureGatherOffset.Offsets
- ? TextureFlags.Offsets
- : TextureFlags.Offset;
- }
-
- sourcesList.Add(Const(op.GatherCompIndex));
-
- Operand[] sources = sourcesList.ToArray();
-
- int rdIndex = op.Rd.Index;
-
- Operand GetDest()
- {
- if (rdIndex > RegisterConsts.RegisterZeroIndex)
- {
- return Const(0);
- }
-
- return Register(rdIndex++, RegisterType.Gpr);
- }
-
- int handle = op.Immediate;
-
- for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
- {
- if ((compMask & 1) != 0)
- {
- Operand dest = GetDest();
-
- TextureOperation operation = new TextureOperation(
- Instruction.TextureSample,
- type,
- flags,
- handle,
- compIndex,
- dest,
- sources);
-
- context.Add(operation);
- }
- }
- }
-
- public static void Txq(EmitterContext context)
- {
- Txq(context, bindless: false);
- }
-
- public static void Txq_B(EmitterContext context)
- {
- Txq(context, bindless: true);
- }
-
- private static void Txq(EmitterContext context, bool bindless)
- {
- OpCodeTex op = (OpCodeTex)context.CurrOp;
-
- if (op.Rd.IsRZ)
- {
- return;
- }
-
- TextureProperty property = (TextureProperty)op.RawOpCode.Extract(22, 6);
-
- // TODO: Validate and use property.
- Instruction inst = Instruction.TextureSize;
-
- TextureType type = TextureType.Texture2D;
-
- TextureFlags flags = bindless ? TextureFlags.Bindless : TextureFlags.None;
-
- int raIndex = op.Ra.Index;
-
- Operand Ra()
- {
- if (raIndex > RegisterConsts.RegisterZeroIndex)
- {
- return Const(0);
- }
-
- return context.Copy(Register(raIndex++, RegisterType.Gpr));
- }
-
- List<Operand> sourcesList = new List<Operand>();
-
- if (bindless)
- {
- sourcesList.Add(Ra());
- }
-
- sourcesList.Add(Ra());
-
- Operand[] sources = sourcesList.ToArray();
-
- int rdIndex = op.Rd.Index;
-
- Operand GetDest()
- {
- if (rdIndex > RegisterConsts.RegisterZeroIndex)
- {
- return Const(0);
- }
-
- return Register(rdIndex++, RegisterType.Gpr);
- }
-
- int handle = !bindless ? op.Immediate : 0;
-
- for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
- {
- if ((compMask & 1) != 0)
- {
- Operand dest = GetDest();
-
- TextureOperation operation = new TextureOperation(
- inst,
- type,
- flags,
- handle,
- compIndex,
- dest,
- sources);
-
- context.Add(operation);
- }
- }
- }
-
- private static void Tex(EmitterContext context, TextureFlags flags)
- {
- OpCodeTexture op = (OpCodeTexture)context.CurrOp;
-
- bool isBindless = (flags & TextureFlags.Bindless) != 0;
- bool intCoords = (flags & TextureFlags.IntCoords) != 0;
-
- if (op.Rd.IsRZ)
- {
- return;
- }
-
- int raIndex = op.Ra.Index;
- int rbIndex = op.Rb.Index;
-
- Operand Ra()
- {
- if (raIndex > RegisterConsts.RegisterZeroIndex)
- {
- return Const(0);
- }
-
- return context.Copy(Register(raIndex++, RegisterType.Gpr));
- }
-
- Operand Rb()
- {
- if (rbIndex > RegisterConsts.RegisterZeroIndex)
- {
- return Const(0);
- }
-
- return context.Copy(Register(rbIndex++, RegisterType.Gpr));
- }
-
- Operand arrayIndex = op.IsArray ? Ra() : null;
-
- List<Operand> sourcesList = new List<Operand>();
-
- if (isBindless)
- {
- sourcesList.Add(Rb());
- }
-
- TextureType type = GetTextureType(op.Dimensions);
-
- int coordsCount = type.GetCoordsCount();
-
- for (int index = 0; index < coordsCount; index++)
- {
- sourcesList.Add(Ra());
- }
-
- if (op.IsArray)
- {
- sourcesList.Add(arrayIndex);
-
- type |= TextureType.Array;
- }
-
- bool hasLod = op.LodMode > TextureLodMode.LodZero;
-
- Operand lodValue = hasLod ? Rb() : ConstF(0);
-
- Operand packedOffs = op.HasOffset ? Rb() : null;
-
- if (op.HasDepthCompare)
- {
- sourcesList.Add(Rb());
-
- type |= TextureType.Shadow;
- }
-
- if ((op.LodMode == TextureLodMode.LodZero ||
- op.LodMode == TextureLodMode.LodLevel ||
- op.LodMode == TextureLodMode.LodLevelA) && !op.IsMultisample)
- {
- sourcesList.Add(lodValue);
-
- flags |= TextureFlags.LodLevel;
- }
-
- if (op.HasOffset)
- {
- for (int index = 0; index < coordsCount; index++)
- {
- sourcesList.Add(context.BitfieldExtractS32(packedOffs, Const(index * 4), Const(4)));
- }
-
- flags |= TextureFlags.Offset;
- }
-
- if (op.LodMode == TextureLodMode.LodBias ||
- op.LodMode == TextureLodMode.LodBiasA)
- {
- sourcesList.Add(lodValue);
-
- flags |= TextureFlags.LodBias;
- }
-
- if (op.IsMultisample)
- {
- sourcesList.Add(Rb());
-
- type |= TextureType.Multisample;
- }
-
- Operand[] sources = sourcesList.ToArray();
-
- int rdIndex = op.Rd.Index;
-
- Operand GetDest()
- {
- if (rdIndex > RegisterConsts.RegisterZeroIndex)
- {
- return Const(0);
- }
-
- return Register(rdIndex++, RegisterType.Gpr);
- }
-
- int handle = !isBindless ? op.Immediate : 0;
-
- for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
- {
- if ((compMask & 1) != 0)
- {
- Operand dest = GetDest();
-
- TextureOperation operation = new TextureOperation(
- Instruction.TextureSample,
- type,
- flags,
- handle,
- compIndex,
- dest,
- sources);
-
- context.Add(operation);
- }
- }
- }
-
- private static TextureType GetTextureType(TextureDimensions dimensions)
- {
- switch (dimensions)
- {
- case TextureDimensions.Texture1D: return TextureType.Texture1D;
- case TextureDimensions.Texture2D: return TextureType.Texture2D;
- case TextureDimensions.Texture3D: return TextureType.Texture3D;
- case TextureDimensions.TextureCube: return TextureType.TextureCube;
- }
-
- throw new ArgumentException($"Invalid texture dimensions \"{dimensions}\".");
- }
-
- private static TextureType GetTextureType(TextureScalarType type)
- {
- switch (type)
- {
- case TextureScalarType.Texture1DLodZero:
- return TextureType.Texture1D;
-
- case TextureScalarType.Texture2D:
- case TextureScalarType.Texture2DLodZero:
- case TextureScalarType.Texture2DLodLevel:
- return TextureType.Texture2D;
-
- case TextureScalarType.Texture2DDepthCompare:
- case TextureScalarType.Texture2DLodLevelDepthCompare:
- case TextureScalarType.Texture2DLodZeroDepthCompare:
- return TextureType.Texture2D | TextureType.Shadow;
-
- case TextureScalarType.Texture2DArray:
- case TextureScalarType.Texture2DArrayLodZero:
- return TextureType.Texture2D | TextureType.Array;
-
- case TextureScalarType.Texture2DArrayLodZeroDepthCompare:
- return TextureType.Texture2D | TextureType.Array | TextureType.Shadow;
-
- case TextureScalarType.Texture3D:
- case TextureScalarType.Texture3DLodZero:
- return TextureType.Texture3D;
-
- case TextureScalarType.TextureCube:
- case TextureScalarType.TextureCubeLodLevel:
- return TextureType.TextureCube;
- }
-
- throw new ArgumentException($"Invalid texture type \"{type}\".");
- }
-
- private static TextureType GetTextureType(TexelLoadScalarType type)
- {
- switch (type)
- {
- case TexelLoadScalarType.Texture1DLodZero:
- case TexelLoadScalarType.Texture1DLodLevel:
- return TextureType.Texture1D;
-
- case TexelLoadScalarType.Texture2DLodZero:
- case TexelLoadScalarType.Texture2DLodZeroOffset:
- case TexelLoadScalarType.Texture2DLodLevel:
- case TexelLoadScalarType.Texture2DLodLevelOffset:
- return TextureType.Texture2D;
-
- case TexelLoadScalarType.Texture2DLodZeroMultisample:
- return TextureType.Texture2D | TextureType.Multisample;
-
- case TexelLoadScalarType.Texture3DLodZero:
- return TextureType.Texture3D;
-
- case TexelLoadScalarType.Texture2DArrayLodZero:
- return TextureType.Texture2D | TextureType.Array;
- }
-
- throw new ArgumentException($"Invalid texture type \"{type}\".");
- }
-
- private static TextureFlags GetTextureFlags(TextureScalarType type)
- {
- switch (type)
- {
- case TextureScalarType.Texture1DLodZero:
- case TextureScalarType.Texture2DLodZero:
- case TextureScalarType.Texture2DLodLevel:
- case TextureScalarType.Texture2DLodLevelDepthCompare:
- case TextureScalarType.Texture2DLodZeroDepthCompare:
- case TextureScalarType.Texture2DArrayLodZero:
- case TextureScalarType.Texture2DArrayLodZeroDepthCompare:
- case TextureScalarType.Texture3DLodZero:
- case TextureScalarType.TextureCubeLodLevel:
- return TextureFlags.LodLevel;
-
- case TextureScalarType.Texture2D:
- case TextureScalarType.Texture2DDepthCompare:
- case TextureScalarType.Texture2DArray:
- case TextureScalarType.Texture3D:
- case TextureScalarType.TextureCube:
- return TextureFlags.None;
- }
-
- throw new ArgumentException($"Invalid texture type \"{type}\".");
- }
-
- private static TextureFlags GetTextureFlags(TexelLoadScalarType type)
- {
- switch (type)
- {
- case TexelLoadScalarType.Texture1DLodZero:
- case TexelLoadScalarType.Texture1DLodLevel:
- case TexelLoadScalarType.Texture2DLodZero:
- case TexelLoadScalarType.Texture2DLodLevel:
- case TexelLoadScalarType.Texture2DLodZeroMultisample:
- case TexelLoadScalarType.Texture3DLodZero:
- case TexelLoadScalarType.Texture2DArrayLodZero:
- return TextureFlags.LodLevel;
-
- case TexelLoadScalarType.Texture2DLodZeroOffset:
- case TexelLoadScalarType.Texture2DLodLevelOffset:
- return TextureFlags.LodLevel | TextureFlags.Offset;
- }
-
- throw new ArgumentException($"Invalid texture type \"{type}\".");
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitter.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitter.cs
deleted file mode 100644
index 91c740b6..00000000
--- a/Ryujinx.Graphics/Shader/Instructions/InstEmitter.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-using Ryujinx.Graphics.Shader.Translation;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
- delegate void InstEmitter(EmitterContext context);
-} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Shader/Instructions/Lop3Expression.cs b/Ryujinx.Graphics/Shader/Instructions/Lop3Expression.cs
deleted file mode 100644
index 67e24957..00000000
--- a/Ryujinx.Graphics/Shader/Instructions/Lop3Expression.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-
-using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
- static class Lop3Expression
- {
- public static Operand GetFromTruthTable(
- EmitterContext context,
- Operand srcA,
- Operand srcB,
- Operand srcC,
- int imm)
- {
- Operand expr = null;
-
- // Handle some simple cases, or cases where
- // the KMap would yield poor results (like XORs).
- if (imm == 0x96 || imm == 0x69)
- {
- // XOR (0x96) and XNOR (0x69).
- if (imm == 0x69)
- {
- srcA = context.BitwiseNot(srcA);
- }
-
- expr = context.BitwiseExclusiveOr(srcA, srcB);
- expr = context.BitwiseExclusiveOr(expr, srcC);
-
- return expr;
- }
- else if (imm == 0)
- {
- // Always false.
- return Const(IrConsts.False);
- }
- else if (imm == 0xff)
- {
- // Always true.
- return Const(IrConsts.True);
- }
-
- int map;
-
- // Encode into gray code.
- map = ((imm >> 0) & 1) << 0;
- map |= ((imm >> 1) & 1) << 4;
- map |= ((imm >> 2) & 1) << 1;
- map |= ((imm >> 3) & 1) << 5;
- map |= ((imm >> 4) & 1) << 3;
- map |= ((imm >> 5) & 1) << 7;
- map |= ((imm >> 6) & 1) << 2;
- map |= ((imm >> 7) & 1) << 6;
-
- // Solve KMap, get sum of products.
- int visited = 0;
-
- for (int index = 0; index < 8 && visited != 0xff; index++)
- {
- if ((map & (1 << index)) == 0)
- {
- continue;
- }
-
- int mask = 0;
-
- for (int mSize = 4; mSize != 0; mSize >>= 1)
- {
- mask = RotateLeft4((1 << mSize) - 1, index & 3) << (index & 4);
-
- if ((map & mask) == mask)
- {
- break;
- }
- }
-
- // The mask should wrap, if we are on the high row, shift to low etc.
- int mask2 = (index & 4) != 0 ? mask >> 4 : mask << 4;
-
- if ((map & mask2) == mask2)
- {
- mask |= mask2;
- }
-
- if ((mask & visited) == mask)
- {
- continue;
- }
-
- bool notA = (mask & 0x33) != 0;
- bool notB = (mask & 0x99) != 0;
- bool notC = (mask & 0x0f) != 0;
-
- bool aChanges = (mask & 0xcc) != 0 && notA;
- bool bChanges = (mask & 0x66) != 0 && notB;
- bool cChanges = (mask & 0xf0) != 0 && notC;
-
- Operand localExpr = null;
-
- void And(Operand source)
- {
- if (localExpr != null)
- {
- localExpr = context.BitwiseAnd(localExpr, source);
- }
- else
- {
- localExpr = source;
- }
- }
-
- if (!aChanges)
- {
- And(context.BitwiseNot(srcA, notA));
- }
-
- if (!bChanges)
- {
- And(context.BitwiseNot(srcB, notB));
- }
-
- if (!cChanges)
- {
- And(context.BitwiseNot(srcC, notC));
- }
-
- if (expr != null)
- {
- expr = context.BitwiseOr(expr, localExpr);
- }
- else
- {
- expr = localExpr;
- }
-
- visited |= mask;
- }
-
- return expr;
- }
-
- private static int RotateLeft4(int value, int shift)
- {
- return ((value << shift) | (value >> (4 - shift))) & 0xf;
- }
- }
-} \ No newline at end of file