diff options
| author | 2018-06-04 20:47:11 -0400 | |
|---|---|---|
| committer | 2018-06-04 20:47:11 -0400 | |
| commit | f564822e781ade1fe16ecd3cf93f1ffa247ed82e (patch) | |
| tree | c51f197ddaac4a0c9df01b87aef6d5bdbb6a0e2f | |
| parent | Merge pull request #512 from Subv/fset (diff) | |
| parent | GPU: Use explicit types when retrieving the uniform values for fsetp/fset and... (diff) | |
| download | yuzu-f564822e781ade1fe16ecd3cf93f1ffa247ed82e.tar.gz yuzu-f564822e781ade1fe16ecd3cf93f1ffa247ed82e.tar.xz yuzu-f564822e781ade1fe16ecd3cf93f1ffa247ed82e.zip | |
Merge pull request #510 from Subv/isetp
GPU: Implemented the ISETP_R and ISETP_C instructions
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 59 |
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 | ||