diff options
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 43 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 55 |
2 files changed, 89 insertions, 9 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 5a006aee5..f4d11fa5d 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -214,6 +214,20 @@ union Instruction { | |||
| 214 | BitField<56, 1, u64> neg_b; | 214 | BitField<56, 1, u64> neg_b; |
| 215 | } fsetp; | 215 | } fsetp; |
| 216 | 216 | ||
| 217 | union { | ||
| 218 | BitField<39, 3, u64> pred39; | ||
| 219 | BitField<42, 1, u64> neg_pred; | ||
| 220 | BitField<43, 1, u64> neg_a; | ||
| 221 | BitField<44, 1, u64> abs_b; | ||
| 222 | BitField<45, 2, PredOperation> op; | ||
| 223 | BitField<48, 4, PredCondition> cond; | ||
| 224 | BitField<53, 1, u64> neg_b; | ||
| 225 | BitField<54, 1, u64> abs_a; | ||
| 226 | BitField<52, 1, u64> bf; | ||
| 227 | BitField<55, 1, u64> ftz; | ||
| 228 | BitField<56, 1, u64> neg_imm; | ||
| 229 | } fset; | ||
| 230 | |||
| 217 | BitField<61, 1, u64> is_b_imm; | 231 | BitField<61, 1, u64> is_b_imm; |
| 218 | BitField<60, 1, u64> is_b_gpr; | 232 | BitField<60, 1, u64> is_b_gpr; |
| 219 | BitField<59, 1, u64> is_c_gpr; | 233 | BitField<59, 1, u64> is_c_gpr; |
| @@ -261,6 +275,9 @@ public: | |||
| 261 | I2F_C, | 275 | I2F_C, |
| 262 | I2F_R, | 276 | I2F_R, |
| 263 | I2F_IMM, | 277 | I2F_IMM, |
| 278 | I2I_C, | ||
| 279 | I2I_R, | ||
| 280 | I2I_IMM, | ||
| 264 | LOP32I, | 281 | LOP32I, |
| 265 | MOV_C, | 282 | MOV_C, |
| 266 | MOV_R, | 283 | MOV_R, |
| @@ -272,6 +289,9 @@ public: | |||
| 272 | FSETP_C, // Set Predicate | 289 | FSETP_C, // Set Predicate |
| 273 | FSETP_R, | 290 | FSETP_R, |
| 274 | FSETP_IMM, | 291 | FSETP_IMM, |
| 292 | FSET_C, | ||
| 293 | FSET_R, | ||
| 294 | FSET_IMM, | ||
| 275 | ISETP_C, | 295 | ISETP_C, |
| 276 | ISETP_IMM, | 296 | ISETP_IMM, |
| 277 | ISETP_R, | 297 | ISETP_R, |
| @@ -283,8 +303,9 @@ public: | |||
| 283 | Ffma, | 303 | Ffma, |
| 284 | Flow, | 304 | Flow, |
| 285 | Memory, | 305 | Memory, |
| 286 | FloatPredicate, | 306 | FloatSet, |
| 287 | IntegerPredicate, | 307 | FloatSetPredicate, |
| 308 | IntegerSetPredicate, | ||
| 288 | Unknown, | 309 | Unknown, |
| 289 | }; | 310 | }; |
| 290 | 311 | ||
| @@ -409,6 +430,9 @@ private: | |||
| 409 | INST("0100110010111---", Id::I2F_C, Type::Arithmetic, "I2F_C"), | 430 | INST("0100110010111---", Id::I2F_C, Type::Arithmetic, "I2F_C"), |
| 410 | INST("0101110010111---", Id::I2F_R, Type::Arithmetic, "I2F_R"), | 431 | INST("0101110010111---", Id::I2F_R, Type::Arithmetic, "I2F_R"), |
| 411 | INST("0011100-10111---", Id::I2F_IMM, Type::Arithmetic, "I2F_IMM"), | 432 | INST("0011100-10111---", Id::I2F_IMM, Type::Arithmetic, "I2F_IMM"), |
| 433 | INST("0100110011100---", Id::I2I_C, Type::Arithmetic, "I2I_C"), | ||
| 434 | INST("0101110011100---", Id::I2I_R, Type::Arithmetic, "I2I_R"), | ||
| 435 | INST("01110001-1000---", Id::I2I_IMM, Type::Arithmetic, "I2I_IMM"), | ||
| 412 | INST("000001----------", Id::LOP32I, Type::Arithmetic, "LOP32I"), | 436 | INST("000001----------", Id::LOP32I, Type::Arithmetic, "LOP32I"), |
| 413 | INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"), | 437 | INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"), |
| 414 | INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"), | 438 | INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"), |
| @@ -417,12 +441,15 @@ private: | |||
| 417 | INST("0100110000101---", Id::SHR_C, Type::Arithmetic, "SHR_C"), | 441 | INST("0100110000101---", Id::SHR_C, Type::Arithmetic, "SHR_C"), |
| 418 | INST("0101110000101---", Id::SHR_R, Type::Arithmetic, "SHR_R"), | 442 | INST("0101110000101---", Id::SHR_R, Type::Arithmetic, "SHR_R"), |
| 419 | INST("0011100-00101---", Id::SHR_IMM, Type::Arithmetic, "SHR_IMM"), | 443 | INST("0011100-00101---", Id::SHR_IMM, Type::Arithmetic, "SHR_IMM"), |
| 420 | INST("010010111011----", Id::FSETP_C, Type::FloatPredicate, "FSETP_C"), | 444 | INST("01011000--------", Id::FSET_R, Type::FloatSet, "FSET_R"), |
| 421 | INST("010110111011----", Id::FSETP_R, Type::FloatPredicate, "FSETP_R"), | 445 | INST("0100100---------", Id::FSET_C, Type::FloatSet, "FSET_C"), |
| 422 | INST("0011011-1011----", Id::FSETP_IMM, Type::FloatPredicate, "FSETP_IMM"), | 446 | INST("0011000---------", Id::FSET_IMM, Type::FloatSet, "FSET_IMM"), |
| 423 | INST("010010110110----", Id::ISETP_C, Type::IntegerPredicate, "ISETP_C"), | 447 | INST("010010111011----", Id::FSETP_C, Type::FloatSetPredicate, "FSETP_C"), |
| 424 | INST("010110110110----", Id::ISETP_R, Type::IntegerPredicate, "ISETP_R"), | 448 | INST("010110111011----", Id::FSETP_R, Type::FloatSetPredicate, "FSETP_R"), |
| 425 | INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerPredicate, "ISETP_IMM"), | 449 | INST("0011011-1011----", Id::FSETP_IMM, Type::FloatSetPredicate, "FSETP_IMM"), |
| 450 | INST("010010110110----", Id::ISETP_C, Type::IntegerSetPredicate, "ISETP_C"), | ||
| 451 | INST("010110110110----", Id::ISETP_R, Type::IntegerSetPredicate, "ISETP_R"), | ||
| 452 | INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerSetPredicate, "ISETP_IMM"), | ||
| 426 | }; | 453 | }; |
| 427 | #undef INST | 454 | #undef INST |
| 428 | std::stable_sort(table.begin(), table.end(), [](const auto& a, const auto& b) { | 455 | std::stable_sort(table.begin(), table.end(), [](const auto& a, const auto& b) { |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 086424395..3dffb205d 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -519,7 +519,7 @@ private: | |||
| 519 | } | 519 | } |
| 520 | break; | 520 | break; |
| 521 | } | 521 | } |
| 522 | case OpCode::Type::FloatPredicate: { | 522 | case OpCode::Type::FloatSetPredicate: { |
| 523 | std::string op_a = instr.fsetp.neg_a ? "-" : ""; | 523 | std::string op_a = instr.fsetp.neg_a ? "-" : ""; |
| 524 | op_a += GetRegister(instr.gpr8); | 524 | op_a += GetRegister(instr.gpr8); |
| 525 | 525 | ||
| @@ -570,6 +570,59 @@ private: | |||
| 570 | } | 570 | } |
| 571 | break; | 571 | break; |
| 572 | } | 572 | } |
| 573 | case OpCode::Type::FloatSet: { | ||
| 574 | std::string dest = GetRegister(instr.gpr0); | ||
| 575 | std::string op_a = instr.fset.neg_a ? "-" : ""; | ||
| 576 | op_a += GetRegister(instr.gpr8); | ||
| 577 | |||
| 578 | if (instr.fset.abs_a) { | ||
| 579 | op_a = "abs(" + op_a + ')'; | ||
| 580 | } | ||
| 581 | |||
| 582 | std::string op_b = instr.fset.neg_b ? "-" : ""; | ||
| 583 | |||
| 584 | if (instr.is_b_imm) { | ||
| 585 | std::string imm = GetImmediate19(instr); | ||
| 586 | if (instr.fset.neg_imm) | ||
| 587 | op_b += "(-" + imm + ')'; | ||
| 588 | else | ||
| 589 | op_b += imm; | ||
| 590 | } else { | ||
| 591 | if (instr.is_b_gpr) { | ||
| 592 | op_b += GetRegister(instr.gpr20); | ||
| 593 | } else { | ||
| 594 | op_b += GetUniform(instr.uniform); | ||
| 595 | } | ||
| 596 | } | ||
| 597 | |||
| 598 | if (instr.fset.abs_b) { | ||
| 599 | op_b = "abs(" + op_b + ")"; | ||
| 600 | } | ||
| 601 | |||
| 602 | using Tegra::Shader::Pred; | ||
| 603 | ASSERT_MSG(instr.fset.pred39 == static_cast<u64>(Pred::UnusedIndex), | ||
| 604 | "Compound predicates are not implemented"); | ||
| 605 | |||
| 606 | // The fset instruction sets a register to 1.0 if the condition is true, and to 0 | ||
| 607 | // otherwise. | ||
| 608 | using Tegra::Shader::PredCondition; | ||
| 609 | switch (instr.fset.cond) { | ||
| 610 | case PredCondition::LessThan: | ||
| 611 | SetDest(0, dest, "((" + op_a + ") < (" + op_b + ")) ? 1.0 : 0", 1, 1); | ||
| 612 | break; | ||
| 613 | case PredCondition::Equal: | ||
| 614 | SetDest(0, dest, "((" + op_a + ") == (" + op_b + ")) ? 1.0 : 0", 1, 1); | ||
| 615 | break; | ||
| 616 | case PredCondition::GreaterThan: | ||
| 617 | SetDest(0, dest, "((" + op_a + ") > (" + op_b + ")) ? 1.0 : 0", 1, 1); | ||
| 618 | break; | ||
| 619 | default: | ||
| 620 | NGLOG_CRITICAL(HW_GPU, "Unhandled predicate condition: {} (a: {}, b: {})", | ||
| 621 | static_cast<unsigned>(instr.fset.cond.Value()), op_a, op_b); | ||
| 622 | UNREACHABLE(); | ||
| 623 | } | ||
| 624 | break; | ||
| 625 | } | ||
| 573 | default: { | 626 | default: { |
| 574 | switch (opcode->GetId()) { | 627 | switch (opcode->GetId()) { |
| 575 | case OpCode::Id::EXIT: { | 628 | case OpCode::Id::EXIT: { |