diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/ir_opt/rescaling_pass.cpp | 15 |
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 | ||
| 33 | void VisitMark(const IR::Inst& inst) { | 33 | void 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 | } |