InstEmitPredicate.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. using Ryujinx.Graphics.Shader.Decoders;
  2. using Ryujinx.Graphics.Shader.IntermediateRepresentation;
  3. using Ryujinx.Graphics.Shader.Translation;
  4. using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
  5. using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
  6. using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
  7. namespace Ryujinx.Graphics.Shader.Instructions
  8. {
  9. static partial class InstEmit
  10. {
  11. public static void Pset(EmitterContext context)
  12. {
  13. InstPset op = context.GetOp<InstPset>();
  14. Operand srcA = context.BitwiseNot(Register(op.Src2Pred, RegisterType.Predicate), op.Src2PredInv);
  15. Operand srcB = context.BitwiseNot(Register(op.Src1Pred, RegisterType.Predicate), op.Src1PredInv);
  16. Operand srcC = context.BitwiseNot(Register(op.SrcPred, RegisterType.Predicate), op.SrcPredInv);
  17. Operand res = GetPredLogicalOp(context, op.BoolOpAB, srcA, srcB);
  18. res = GetPredLogicalOp(context, op.BoolOpC, res, srcC);
  19. Operand dest = GetDest(op.Dest);
  20. if (op.BVal)
  21. {
  22. context.Copy(dest, context.ConditionalSelect(res, ConstF(1), ConstF(0)));
  23. }
  24. else
  25. {
  26. context.Copy(dest, res);
  27. }
  28. }
  29. public static void Psetp(EmitterContext context)
  30. {
  31. InstPsetp op = context.GetOp<InstPsetp>();
  32. Operand srcA = context.BitwiseNot(Register(op.Src2Pred, RegisterType.Predicate), op.Src2PredInv);
  33. Operand srcB = context.BitwiseNot(Register(op.Src1Pred, RegisterType.Predicate), op.Src1PredInv);
  34. Operand p0Res = GetPredLogicalOp(context, op.BoolOpAB, srcA, srcB);
  35. Operand p1Res = context.BitwiseNot(p0Res);
  36. Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
  37. p0Res = GetPredLogicalOp(context, op.BoolOpC, p0Res, srcPred);
  38. p1Res = GetPredLogicalOp(context, op.BoolOpC, p1Res, srcPred);
  39. context.Copy(Register(op.DestPred, RegisterType.Predicate), p0Res);
  40. context.Copy(Register(op.DestPredInv, RegisterType.Predicate), p1Res);
  41. }
  42. public static void P2rC(EmitterContext context)
  43. {
  44. InstP2rC op = context.GetOp<InstP2rC>();
  45. Operand srcA = GetSrcReg(context, op.SrcA);
  46. Operand dest = GetSrcReg(context, op.Dest);
  47. Operand mask = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
  48. EmitP2r(context, srcA, dest, mask, op.ByteSel, op.Ccpr);
  49. }
  50. public static void P2rI(EmitterContext context)
  51. {
  52. InstP2rI op = context.GetOp<InstP2rI>();
  53. Operand srcA = GetSrcReg(context, op.SrcA);
  54. Operand dest = GetSrcReg(context, op.Dest);
  55. Operand mask = GetSrcImm(context, op.Imm20);
  56. EmitP2r(context, srcA, dest, mask, op.ByteSel, op.Ccpr);
  57. }
  58. public static void P2rR(EmitterContext context)
  59. {
  60. InstP2rR op = context.GetOp<InstP2rR>();
  61. Operand srcA = GetSrcReg(context, op.SrcA);
  62. Operand dest = GetSrcReg(context, op.Dest);
  63. Operand mask = GetSrcReg(context, op.SrcB);
  64. EmitP2r(context, srcA, dest, mask, op.ByteSel, op.Ccpr);
  65. }
  66. private static void EmitP2r(
  67. EmitterContext context,
  68. Operand srcA,
  69. Operand dest,
  70. Operand mask,
  71. ByteSel byteSel,
  72. bool ccpr)
  73. {
  74. int count = ccpr ? RegisterConsts.FlagsCount : RegisterConsts.PredsCount;
  75. int shift = (int)byteSel * 8;
  76. mask = context.BitwiseAnd(mask, Const(0xff));
  77. Operand insert = Const(0);
  78. for (int i = 0; i < count; i++)
  79. {
  80. Operand condition = ccpr
  81. ? Register(i, RegisterType.Flag)
  82. : Register(i, RegisterType.Predicate);
  83. Operand bit = context.ConditionalSelect(condition, Const(1 << (i + shift)), Const(0));
  84. insert = context.BitwiseOr(insert, bit);
  85. }
  86. Operand maskShifted = context.ShiftLeft(mask, Const(shift));
  87. Operand masked = context.BitwiseAnd(srcA, context.BitwiseNot(maskShifted));
  88. Operand res = context.BitwiseOr(masked, context.BitwiseAnd(insert, maskShifted));
  89. context.Copy(dest, res);
  90. }
  91. }
  92. }