video_set_predicate.cpp 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "common/common_types.h"
  5. #include "shader_recompiler/exception.h"
  6. #include "shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h"
  7. #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
  8. #include "shader_recompiler/frontend/maxwell/translate/impl/video_helper.h"
  9. namespace Shader::Maxwell {
  10. namespace {
  11. enum class VsetpCompareOp : u64 {
  12. False = 0,
  13. LessThan,
  14. Equal,
  15. LessThanEqual,
  16. GreaterThan = 16,
  17. NotEqual,
  18. GreaterThanEqual,
  19. True,
  20. };
  21. CompareOp VsetpToShaderCompareOp(VsetpCompareOp op) {
  22. switch (op) {
  23. case VsetpCompareOp::False:
  24. return CompareOp::False;
  25. case VsetpCompareOp::LessThan:
  26. return CompareOp::LessThan;
  27. case VsetpCompareOp::Equal:
  28. return CompareOp::Equal;
  29. case VsetpCompareOp::LessThanEqual:
  30. return CompareOp::LessThanEqual;
  31. case VsetpCompareOp::GreaterThan:
  32. return CompareOp::GreaterThan;
  33. case VsetpCompareOp::NotEqual:
  34. return CompareOp::NotEqual;
  35. case VsetpCompareOp::GreaterThanEqual:
  36. return CompareOp::GreaterThanEqual;
  37. case VsetpCompareOp::True:
  38. return CompareOp::True;
  39. default:
  40. throw NotImplementedException("Invalid compare op {}", op);
  41. }
  42. }
  43. } // Anonymous namespace
  44. void TranslatorVisitor::VSETP(u64 insn) {
  45. union {
  46. u64 raw;
  47. BitField<0, 3, IR::Pred> dest_pred_b;
  48. BitField<3, 3, IR::Pred> dest_pred_a;
  49. BitField<20, 16, u64> src_b_imm;
  50. BitField<28, 2, u64> src_b_selector;
  51. BitField<29, 2, VideoWidth> src_b_width;
  52. BitField<36, 2, u64> src_a_selector;
  53. BitField<37, 2, VideoWidth> src_a_width;
  54. BitField<39, 3, IR::Pred> bop_pred;
  55. BitField<42, 1, u64> neg_bop_pred;
  56. BitField<43, 5, VsetpCompareOp> compare_op;
  57. BitField<45, 2, BooleanOp> bop;
  58. BitField<48, 1, u64> src_a_sign;
  59. BitField<49, 1, u64> src_b_sign;
  60. BitField<50, 1, u64> is_src_b_reg;
  61. } const vsetp{insn};
  62. const bool is_b_imm{vsetp.is_src_b_reg == 0};
  63. const IR::U32 src_a{GetReg8(insn)};
  64. const IR::U32 src_b{is_b_imm ? ir.Imm32(static_cast<u32>(vsetp.src_b_imm)) : GetReg20(insn)};
  65. const u32 a_selector{static_cast<u32>(vsetp.src_a_selector)};
  66. const u32 b_selector{is_b_imm ? 0U : static_cast<u32>(vsetp.src_b_selector)};
  67. const VideoWidth a_width{vsetp.src_a_width};
  68. const VideoWidth b_width{GetVideoSourceWidth(vsetp.src_b_width, is_b_imm)};
  69. const bool src_a_signed{vsetp.src_a_sign != 0};
  70. const bool src_b_signed{vsetp.src_b_sign != 0};
  71. const IR::U32 op_a{ExtractVideoOperandValue(ir, src_a, a_width, a_selector, src_a_signed)};
  72. const IR::U32 op_b{ExtractVideoOperandValue(ir, src_b, b_width, a_selector, src_b_signed)};
  73. // Compare operation's sign is only dependent on operand b's sign
  74. const bool compare_signed{src_b_signed};
  75. const CompareOp compare_op{VsetpToShaderCompareOp(vsetp.compare_op)};
  76. const IR::U1 comparison{IntegerCompare(ir, op_a, op_b, compare_op, compare_signed)};
  77. const IR::U1 bop_pred{ir.GetPred(vsetp.bop_pred, vsetp.neg_bop_pred != 0)};
  78. const IR::U1 result_a{PredicateCombine(ir, comparison, bop_pred, vsetp.bop)};
  79. const IR::U1 result_b{PredicateCombine(ir, ir.LogicalNot(comparison), bop_pred, vsetp.bop)};
  80. ir.SetPred(vsetp.dest_pred_a, result_a);
  81. ir.SetPred(vsetp.dest_pred_b, result_b);
  82. }
  83. } // namespace Shader::Maxwell