diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 91 |
1 files changed, 91 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 e350113f1..582c811e0 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -1505,6 +1505,73 @@ private: | |||
| 1505 | 1, 1); | 1505 | 1, 1); |
| 1506 | break; | 1506 | break; |
| 1507 | } | 1507 | } |
| 1508 | case OpCode::Id::LEA_R2: | ||
| 1509 | case OpCode::Id::LEA_R1: | ||
| 1510 | case OpCode::Id::LEA_IMM: | ||
| 1511 | case OpCode::Id::LEA_RZ: | ||
| 1512 | case OpCode::Id::LEA_HI: { | ||
| 1513 | std::string op_a; | ||
| 1514 | std::string op_b; | ||
| 1515 | std::string op_c; | ||
| 1516 | |||
| 1517 | switch (opcode->GetId()) { | ||
| 1518 | case OpCode::Id::LEA_R2: { | ||
| 1519 | op_a = regs.GetRegisterAsInteger(instr.gpr20); | ||
| 1520 | op_b = regs.GetRegisterAsInteger(instr.gpr39); | ||
| 1521 | op_c = std::to_string(instr.lea.r2.entry_a); | ||
| 1522 | break; | ||
| 1523 | } | ||
| 1524 | |||
| 1525 | case OpCode::Id::LEA_R1: { | ||
| 1526 | const bool neg = instr.lea.r1.neg != 0; | ||
| 1527 | op_a = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 1528 | if (neg) | ||
| 1529 | op_a = "-(" + op_a + ')'; | ||
| 1530 | op_b = regs.GetRegisterAsInteger(instr.gpr20); | ||
| 1531 | op_c = std::to_string(instr.lea.r1.entry_a); | ||
| 1532 | break; | ||
| 1533 | } | ||
| 1534 | |||
| 1535 | case OpCode::Id::LEA_IMM: { | ||
| 1536 | const bool neg = instr.lea.imm.neg != 0; | ||
| 1537 | op_b = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 1538 | if (neg) | ||
| 1539 | op_b = "-(" + op_b + ')'; | ||
| 1540 | op_a = std::to_string(instr.lea.imm.entry_a); | ||
| 1541 | op_c = std::to_string(instr.lea.imm.entry_b); | ||
| 1542 | break; | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | case OpCode::Id::LEA_RZ: { | ||
| 1546 | const bool neg = instr.lea.rz.neg != 0; | ||
| 1547 | op_b = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 1548 | if (neg) | ||
| 1549 | op_b = "-(" + op_b + ')'; | ||
| 1550 | op_a = regs.GetUniform(instr.lea.rz.cb_index, instr.lea.rz.cb_offset, | ||
| 1551 | GLSLRegister::Type::Integer); | ||
| 1552 | op_c = std::to_string(instr.lea.rz.entry_a); | ||
| 1553 | |||
| 1554 | break; | ||
| 1555 | } | ||
| 1556 | |||
| 1557 | case OpCode::Id::LEA_HI: | ||
| 1558 | default: { | ||
| 1559 | op_b = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 1560 | op_a = std::to_string(instr.lea.imm.entry_a); | ||
| 1561 | op_c = std::to_string(instr.lea.imm.entry_b); | ||
| 1562 | LOG_CRITICAL(HW_GPU, "Unhandled LEA subinstruction: {}", opcode->GetName()); | ||
| 1563 | UNREACHABLE(); | ||
| 1564 | } | ||
| 1565 | } | ||
| 1566 | if (instr.lea.pred48 != static_cast<u64>(Pred::UnusedIndex)) { | ||
| 1567 | LOG_ERROR(HW_GPU, "Unhandled LEA Predicate"); | ||
| 1568 | UNREACHABLE(); | ||
| 1569 | } | ||
| 1570 | const std::string value = '(' + op_a + " + (" + op_b + "*(1 << " + op_c + ")))"; | ||
| 1571 | regs.SetRegisterToInteger(instr.gpr0, true, 0, value, 1, 1); | ||
| 1572 | |||
| 1573 | break; | ||
| 1574 | } | ||
| 1508 | default: { | 1575 | default: { |
| 1509 | LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}", | 1576 | LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}", |
| 1510 | opcode->GetName()); | 1577 | opcode->GetName()); |
| @@ -2087,6 +2154,30 @@ private: | |||
| 2087 | } | 2154 | } |
| 2088 | break; | 2155 | break; |
| 2089 | } | 2156 | } |
| 2157 | case OpCode::Type::PredicateSetRegister: { | ||
| 2158 | const std::string op_a = | ||
| 2159 | GetPredicateCondition(instr.pset.pred12, instr.pset.neg_pred12 != 0); | ||
| 2160 | const std::string op_b = | ||
| 2161 | GetPredicateCondition(instr.pset.pred29, instr.pset.neg_pred29 != 0); | ||
| 2162 | |||
| 2163 | const std::string second_pred = | ||
| 2164 | GetPredicateCondition(instr.pset.pred39, instr.pset.neg_pred39 != 0); | ||
| 2165 | |||
| 2166 | const std::string combiner = GetPredicateCombiner(instr.pset.op); | ||
| 2167 | |||
| 2168 | const std::string predicate = | ||
| 2169 | '(' + op_a + ") " + GetPredicateCombiner(instr.pset.cond) + " (" + op_b + ')'; | ||
| 2170 | const std::string result = '(' + predicate + ") " + combiner + " (" + second_pred + ')'; | ||
| 2171 | if (instr.pset.bf == 0) { | ||
| 2172 | const std::string value = '(' + result + ") ? 0xFFFFFFFF : 0"; | ||
| 2173 | regs.SetRegisterToInteger(instr.gpr0, false, 0, value, 1, 1); | ||
| 2174 | } else { | ||
| 2175 | const std::string value = '(' + result + ") ? 1.0 : 0.0"; | ||
| 2176 | regs.SetRegisterToFloat(instr.gpr0, 0, value, 1, 1); | ||
| 2177 | } | ||
| 2178 | |||
| 2179 | break; | ||
| 2180 | } | ||
| 2090 | case OpCode::Type::PredicateSetPredicate: { | 2181 | case OpCode::Type::PredicateSetPredicate: { |
| 2091 | const std::string op_a = | 2182 | const std::string op_a = |
| 2092 | GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0); | 2183 | GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0); |