diff options
Diffstat (limited to 'src/video_core/renderer_opengl')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
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"); |