summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h14
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp28
2 files changed, 42 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 639bedb80..52d03aee8 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -368,6 +368,11 @@ enum class HalfPrecision : u64 {
368 FMZ = 2, 368 FMZ = 2,
369}; 369};
370 370
371enum class R2pMode : u64 {
372 Pr = 0,
373 Cc = 1,
374};
375
371enum class IpaInterpMode : u64 { 376enum class IpaInterpMode : u64 {
372 Linear = 0, 377 Linear = 0,
373 Perspective = 1, 378 Perspective = 1,
@@ -857,6 +862,12 @@ union Instruction {
857 } hsetp2; 862 } hsetp2;
858 863
859 union { 864 union {
865 BitField<40, 1, R2pMode> mode;
866 BitField<41, 2, u64> byte;
867 BitField<20, 7, u64> immediate_mask;
868 } r2p;
869
870 union {
860 BitField<39, 3, u64> pred39; 871 BitField<39, 3, u64> pred39;
861 BitField<42, 1, u64> neg_pred; 872 BitField<42, 1, u64> neg_pred;
862 BitField<43, 1, u64> neg_a; 873 BitField<43, 1, u64> neg_a;
@@ -1383,6 +1394,7 @@ public:
1383 PSETP, 1394 PSETP,
1384 PSET, 1395 PSET,
1385 CSETP, 1396 CSETP,
1397 R2P_IMM,
1386 XMAD_IMM, 1398 XMAD_IMM,
1387 XMAD_CR, 1399 XMAD_CR,
1388 XMAD_RC, 1400 XMAD_RC,
@@ -1412,6 +1424,7 @@ public:
1412 HalfSetPredicate, 1424 HalfSetPredicate,
1413 PredicateSetPredicate, 1425 PredicateSetPredicate,
1414 PredicateSetRegister, 1426 PredicateSetRegister,
1427 RegisterSetPredicate,
1415 Conversion, 1428 Conversion,
1416 Xmad, 1429 Xmad,
1417 Unknown, 1430 Unknown,
@@ -1649,6 +1662,7 @@ private:
1649 INST("0101000010001---", Id::PSET, Type::PredicateSetRegister, "PSET"), 1662 INST("0101000010001---", Id::PSET, Type::PredicateSetRegister, "PSET"),
1650 INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"), 1663 INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"),
1651 INST("010100001010----", Id::CSETP, Type::PredicateSetPredicate, "CSETP"), 1664 INST("010100001010----", Id::CSETP, Type::PredicateSetPredicate, "CSETP"),
1665 INST("0011100-11110---", Id::R2P_IMM, Type::RegisterSetPredicate, "R2P_IMM"),
1652 INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"), 1666 INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"),
1653 INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"), 1667 INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"),
1654 INST("010100010-------", Id::XMAD_RC, Type::Xmad, "XMAD_RC"), 1668 INST("010100010-------", Id::XMAD_RC, Type::Xmad, "XMAD_RC"),
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 9dbaf26d4..3a75f9d16 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -3315,6 +3315,34 @@ private:
3315 } 3315 }
3316 break; 3316 break;
3317 } 3317 }
3318 case OpCode::Type::RegisterSetPredicate: {
3319 UNIMPLEMENTED_IF(instr.r2p.mode != Tegra::Shader::R2pMode::Pr);
3320
3321 const std::string apply_mask = [&]() {
3322 switch (opcode->get().GetId()) {
3323 case OpCode::Id::R2P_IMM:
3324 return std::to_string(instr.r2p.immediate_mask);
3325 default:
3326 UNREACHABLE();
3327 }
3328 }();
3329 const std::string mask = '(' + regs.GetRegisterAsInteger(instr.gpr8, 0, false) +
3330 " >> " + std::to_string(instr.r2p.byte) + ')';
3331
3332 constexpr u64 programmable_preds = 7;
3333 for (u64 pred = 0; pred < programmable_preds; ++pred) {
3334 const auto shift = std::to_string(1 << pred);
3335
3336 shader.AddLine("if ((" + apply_mask + " & " + shift + ") != 0) {");
3337 ++shader.scope;
3338
3339 SetPredicate(pred, '(' + mask + " & " + shift + ") != 0");
3340
3341 --shader.scope;
3342 shader.AddLine('}');
3343 }
3344 break;
3345 }
3318 case OpCode::Type::FloatSet: { 3346 case OpCode::Type::FloatSet: {
3319 const std::string op_a = GetOperandAbsNeg(regs.GetRegisterAsFloat(instr.gpr8), 3347 const std::string op_a = GetOperandAbsNeg(regs.GetRegisterAsFloat(instr.gpr8),
3320 instr.fset.abs_a != 0, instr.fset.neg_a != 0); 3348 instr.fset.abs_a != 0, instr.fset.neg_a != 0);