summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/engines/shader_bytecode.h16
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp39
2 files changed, 53 insertions, 2 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index d748026b8..ec8dbd370 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -330,6 +330,15 @@ union Instruction {
330 } fset; 330 } fset;
331 331
332 union { 332 union {
333 BitField<39, 3, u64> pred39;
334 BitField<42, 1, u64> neg_pred;
335 BitField<44, 1, u64> bf;
336 BitField<45, 2, PredOperation> op;
337 BitField<48, 1, u64> is_signed;
338 BitField<49, 3, PredCondition> cond;
339 } iset;
340
341 union {
333 BitField<10, 2, Register::Size> size; 342 BitField<10, 2, Register::Size> size;
334 BitField<12, 1, u64> is_output_signed; 343 BitField<12, 1, u64> is_output_signed;
335 BitField<13, 1, u64> is_input_signed; 344 BitField<13, 1, u64> is_input_signed;
@@ -487,6 +496,9 @@ public:
487 ISETP_C, 496 ISETP_C,
488 ISETP_IMM, 497 ISETP_IMM,
489 ISETP_R, 498 ISETP_R,
499 ISET_R,
500 ISET_C,
501 ISET_IMM,
490 PSETP, 502 PSETP,
491 XMAD_IMM, 503 XMAD_IMM,
492 XMAD_CR, 504 XMAD_CR,
@@ -506,6 +518,7 @@ public:
506 Memory, 518 Memory,
507 FloatSet, 519 FloatSet,
508 FloatSetPredicate, 520 FloatSetPredicate,
521 IntegerSet,
509 IntegerSetPredicate, 522 IntegerSetPredicate,
510 PredicateSetPredicate, 523 PredicateSetPredicate,
511 Conversion, 524 Conversion,
@@ -677,6 +690,9 @@ private:
677 INST("010010110110----", Id::ISETP_C, Type::IntegerSetPredicate, "ISETP_C"), 690 INST("010010110110----", Id::ISETP_C, Type::IntegerSetPredicate, "ISETP_C"),
678 INST("010110110110----", Id::ISETP_R, Type::IntegerSetPredicate, "ISETP_R"), 691 INST("010110110110----", Id::ISETP_R, Type::IntegerSetPredicate, "ISETP_R"),
679 INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerSetPredicate, "ISETP_IMM"), 692 INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerSetPredicate, "ISETP_IMM"),
693 INST("010110110101----", Id::ISET_R, Type::IntegerSet, "ISET_R"),
694 INST("010010110101----", Id::ISET_C, Type::IntegerSet, "ISET_C"),
695 INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"),
680 INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"), 696 INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"),
681 INST("0011011-00------", Id::XMAD_IMM, Type::Arithmetic, "XMAD_IMM"), 697 INST("0011011-00------", Id::XMAD_IMM, Type::Arithmetic, "XMAD_IMM"),
682 INST("0100111---------", Id::XMAD_CR, Type::Arithmetic, "XMAD_CR"), 698 INST("0100111---------", Id::XMAD_CR, Type::Arithmetic, "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 37fbb94da..8521be4a1 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1423,8 +1423,8 @@ private:
1423 op_b = "abs(" + op_b + ')'; 1423 op_b = "abs(" + op_b + ')';
1424 } 1424 }
1425 1425
1426 // The fset instruction sets a register to 1.0 if the condition is true, and to 0 1426 // The fset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the
1427 // otherwise. 1427 // condition is true, and to 0 otherwise.
1428 std::string second_pred = 1428 std::string second_pred =
1429 GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0); 1429 GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0);
1430 1430
@@ -1442,6 +1442,41 @@ private:
1442 } 1442 }
1443 break; 1443 break;
1444 } 1444 }
1445 case OpCode::Type::IntegerSet: {
1446 std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.iset.is_signed);
1447
1448 std::string op_b;
1449
1450 if (instr.is_b_imm) {
1451 op_b = std::to_string(instr.alu.GetSignedImm20_20());
1452 } else {
1453 if (instr.is_b_gpr) {
1454 op_b = regs.GetRegisterAsInteger(instr.gpr20, 0, instr.iset.is_signed);
1455 } else {
1456 op_b = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
1457 GLSLRegister::Type::Integer);
1458 }
1459 }
1460
1461 // The iset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the
1462 // condition is true, and to 0 otherwise.
1463 std::string second_pred =
1464 GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0);
1465
1466 std::string comparator = GetPredicateComparison(instr.iset.cond);
1467 std::string combiner = GetPredicateCombiner(instr.iset.op);
1468
1469 std::string predicate = "(((" + op_a + ") " + comparator + " (" + op_b + ")) " +
1470 combiner + " (" + second_pred + "))";
1471
1472 if (instr.iset.bf) {
1473 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1);
1474 } else {
1475 regs.SetRegisterToInteger(instr.gpr0, false, 0, predicate + " ? 0xFFFFFFFF : 0", 1,
1476 1);
1477 }
1478 break;
1479 }
1445 default: { 1480 default: {
1446 switch (opcode->GetId()) { 1481 switch (opcode->GetId()) {
1447 case OpCode::Id::EXIT: { 1482 case OpCode::Id::EXIT: {