summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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.cpp59
2 files changed, 63 insertions, 6 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index e7ef7e71f..3add56155 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -239,6 +239,16 @@ union Instruction {
239 } fsetp; 239 } fsetp;
240 240
241 union { 241 union {
242 BitField<0, 3, u64> pred0;
243 BitField<3, 3, u64> pred3;
244 BitField<39, 3, u64> pred39;
245 BitField<42, 1, u64> neg_pred;
246 BitField<45, 2, PredOperation> op;
247 BitField<48, 1, u64> is_signed;
248 BitField<49, 3, PredCondition> cond;
249 } isetp;
250
251 union {
242 BitField<39, 3, u64> pred39; 252 BitField<39, 3, u64> pred39;
243 BitField<42, 1, u64> neg_pred; 253 BitField<42, 1, u64> neg_pred;
244 BitField<43, 1, u64> neg_a; 254 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 45d120757..8c263f15f 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -219,6 +219,11 @@ public:
219 return active_type == Type::Integer; 219 return active_type == Type::Integer;
220 } 220 }
221 221
222 /// Returns the current active type of the register
223 Type GetActiveType() const {
224 return active_type;
225 }
226
222 /// Returns the index of the register 227 /// Returns the index of the register
223 size_t GetIndex() const { 228 size_t GetIndex() const {
224 return index; 229 return index;
@@ -350,22 +355,28 @@ public:
350 shader.AddLine(dest + " = " + src + ';'); 355 shader.AddLine(dest + " = " + src + ';');
351 } 356 }
352 357
353 /// Generates code representing a uniform (C buffer) register. 358 /// Generates code representing a uniform (C buffer) register, interpreted as the input type.
354 std::string GetUniform(const Uniform& uniform, const Register& dest_reg) { 359 std::string GetUniform(const Uniform& uniform, GLSLRegister::Type type) {
355 declr_const_buffers[uniform.index].MarkAsUsed(static_cast<unsigned>(uniform.index), 360 declr_const_buffers[uniform.index].MarkAsUsed(static_cast<unsigned>(uniform.index),
356 static_cast<unsigned>(uniform.offset), stage); 361 static_cast<unsigned>(uniform.offset), stage);
357 std::string value = 362 std::string value =
358 'c' + std::to_string(uniform.index) + '[' + std::to_string(uniform.offset) + ']'; 363 'c' + std::to_string(uniform.index) + '[' + std::to_string(uniform.offset) + ']';
359 364
360 if (regs[dest_reg].IsFloat()) { 365 if (type == GLSLRegister::Type::Float) {
361 return value; 366 return value;
362 } else if (regs[dest_reg].IsInteger()) { 367 } else if (type == GLSLRegister::Type::Integer) {
363 return "floatBitsToInt(" + value + ')'; 368 return "floatBitsToInt(" + value + ')';
364 } else { 369 } else {
365 UNREACHABLE(); 370 UNREACHABLE();
366 } 371 }
367 } 372 }
368 373
374 /// Generates code representing a uniform (C buffer) register, interpreted as the type of the
375 /// destination register.
376 std::string GetUniform(const Uniform& uniform, const Register& dest_reg) {
377 return GetUniform(uniform, regs[dest_reg].GetActiveType());
378 }
379
369 /// Add declarations for registers 380 /// Add declarations for registers
370 void GenerateDeclarations() { 381 void GenerateDeclarations() {
371 for (const auto& reg : regs) { 382 for (const auto& reg : regs) {
@@ -1018,7 +1029,7 @@ private:
1018 if (instr.is_b_gpr) { 1029 if (instr.is_b_gpr) {
1019 op_b += regs.GetRegisterAsFloat(instr.gpr20); 1030 op_b += regs.GetRegisterAsFloat(instr.gpr20);
1020 } else { 1031 } else {
1021 op_b += regs.GetUniform(instr.uniform, instr.gpr0); 1032 op_b += regs.GetUniform(instr.uniform, GLSLRegister::Type::Float);
1022 } 1033 }
1023 } 1034 }
1024 1035
@@ -1049,6 +1060,42 @@ private:
1049 } 1060 }
1050 break; 1061 break;
1051 } 1062 }
1063 case OpCode::Type::IntegerSetPredicate: {
1064 std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.isetp.is_signed);
1065
1066 std::string op_b{};
1067
1068 ASSERT_MSG(!instr.is_b_imm, "ISETP_IMM not implemented");
1069
1070 if (instr.is_b_gpr) {
1071 op_b += regs.GetRegisterAsInteger(instr.gpr20, 0, instr.isetp.is_signed);
1072 } else {
1073 op_b += regs.GetUniform(instr.uniform, GLSLRegister::Type::Integer);
1074 }
1075
1076 using Tegra::Shader::Pred;
1077 // We can't use the constant predicate as destination.
1078 ASSERT(instr.isetp.pred3 != static_cast<u64>(Pred::UnusedIndex));
1079
1080 std::string second_pred =
1081 GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0);
1082
1083 std::string comparator = GetPredicateComparison(instr.isetp.cond);
1084 std::string combiner = GetPredicateCombiner(instr.isetp.op);
1085
1086 std::string predicate = '(' + op_a + ") " + comparator + " (" + op_b + ')';
1087 // Set the primary predicate to the result of Predicate OP SecondPredicate
1088 SetPredicate(instr.isetp.pred3,
1089 '(' + predicate + ") " + combiner + " (" + second_pred + ')');
1090
1091 if (instr.isetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) {
1092 // Set the secondary predicate to the result of !Predicate OP SecondPredicate,
1093 // if enabled
1094 SetPredicate(instr.isetp.pred0,
1095 "!(" + predicate + ") " + combiner + " (" + second_pred + ')');
1096 }
1097 break;
1098 }
1052 case OpCode::Type::FloatSet: { 1099 case OpCode::Type::FloatSet: {
1053 std::string op_a = instr.fset.neg_a ? "-" : ""; 1100 std::string op_a = instr.fset.neg_a ? "-" : "";
1054 op_a += regs.GetRegisterAsFloat(instr.gpr8); 1101 op_a += regs.GetRegisterAsFloat(instr.gpr8);
@@ -1069,7 +1116,7 @@ private:
1069 if (instr.is_b_gpr) { 1116 if (instr.is_b_gpr) {
1070 op_b += regs.GetRegisterAsFloat(instr.gpr20); 1117 op_b += regs.GetRegisterAsFloat(instr.gpr20);
1071 } else { 1118 } else {
1072 op_b += regs.GetUniform(instr.uniform, instr.gpr0); 1119 op_b += regs.GetUniform(instr.uniform, GLSLRegister::Type::Float);
1073 } 1120 }
1074 } 1121 }
1075 1122