summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate_program.cpp4
-rw-r--r--src/shader_recompiler/ir_opt/rescaling_pass.cpp53
2 files changed, 55 insertions, 2 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
index 795f5cf08..743fb2420 100644
--- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
@@ -178,10 +178,12 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo
178 Optimization::GlobalMemoryToStorageBufferPass(program); 178 Optimization::GlobalMemoryToStorageBufferPass(program);
179 Optimization::TexturePass(env, program); 179 Optimization::TexturePass(env, program);
180 180
181 Optimization::ConstantPropagationPass(program);
182
181 if (Settings::values.resolution_info.active) { 183 if (Settings::values.resolution_info.active) {
182 Optimization::RescalingPass(program); 184 Optimization::RescalingPass(program);
183 } 185 }
184 Optimization::ConstantPropagationPass(program); 186
185 Optimization::DeadCodeEliminationPass(program); 187 Optimization::DeadCodeEliminationPass(program);
186 if (Settings::values.renderer_debug) { 188 if (Settings::values.renderer_debug) {
187 Optimization::VerificationPass(program); 189 Optimization::VerificationPass(program);
diff --git a/src/shader_recompiler/ir_opt/rescaling_pass.cpp b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
index 71c9d9e6f..4d23b60c8 100644
--- a/src/shader_recompiler/ir_opt/rescaling_pass.cpp
+++ b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
@@ -14,6 +14,52 @@
14 14
15namespace Shader::Optimization { 15namespace Shader::Optimization {
16namespace { 16namespace {
17void VisitMark(const IR::Program& program, IR::Inst& inst) {
18 const bool is_fragment_shader{program.stage == Stage::Fragment};
19 switch (inst.GetOpcode()) {
20 case IR::Opcode::ShuffleIndex:
21 case IR::Opcode::ShuffleUp:
22 case IR::Opcode::ShuffleDown:
23 case IR::Opcode::ShuffleButterfly: {
24 const auto try_mark = [is_fragment_shader](IR::Inst* op) {
25 const IR::Attribute attr{op->Arg(0).Attribute()};
26 switch (attr) {
27 case IR::Attribute::PositionX:
28 case IR::Attribute::PositionY:
29 if (is_fragment_shader) {
30 op->SetFlags<u32>(0xDEADBEEF);
31 }
32 break;
33 default:
34 break;
35 }
36 };
37 const IR::Value param_1{inst.Arg(0)};
38 if (param_1.IsImmediate()) {
39 break;
40 }
41 IR::Inst* op_a{param_1.InstRecursive()};
42 if (op_a->GetOpcode() == IR::Opcode::GetAttribute) {
43 try_mark(op_a);
44 break;
45 }
46 if (op_a->GetOpcode() != IR::Opcode::BitCastF32U32) {
47 break;
48 }
49 const IR::Value param_2{op_a->Arg(0)};
50 if (param_2.IsImmediate()) {
51 break;
52 }
53 IR::Inst* op_b{param_2.InstRecursive()};
54 if (op_b->GetOpcode() == IR::Opcode::GetAttribute) {
55 try_mark(op_b);
56 }
57 break;
58 }
59 default:
60 break;
61 }
62}
17void PatchFragCoord(IR::Block& block, IR::Inst& inst) { 63void PatchFragCoord(IR::Block& block, IR::Inst& inst) {
18 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; 64 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
19 const IR::F32 down_factor{ir.ResolutionDownFactor()}; 65 const IR::F32 down_factor{ir.ResolutionDownFactor()};
@@ -219,7 +265,7 @@ void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) {
219 switch (attr) { 265 switch (attr) {
220 case IR::Attribute::PositionX: 266 case IR::Attribute::PositionX:
221 case IR::Attribute::PositionY: 267 case IR::Attribute::PositionY:
222 if (is_fragment_shader) { 268 if (is_fragment_shader && inst.Flags<u32>() != 0xDEADBEEF) {
223 PatchFragCoord(block, inst); 269 PatchFragCoord(block, inst);
224 } 270 }
225 break; 271 break;
@@ -256,6 +302,11 @@ void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) {
256void RescalingPass(IR::Program& program) { 302void RescalingPass(IR::Program& program) {
257 for (IR::Block* const block : program.post_order_blocks) { 303 for (IR::Block* const block : program.post_order_blocks) {
258 for (IR::Inst& inst : block->Instructions()) { 304 for (IR::Inst& inst : block->Instructions()) {
305 VisitMark(program, inst);
306 }
307 }
308 for (IR::Block* const block : program.post_order_blocks) {
309 for (IR::Inst& inst : block->Instructions()) {
259 Visit(program, *block, inst); 310 Visit(program, *block, inst);
260 } 311 }
261 } 312 }