summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/ir_opt/rescaling_pass.cpp15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/shader_recompiler/ir_opt/rescaling_pass.cpp b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
index 81098c038..c28500dd1 100644
--- a/src/shader_recompiler/ir_opt/rescaling_pass.cpp
+++ b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
@@ -30,7 +30,7 @@ namespace {
30 return false; 30 return false;
31} 31}
32 32
33void VisitMark(const IR::Inst& inst) { 33void VisitMark(IR::Block& block, IR::Inst& inst) {
34 switch (inst.GetOpcode()) { 34 switch (inst.GetOpcode()) {
35 case IR::Opcode::ShuffleIndex: 35 case IR::Opcode::ShuffleIndex:
36 case IR::Opcode::ShuffleUp: 36 case IR::Opcode::ShuffleUp:
@@ -49,19 +49,30 @@ void VisitMark(const IR::Inst& inst) {
49 break; 49 break;
50 } 50 }
51 IR::Inst* const bitcast_inst{bitcast_arg.InstRecursive()}; 51 IR::Inst* const bitcast_inst{bitcast_arg.InstRecursive()};
52 bool must_patch_outside = false;
52 if (bitcast_inst->GetOpcode() == IR::Opcode::GetAttribute) { 53 if (bitcast_inst->GetOpcode() == IR::Opcode::GetAttribute) {
53 const IR::Attribute attr{bitcast_inst->Arg(0).Attribute()}; 54 const IR::Attribute attr{bitcast_inst->Arg(0).Attribute()};
54 switch (attr) { 55 switch (attr) {
55 case IR::Attribute::PositionX: 56 case IR::Attribute::PositionX:
56 case IR::Attribute::PositionY: 57 case IR::Attribute::PositionY:
57 bitcast_inst->SetFlags<u32>(0xDEADBEEF); 58 bitcast_inst->SetFlags<u32>(0xDEADBEEF);
59 must_patch_outside = true;
58 break; 60 break;
59 default: 61 default:
60 break; 62 break;
61 } 63 }
62 } 64 }
65 if (must_patch_outside) {
66 const auto it{IR::Block::InstructionList::s_iterator_to(inst)};
67 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
68 const IR::F32 new_inst{&*block.PrependNewInst(it, inst)};
69 const IR::F32 up_factor{ir.FPRecip(ir.ResolutionDownFactor())};
70 const IR::Value converted{ir.FPMul(new_inst, up_factor)};
71 inst.ReplaceUsesWith(converted);
72 }
63 break; 73 break;
64 } 74 }
75
65 default: 76 default:
66 break; 77 break;
67 } 78 }
@@ -302,7 +313,7 @@ void RescalingPass(IR::Program& program) {
302 if (is_fragment_shader) { 313 if (is_fragment_shader) {
303 for (IR::Block* const block : program.post_order_blocks) { 314 for (IR::Block* const block : program.post_order_blocks) {
304 for (IR::Inst& inst : block->Instructions()) { 315 for (IR::Inst& inst : block->Instructions()) {
305 VisitMark(inst); 316 VisitMark(*block, inst);
306 } 317 }
307 } 318 }
308 } 319 }