summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h64
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp91
2 files changed, 155 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 9176a8dbc..2db906ea5 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -424,6 +424,45 @@ union Instruction {
424 } bfe; 424 } bfe;
425 425
426 union { 426 union {
427 BitField<48, 3, u64> pred48;
428
429 union {
430 BitField<20, 20, u64> entry_a;
431 BitField<39, 5, u64> entry_b;
432 BitField<45, 1, u64> neg;
433 BitField<46, 1, u64> uses_cc;
434 } imm;
435
436 union {
437 BitField<20, 14, u64> cb_index;
438 BitField<34, 5, u64> cb_offset;
439 BitField<56, 1, u64> neg;
440 BitField<57, 1, u64> uses_cc;
441 } hi;
442
443 union {
444 BitField<20, 14, u64> cb_index;
445 BitField<34, 5, u64> cb_offset;
446 BitField<39, 5, u64> entry_a;
447 BitField<45, 1, u64> neg;
448 BitField<46, 1, u64> uses_cc;
449 } rz;
450
451 union {
452 BitField<39, 5, u64> entry_a;
453 BitField<45, 1, u64> neg;
454 BitField<46, 1, u64> uses_cc;
455 } r1;
456
457 union {
458 BitField<28, 8, u64> entry_a;
459 BitField<37, 1, u64> neg;
460 BitField<38, 1, u64> uses_cc;
461 } r2;
462
463 } lea;
464
465 union {
427 BitField<0, 5, FlowCondition> cond; 466 BitField<0, 5, FlowCondition> cond;
428 } flow; 467 } flow;
429 468
@@ -478,6 +517,18 @@ union Instruction {
478 } psetp; 517 } psetp;
479 518
480 union { 519 union {
520 BitField<12, 3, u64> pred12;
521 BitField<15, 1, u64> neg_pred12;
522 BitField<24, 2, PredOperation> cond;
523 BitField<29, 3, u64> pred29;
524 BitField<32, 1, u64> neg_pred29;
525 BitField<39, 3, u64> pred39;
526 BitField<42, 1, u64> neg_pred39;
527 BitField<44, 1, u64> bf;
528 BitField<45, 2, PredOperation> op;
529 } pset;
530
531 union {
481 BitField<39, 3, u64> pred39; 532 BitField<39, 3, u64> pred39;
482 BitField<42, 1, u64> neg_pred; 533 BitField<42, 1, u64> neg_pred;
483 BitField<43, 1, u64> neg_a; 534 BitField<43, 1, u64> neg_a;
@@ -726,6 +777,11 @@ public:
726 ISCADD_C, // Scale and Add 777 ISCADD_C, // Scale and Add
727 ISCADD_R, 778 ISCADD_R,
728 ISCADD_IMM, 779 ISCADD_IMM,
780 LEA_R1,
781 LEA_R2,
782 LEA_RZ,
783 LEA_IMM,
784 LEA_HI,
729 POPC_C, 785 POPC_C,
730 POPC_R, 786 POPC_R,
731 POPC_IMM, 787 POPC_IMM,
@@ -784,6 +840,7 @@ public:
784 ISET_C, 840 ISET_C,
785 ISET_IMM, 841 ISET_IMM,
786 PSETP, 842 PSETP,
843 PSET,
787 XMAD_IMM, 844 XMAD_IMM,
788 XMAD_CR, 845 XMAD_CR,
789 XMAD_RC, 846 XMAD_RC,
@@ -807,6 +864,7 @@ public:
807 IntegerSet, 864 IntegerSet,
808 IntegerSetPredicate, 865 IntegerSetPredicate,
809 PredicateSetPredicate, 866 PredicateSetPredicate,
867 PredicateSetRegister,
810 Conversion, 868 Conversion,
811 Xmad, 869 Xmad,
812 Unknown, 870 Unknown,
@@ -958,6 +1016,11 @@ private:
958 INST("0100110010100---", Id::SEL_C, Type::ArithmeticInteger, "SEL_C"), 1016 INST("0100110010100---", Id::SEL_C, Type::ArithmeticInteger, "SEL_C"),
959 INST("0101110010100---", Id::SEL_R, Type::ArithmeticInteger, "SEL_R"), 1017 INST("0101110010100---", Id::SEL_R, Type::ArithmeticInteger, "SEL_R"),
960 INST("0011100-10100---", Id::SEL_IMM, Type::ArithmeticInteger, "SEL_IMM"), 1018 INST("0011100-10100---", Id::SEL_IMM, Type::ArithmeticInteger, "SEL_IMM"),
1019 INST("0101101111011---", Id::LEA_R2, Type::ArithmeticInteger, "LEA_R2"),
1020 INST("0101101111010---", Id::LEA_R1, Type::ArithmeticInteger, "LEA_R1"),
1021 INST("001101101101----", Id::LEA_IMM, Type::ArithmeticInteger, "LEA_IMM"),
1022 INST("010010111101----", Id::LEA_RZ, Type::ArithmeticInteger, "LEA_RZ"),
1023 INST("00011000--------", Id::LEA_HI, Type::ArithmeticInteger, "LEA_HI"),
961 INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), 1024 INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"),
962 INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), 1025 INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"),
963 INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), 1026 INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"),
@@ -1012,6 +1075,7 @@ private:
1012 INST("010110110101----", Id::ISET_R, Type::IntegerSet, "ISET_R"), 1075 INST("010110110101----", Id::ISET_R, Type::IntegerSet, "ISET_R"),
1013 INST("010010110101----", Id::ISET_C, Type::IntegerSet, "ISET_C"), 1076 INST("010010110101----", Id::ISET_C, Type::IntegerSet, "ISET_C"),
1014 INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"), 1077 INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"),
1078 INST("0101000010001---", Id::PSET, Type::PredicateSetRegister, "PSET"),
1015 INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"), 1079 INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"),
1016 INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"), 1080 INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"),
1017 INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"), 1081 INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"),
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);