diff options
Diffstat (limited to 'src/shader_recompiler/frontend')
| -rw-r--r-- | src/shader_recompiler/frontend/ir/ir_emitter.cpp | 20 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/ir_emitter.h | 5 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/microinstruction.cpp | 26 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/microinstruction.h | 4 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/opcode.inc | 22 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/type.cpp | 2 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/type.h | 1 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/value.cpp | 17 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/value.h | 1 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/program.cpp | 6 |
10 files changed, 77 insertions, 27 deletions
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 87b253c9a..1c5ae0109 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -504,6 +504,20 @@ U32U64 IREmitter::IAdd(const U32U64& a, const U32U64& b) { | |||
| 504 | } | 504 | } |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | U32U64 IREmitter::ISub(const U32U64& a, const U32U64& b) { | ||
| 508 | if (a.Type() != b.Type()) { | ||
| 509 | throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); | ||
| 510 | } | ||
| 511 | switch (a.Type()) { | ||
| 512 | case Type::U32: | ||
| 513 | return Inst<U32>(Opcode::ISub32, a, b); | ||
| 514 | case Type::U64: | ||
| 515 | return Inst<U64>(Opcode::ISub64, a, b); | ||
| 516 | default: | ||
| 517 | ThrowInvalidType(a.Type()); | ||
| 518 | } | ||
| 519 | } | ||
| 520 | |||
| 507 | U32 IREmitter::IMul(const U32& a, const U32& b) { | 521 | U32 IREmitter::IMul(const U32& a, const U32& b) { |
| 508 | return Inst<U32>(Opcode::IMul32, a, b); | 522 | return Inst<U32>(Opcode::IMul32, a, b); |
| 509 | } | 523 | } |
| @@ -679,8 +693,8 @@ U32U64 IREmitter::ConvertFToI(size_t bitsize, bool is_signed, const U16U32U64& v | |||
| 679 | } | 693 | } |
| 680 | } | 694 | } |
| 681 | 695 | ||
| 682 | U32U64 IREmitter::ConvertU(size_t bitsize, const U32U64& value) { | 696 | U32U64 IREmitter::ConvertU(size_t result_bitsize, const U32U64& value) { |
| 683 | switch (bitsize) { | 697 | switch (result_bitsize) { |
| 684 | case 32: | 698 | case 32: |
| 685 | switch (value.Type()) { | 699 | switch (value.Type()) { |
| 686 | case Type::U32: | 700 | case Type::U32: |
| @@ -703,7 +717,7 @@ U32U64 IREmitter::ConvertU(size_t bitsize, const U32U64& value) { | |||
| 703 | break; | 717 | break; |
| 704 | } | 718 | } |
| 705 | } | 719 | } |
| 706 | throw NotImplementedException("Conversion from {} to {} bits", value.Type(), bitsize); | 720 | throw NotImplementedException("Conversion from {} to {} bits", value.Type(), result_bitsize); |
| 707 | } | 721 | } |
| 708 | 722 | ||
| 709 | } // namespace Shader::IR | 723 | } // namespace Shader::IR |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index 7ff763ecf..84b844898 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -17,6 +17,8 @@ namespace Shader::IR { | |||
| 17 | class IREmitter { | 17 | class IREmitter { |
| 18 | public: | 18 | public: |
| 19 | explicit IREmitter(Block& block_) : block{block_}, insertion_point{block.end()} {} | 19 | explicit IREmitter(Block& block_) : block{block_}, insertion_point{block.end()} {} |
| 20 | explicit IREmitter(Block& block_, Block::iterator insertion_point_) | ||
| 21 | : block{block_}, insertion_point{insertion_point_} {} | ||
| 20 | 22 | ||
| 21 | Block& block; | 23 | Block& block; |
| 22 | 24 | ||
| @@ -125,6 +127,7 @@ public: | |||
| 125 | [[nodiscard]] U16U32U64 FPTrunc(const U16U32U64& value); | 127 | [[nodiscard]] U16U32U64 FPTrunc(const U16U32U64& value); |
| 126 | 128 | ||
| 127 | [[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b); | 129 | [[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b); |
| 130 | [[nodiscard]] U32U64 ISub(const U32U64& a, const U32U64& b); | ||
| 128 | [[nodiscard]] U32 IMul(const U32& a, const U32& b); | 131 | [[nodiscard]] U32 IMul(const U32& a, const U32& b); |
| 129 | [[nodiscard]] U32 INeg(const U32& value); | 132 | [[nodiscard]] U32 INeg(const U32& value); |
| 130 | [[nodiscard]] U32 IAbs(const U32& value); | 133 | [[nodiscard]] U32 IAbs(const U32& value); |
| @@ -155,7 +158,7 @@ public: | |||
| 155 | [[nodiscard]] U32U64 ConvertFToU(size_t bitsize, const U16U32U64& value); | 158 | [[nodiscard]] U32U64 ConvertFToU(size_t bitsize, const U16U32U64& value); |
| 156 | [[nodiscard]] U32U64 ConvertFToI(size_t bitsize, bool is_signed, const U16U32U64& value); | 159 | [[nodiscard]] U32U64 ConvertFToI(size_t bitsize, bool is_signed, const U16U32U64& value); |
| 157 | 160 | ||
| 158 | [[nodiscard]] U32U64 ConvertU(size_t bitsize, const U32U64& value); | 161 | [[nodiscard]] U32U64 ConvertU(size_t result_bitsize, const U32U64& value); |
| 159 | 162 | ||
| 160 | private: | 163 | private: |
| 161 | IR::Block::iterator insertion_point; | 164 | IR::Block::iterator insertion_point; |
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index ecf76e23d..de953838c 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 6 | |||
| 5 | #include "shader_recompiler/exception.h" | 7 | #include "shader_recompiler/exception.h" |
| 6 | #include "shader_recompiler/frontend/ir/microinstruction.h" | 8 | #include "shader_recompiler/frontend/ir/microinstruction.h" |
| 7 | #include "shader_recompiler/frontend/ir/type.h" | 9 | #include "shader_recompiler/frontend/ir/type.h" |
| @@ -44,6 +46,13 @@ bool Inst::MayHaveSideEffects() const noexcept { | |||
| 44 | case Opcode::WriteGlobal32: | 46 | case Opcode::WriteGlobal32: |
| 45 | case Opcode::WriteGlobal64: | 47 | case Opcode::WriteGlobal64: |
| 46 | case Opcode::WriteGlobal128: | 48 | case Opcode::WriteGlobal128: |
| 49 | case Opcode::WriteStorageU8: | ||
| 50 | case Opcode::WriteStorageS8: | ||
| 51 | case Opcode::WriteStorageU16: | ||
| 52 | case Opcode::WriteStorageS16: | ||
| 53 | case Opcode::WriteStorage32: | ||
| 54 | case Opcode::WriteStorage64: | ||
| 55 | case Opcode::WriteStorage128: | ||
| 47 | return true; | 56 | return true; |
| 48 | default: | 57 | default: |
| 49 | return false; | 58 | return false; |
| @@ -56,15 +65,19 @@ bool Inst::IsPseudoInstruction() const noexcept { | |||
| 56 | case Opcode::GetSignFromOp: | 65 | case Opcode::GetSignFromOp: |
| 57 | case Opcode::GetCarryFromOp: | 66 | case Opcode::GetCarryFromOp: |
| 58 | case Opcode::GetOverflowFromOp: | 67 | case Opcode::GetOverflowFromOp: |
| 59 | case Opcode::GetZSCOFromOp: | ||
| 60 | return true; | 68 | return true; |
| 61 | default: | 69 | default: |
| 62 | return false; | 70 | return false; |
| 63 | } | 71 | } |
| 64 | } | 72 | } |
| 65 | 73 | ||
| 74 | bool Inst::AreAllArgsImmediates() const noexcept { | ||
| 75 | return std::all_of(args.begin(), args.begin() + NumArgs(), | ||
| 76 | [](const IR::Value& value) { return value.IsImmediate(); }); | ||
| 77 | } | ||
| 78 | |||
| 66 | bool Inst::HasAssociatedPseudoOperation() const noexcept { | 79 | bool Inst::HasAssociatedPseudoOperation() const noexcept { |
| 67 | return zero_inst || sign_inst || carry_inst || overflow_inst || zsco_inst; | 80 | return zero_inst || sign_inst || carry_inst || overflow_inst; |
| 68 | } | 81 | } |
| 69 | 82 | ||
| 70 | Inst* Inst::GetAssociatedPseudoOperation(IR::Opcode opcode) { | 83 | Inst* Inst::GetAssociatedPseudoOperation(IR::Opcode opcode) { |
| @@ -82,9 +95,6 @@ Inst* Inst::GetAssociatedPseudoOperation(IR::Opcode opcode) { | |||
| 82 | case Opcode::GetOverflowFromOp: | 95 | case Opcode::GetOverflowFromOp: |
| 83 | CheckPseudoInstruction(overflow_inst, Opcode::GetOverflowFromOp); | 96 | CheckPseudoInstruction(overflow_inst, Opcode::GetOverflowFromOp); |
| 84 | return overflow_inst; | 97 | return overflow_inst; |
| 85 | case Opcode::GetZSCOFromOp: | ||
| 86 | CheckPseudoInstruction(zsco_inst, Opcode::GetZSCOFromOp); | ||
| 87 | return zsco_inst; | ||
| 88 | default: | 98 | default: |
| 89 | throw InvalidArgument("{} is not a pseudo-instruction", opcode); | 99 | throw InvalidArgument("{} is not a pseudo-instruction", opcode); |
| 90 | } | 100 | } |
| @@ -176,9 +186,6 @@ void Inst::Use(const Value& value) { | |||
| 176 | case Opcode::GetOverflowFromOp: | 186 | case Opcode::GetOverflowFromOp: |
| 177 | SetPseudoInstruction(value.Inst()->overflow_inst, this); | 187 | SetPseudoInstruction(value.Inst()->overflow_inst, this); |
| 178 | break; | 188 | break; |
| 179 | case Opcode::GetZSCOFromOp: | ||
| 180 | SetPseudoInstruction(value.Inst()->zsco_inst, this); | ||
| 181 | break; | ||
| 182 | default: | 189 | default: |
| 183 | break; | 190 | break; |
| 184 | } | 191 | } |
| @@ -200,9 +207,6 @@ void Inst::UndoUse(const Value& value) { | |||
| 200 | case Opcode::GetOverflowFromOp: | 207 | case Opcode::GetOverflowFromOp: |
| 201 | RemovePseudoInstruction(value.Inst()->overflow_inst, Opcode::GetOverflowFromOp); | 208 | RemovePseudoInstruction(value.Inst()->overflow_inst, Opcode::GetOverflowFromOp); |
| 202 | break; | 209 | break; |
| 203 | case Opcode::GetZSCOFromOp: | ||
| 204 | RemovePseudoInstruction(value.Inst()->zsco_inst, Opcode::GetZSCOFromOp); | ||
| 205 | break; | ||
| 206 | default: | 210 | default: |
| 207 | break; | 211 | break; |
| 208 | } | 212 | } |
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.h b/src/shader_recompiler/frontend/ir/microinstruction.h index 61849695a..22101c9e2 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.h +++ b/src/shader_recompiler/frontend/ir/microinstruction.h | |||
| @@ -49,6 +49,9 @@ public: | |||
| 49 | /// Pseudo-instructions depend on their parent instructions for their semantics. | 49 | /// Pseudo-instructions depend on their parent instructions for their semantics. |
| 50 | [[nodiscard]] bool IsPseudoInstruction() const noexcept; | 50 | [[nodiscard]] bool IsPseudoInstruction() const noexcept; |
| 51 | 51 | ||
| 52 | /// Determines if all arguments of this instruction are immediates. | ||
| 53 | [[nodiscard]] bool AreAllArgsImmediates() const noexcept; | ||
| 54 | |||
| 52 | /// Determines if there is a pseudo-operation associated with this instruction. | 55 | /// Determines if there is a pseudo-operation associated with this instruction. |
| 53 | [[nodiscard]] bool HasAssociatedPseudoOperation() const noexcept; | 56 | [[nodiscard]] bool HasAssociatedPseudoOperation() const noexcept; |
| 54 | /// Gets a pseudo-operation associated with this instruction | 57 | /// Gets a pseudo-operation associated with this instruction |
| @@ -94,7 +97,6 @@ private: | |||
| 94 | Inst* sign_inst{}; | 97 | Inst* sign_inst{}; |
| 95 | Inst* carry_inst{}; | 98 | Inst* carry_inst{}; |
| 96 | Inst* overflow_inst{}; | 99 | Inst* overflow_inst{}; |
| 97 | Inst* zsco_inst{}; | ||
| 98 | std::vector<std::pair<Block*, Value>> phi_operands; | 100 | std::vector<std::pair<Block*, Value>> phi_operands; |
| 99 | u64 flags{}; | 101 | u64 flags{}; |
| 100 | }; | 102 | }; |
diff --git a/src/shader_recompiler/frontend/ir/opcode.inc b/src/shader_recompiler/frontend/ir/opcode.inc index 4ecb5e936..4596bf39f 100644 --- a/src/shader_recompiler/frontend/ir/opcode.inc +++ b/src/shader_recompiler/frontend/ir/opcode.inc | |||
| @@ -24,9 +24,6 @@ OPCODE(GetAttribute, U32, Attr | |||
| 24 | OPCODE(SetAttribute, U32, Attribute, ) | 24 | OPCODE(SetAttribute, U32, Attribute, ) |
| 25 | OPCODE(GetAttributeIndexed, U32, U32, ) | 25 | OPCODE(GetAttributeIndexed, U32, U32, ) |
| 26 | OPCODE(SetAttributeIndexed, U32, U32, ) | 26 | OPCODE(SetAttributeIndexed, U32, U32, ) |
| 27 | OPCODE(GetZSCORaw, U32, ) | ||
| 28 | OPCODE(SetZSCORaw, Void, U32, ) | ||
| 29 | OPCODE(SetZSCO, Void, ZSCO, ) | ||
| 30 | OPCODE(GetZFlag, U1, Void, ) | 27 | OPCODE(GetZFlag, U1, Void, ) |
| 31 | OPCODE(GetSFlag, U1, Void, ) | 28 | OPCODE(GetSFlag, U1, Void, ) |
| 32 | OPCODE(GetCFlag, U1, Void, ) | 29 | OPCODE(GetCFlag, U1, Void, ) |
| @@ -65,6 +62,22 @@ OPCODE(WriteGlobal32, Void, U64, | |||
| 65 | OPCODE(WriteGlobal64, Void, U64, Opaque, ) | 62 | OPCODE(WriteGlobal64, Void, U64, Opaque, ) |
| 66 | OPCODE(WriteGlobal128, Void, U64, Opaque, ) | 63 | OPCODE(WriteGlobal128, Void, U64, Opaque, ) |
| 67 | 64 | ||
| 65 | // Storage buffer operations | ||
| 66 | OPCODE(LoadStorageU8, U32, U32, U32, ) | ||
| 67 | OPCODE(LoadStorageS8, U32, U32, U32, ) | ||
| 68 | OPCODE(LoadStorageU16, U32, U32, U32, ) | ||
| 69 | OPCODE(LoadStorageS16, U32, U32, U32, ) | ||
| 70 | OPCODE(LoadStorage32, U32, U32, U32, ) | ||
| 71 | OPCODE(LoadStorage64, Opaque, U32, U32, ) | ||
| 72 | OPCODE(LoadStorage128, Opaque, U32, U32, ) | ||
| 73 | OPCODE(WriteStorageU8, Void, U32, U32, U32, ) | ||
| 74 | OPCODE(WriteStorageS8, Void, U32, U32, U32, ) | ||
| 75 | OPCODE(WriteStorageU16, Void, U32, U32, U32, ) | ||
| 76 | OPCODE(WriteStorageS16, Void, U32, U32, U32, ) | ||
| 77 | OPCODE(WriteStorage32, Void, U32, U32, U32, ) | ||
| 78 | OPCODE(WriteStorage64, Void, U32, U32, Opaque, ) | ||
| 79 | OPCODE(WriteStorage128, Void, U32, U32, Opaque, ) | ||
| 80 | |||
| 68 | // Vector utility | 81 | // Vector utility |
| 69 | OPCODE(CompositeConstruct2, Opaque, Opaque, Opaque, ) | 82 | OPCODE(CompositeConstruct2, Opaque, Opaque, Opaque, ) |
| 70 | OPCODE(CompositeConstruct3, Opaque, Opaque, Opaque, Opaque, ) | 83 | OPCODE(CompositeConstruct3, Opaque, Opaque, Opaque, Opaque, ) |
| @@ -90,7 +103,6 @@ OPCODE(GetZeroFromOp, U1, Opaq | |||
| 90 | OPCODE(GetSignFromOp, U1, Opaque, ) | 103 | OPCODE(GetSignFromOp, U1, Opaque, ) |
| 91 | OPCODE(GetCarryFromOp, U1, Opaque, ) | 104 | OPCODE(GetCarryFromOp, U1, Opaque, ) |
| 92 | OPCODE(GetOverflowFromOp, U1, Opaque, ) | 105 | OPCODE(GetOverflowFromOp, U1, Opaque, ) |
| 93 | OPCODE(GetZSCOFromOp, ZSCO, Opaque, ) | ||
| 94 | 106 | ||
| 95 | // Floating-point operations | 107 | // Floating-point operations |
| 96 | OPCODE(FPAbs16, U16, U16, ) | 108 | OPCODE(FPAbs16, U16, U16, ) |
| @@ -143,6 +155,8 @@ OPCODE(FPTrunc64, U64, U64, | |||
| 143 | // Integer operations | 155 | // Integer operations |
| 144 | OPCODE(IAdd32, U32, U32, U32, ) | 156 | OPCODE(IAdd32, U32, U32, U32, ) |
| 145 | OPCODE(IAdd64, U64, U64, U64, ) | 157 | OPCODE(IAdd64, U64, U64, U64, ) |
| 158 | OPCODE(ISub32, U32, U32, U32, ) | ||
| 159 | OPCODE(ISub64, U64, U64, U64, ) | ||
| 146 | OPCODE(IMul32, U32, U32, U32, ) | 160 | OPCODE(IMul32, U32, U32, U32, ) |
| 147 | OPCODE(INeg32, U32, U32, ) | 161 | OPCODE(INeg32, U32, U32, ) |
| 148 | OPCODE(IAbs32, U32, U32, ) | 162 | OPCODE(IAbs32, U32, U32, ) |
diff --git a/src/shader_recompiler/frontend/ir/type.cpp b/src/shader_recompiler/frontend/ir/type.cpp index da1e2a0f6..13cc09195 100644 --- a/src/shader_recompiler/frontend/ir/type.cpp +++ b/src/shader_recompiler/frontend/ir/type.cpp | |||
| @@ -11,7 +11,7 @@ namespace Shader::IR { | |||
| 11 | 11 | ||
| 12 | std::string NameOf(Type type) { | 12 | std::string NameOf(Type type) { |
| 13 | static constexpr std::array names{ | 13 | static constexpr std::array names{ |
| 14 | "Opaque", "Label", "Reg", "Pred", "Attribute", "U1", "U8", "U16", "U32", "U64", "ZSCO", | 14 | "Opaque", "Label", "Reg", "Pred", "Attribute", "U1", "U8", "U16", "U32", "U64", |
| 15 | }; | 15 | }; |
| 16 | const size_t bits{static_cast<size_t>(type)}; | 16 | const size_t bits{static_cast<size_t>(type)}; |
| 17 | if (bits == 0) { | 17 | if (bits == 0) { |
diff --git a/src/shader_recompiler/frontend/ir/type.h b/src/shader_recompiler/frontend/ir/type.h index f753628e8..397875018 100644 --- a/src/shader_recompiler/frontend/ir/type.h +++ b/src/shader_recompiler/frontend/ir/type.h | |||
| @@ -25,7 +25,6 @@ enum class Type { | |||
| 25 | U16 = 1 << 7, | 25 | U16 = 1 << 7, |
| 26 | U32 = 1 << 8, | 26 | U32 = 1 << 8, |
| 27 | U64 = 1 << 9, | 27 | U64 = 1 << 9, |
| 28 | ZSCO = 1 << 10, | ||
| 29 | }; | 28 | }; |
| 30 | DECLARE_ENUM_FLAG_OPERATORS(Type) | 29 | DECLARE_ENUM_FLAG_OPERATORS(Type) |
| 31 | 30 | ||
diff --git a/src/shader_recompiler/frontend/ir/value.cpp b/src/shader_recompiler/frontend/ir/value.cpp index 1e974e88c..59a9b10dc 100644 --- a/src/shader_recompiler/frontend/ir/value.cpp +++ b/src/shader_recompiler/frontend/ir/value.cpp | |||
| @@ -91,26 +91,41 @@ IR::Attribute Value::Attribute() const { | |||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | bool Value::U1() const { | 93 | bool Value::U1() const { |
| 94 | if (IsIdentity()) { | ||
| 95 | return inst->Arg(0).U1(); | ||
| 96 | } | ||
| 94 | ValidateAccess(Type::U1); | 97 | ValidateAccess(Type::U1); |
| 95 | return imm_u1; | 98 | return imm_u1; |
| 96 | } | 99 | } |
| 97 | 100 | ||
| 98 | u8 Value::U8() const { | 101 | u8 Value::U8() const { |
| 102 | if (IsIdentity()) { | ||
| 103 | return inst->Arg(0).U8(); | ||
| 104 | } | ||
| 99 | ValidateAccess(Type::U8); | 105 | ValidateAccess(Type::U8); |
| 100 | return imm_u8; | 106 | return imm_u8; |
| 101 | } | 107 | } |
| 102 | 108 | ||
| 103 | u16 Value::U16() const { | 109 | u16 Value::U16() const { |
| 110 | if (IsIdentity()) { | ||
| 111 | return inst->Arg(0).U16(); | ||
| 112 | } | ||
| 104 | ValidateAccess(Type::U16); | 113 | ValidateAccess(Type::U16); |
| 105 | return imm_u16; | 114 | return imm_u16; |
| 106 | } | 115 | } |
| 107 | 116 | ||
| 108 | u32 Value::U32() const { | 117 | u32 Value::U32() const { |
| 118 | if (IsIdentity()) { | ||
| 119 | return inst->Arg(0).U32(); | ||
| 120 | } | ||
| 109 | ValidateAccess(Type::U32); | 121 | ValidateAccess(Type::U32); |
| 110 | return imm_u32; | 122 | return imm_u32; |
| 111 | } | 123 | } |
| 112 | 124 | ||
| 113 | u64 Value::U64() const { | 125 | u64 Value::U64() const { |
| 126 | if (IsIdentity()) { | ||
| 127 | return inst->Arg(0).U64(); | ||
| 128 | } | ||
| 114 | ValidateAccess(Type::U64); | 129 | ValidateAccess(Type::U64); |
| 115 | return imm_u64; | 130 | return imm_u64; |
| 116 | } | 131 | } |
| @@ -142,8 +157,6 @@ bool Value::operator==(const Value& other) const { | |||
| 142 | return imm_u32 == other.imm_u32; | 157 | return imm_u32 == other.imm_u32; |
| 143 | case Type::U64: | 158 | case Type::U64: |
| 144 | return imm_u64 == other.imm_u64; | 159 | return imm_u64 == other.imm_u64; |
| 145 | case Type::ZSCO: | ||
| 146 | throw NotImplementedException("ZSCO comparison"); | ||
| 147 | } | 160 | } |
| 148 | throw LogicError("Invalid type {}", type); | 161 | throw LogicError("Invalid type {}", type); |
| 149 | } | 162 | } |
diff --git a/src/shader_recompiler/frontend/ir/value.h b/src/shader_recompiler/frontend/ir/value.h index 368119921..31f831794 100644 --- a/src/shader_recompiler/frontend/ir/value.h +++ b/src/shader_recompiler/frontend/ir/value.h | |||
| @@ -96,6 +96,5 @@ using U64 = TypedValue<Type::U64>; | |||
| 96 | using U32U64 = TypedValue<Type::U32 | Type::U64>; | 96 | using U32U64 = TypedValue<Type::U32 | Type::U64>; |
| 97 | using U16U32U64 = TypedValue<Type::U16 | Type::U32 | Type::U64>; | 97 | using U16U32U64 = TypedValue<Type::U16 | Type::U32 | Type::U64>; |
| 98 | using UAny = TypedValue<Type::U8 | Type::U16 | Type::U32 | Type::U64>; | 98 | using UAny = TypedValue<Type::U8 | Type::U16 | Type::U32 | Type::U64>; |
| 99 | using ZSCO = TypedValue<Type::ZSCO>; | ||
| 100 | 99 | ||
| 101 | } // namespace Shader::IR | 100 | } // namespace Shader::IR |
diff --git a/src/shader_recompiler/frontend/maxwell/program.cpp b/src/shader_recompiler/frontend/maxwell/program.cpp index bd1f96c07..b3f2de852 100644 --- a/src/shader_recompiler/frontend/maxwell/program.cpp +++ b/src/shader_recompiler/frontend/maxwell/program.cpp | |||
| @@ -52,9 +52,11 @@ Program::Program(Environment& env, const Flow::CFG& cfg) { | |||
| 52 | } | 52 | } |
| 53 | std::ranges::for_each(functions, Optimization::SsaRewritePass); | 53 | std::ranges::for_each(functions, Optimization::SsaRewritePass); |
| 54 | for (IR::Function& function : functions) { | 54 | for (IR::Function& function : functions) { |
| 55 | Optimization::Invoke(Optimization::GlobalMemoryToStorageBufferPass, function); | ||
| 56 | Optimization::Invoke(Optimization::ConstantPropagationPass, function); | ||
| 55 | Optimization::Invoke(Optimization::DeadCodeEliminationPass, function); | 57 | Optimization::Invoke(Optimization::DeadCodeEliminationPass, function); |
| 56 | Optimization::Invoke(Optimization::IdentityRemovalPass, function); | 58 | Optimization::IdentityRemovalPass(function); |
| 57 | // Optimization::Invoke(Optimization::VerificationPass, function); | 59 | Optimization::VerificationPass(function); |
| 58 | } | 60 | } |
| 59 | //*/ | 61 | //*/ |
| 60 | } | 62 | } |