summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/engines/shader_bytecode.h18
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp44
2 files changed, 62 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index a6e764ea4..39ae065de 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -832,6 +832,21 @@ union Instruction {
832 } fset; 832 } fset;
833 833
834 union { 834 union {
835 BitField<49, 1, u64> bf;
836 BitField<35, 3, PredCondition> cond;
837 BitField<50, 1, u64> ftz;
838 BitField<45, 2, PredOperation> op;
839 BitField<43, 1, u64> negate_a;
840 BitField<44, 1, u64> abs_a;
841 BitField<47, 2, HalfType> type_a;
842 BitField<31, 1, u64> negate_b;
843 BitField<30, 1, u64> abs_b;
844 BitField<28, 2, HalfType> type_b;
845 BitField<42, 1, u64> neg_pred;
846 BitField<39, 3, u64> pred39;
847 } hset2;
848
849 union {
835 BitField<39, 3, u64> pred39; 850 BitField<39, 3, u64> pred39;
836 BitField<42, 1, u64> neg_pred; 851 BitField<42, 1, u64> neg_pred;
837 BitField<44, 1, u64> bf; 852 BitField<44, 1, u64> bf;
@@ -1257,6 +1272,7 @@ public:
1257 HFMA2_RR, 1272 HFMA2_RR,
1258 HFMA2_IMM_R, 1273 HFMA2_IMM_R,
1259 HSETP2_R, 1274 HSETP2_R,
1275 HSET2_R,
1260 POPC_C, 1276 POPC_C,
1261 POPC_R, 1277 POPC_R,
1262 POPC_IMM, 1278 POPC_IMM,
@@ -1343,6 +1359,7 @@ public:
1343 FloatSetPredicate, 1359 FloatSetPredicate,
1344 IntegerSet, 1360 IntegerSet,
1345 IntegerSetPredicate, 1361 IntegerSetPredicate,
1362 HalfSet,
1346 HalfSetPredicate, 1363 HalfSetPredicate,
1347 PredicateSetPredicate, 1364 PredicateSetPredicate,
1348 PredicateSetRegister, 1365 PredicateSetRegister,
@@ -1516,6 +1533,7 @@ private:
1516 INST("0101110100000---", Id::HFMA2_RR, Type::Hfma2, "HFMA2_RR"), 1533 INST("0101110100000---", Id::HFMA2_RR, Type::Hfma2, "HFMA2_RR"),
1517 INST("01110---0-------", Id::HFMA2_IMM_R, Type::Hfma2, "HFMA2_R_IMM"), 1534 INST("01110---0-------", Id::HFMA2_IMM_R, Type::Hfma2, "HFMA2_R_IMM"),
1518 INST("0101110100100---", Id::HSETP2_R, Type::HalfSetPredicate, "HSETP_R"), 1535 INST("0101110100100---", Id::HSETP2_R, Type::HalfSetPredicate, "HSETP_R"),
1536 INST("0101110100011---", Id::HSET2_R, Type::HalfSet, "HSET2_R"),
1519 INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), 1537 INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"),
1520 INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), 1538 INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"),
1521 INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), 1539 INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"),
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 06f85fad2..23349b1a1 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -2996,6 +2996,50 @@ private:
2996 } 2996 }
2997 break; 2997 break;
2998 } 2998 }
2999 case OpCode::Type::HalfSet: {
3000 ASSERT_MSG(instr.hset2.ftz == 0, "Unimplemented");
3001
3002 const std::string op_a =
3003 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.hset2.type_a,
3004 instr.hset2.abs_a != 0, instr.hset2.negate_a != 0);
3005
3006 const std::string op_b = [&]() {
3007 switch (opcode->GetId()) {
3008 case OpCode::Id::HSET2_R:
3009 return GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr20, 0, false),
3010 instr.hset2.type_b, instr.hset2.abs_b != 0,
3011 instr.hset2.negate_b != 0);
3012 default:
3013 UNREACHABLE();
3014 return std::string("vec2(0)");
3015 }
3016 }();
3017
3018 const std::string second_pred =
3019 GetPredicateCondition(instr.hset2.pred39, instr.hset2.neg_pred != 0);
3020
3021 const std::string combiner = GetPredicateCombiner(instr.hset2.op);
3022
3023 // HSET2 operates on each half float in the pack.
3024 std::string result;
3025 for (int i = 0; i < 2; ++i) {
3026 const std::string float_value = i == 0 ? "0x00003c00" : "0x3c000000";
3027 const std::string integer_value = i == 0 ? "0x0000ffff" : "0xffff0000";
3028 const std::string value = instr.hset2.bf == 1 ? float_value : integer_value;
3029
3030 const std::string comp = std::string(".") + "xy"[i];
3031 const std::string predicate =
3032 "((" + GetPredicateComparison(instr.hset2.cond, op_a + comp, op_b + comp) +
3033 ") " + combiner + " (" + second_pred + "))";
3034
3035 result += '(' + predicate + " ? " + value + " : 0)";
3036 if (i == 0) {
3037 result += " | ";
3038 }
3039 }
3040 regs.SetRegisterToInteger(instr.gpr0, false, 0, '(' + result + ')', 1, 1);
3041 break;
3042 }
2999 case OpCode::Type::Xmad: { 3043 case OpCode::Type::Xmad: {
3000 ASSERT_MSG(!instr.xmad.sign_a, "Unimplemented"); 3044 ASSERT_MSG(!instr.xmad.sign_a, "Unimplemented");
3001 ASSERT_MSG(!instr.xmad.sign_b, "Unimplemented"); 3045 ASSERT_MSG(!instr.xmad.sign_b, "Unimplemented");