summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Subv2018-07-04 15:15:03 -0500
committerGravatar Subv2018-07-04 15:15:03 -0500
commit53a55bd751f6f89ac6c9d9eac9d3e9a8bd28c552 (patch)
tree8f549f2dbadb1e37c26fb7259ddc1a4ca5fdb5d4
parentMerge pull request #618 from Subv/clear_used_buffers (diff)
downloadyuzu-53a55bd751f6f89ac6c9d9eac9d3e9a8bd28c552.tar.gz
yuzu-53a55bd751f6f89ac6c9d9eac9d3e9a8bd28c552.tar.xz
yuzu-53a55bd751f6f89ac6c9d9eac9d3e9a8bd28c552.zip
GPU: Implemented the PSETP shader instruction.
It's similar to the isetp and fsetp instructions but it works on predicates instead.
-rw-r--r--src/video_core/engines/shader_bytecode.h13
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp30
2 files changed, 43 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index c1226a649..95b7d46ec 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -329,6 +329,19 @@ union Instruction {
329 } isetp; 329 } isetp;
330 330
331 union { 331 union {
332 BitField<0, 3, u64> pred0;
333 BitField<3, 3, u64> pred3;
334 BitField<12, 3, u64> pred12;
335 BitField<15, 1, u64> neg_pred12;
336 BitField<24, 2, PredOperation> cond;
337 BitField<29, 3, u64> pred29;
338 BitField<32, 1, u64> neg_pred29;
339 BitField<39, 3, u64> pred39;
340 BitField<42, 1, u64> neg_pred39;
341 BitField<45, 2, PredOperation> op;
342 } psetp;
343
344 union {
332 BitField<39, 3, u64> pred39; 345 BitField<39, 3, u64> pred39;
333 BitField<42, 1, u64> neg_pred; 346 BitField<42, 1, u64> neg_pred;
334 BitField<43, 1, u64> neg_a; 347 BitField<43, 1, u64> neg_a;
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index ec9956edb..a4b730e1c 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1477,6 +1477,36 @@ private:
1477 } 1477 }
1478 break; 1478 break;
1479 } 1479 }
1480 case OpCode::Type::PredicateSetPredicate: {
1481 std::string op_a =
1482 GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0);
1483 std::string op_b =
1484 GetPredicateCondition(instr.psetp.pred29, instr.psetp.neg_pred29 != 0);
1485
1486 using Tegra::Shader::Pred;
1487 // We can't use the constant predicate as destination.
1488 ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex));
1489
1490 std::string second_pred =
1491 GetPredicateCondition(instr.psetp.pred39, instr.psetp.neg_pred39 != 0);
1492
1493 std::string combiner = GetPredicateCombiner(instr.psetp.op);
1494
1495 std::string predicate =
1496 '(' + op_a + ") " + GetPredicateCombiner(instr.psetp.cond) + " (" + op_b + ')';
1497
1498 // Set the primary predicate to the result of Predicate OP SecondPredicate
1499 SetPredicate(instr.psetp.pred3,
1500 '(' + predicate + ") " + combiner + " (" + second_pred + ')');
1501
1502 if (instr.psetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) {
1503 // Set the secondary predicate to the result of !Predicate OP SecondPredicate,
1504 // if enabled
1505 SetPredicate(instr.psetp.pred0,
1506 "!(" + predicate + ") " + combiner + " (" + second_pred + ')');
1507 }
1508 break;
1509 }
1480 case OpCode::Type::FloatSet: { 1510 case OpCode::Type::FloatSet: {
1481 std::string op_a = instr.fset.neg_a ? "-" : ""; 1511 std::string op_a = instr.fset.neg_a ? "-" : "";
1482 op_a += regs.GetRegisterAsFloat(instr.gpr8); 1512 op_a += regs.GetRegisterAsFloat(instr.gpr8);