diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 412 |
1 files changed, 411 insertions, 1 deletions
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 5f174bb7f..e4c3e3d9c 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -30,6 +30,7 @@ using namespace VideoCommon::Shader; | |||
| 30 | 30 | ||
| 31 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; | 31 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; |
| 32 | using ShaderStage = Tegra::Engines::Maxwell3D::Regs::ShaderStage; | 32 | using ShaderStage = Tegra::Engines::Maxwell3D::Regs::ShaderStage; |
| 33 | using Operation = const OperationNode&; | ||
| 33 | 34 | ||
| 34 | // TODO(Rodrigo): Use rasterizer's value | 35 | // TODO(Rodrigo): Use rasterizer's value |
| 35 | constexpr u32 MAX_CONSTBUFFER_ELEMENTS = 0x1000; | 36 | constexpr u32 MAX_CONSTBUFFER_ELEMENTS = 0x1000; |
| @@ -73,6 +74,19 @@ constexpr u32 GetGenericAttributeLocation(Attribute::Index attribute) { | |||
| 73 | return static_cast<u32>(attribute) - static_cast<u32>(Attribute::Index::Attribute_0); | 74 | return static_cast<u32>(attribute) - static_cast<u32>(Attribute::Index::Attribute_0); |
| 74 | } | 75 | } |
| 75 | 76 | ||
| 77 | /// Returns true if an object has to be treated as precise | ||
| 78 | bool IsPrecise(Operation operand) { | ||
| 79 | const auto& meta = operand.GetMeta(); | ||
| 80 | |||
| 81 | if (std::holds_alternative<MetaArithmetic>(meta)) { | ||
| 82 | return std::get<MetaArithmetic>(meta).precise; | ||
| 83 | } | ||
| 84 | if (std::holds_alternative<MetaHalfArithmetic>(meta)) { | ||
| 85 | return std::get<MetaHalfArithmetic>(meta).precise; | ||
| 86 | } | ||
| 87 | return false; | ||
| 88 | } | ||
| 89 | |||
| 76 | } // namespace | 90 | } // namespace |
| 77 | 91 | ||
| 78 | class SPIRVDecompiler : public Sirit::Module { | 92 | class SPIRVDecompiler : public Sirit::Module { |
| @@ -194,6 +208,10 @@ public: | |||
| 194 | } | 208 | } |
| 195 | 209 | ||
| 196 | private: | 210 | private: |
| 211 | using OperationDecompilerFn = Id (SPIRVDecompiler::*)(Operation); | ||
| 212 | using OperationDecompilersArray = | ||
| 213 | std::array<OperationDecompilerFn, static_cast<std::size_t>(OperationCode::Amount)>; | ||
| 214 | |||
| 197 | static constexpr auto INTERNAL_FLAGS_COUNT = static_cast<std::size_t>(InternalFlag::Amount); | 215 | static constexpr auto INTERNAL_FLAGS_COUNT = static_cast<std::size_t>(InternalFlag::Amount); |
| 198 | static constexpr u32 CBUF_STRIDE = 16; | 216 | static constexpr u32 CBUF_STRIDE = 16; |
| 199 | 217 | ||
| @@ -468,7 +486,12 @@ private: | |||
| 468 | 486 | ||
| 469 | Id Visit(Node node) { | 487 | Id Visit(Node node) { |
| 470 | if (const auto operation = std::get_if<OperationNode>(node)) { | 488 | if (const auto operation = std::get_if<OperationNode>(node)) { |
| 471 | UNIMPLEMENTED(); | 489 | const auto operation_index = static_cast<std::size_t>(operation->GetCode()); |
| 490 | const auto decompiler = operation_decompilers[operation_index]; | ||
| 491 | if (decompiler == nullptr) { | ||
| 492 | UNREACHABLE_MSG("Operation decompiler {} not defined", operation_index); | ||
| 493 | } | ||
| 494 | return (this->*decompiler)(*operation); | ||
| 472 | 495 | ||
| 473 | } else if (const auto gpr = std::get_if<GprNode>(node)) { | 496 | } else if (const auto gpr = std::get_if<GprNode>(node)) { |
| 474 | UNIMPLEMENTED(); | 497 | UNIMPLEMENTED(); |
| @@ -500,6 +523,184 @@ private: | |||
| 500 | return {}; | 523 | return {}; |
| 501 | } | 524 | } |
| 502 | 525 | ||
| 526 | template <Id (Module::*func)(Id, Id), Type result_type, Type type_a = result_type> | ||
| 527 | Id Unary(Operation operation) { | ||
| 528 | const Id type_def = GetTypeDefinition(result_type); | ||
| 529 | const Id op_a = VisitOperand<type_a>(operation, 0); | ||
| 530 | |||
| 531 | const Id value = BitcastFrom<result_type>(Emit((this->*func)(type_def, op_a))); | ||
| 532 | if (IsPrecise(operation)) { | ||
| 533 | Decorate(value, spv::Decoration::NoContraction); | ||
| 534 | } | ||
| 535 | return value; | ||
| 536 | } | ||
| 537 | |||
| 538 | template <Id (Module::*func)(Id, Id, Id), Type result_type, Type type_a = result_type, | ||
| 539 | Type type_b = type_a> | ||
| 540 | Id Binary(Operation operation) { | ||
| 541 | const Id type_def = GetTypeDefinition(result_type); | ||
| 542 | const Id op_a = VisitOperand<type_a>(operation, 0); | ||
| 543 | const Id op_b = VisitOperand<type_b>(operation, 1); | ||
| 544 | |||
| 545 | const Id value = BitcastFrom<result_type>(Emit((this->*func)(type_def, op_a, op_b))); | ||
| 546 | if (IsPrecise(operation)) { | ||
| 547 | Decorate(value, spv::Decoration::NoContraction); | ||
| 548 | } | ||
| 549 | return value; | ||
| 550 | } | ||
| 551 | |||
| 552 | template <Id (Module::*func)(Id, Id, Id, Id), Type result_type, Type type_a = result_type, | ||
| 553 | Type type_b = type_a, Type type_c = type_b> | ||
| 554 | Id Ternary(Operation operation) { | ||
| 555 | const Id type_def = GetTypeDefinition(result_type); | ||
| 556 | const Id op_a = VisitOperand<type_a>(operation, 0); | ||
| 557 | const Id op_b = VisitOperand<type_b>(operation, 1); | ||
| 558 | const Id op_c = VisitOperand<type_c>(operation, 2); | ||
| 559 | |||
| 560 | const Id value = BitcastFrom<result_type>(Emit((this->*func)(type_def, op_a, op_b, op_c))); | ||
| 561 | if (IsPrecise(operation)) { | ||
| 562 | Decorate(value, spv::Decoration::NoContraction); | ||
| 563 | } | ||
| 564 | return value; | ||
| 565 | } | ||
| 566 | |||
| 567 | template <Id (Module::*func)(Id, Id, Id, Id, Id), Type result_type, Type type_a = result_type, | ||
| 568 | Type type_b = type_a, Type type_c = type_b, Type type_d = type_c> | ||
| 569 | Id Quaternary(Operation operation) { | ||
| 570 | const Id type_def = GetTypeDefinition(result_type); | ||
| 571 | const Id op_a = VisitOperand<type_a>(operation, 0); | ||
| 572 | const Id op_b = VisitOperand<type_b>(operation, 1); | ||
| 573 | const Id op_c = VisitOperand<type_c>(operation, 2); | ||
| 574 | const Id op_d = VisitOperand<type_d>(operation, 3); | ||
| 575 | |||
| 576 | const Id value = | ||
| 577 | BitcastFrom<result_type>(Emit((this->*func)(type_def, op_a, op_b, op_c, op_d))); | ||
| 578 | if (IsPrecise(operation)) { | ||
| 579 | Decorate(value, spv::Decoration::NoContraction); | ||
| 580 | } | ||
| 581 | return value; | ||
| 582 | } | ||
| 583 | |||
| 584 | Id Assign(Operation operation) { | ||
| 585 | UNIMPLEMENTED(); | ||
| 586 | return {}; | ||
| 587 | } | ||
| 588 | |||
| 589 | Id HNegate(Operation operation) { | ||
| 590 | UNIMPLEMENTED(); | ||
| 591 | return {}; | ||
| 592 | } | ||
| 593 | |||
| 594 | Id HMergeF32(Operation operation) { | ||
| 595 | UNIMPLEMENTED(); | ||
| 596 | return {}; | ||
| 597 | } | ||
| 598 | |||
| 599 | Id HMergeH0(Operation operation) { | ||
| 600 | UNIMPLEMENTED(); | ||
| 601 | return {}; | ||
| 602 | } | ||
| 603 | |||
| 604 | Id HMergeH1(Operation operation) { | ||
| 605 | UNIMPLEMENTED(); | ||
| 606 | return {}; | ||
| 607 | } | ||
| 608 | |||
| 609 | Id HPack2(Operation operation) { | ||
| 610 | UNIMPLEMENTED(); | ||
| 611 | return {}; | ||
| 612 | } | ||
| 613 | |||
| 614 | Id LogicalAssign(Operation operation) { | ||
| 615 | UNIMPLEMENTED(); | ||
| 616 | return {}; | ||
| 617 | } | ||
| 618 | |||
| 619 | Id LogicalPick2(Operation operation) { | ||
| 620 | UNIMPLEMENTED(); | ||
| 621 | return {}; | ||
| 622 | } | ||
| 623 | |||
| 624 | Id LogicalAll2(Operation operation) { | ||
| 625 | UNIMPLEMENTED(); | ||
| 626 | return {}; | ||
| 627 | } | ||
| 628 | |||
| 629 | Id LogicalAny2(Operation operation) { | ||
| 630 | UNIMPLEMENTED(); | ||
| 631 | return {}; | ||
| 632 | } | ||
| 633 | |||
| 634 | Id Texture(Operation operation) { | ||
| 635 | UNIMPLEMENTED(); | ||
| 636 | return {}; | ||
| 637 | } | ||
| 638 | |||
| 639 | Id TextureLod(Operation operation) { | ||
| 640 | UNIMPLEMENTED(); | ||
| 641 | return {}; | ||
| 642 | } | ||
| 643 | |||
| 644 | Id TextureGather(Operation operation) { | ||
| 645 | UNIMPLEMENTED(); | ||
| 646 | return {}; | ||
| 647 | } | ||
| 648 | |||
| 649 | Id TextureQueryDimensions(Operation operation) { | ||
| 650 | UNIMPLEMENTED(); | ||
| 651 | return {}; | ||
| 652 | } | ||
| 653 | |||
| 654 | Id TextureQueryLod(Operation operation) { | ||
| 655 | UNIMPLEMENTED(); | ||
| 656 | return {}; | ||
| 657 | } | ||
| 658 | |||
| 659 | Id TexelFetch(Operation operation) { | ||
| 660 | UNIMPLEMENTED(); | ||
| 661 | return {}; | ||
| 662 | } | ||
| 663 | |||
| 664 | Id Branch(Operation operation) { | ||
| 665 | UNIMPLEMENTED(); | ||
| 666 | return {}; | ||
| 667 | } | ||
| 668 | |||
| 669 | Id PushFlowStack(Operation operation) { | ||
| 670 | UNIMPLEMENTED(); | ||
| 671 | return {}; | ||
| 672 | } | ||
| 673 | |||
| 674 | Id PopFlowStack(Operation operation) { | ||
| 675 | UNIMPLEMENTED(); | ||
| 676 | return {}; | ||
| 677 | } | ||
| 678 | |||
| 679 | Id Exit(Operation operation) { | ||
| 680 | UNIMPLEMENTED(); | ||
| 681 | return {}; | ||
| 682 | } | ||
| 683 | |||
| 684 | Id Discard(Operation operation) { | ||
| 685 | UNIMPLEMENTED(); | ||
| 686 | return {}; | ||
| 687 | } | ||
| 688 | |||
| 689 | Id EmitVertex(Operation operation) { | ||
| 690 | UNIMPLEMENTED(); | ||
| 691 | return {}; | ||
| 692 | } | ||
| 693 | |||
| 694 | Id EndPrimitive(Operation operation) { | ||
| 695 | UNIMPLEMENTED(); | ||
| 696 | return {}; | ||
| 697 | } | ||
| 698 | |||
| 699 | Id YNegate(Operation operation) { | ||
| 700 | UNIMPLEMENTED(); | ||
| 701 | return {}; | ||
| 702 | } | ||
| 703 | |||
| 503 | Id DeclareBuiltIn(spv::BuiltIn builtin, spv::StorageClass storage, Id type, | 704 | Id DeclareBuiltIn(spv::BuiltIn builtin, spv::StorageClass storage, Id type, |
| 504 | const std::string& name) { | 705 | const std::string& name) { |
| 505 | const Id id = OpVariable(type, storage); | 706 | const Id id = OpVariable(type, storage); |
| @@ -518,6 +719,215 @@ private: | |||
| 518 | return false; | 719 | return false; |
| 519 | } | 720 | } |
| 520 | 721 | ||
| 722 | template <Type type> | ||
| 723 | Id VisitOperand(Operation operation, std::size_t operand_index) { | ||
| 724 | const Id value = Visit(operation[operand_index]); | ||
| 725 | |||
| 726 | switch (type) { | ||
| 727 | case Type::Bool: | ||
| 728 | case Type::Bool2: | ||
| 729 | case Type::Float: | ||
| 730 | return value; | ||
| 731 | case Type::Int: | ||
| 732 | return Emit(OpBitcast(t_int, value)); | ||
| 733 | case Type::Uint: | ||
| 734 | return Emit(OpBitcast(t_uint, value)); | ||
| 735 | case Type::HalfFloat: | ||
| 736 | UNIMPLEMENTED(); | ||
| 737 | } | ||
| 738 | UNREACHABLE(); | ||
| 739 | return value; | ||
| 740 | } | ||
| 741 | |||
| 742 | template <Type type> | ||
| 743 | Id BitcastFrom(Id value) { | ||
| 744 | switch (type) { | ||
| 745 | case Type::Bool: | ||
| 746 | case Type::Bool2: | ||
| 747 | case Type::Float: | ||
| 748 | return value; | ||
| 749 | case Type::Int: | ||
| 750 | case Type::Uint: | ||
| 751 | return Emit(OpBitcast(t_float, value)); | ||
| 752 | case Type::HalfFloat: | ||
| 753 | UNIMPLEMENTED(); | ||
| 754 | } | ||
| 755 | UNREACHABLE(); | ||
| 756 | return value; | ||
| 757 | } | ||
| 758 | |||
| 759 | template <Type type> | ||
| 760 | Id BitcastTo(Id value) { | ||
| 761 | switch (type) { | ||
| 762 | case Type::Bool: | ||
| 763 | case Type::Bool2: | ||
| 764 | UNREACHABLE(); | ||
| 765 | case Type::Float: | ||
| 766 | return Emit(OpBitcast(t_float, value)); | ||
| 767 | case Type::Int: | ||
| 768 | return Emit(OpBitcast(t_int, value)); | ||
| 769 | case Type::Uint: | ||
| 770 | return Emit(OpBitcast(t_uint, value)); | ||
| 771 | case Type::HalfFloat: | ||
| 772 | UNIMPLEMENTED(); | ||
| 773 | } | ||
| 774 | UNREACHABLE(); | ||
| 775 | return value; | ||
| 776 | } | ||
| 777 | |||
| 778 | Id GetTypeDefinition(Type type) { | ||
| 779 | switch (type) { | ||
| 780 | case Type::Bool: | ||
| 781 | return t_bool; | ||
| 782 | case Type::Bool2: | ||
| 783 | return t_bool2; | ||
| 784 | case Type::Float: | ||
| 785 | return t_float; | ||
| 786 | case Type::Int: | ||
| 787 | return t_int; | ||
| 788 | case Type::Uint: | ||
| 789 | return t_uint; | ||
| 790 | case Type::HalfFloat: | ||
| 791 | UNIMPLEMENTED(); | ||
| 792 | } | ||
| 793 | UNREACHABLE(); | ||
| 794 | return {}; | ||
| 795 | } | ||
| 796 | |||
| 797 | static constexpr OperationDecompilersArray operation_decompilers = { | ||
| 798 | &SPIRVDecompiler::Assign, | ||
| 799 | |||
| 800 | &SPIRVDecompiler::Ternary<&Module::OpSelect, Type::Float, Type::Bool, Type::Float, | ||
| 801 | Type::Float>, | ||
| 802 | |||
| 803 | &SPIRVDecompiler::Binary<&Module::OpFAdd, Type::Float>, | ||
| 804 | &SPIRVDecompiler::Binary<&Module::OpFMul, Type::Float>, | ||
| 805 | &SPIRVDecompiler::Binary<&Module::OpFDiv, Type::Float>, | ||
| 806 | &SPIRVDecompiler::Ternary<&Module::OpFma, Type::Float>, | ||
| 807 | &SPIRVDecompiler::Unary<&Module::OpFNegate, Type::Float>, | ||
| 808 | &SPIRVDecompiler::Unary<&Module::OpFAbs, Type::Float>, | ||
| 809 | &SPIRVDecompiler::Ternary<&Module::OpFClamp, Type::Float>, | ||
| 810 | &SPIRVDecompiler::Binary<&Module::OpFMin, Type::Float>, | ||
| 811 | &SPIRVDecompiler::Binary<&Module::OpFMax, Type::Float>, | ||
| 812 | &SPIRVDecompiler::Unary<&Module::OpCos, Type::Float>, | ||
| 813 | &SPIRVDecompiler::Unary<&Module::OpSin, Type::Float>, | ||
| 814 | &SPIRVDecompiler::Unary<&Module::OpExp2, Type::Float>, | ||
| 815 | &SPIRVDecompiler::Unary<&Module::OpLog2, Type::Float>, | ||
| 816 | &SPIRVDecompiler::Unary<&Module::OpInverseSqrt, Type::Float>, | ||
| 817 | &SPIRVDecompiler::Unary<&Module::OpSqrt, Type::Float>, | ||
| 818 | &SPIRVDecompiler::Unary<&Module::OpRoundEven, Type::Float>, | ||
| 819 | &SPIRVDecompiler::Unary<&Module::OpFloor, Type::Float>, | ||
| 820 | &SPIRVDecompiler::Unary<&Module::OpCeil, Type::Float>, | ||
| 821 | &SPIRVDecompiler::Unary<&Module::OpTrunc, Type::Float>, | ||
| 822 | &SPIRVDecompiler::Unary<&Module::OpConvertSToF, Type::Float, Type::Int>, | ||
| 823 | &SPIRVDecompiler::Unary<&Module::OpConvertUToF, Type::Float, Type::Uint>, | ||
| 824 | |||
| 825 | &SPIRVDecompiler::Binary<&Module::OpIAdd, Type::Int>, | ||
| 826 | &SPIRVDecompiler::Binary<&Module::OpIMul, Type::Int>, | ||
| 827 | &SPIRVDecompiler::Binary<&Module::OpSDiv, Type::Int>, | ||
| 828 | &SPIRVDecompiler::Unary<&Module::OpSNegate, Type::Int>, | ||
| 829 | &SPIRVDecompiler::Unary<&Module::OpSAbs, Type::Int>, | ||
| 830 | &SPIRVDecompiler::Binary<&Module::OpSMin, Type::Int>, | ||
| 831 | &SPIRVDecompiler::Binary<&Module::OpSMax, Type::Int>, | ||
| 832 | |||
| 833 | &SPIRVDecompiler::Unary<&Module::OpConvertFToS, Type::Int, Type::Float>, | ||
| 834 | &SPIRVDecompiler::Unary<&Module::OpBitcast, Type::Int, Type::Uint>, | ||
| 835 | &SPIRVDecompiler::Binary<&Module::OpShiftLeftLogical, Type::Int, Type::Int, Type::Uint>, | ||
| 836 | &SPIRVDecompiler::Binary<&Module::OpShiftRightLogical, Type::Int, Type::Int, Type::Uint>, | ||
| 837 | &SPIRVDecompiler::Binary<&Module::OpShiftRightArithmetic, Type::Int, Type::Int, Type::Uint>, | ||
| 838 | &SPIRVDecompiler::Binary<&Module::OpBitwiseAnd, Type::Int>, | ||
| 839 | &SPIRVDecompiler::Binary<&Module::OpBitwiseOr, Type::Int>, | ||
| 840 | &SPIRVDecompiler::Binary<&Module::OpBitwiseXor, Type::Int>, | ||
| 841 | &SPIRVDecompiler::Unary<&Module::OpNot, Type::Int>, | ||
| 842 | &SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Int>, | ||
| 843 | &SPIRVDecompiler::Ternary<&Module::OpBitFieldSExtract, Type::Int>, | ||
| 844 | &SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Int>, | ||
| 845 | |||
| 846 | &SPIRVDecompiler::Binary<&Module::OpIAdd, Type::Uint>, | ||
| 847 | &SPIRVDecompiler::Binary<&Module::OpIMul, Type::Uint>, | ||
| 848 | &SPIRVDecompiler::Binary<&Module::OpUDiv, Type::Uint>, | ||
| 849 | &SPIRVDecompiler::Binary<&Module::OpUMin, Type::Uint>, | ||
| 850 | &SPIRVDecompiler::Binary<&Module::OpUMax, Type::Uint>, | ||
| 851 | &SPIRVDecompiler::Unary<&Module::OpConvertFToU, Type::Uint, Type::Float>, | ||
| 852 | &SPIRVDecompiler::Unary<&Module::OpBitcast, Type::Uint, Type::Int>, | ||
| 853 | &SPIRVDecompiler::Binary<&Module::OpShiftLeftLogical, Type::Uint>, | ||
| 854 | &SPIRVDecompiler::Binary<&Module::OpShiftRightLogical, Type::Uint>, | ||
| 855 | &SPIRVDecompiler::Binary<&Module::OpShiftRightArithmetic, Type::Uint>, | ||
| 856 | &SPIRVDecompiler::Binary<&Module::OpBitwiseAnd, Type::Uint>, | ||
| 857 | &SPIRVDecompiler::Binary<&Module::OpBitwiseOr, Type::Uint>, | ||
| 858 | &SPIRVDecompiler::Binary<&Module::OpBitwiseXor, Type::Uint>, | ||
| 859 | &SPIRVDecompiler::Unary<&Module::OpNot, Type::Uint>, | ||
| 860 | &SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Uint>, | ||
| 861 | &SPIRVDecompiler::Ternary<&Module::OpBitFieldUExtract, Type::Uint>, | ||
| 862 | &SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Uint>, | ||
| 863 | |||
| 864 | &SPIRVDecompiler::Binary<&Module::OpFAdd, Type::HalfFloat>, | ||
| 865 | &SPIRVDecompiler::Binary<&Module::OpFMul, Type::HalfFloat>, | ||
| 866 | &SPIRVDecompiler::Ternary<&Module::OpFma, Type::HalfFloat>, | ||
| 867 | &SPIRVDecompiler::Unary<&Module::OpFAbs, Type::HalfFloat>, | ||
| 868 | &SPIRVDecompiler::HNegate, | ||
| 869 | &SPIRVDecompiler::HMergeF32, | ||
| 870 | &SPIRVDecompiler::HMergeH0, | ||
| 871 | &SPIRVDecompiler::HMergeH1, | ||
| 872 | &SPIRVDecompiler::HPack2, | ||
| 873 | |||
| 874 | &SPIRVDecompiler::LogicalAssign, | ||
| 875 | &SPIRVDecompiler::Binary<&Module::OpLogicalAnd, Type::Bool>, | ||
| 876 | &SPIRVDecompiler::Binary<&Module::OpLogicalOr, Type::Bool>, | ||
| 877 | &SPIRVDecompiler::Binary<&Module::OpLogicalNotEqual, Type::Bool>, | ||
| 878 | &SPIRVDecompiler::Unary<&Module::OpLogicalNot, Type::Bool>, | ||
| 879 | &SPIRVDecompiler::LogicalPick2, | ||
| 880 | &SPIRVDecompiler::LogicalAll2, | ||
| 881 | &SPIRVDecompiler::LogicalAny2, | ||
| 882 | |||
| 883 | &SPIRVDecompiler::Binary<&Module::OpFOrdLessThan, Type::Bool, Type::Float>, | ||
| 884 | &SPIRVDecompiler::Binary<&Module::OpFOrdEqual, Type::Bool, Type::Float>, | ||
| 885 | &SPIRVDecompiler::Binary<&Module::OpFOrdLessThanEqual, Type::Bool, Type::Float>, | ||
| 886 | &SPIRVDecompiler::Binary<&Module::OpFOrdGreaterThan, Type::Bool, Type::Float>, | ||
| 887 | &SPIRVDecompiler::Binary<&Module::OpFOrdNotEqual, Type::Bool, Type::Float>, | ||
| 888 | &SPIRVDecompiler::Binary<&Module::OpFOrdGreaterThanEqual, Type::Bool, Type::Float>, | ||
| 889 | &SPIRVDecompiler::Unary<&Module::OpIsNan, Type::Bool>, | ||
| 890 | |||
| 891 | &SPIRVDecompiler::Binary<&Module::OpSLessThan, Type::Bool, Type::Int>, | ||
| 892 | &SPIRVDecompiler::Binary<&Module::OpIEqual, Type::Bool, Type::Int>, | ||
| 893 | &SPIRVDecompiler::Binary<&Module::OpSLessThanEqual, Type::Bool, Type::Int>, | ||
| 894 | &SPIRVDecompiler::Binary<&Module::OpSGreaterThan, Type::Bool, Type::Int>, | ||
| 895 | &SPIRVDecompiler::Binary<&Module::OpINotEqual, Type::Bool, Type::Int>, | ||
| 896 | &SPIRVDecompiler::Binary<&Module::OpSGreaterThanEqual, Type::Bool, Type::Int>, | ||
| 897 | |||
| 898 | &SPIRVDecompiler::Binary<&Module::OpULessThan, Type::Bool, Type::Uint>, | ||
| 899 | &SPIRVDecompiler::Binary<&Module::OpIEqual, Type::Bool, Type::Uint>, | ||
| 900 | &SPIRVDecompiler::Binary<&Module::OpULessThanEqual, Type::Bool, Type::Uint>, | ||
| 901 | &SPIRVDecompiler::Binary<&Module::OpUGreaterThan, Type::Bool, Type::Uint>, | ||
| 902 | &SPIRVDecompiler::Binary<&Module::OpINotEqual, Type::Bool, Type::Uint>, | ||
| 903 | &SPIRVDecompiler::Binary<&Module::OpUGreaterThanEqual, Type::Bool, Type::Uint>, | ||
| 904 | |||
| 905 | &SPIRVDecompiler::Binary<&Module::OpFOrdLessThan, Type::Bool, Type::HalfFloat>, | ||
| 906 | &SPIRVDecompiler::Binary<&Module::OpFOrdEqual, Type::Bool, Type::HalfFloat>, | ||
| 907 | &SPIRVDecompiler::Binary<&Module::OpFOrdLessThanEqual, Type::Bool, Type::HalfFloat>, | ||
| 908 | &SPIRVDecompiler::Binary<&Module::OpFOrdGreaterThan, Type::Bool, Type::HalfFloat>, | ||
| 909 | &SPIRVDecompiler::Binary<&Module::OpFOrdNotEqual, Type::Bool, Type::HalfFloat>, | ||
| 910 | &SPIRVDecompiler::Binary<&Module::OpFOrdGreaterThanEqual, Type::Bool, Type::HalfFloat>, | ||
| 911 | |||
| 912 | &SPIRVDecompiler::Texture, | ||
| 913 | &SPIRVDecompiler::TextureLod, | ||
| 914 | &SPIRVDecompiler::TextureGather, | ||
| 915 | &SPIRVDecompiler::TextureQueryDimensions, | ||
| 916 | &SPIRVDecompiler::TextureQueryLod, | ||
| 917 | &SPIRVDecompiler::TexelFetch, | ||
| 918 | |||
| 919 | &SPIRVDecompiler::Branch, | ||
| 920 | &SPIRVDecompiler::PushFlowStack, | ||
| 921 | &SPIRVDecompiler::PopFlowStack, | ||
| 922 | &SPIRVDecompiler::Exit, | ||
| 923 | &SPIRVDecompiler::Discard, | ||
| 924 | |||
| 925 | &SPIRVDecompiler::EmitVertex, | ||
| 926 | &SPIRVDecompiler::EndPrimitive, | ||
| 927 | |||
| 928 | &SPIRVDecompiler::YNegate, | ||
| 929 | }; | ||
| 930 | |||
| 521 | const ShaderIR& ir; | 931 | const ShaderIR& ir; |
| 522 | const ShaderStage stage; | 932 | const ShaderStage stage; |
| 523 | const Tegra::Shader::Header header; | 933 | const Tegra::Shader::Header header; |