diff options
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 18 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 44 |
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"); |