diff options
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 98 |
2 files changed, 103 insertions, 1 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index b84da512f..27c011e6f 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -578,6 +578,10 @@ union Instruction { | |||
| 578 | } fmul32; | 578 | } fmul32; |
| 579 | 579 | ||
| 580 | union { | 580 | union { |
| 581 | BitField<52, 1, u64> generates_cc; | ||
| 582 | } op_32; | ||
| 583 | |||
| 584 | union { | ||
| 581 | BitField<48, 1, u64> is_signed; | 585 | BitField<48, 1, u64> is_signed; |
| 582 | } shift; | 586 | } shift; |
| 583 | 587 | ||
| @@ -1658,4 +1662,4 @@ private: | |||
| 1658 | } | 1662 | } |
| 1659 | }; | 1663 | }; |
| 1660 | 1664 | ||
| 1661 | } // namespace Tegra::Shader \ No newline at end of file | 1665 | } // namespace Tegra::Shader |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index d1f6ffe40..601c41f31 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -373,6 +373,7 @@ public: | |||
| 373 | if (sets_cc) { | 373 | if (sets_cc) { |
| 374 | const std::string zero_condition = "( " + ConvertIntegerSize(value, size) + " == 0 )"; | 374 | const std::string zero_condition = "( " + ConvertIntegerSize(value, size) + " == 0 )"; |
| 375 | SetInternalFlag(InternalFlag::ZeroFlag, zero_condition); | 375 | SetInternalFlag(InternalFlag::ZeroFlag, zero_condition); |
| 376 | LOG_WARNING(HW_GPU, "Control Codes Imcomplete."); | ||
| 376 | } | 377 | } |
| 377 | } | 378 | } |
| 378 | 379 | ||
| @@ -1525,6 +1526,10 @@ private: | |||
| 1525 | 1526 | ||
| 1526 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " * " + op_b, 1, 1, | 1527 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " * " + op_b, 1, 1, |
| 1527 | instr.alu.saturate_d, 0, true); | 1528 | instr.alu.saturate_d, 0, true); |
| 1529 | if (instr.generates_cc) { | ||
| 1530 | LOG_CRITICAL(HW_GPU, "FMUL Generates an unhandled Control Code"); | ||
| 1531 | UNREACHABLE(); | ||
| 1532 | } | ||
| 1528 | break; | 1533 | break; |
| 1529 | } | 1534 | } |
| 1530 | case OpCode::Id::FADD_C: | 1535 | case OpCode::Id::FADD_C: |
| @@ -1535,6 +1540,10 @@ private: | |||
| 1535 | 1540 | ||
| 1536 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " + " + op_b, 1, 1, | 1541 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " + " + op_b, 1, 1, |
| 1537 | instr.alu.saturate_d, 0, true); | 1542 | instr.alu.saturate_d, 0, true); |
| 1543 | if (instr.generates_cc) { | ||
| 1544 | LOG_CRITICAL(HW_GPU, "FADD Generates an unhandled Control Code"); | ||
| 1545 | UNREACHABLE(); | ||
| 1546 | } | ||
| 1538 | break; | 1547 | break; |
| 1539 | } | 1548 | } |
| 1540 | case OpCode::Id::MUFU: { | 1549 | case OpCode::Id::MUFU: { |
| @@ -1588,6 +1597,10 @@ private: | |||
| 1588 | '(' + condition + ") ? min(" + parameters + ") : max(" + | 1597 | '(' + condition + ") ? min(" + parameters + ") : max(" + |
| 1589 | parameters + ')', | 1598 | parameters + ')', |
| 1590 | 1, 1, false, 0, true); | 1599 | 1, 1, false, 0, true); |
| 1600 | if (instr.generates_cc) { | ||
| 1601 | LOG_CRITICAL(HW_GPU, "FMNMX Generates an unhandled Control Code"); | ||
| 1602 | UNREACHABLE(); | ||
| 1603 | } | ||
| 1591 | break; | 1604 | break; |
| 1592 | } | 1605 | } |
| 1593 | case OpCode::Id::RRO_C: | 1606 | case OpCode::Id::RRO_C: |
| @@ -1618,6 +1631,10 @@ private: | |||
| 1618 | regs.GetRegisterAsFloat(instr.gpr8) + " * " + | 1631 | regs.GetRegisterAsFloat(instr.gpr8) + " * " + |
| 1619 | GetImmediate32(instr), | 1632 | GetImmediate32(instr), |
| 1620 | 1, 1, instr.fmul32.saturate, 0, true); | 1633 | 1, 1, instr.fmul32.saturate, 0, true); |
| 1634 | if (instr.op_32.generates_cc) { | ||
| 1635 | LOG_CRITICAL(HW_GPU, "FMUL32 Generates an unhandled Control Code"); | ||
| 1636 | UNREACHABLE(); | ||
| 1637 | } | ||
| 1621 | break; | 1638 | break; |
| 1622 | } | 1639 | } |
| 1623 | case OpCode::Id::FADD32I: { | 1640 | case OpCode::Id::FADD32I: { |
| @@ -1641,6 +1658,10 @@ private: | |||
| 1641 | } | 1658 | } |
| 1642 | 1659 | ||
| 1643 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " + " + op_b, 1, 1, false, 0, true); | 1660 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " + " + op_b, 1, 1, false, 0, true); |
| 1661 | if (instr.op_32.generates_cc) { | ||
| 1662 | LOG_CRITICAL(HW_GPU, "FADD32 Generates an unhandled Control Code"); | ||
| 1663 | UNREACHABLE(); | ||
| 1664 | } | ||
| 1644 | break; | 1665 | break; |
| 1645 | } | 1666 | } |
| 1646 | } | 1667 | } |
| @@ -1661,6 +1682,10 @@ private: | |||
| 1661 | std::to_string(instr.bfe.GetLeftShiftValue() + instr.bfe.shift_position) + ')'; | 1682 | std::to_string(instr.bfe.GetLeftShiftValue() + instr.bfe.shift_position) + ')'; |
| 1662 | 1683 | ||
| 1663 | regs.SetRegisterToInteger(instr.gpr0, true, 0, outer_shift, 1, 1); | 1684 | regs.SetRegisterToInteger(instr.gpr0, true, 0, outer_shift, 1, 1); |
| 1685 | if (instr.generates_cc) { | ||
| 1686 | LOG_CRITICAL(HW_GPU, "BFE Generates an unhandled Control Code"); | ||
| 1687 | UNREACHABLE(); | ||
| 1688 | } | ||
| 1664 | break; | 1689 | break; |
| 1665 | } | 1690 | } |
| 1666 | default: { | 1691 | default: { |
| @@ -1698,12 +1723,20 @@ private: | |||
| 1698 | // Cast to int is superfluous for arithmetic shift, it's only for a logical shift | 1723 | // Cast to int is superfluous for arithmetic shift, it's only for a logical shift |
| 1699 | regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(" + op_a + " >> " + op_b + ')', | 1724 | regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(" + op_a + " >> " + op_b + ')', |
| 1700 | 1, 1); | 1725 | 1, 1); |
| 1726 | if (instr.generates_cc) { | ||
| 1727 | LOG_CRITICAL(HW_GPU, "SHR Generates an unhandled Control Code"); | ||
| 1728 | UNREACHABLE(); | ||
| 1729 | } | ||
| 1701 | break; | 1730 | break; |
| 1702 | } | 1731 | } |
| 1703 | case OpCode::Id::SHL_C: | 1732 | case OpCode::Id::SHL_C: |
| 1704 | case OpCode::Id::SHL_R: | 1733 | case OpCode::Id::SHL_R: |
| 1705 | case OpCode::Id::SHL_IMM: | 1734 | case OpCode::Id::SHL_IMM: |
| 1706 | regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1); | 1735 | regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1); |
| 1736 | if (instr.generates_cc) { | ||
| 1737 | LOG_CRITICAL(HW_GPU, "SHL Generates an unhandled Control Code"); | ||
| 1738 | UNREACHABLE(); | ||
| 1739 | } | ||
| 1707 | break; | 1740 | break; |
| 1708 | default: { | 1741 | default: { |
| 1709 | LOG_CRITICAL(HW_GPU, "Unhandled shift instruction: {}", opcode->get().GetName()); | 1742 | LOG_CRITICAL(HW_GPU, "Unhandled shift instruction: {}", opcode->get().GetName()); |
| @@ -1723,6 +1756,10 @@ private: | |||
| 1723 | 1756 | ||
| 1724 | regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " + " + op_b, 1, 1, | 1757 | regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " + " + op_b, 1, 1, |
| 1725 | instr.iadd32i.saturate != 0); | 1758 | instr.iadd32i.saturate != 0); |
| 1759 | if (instr.op_32.generates_cc) { | ||
| 1760 | LOG_CRITICAL(HW_GPU, "IADD32 Generates an unhandled Control Code"); | ||
| 1761 | UNREACHABLE(); | ||
| 1762 | } | ||
| 1726 | break; | 1763 | break; |
| 1727 | case OpCode::Id::LOP32I: { | 1764 | case OpCode::Id::LOP32I: { |
| 1728 | if (instr.alu.lop32i.invert_a) | 1765 | if (instr.alu.lop32i.invert_a) |
| @@ -1734,6 +1771,10 @@ private: | |||
| 1734 | WriteLogicOperation(instr.gpr0, instr.alu.lop32i.operation, op_a, op_b, | 1771 | WriteLogicOperation(instr.gpr0, instr.alu.lop32i.operation, op_a, op_b, |
| 1735 | Tegra::Shader::PredicateResultMode::None, | 1772 | Tegra::Shader::PredicateResultMode::None, |
| 1736 | Tegra::Shader::Pred::UnusedIndex); | 1773 | Tegra::Shader::Pred::UnusedIndex); |
| 1774 | if (instr.op_32.generates_cc) { | ||
| 1775 | LOG_CRITICAL(HW_GPU, "LOP32I Generates an unhandled Control Code"); | ||
| 1776 | UNREACHABLE(); | ||
| 1777 | } | ||
| 1737 | break; | 1778 | break; |
| 1738 | } | 1779 | } |
| 1739 | default: { | 1780 | default: { |
| @@ -1770,6 +1811,10 @@ private: | |||
| 1770 | 1811 | ||
| 1771 | regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " + " + op_b, 1, 1, | 1812 | regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " + " + op_b, 1, 1, |
| 1772 | instr.alu.saturate_d); | 1813 | instr.alu.saturate_d); |
| 1814 | if (instr.generates_cc) { | ||
| 1815 | LOG_CRITICAL(HW_GPU, "IADD Generates an unhandled Control Code"); | ||
| 1816 | UNREACHABLE(); | ||
| 1817 | } | ||
| 1773 | break; | 1818 | break; |
| 1774 | } | 1819 | } |
| 1775 | case OpCode::Id::IADD3_C: | 1820 | case OpCode::Id::IADD3_C: |
| @@ -1831,6 +1876,11 @@ private: | |||
| 1831 | } | 1876 | } |
| 1832 | 1877 | ||
| 1833 | regs.SetRegisterToInteger(instr.gpr0, true, 0, result, 1, 1); | 1878 | regs.SetRegisterToInteger(instr.gpr0, true, 0, result, 1, 1); |
| 1879 | |||
| 1880 | if (instr.generates_cc) { | ||
| 1881 | LOG_CRITICAL(HW_GPU, "IADD3 Generates an unhandled Control Code"); | ||
| 1882 | UNREACHABLE(); | ||
| 1883 | } | ||
| 1834 | break; | 1884 | break; |
| 1835 | } | 1885 | } |
| 1836 | case OpCode::Id::ISCADD_C: | 1886 | case OpCode::Id::ISCADD_C: |
| @@ -1846,6 +1896,10 @@ private: | |||
| 1846 | 1896 | ||
| 1847 | regs.SetRegisterToInteger(instr.gpr0, true, 0, | 1897 | regs.SetRegisterToInteger(instr.gpr0, true, 0, |
| 1848 | "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1); | 1898 | "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1); |
| 1899 | if (instr.generates_cc) { | ||
| 1900 | LOG_CRITICAL(HW_GPU, "ISCADD Generates an unhandled Control Code"); | ||
| 1901 | UNREACHABLE(); | ||
| 1902 | } | ||
| 1849 | break; | 1903 | break; |
| 1850 | } | 1904 | } |
| 1851 | case OpCode::Id::POPC_C: | 1905 | case OpCode::Id::POPC_C: |
| @@ -1877,6 +1931,10 @@ private: | |||
| 1877 | 1931 | ||
| 1878 | WriteLogicOperation(instr.gpr0, instr.alu.lop.operation, op_a, op_b, | 1932 | WriteLogicOperation(instr.gpr0, instr.alu.lop.operation, op_a, op_b, |
| 1879 | instr.alu.lop.pred_result_mode, instr.alu.lop.pred48); | 1933 | instr.alu.lop.pred_result_mode, instr.alu.lop.pred48); |
| 1934 | if (instr.generates_cc) { | ||
| 1935 | LOG_CRITICAL(HW_GPU, "LOP Generates an unhandled Control Code"); | ||
| 1936 | UNREACHABLE(); | ||
| 1937 | } | ||
| 1880 | break; | 1938 | break; |
| 1881 | } | 1939 | } |
| 1882 | case OpCode::Id::LOP3_C: | 1940 | case OpCode::Id::LOP3_C: |
| @@ -1892,6 +1950,10 @@ private: | |||
| 1892 | } | 1950 | } |
| 1893 | 1951 | ||
| 1894 | WriteLop3Instruction(instr.gpr0, op_a, op_b, op_c, lut); | 1952 | WriteLop3Instruction(instr.gpr0, op_a, op_b, op_c, lut); |
| 1953 | if (instr.generates_cc) { | ||
| 1954 | LOG_CRITICAL(HW_GPU, "LOP3 Generates an unhandled Control Code"); | ||
| 1955 | UNREACHABLE(); | ||
| 1956 | } | ||
| 1895 | break; | 1957 | break; |
| 1896 | } | 1958 | } |
| 1897 | case OpCode::Id::IMNMX_C: | 1959 | case OpCode::Id::IMNMX_C: |
| @@ -1906,6 +1968,10 @@ private: | |||
| 1906 | '(' + condition + ") ? min(" + parameters + ") : max(" + | 1968 | '(' + condition + ") ? min(" + parameters + ") : max(" + |
| 1907 | parameters + ')', | 1969 | parameters + ')', |
| 1908 | 1, 1); | 1970 | 1, 1); |
| 1971 | if (instr.generates_cc) { | ||
| 1972 | LOG_CRITICAL(HW_GPU, "IMNMX Generates an unhandled Control Code"); | ||
| 1973 | UNREACHABLE(); | ||
| 1974 | } | ||
| 1909 | break; | 1975 | break; |
| 1910 | } | 1976 | } |
| 1911 | case OpCode::Id::LEA_R2: | 1977 | case OpCode::Id::LEA_R2: |
| @@ -2107,6 +2173,10 @@ private: | |||
| 2107 | 2173 | ||
| 2108 | regs.SetRegisterToFloat(instr.gpr0, 0, "fma(" + op_a + ", " + op_b + ", " + op_c + ')', | 2174 | regs.SetRegisterToFloat(instr.gpr0, 0, "fma(" + op_a + ", " + op_b + ", " + op_c + ')', |
| 2109 | 1, 1, instr.alu.saturate_d, 0, true); | 2175 | 1, 1, instr.alu.saturate_d, 0, true); |
| 2176 | if (instr.generates_cc) { | ||
| 2177 | LOG_CRITICAL(HW_GPU, "FFMA Generates an unhandled Control Code"); | ||
| 2178 | UNREACHABLE(); | ||
| 2179 | } | ||
| 2110 | 2180 | ||
| 2111 | break; | 2181 | break; |
| 2112 | } | 2182 | } |
| @@ -2212,6 +2282,11 @@ private: | |||
| 2212 | } | 2282 | } |
| 2213 | 2283 | ||
| 2214 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); | 2284 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); |
| 2285 | |||
| 2286 | if (instr.generates_cc) { | ||
| 2287 | LOG_CRITICAL(HW_GPU, "I2F Generates an unhandled Control Code"); | ||
| 2288 | UNREACHABLE(); | ||
| 2289 | } | ||
| 2215 | break; | 2290 | break; |
| 2216 | } | 2291 | } |
| 2217 | case OpCode::Id::F2F_R: { | 2292 | case OpCode::Id::F2F_R: { |
| @@ -2250,6 +2325,11 @@ private: | |||
| 2250 | } | 2325 | } |
| 2251 | 2326 | ||
| 2252 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1, instr.alu.saturate_d); | 2327 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1, instr.alu.saturate_d); |
| 2328 | |||
| 2329 | if (instr.generates_cc) { | ||
| 2330 | LOG_CRITICAL(HW_GPU, "F2F Generates an unhandled Control Code"); | ||
| 2331 | UNREACHABLE(); | ||
| 2332 | } | ||
| 2253 | break; | 2333 | break; |
| 2254 | } | 2334 | } |
| 2255 | case OpCode::Id::F2I_R: | 2335 | case OpCode::Id::F2I_R: |
| @@ -2299,6 +2379,10 @@ private: | |||
| 2299 | 2379 | ||
| 2300 | regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1, | 2380 | regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1, |
| 2301 | 1, false, 0, instr.conversion.dest_size); | 2381 | 1, false, 0, instr.conversion.dest_size); |
| 2382 | if (instr.generates_cc) { | ||
| 2383 | LOG_CRITICAL(HW_GPU, "F2I Generates an unhandled Control Code"); | ||
| 2384 | UNREACHABLE(); | ||
| 2385 | } | ||
| 2302 | break; | 2386 | break; |
| 2303 | } | 2387 | } |
| 2304 | default: { | 2388 | default: { |
| @@ -3107,6 +3191,11 @@ private: | |||
| 3107 | regs.SetRegisterToFloat(instr.gpr0, 0, value, 1, 1); | 3191 | regs.SetRegisterToFloat(instr.gpr0, 0, value, 1, 1); |
| 3108 | } | 3192 | } |
| 3109 | 3193 | ||
| 3194 | if (instr.generates_cc) { | ||
| 3195 | LOG_CRITICAL(HW_GPU, "PSET Generates an unhandled Control Code"); | ||
| 3196 | UNREACHABLE(); | ||
| 3197 | } | ||
| 3198 | |||
| 3110 | break; | 3199 | break; |
| 3111 | } | 3200 | } |
| 3112 | case OpCode::Type::PredicateSetPredicate: { | 3201 | case OpCode::Type::PredicateSetPredicate: { |
| @@ -3372,6 +3461,10 @@ private: | |||
| 3372 | } | 3461 | } |
| 3373 | 3462 | ||
| 3374 | regs.SetRegisterToInteger(instr.gpr0, is_signed, 0, sum, 1, 1); | 3463 | regs.SetRegisterToInteger(instr.gpr0, is_signed, 0, sum, 1, 1); |
| 3464 | if (instr.generates_cc) { | ||
| 3465 | LOG_CRITICAL(HW_GPU, "XMAD Generates an unhandled Control Code"); | ||
| 3466 | UNREACHABLE(); | ||
| 3467 | } | ||
| 3375 | break; | 3468 | break; |
| 3376 | } | 3469 | } |
| 3377 | default: { | 3470 | default: { |
| @@ -3543,6 +3636,11 @@ private: | |||
| 3543 | regs.SetRegisterToInteger(instr.gpr0, result_signed, 1, result, 1, 1, | 3636 | regs.SetRegisterToInteger(instr.gpr0, result_signed, 1, result, 1, 1, |
| 3544 | instr.vmad.saturate == 1, 0, Register::Size::Word, | 3637 | instr.vmad.saturate == 1, 0, Register::Size::Word, |
| 3545 | instr.vmad.cc); | 3638 | instr.vmad.cc); |
| 3639 | if (instr.generates_cc) { | ||
| 3640 | LOG_CRITICAL(HW_GPU, "VMAD Generates an unhandled Control Code"); | ||
| 3641 | UNREACHABLE(); | ||
| 3642 | } | ||
| 3643 | |||
| 3546 | break; | 3644 | break; |
| 3547 | } | 3645 | } |
| 3548 | case OpCode::Id::VSETP: { | 3646 | case OpCode::Id::VSETP: { |