summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend')
-rw-r--r--src/shader_recompiler/frontend/ir/basic_block.cpp5
-rw-r--r--src/shader_recompiler/frontend/ir/basic_block.h3
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp16
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h7
-rw-r--r--src/shader_recompiler/frontend/ir/microinstruction.cpp11
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc6
-rw-r--r--src/shader_recompiler/frontend/ir/value.h2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate_program.cpp4
8 files changed, 53 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
25Block::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
25Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode op, 30Block::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
378F32 IREmitter::ResolutionDownFactor() {
379 return Inst<F32>(Opcode::ResolutionDownFactor);
380}
381
378U32 IREmitter::LaneId() { 382U32 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
1148U32 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
1144U32U64 IREmitter::INeg(const U32U64& value) { 1152U32U64 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
1949U1 IREmitter::IsTextureScaled(const U32& index) {
1950 return Inst<U1>(Opcode::IsTextureScaled, index);
1951}
1952
1953U1 IREmitter::IsImageScaled(const U32& index) {
1954 return Inst<U1>(Opcode::IsImageScaled, index);
1955}
1956
1941U1 IREmitter::VoteAll(const U1& value) { 1957U1 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
50Inst::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
50Inst::~Inst() { 61Inst::~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,
62OPCODE(SampleId, U32, ) 62OPCODE(SampleId, U32, )
63OPCODE(IsHelperInvocation, U1, ) 63OPCODE(IsHelperInvocation, U1, )
64OPCODE(YDirection, F32, ) 64OPCODE(YDirection, F32, )
65OPCODE(ResolutionDownFactor, F32, )
65 66
66// Undefined 67// Undefined
67OPCODE(UndefU1, U1, ) 68OPCODE(UndefU1, U1, )
@@ -286,6 +287,8 @@ OPCODE(IAdd64, U64, U64,
286OPCODE(ISub32, U32, U32, U32, ) 287OPCODE(ISub32, U32, U32, U32, )
287OPCODE(ISub64, U64, U64, U64, ) 288OPCODE(ISub64, U64, U64, U64, )
288OPCODE(IMul32, U32, U32, U32, ) 289OPCODE(IMul32, U32, U32, U32, )
290OPCODE(SDiv32, U32, U32, U32, )
291OPCODE(UDiv32, U32, U32, U32, )
289OPCODE(INeg32, U32, U32, ) 292OPCODE(INeg32, U32, U32, )
290OPCODE(INeg64, U64, U64, ) 293OPCODE(INeg64, U64, U64, )
291OPCODE(IAbs32, U32, U32, ) 294OPCODE(IAbs32, U32, U32, )
@@ -490,6 +493,9 @@ OPCODE(ImageGradient, F32x4, Opaq
490OPCODE(ImageRead, U32x4, Opaque, Opaque, ) 493OPCODE(ImageRead, U32x4, Opaque, Opaque, )
491OPCODE(ImageWrite, Void, Opaque, Opaque, U32x4, ) 494OPCODE(ImageWrite, Void, Opaque, Opaque, U32x4, )
492 495
496OPCODE(IsTextureScaled, U1, U32, )
497OPCODE(IsImageScaled, U1, U32, )
498
493// Atomic Image operations 499// Atomic Image operations
494 500
495OPCODE(BindlessImageAtomicIAdd32, U32, U32, Opaque, U32, ) 501OPCODE(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:
116class Inst : public boost::intrusive::list_base_hook<> { 116class Inst : public boost::intrusive::list_base_hook<> {
117public: 117public:
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;
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
index 2fc542f0e..267ebe4af 100644
--- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
@@ -179,6 +179,10 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo
179 Optimization::TexturePass(env, program); 179 Optimization::TexturePass(env, program);
180 180
181 Optimization::ConstantPropagationPass(program); 181 Optimization::ConstantPropagationPass(program);
182
183 if (Settings::values.resolution_info.active) {
184 Optimization::RescalingPass(program);
185 }
182 Optimization::DeadCodeEliminationPass(program); 186 Optimization::DeadCodeEliminationPass(program);
183 if (Settings::values.renderer_debug) { 187 if (Settings::values.renderer_debug) {
184 Optimization::VerificationPass(program); 188 Optimization::VerificationPass(program);