summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSubv <subv2112@gmail.com>2018-06-04 18:12:03 +0200
committerSubv <subv2112@gmail.com>2018-06-04 18:12:03 +0200
commit7c181fd4f4940e34bf911dd8f32857b9059a974b (patch)
tree941fdbc2c7a0437233ca297e553b12e5de7c160c /src
parentMerge pull request #500 from Subv/long_queries (diff)
downloadyuzu-7c181fd4f4940e34bf911dd8f32857b9059a974b.tar
yuzu-7c181fd4f4940e34bf911dd8f32857b9059a974b.tar.gz
yuzu-7c181fd4f4940e34bf911dd8f32857b9059a974b.tar.bz2
yuzu-7c181fd4f4940e34bf911dd8f32857b9059a974b.tar.lz
yuzu-7c181fd4f4940e34bf911dd8f32857b9059a974b.tar.xz
yuzu-7c181fd4f4940e34bf911dd8f32857b9059a974b.tar.zst
yuzu-7c181fd4f4940e34bf911dd8f32857b9059a974b.zip
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h10
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp38
2 files changed, 48 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index da64430e9..83f7cc3a9 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -239,6 +239,16 @@ union Instruction {
} fsetp;
union {
+ BitField<0, 3, u64> pred0;
+ BitField<3, 3, u64> pred3;
+ BitField<39, 3, u64> pred39;
+ BitField<42, 1, u64> neg_pred;
+ BitField<45, 2, PredOperation> op;
+ BitField<48, 1, u64> is_signed;
+ BitField<49, 3, PredCondition> cond;
+ } isetp;
+
+ union {
BitField<39, 3, u64> pred39;
BitField<42, 1, u64> neg_pred;
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 bb5209a7e..b27543a65 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1017,6 +1017,44 @@ private:
}
break;
}
+ case OpCode::Type::IntegerSetPredicate: {
+ std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.isetp.is_signed);
+
+ std::string op_b{};
+
+ ASSERT_MSG(!instr.is_b_imm, "ISETP_IMM not implemented");
+
+ if (instr.is_b_gpr) {
+ op_b += regs.GetRegisterAsInteger(instr.gpr20, 0, instr.isetp.is_signed);
+ } else {
+ // TODO(Subv): This family of instructions don't store to a GPR, but GetUniform
+ // needs to know the type of the output register.
+ op_b += regs.GetUniform(instr.uniform, instr.gpr0);
+ }
+
+ using Tegra::Shader::Pred;
+ // We can't use the constant predicate as destination.
+ ASSERT(instr.isetp.pred3 != static_cast<u64>(Pred::UnusedIndex));
+
+ std::string second_pred =
+ GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0);
+
+ std::string comparator = GetPredicateComparison(instr.isetp.cond);
+ std::string combiner = GetPredicateCombiner(instr.isetp.op);
+
+ std::string predicate = '(' + op_a + ") " + comparator + " (" + op_b + ')';
+ // Set the primary predicate to the result of Predicate OP SecondPredicate
+ SetPredicate(instr.isetp.pred3,
+ '(' + predicate + ") " + combiner + " (" + second_pred + ')');
+
+ if (instr.isetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) {
+ // Set the secondary predicate to the result of !Predicate OP SecondPredicate,
+ // if enabled
+ SetPredicate(instr.isetp.pred0,
+ "!(" + predicate + ") " + combiner + " (" + second_pred + ')');
+ }
+ break;
+ }
case OpCode::Type::FloatSet: {
std::string op_a = instr.fset.neg_a ? "-" : "";
op_a += regs.GetRegisterAsFloat(instr.gpr8);