diff options
| author | gdk <gab.dark.100@gmail.com> | 2019-10-13 03:02:07 -0300 |
|---|---|---|
| committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
| commit | 1876b346fea647e8284a66bb6d62c38801035cff (patch) | |
| tree | 6eeff094298cda84d1613dc5ec0691e51d7b35f1 /Ryujinx.Graphics/Shader/Instructions | |
| parent | f617fb542a0e3d36012d77a4b5acbde7b08902f2 (diff) | |
Initial work
Diffstat (limited to 'Ryujinx.Graphics/Shader/Instructions')
| -rw-r--r-- | Ryujinx.Graphics/Shader/Instructions/InstEmitAlu.cs | 684 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Shader/Instructions/InstEmitAluHelper.cs | 88 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Shader/Instructions/InstEmitConversion.cs | 213 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs | 370 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs | 107 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Shader/Instructions/InstEmitHelper.cs | 267 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Shader/Instructions/InstEmitMemory.cs | 138 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Shader/Instructions/InstEmitMove.cs | 32 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Shader/Instructions/InstEmitTexture.cs | 776 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Shader/Instructions/InstEmitter.cs | 6 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Shader/Instructions/Lop3Expression.cs | 149 |
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 |
