diff options
Diffstat (limited to 'src/shader_recompiler/frontend/ir')
| -rw-r--r-- | src/shader_recompiler/frontend/ir/basic_block.cpp | 5 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/basic_block.h | 3 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/ir_emitter.cpp | 16 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/ir_emitter.h | 7 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/microinstruction.cpp | 11 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/opcodes.inc | 6 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/value.h | 2 |
7 files changed, 49 insertions, 1 deletions
diff --git a/src/shader_recompiler/frontend/ir/basic_block.cpp b/src/shader_recompiler/frontend/ir/basic_block.cpp index 7c08b25ce..974efa4a0 100644 --- a/src/shader_recompiler/frontend/ir/basic_block.cpp +++ b/src/shader_recompiler/frontend/ir/basic_block.cpp | |||
| @@ -22,6 +22,11 @@ void Block::AppendNewInst(Opcode op, std::initializer_list<Value> args) { | |||
| 22 | PrependNewInst(end(), op, args); | 22 | PrependNewInst(end(), op, args); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | Block::iterator Block::PrependNewInst(iterator insertion_point, const Inst& base_inst) { | ||
| 26 | Inst* const inst{inst_pool->Create(base_inst)}; | ||
| 27 | return instructions.insert(insertion_point, *inst); | ||
| 28 | } | ||
| 29 | |||
| 25 | Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode op, | 30 | Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode op, |
| 26 | std::initializer_list<Value> args, u32 flags) { | 31 | std::initializer_list<Value> args, u32 flags) { |
| 27 | Inst* const inst{inst_pool->Create(op, flags)}; | 32 | Inst* const inst{inst_pool->Create(op, flags)}; |
diff --git a/src/shader_recompiler/frontend/ir/basic_block.h b/src/shader_recompiler/frontend/ir/basic_block.h index 9ce1ed07e..fbfe98266 100644 --- a/src/shader_recompiler/frontend/ir/basic_block.h +++ b/src/shader_recompiler/frontend/ir/basic_block.h | |||
| @@ -40,6 +40,9 @@ public: | |||
| 40 | /// Appends a new instruction to the end of this basic block. | 40 | /// Appends a new instruction to the end of this basic block. |
| 41 | void AppendNewInst(Opcode op, std::initializer_list<Value> args); | 41 | void AppendNewInst(Opcode op, std::initializer_list<Value> args); |
| 42 | 42 | ||
| 43 | /// Prepends a copy of an instruction to this basic block before the insertion point. | ||
| 44 | iterator PrependNewInst(iterator insertion_point, const Inst& base_inst); | ||
| 45 | |||
| 43 | /// Prepends a new instruction to this basic block before the insertion point. | 46 | /// Prepends a new instruction to this basic block before the insertion point. |
| 44 | iterator PrependNewInst(iterator insertion_point, Opcode op, | 47 | iterator PrependNewInst(iterator insertion_point, Opcode op, |
| 45 | std::initializer_list<Value> args = {}, u32 flags = 0); | 48 | std::initializer_list<Value> args = {}, u32 flags = 0); |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 13159a68d..356f889ac 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -375,6 +375,10 @@ F32 IREmitter::YDirection() { | |||
| 375 | return Inst<F32>(Opcode::YDirection); | 375 | return Inst<F32>(Opcode::YDirection); |
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | F32 IREmitter::ResolutionDownFactor() { | ||
| 379 | return Inst<F32>(Opcode::ResolutionDownFactor); | ||
| 380 | } | ||
| 381 | |||
| 378 | U32 IREmitter::LaneId() { | 382 | U32 IREmitter::LaneId() { |
| 379 | return Inst<U32>(Opcode::LaneId); | 383 | return Inst<U32>(Opcode::LaneId); |
| 380 | } | 384 | } |
| @@ -1141,6 +1145,10 @@ U32 IREmitter::IMul(const U32& a, const U32& b) { | |||
| 1141 | return Inst<U32>(Opcode::IMul32, a, b); | 1145 | return Inst<U32>(Opcode::IMul32, a, b); |
| 1142 | } | 1146 | } |
| 1143 | 1147 | ||
| 1148 | U32 IREmitter::IDiv(const U32& a, const U32& b, bool is_signed) { | ||
| 1149 | return Inst<U32>(is_signed ? Opcode::SDiv32 : Opcode::UDiv32, a, b); | ||
| 1150 | } | ||
| 1151 | |||
| 1144 | U32U64 IREmitter::INeg(const U32U64& value) { | 1152 | U32U64 IREmitter::INeg(const U32U64& value) { |
| 1145 | switch (value.Type()) { | 1153 | switch (value.Type()) { |
| 1146 | case Type::U32: | 1154 | case Type::U32: |
| @@ -1938,6 +1946,14 @@ Value IREmitter::ImageAtomicExchange(const Value& handle, const Value& coords, c | |||
| 1938 | return Inst(op, Flags{info}, handle, coords, value); | 1946 | return Inst(op, Flags{info}, handle, coords, value); |
| 1939 | } | 1947 | } |
| 1940 | 1948 | ||
| 1949 | U1 IREmitter::IsTextureScaled(const U32& index) { | ||
| 1950 | return Inst<U1>(Opcode::IsTextureScaled, index); | ||
| 1951 | } | ||
| 1952 | |||
| 1953 | U1 IREmitter::IsImageScaled(const U32& index) { | ||
| 1954 | return Inst<U1>(Opcode::IsImageScaled, index); | ||
| 1955 | } | ||
| 1956 | |||
| 1941 | U1 IREmitter::VoteAll(const U1& value) { | 1957 | U1 IREmitter::VoteAll(const U1& value) { |
| 1942 | return Inst<U1>(Opcode::VoteAll, value); | 1958 | return Inst<U1>(Opcode::VoteAll, value); |
| 1943 | } | 1959 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index 1b89ca5a0..13eefa88b 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -102,6 +102,8 @@ public: | |||
| 102 | [[nodiscard]] U1 IsHelperInvocation(); | 102 | [[nodiscard]] U1 IsHelperInvocation(); |
| 103 | [[nodiscard]] F32 YDirection(); | 103 | [[nodiscard]] F32 YDirection(); |
| 104 | 104 | ||
| 105 | [[nodiscard]] F32 ResolutionDownFactor(); | ||
| 106 | |||
| 105 | [[nodiscard]] U32 LaneId(); | 107 | [[nodiscard]] U32 LaneId(); |
| 106 | 108 | ||
| 107 | [[nodiscard]] U32 LoadGlobalU8(const U64& address); | 109 | [[nodiscard]] U32 LoadGlobalU8(const U64& address); |
| @@ -207,6 +209,7 @@ public: | |||
| 207 | [[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b); | 209 | [[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b); |
| 208 | [[nodiscard]] U32U64 ISub(const U32U64& a, const U32U64& b); | 210 | [[nodiscard]] U32U64 ISub(const U32U64& a, const U32U64& b); |
| 209 | [[nodiscard]] U32 IMul(const U32& a, const U32& b); | 211 | [[nodiscard]] U32 IMul(const U32& a, const U32& b); |
| 212 | [[nodiscard]] U32 IDiv(const U32& a, const U32& b, bool is_signed = false); | ||
| 210 | [[nodiscard]] U32U64 INeg(const U32U64& value); | 213 | [[nodiscard]] U32U64 INeg(const U32U64& value); |
| 211 | [[nodiscard]] U32 IAbs(const U32& value); | 214 | [[nodiscard]] U32 IAbs(const U32& value); |
| 212 | [[nodiscard]] U32U64 ShiftLeftLogical(const U32U64& base, const U32& shift); | 215 | [[nodiscard]] U32U64 ShiftLeftLogical(const U32U64& base, const U32& shift); |
| @@ -356,6 +359,10 @@ public: | |||
| 356 | TextureInstInfo info); | 359 | TextureInstInfo info); |
| 357 | [[nodiscard]] Value ImageAtomicExchange(const Value& handle, const Value& coords, | 360 | [[nodiscard]] Value ImageAtomicExchange(const Value& handle, const Value& coords, |
| 358 | const Value& value, TextureInstInfo info); | 361 | const Value& value, TextureInstInfo info); |
| 362 | |||
| 363 | [[nodiscard]] U1 IsTextureScaled(const U32& index); | ||
| 364 | [[nodiscard]] U1 IsImageScaled(const U32& index); | ||
| 365 | |||
| 359 | [[nodiscard]] U1 VoteAll(const U1& value); | 366 | [[nodiscard]] U1 VoteAll(const U1& value); |
| 360 | [[nodiscard]] U1 VoteAny(const U1& value); | 367 | [[nodiscard]] U1 VoteAny(const U1& value); |
| 361 | [[nodiscard]] U1 VoteEqual(const U1& value); | 368 | [[nodiscard]] U1 VoteEqual(const U1& value); |
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index 30b470bdd..97e2bf6af 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp | |||
| @@ -47,6 +47,17 @@ Inst::Inst(IR::Opcode op_, u32 flags_) noexcept : op{op_}, flags{flags_} { | |||
| 47 | } | 47 | } |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | Inst::Inst(const Inst& base) : op{base.op}, flags{base.flags} { | ||
| 51 | if (base.op == Opcode::Phi) { | ||
| 52 | throw NotImplementedException("Copying phi node"); | ||
| 53 | } | ||
| 54 | std::construct_at(&args); | ||
| 55 | const size_t num_args{base.NumArgs()}; | ||
| 56 | for (size_t index = 0; index < num_args; ++index) { | ||
| 57 | SetArg(index, base.Arg(index)); | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 50 | Inst::~Inst() { | 61 | Inst::~Inst() { |
| 51 | if (op == Opcode::Phi) { | 62 | if (op == Opcode::Phi) { |
| 52 | std::destroy_at(&phi_args); | 63 | std::destroy_at(&phi_args); |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index d91098c80..6929919df 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -62,6 +62,7 @@ OPCODE(InvocationId, U32, | |||
| 62 | OPCODE(SampleId, U32, ) | 62 | OPCODE(SampleId, U32, ) |
| 63 | OPCODE(IsHelperInvocation, U1, ) | 63 | OPCODE(IsHelperInvocation, U1, ) |
| 64 | OPCODE(YDirection, F32, ) | 64 | OPCODE(YDirection, F32, ) |
| 65 | OPCODE(ResolutionDownFactor, F32, ) | ||
| 65 | 66 | ||
| 66 | // Undefined | 67 | // Undefined |
| 67 | OPCODE(UndefU1, U1, ) | 68 | OPCODE(UndefU1, U1, ) |
| @@ -286,6 +287,8 @@ OPCODE(IAdd64, U64, U64, | |||
| 286 | OPCODE(ISub32, U32, U32, U32, ) | 287 | OPCODE(ISub32, U32, U32, U32, ) |
| 287 | OPCODE(ISub64, U64, U64, U64, ) | 288 | OPCODE(ISub64, U64, U64, U64, ) |
| 288 | OPCODE(IMul32, U32, U32, U32, ) | 289 | OPCODE(IMul32, U32, U32, U32, ) |
| 290 | OPCODE(SDiv32, U32, U32, U32, ) | ||
| 291 | OPCODE(UDiv32, U32, U32, U32, ) | ||
| 289 | OPCODE(INeg32, U32, U32, ) | 292 | OPCODE(INeg32, U32, U32, ) |
| 290 | OPCODE(INeg64, U64, U64, ) | 293 | OPCODE(INeg64, U64, U64, ) |
| 291 | OPCODE(IAbs32, U32, U32, ) | 294 | OPCODE(IAbs32, U32, U32, ) |
| @@ -490,6 +493,9 @@ OPCODE(ImageGradient, F32x4, Opaq | |||
| 490 | OPCODE(ImageRead, U32x4, Opaque, Opaque, ) | 493 | OPCODE(ImageRead, U32x4, Opaque, Opaque, ) |
| 491 | OPCODE(ImageWrite, Void, Opaque, Opaque, U32x4, ) | 494 | OPCODE(ImageWrite, Void, Opaque, Opaque, U32x4, ) |
| 492 | 495 | ||
| 496 | OPCODE(IsTextureScaled, U1, U32, ) | ||
| 497 | OPCODE(IsImageScaled, U1, U32, ) | ||
| 498 | |||
| 493 | // Atomic Image operations | 499 | // Atomic Image operations |
| 494 | 500 | ||
| 495 | OPCODE(BindlessImageAtomicIAdd32, U32, U32, Opaque, U32, ) | 501 | OPCODE(BindlessImageAtomicIAdd32, U32, U32, Opaque, U32, ) |
diff --git a/src/shader_recompiler/frontend/ir/value.h b/src/shader_recompiler/frontend/ir/value.h index 6c9ef6bdd..947579852 100644 --- a/src/shader_recompiler/frontend/ir/value.h +++ b/src/shader_recompiler/frontend/ir/value.h | |||
| @@ -116,10 +116,10 @@ public: | |||
| 116 | class Inst : public boost::intrusive::list_base_hook<> { | 116 | class Inst : public boost::intrusive::list_base_hook<> { |
| 117 | public: | 117 | public: |
| 118 | explicit Inst(IR::Opcode op_, u32 flags_) noexcept; | 118 | explicit Inst(IR::Opcode op_, u32 flags_) noexcept; |
| 119 | explicit Inst(const Inst& base); | ||
| 119 | ~Inst(); | 120 | ~Inst(); |
| 120 | 121 | ||
| 121 | Inst& operator=(const Inst&) = delete; | 122 | Inst& operator=(const Inst&) = delete; |
| 122 | Inst(const Inst&) = delete; | ||
| 123 | 123 | ||
| 124 | Inst& operator=(Inst&&) = delete; | 124 | Inst& operator=(Inst&&) = delete; |
| 125 | Inst(Inst&&) = delete; | 125 | Inst(Inst&&) = delete; |