summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/ir_opt/rescaling_pass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/ir_opt/rescaling_pass.cpp')
-rw-r--r--src/shader_recompiler/ir_opt/rescaling_pass.cpp60
1 files changed, 26 insertions, 34 deletions
diff --git a/src/shader_recompiler/ir_opt/rescaling_pass.cpp b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
index d3ae3f159..293593c78 100644
--- a/src/shader_recompiler/ir_opt/rescaling_pass.cpp
+++ b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
@@ -3,7 +3,9 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/alignment.h" 5#include "common/alignment.h"
6#include "common/settings.h"
6#include "shader_recompiler/environment.h" 7#include "shader_recompiler/environment.h"
8#include "shader_recompiler/frontend/ir/ir_emitter.h"
7#include "shader_recompiler/frontend/ir/modifiers.h" 9#include "shader_recompiler/frontend/ir/modifiers.h"
8#include "shader_recompiler/frontend/ir/program.h" 10#include "shader_recompiler/frontend/ir/program.h"
9#include "shader_recompiler/frontend/ir/value.h" 11#include "shader_recompiler/frontend/ir/value.h"
@@ -12,59 +14,49 @@
12 14
13namespace Shader::Optimization { 15namespace Shader::Optimization {
14namespace { 16namespace {
15 17void PatchFragCoord(IR::Block& block, IR::Inst& inst) {
16void PatchFragCoord(IR::Inst& inst) {
17 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; 18 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
18 const IR::F32 inv_resolution_factor = IR::F32{Settings::values.resolution_info.down_factor}; 19 const IR::F32 down_factor{ir.ResolutionDownFactor()};
19 const IR::F32 new_get_attribute = ir.GetAttribute(inst.Arg(0).Attribute()); 20 const IR::F32 frag_coord{&inst};
20 const IR::F32 mul = ir.FMul(new_get_attribute, inv_resolution_factor); 21 const IR::F32 downscaled_frag_coord{ir.FPMul(frag_coord, down_factor)};
21 const IR::U1 should_rescale = IR::U1{true}; 22 inst.ReplaceUsesWith(downscaled_frag_coord);
22 const IR::F32 selection = ir.Select(should_rescale, mul, new_get_attribute);
23 inst.ReplaceUsesWith(selection);
24} 23}
25 24
26void Visit(Info& info, IR::Inst& inst) { 25void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) {
27 info.requires_rescaling_uniform = false; 26 const bool is_fragment_shader{program.stage == Stage::Fragment};
28 switch (inst.GetOpcode()) { 27 switch (inst.GetOpcode()) {
29 case IR::Opcode::GetAttribute: { 28 case IR::Opcode::GetAttribute: {
30 conast auto attrib = inst.Arg(0).Attribute(); 29 const IR::Attribute attr{inst.Arg(0).Attribute()};
31 const bool is_frag = 30 switch (attr) {
32 attrib == IR::Attribute::PositionX || attrib == IR::Attribute::PositionY; 31 case IR::Attribute::PositionX:
33 const bool must_path = is_frag && program.stage == Stage::Fragment; 32 case IR::Attribute::PositionY:
34 if (must_path) { 33 if (is_fragment_shader) {
35 PatchFragCoord(inst); 34 PatchFragCoord(block, inst);
36 info.requires_rescaling_uniform = true; 35 }
36 break;
37 default:
38 break;
37 } 39 }
38 break; 40 break;
39 } 41 }
40 case IR::Opcode::ImageQueryDimensions: { 42 case IR::Opcode::ImageQueryDimensions:
41 info.requires_rescaling_uniform |= true;
42 break; 43 break;
43 } 44 case IR::Opcode::ImageFetch:
44 case IR::Opcode::ImageFetch: {
45 info.requires_rescaling_uniform |= true;
46 break; 45 break;
47 } 46 case IR::Opcode::ImageRead:
48 case IR::Opcode::ImageRead: {
49 info.requires_rescaling_uniform |= true;
50 break; 47 break;
51 } 48 case IR::Opcode::ImageWrite:
52 case IR::Opcode::ImageWrite: {
53 info.requires_rescaling_uniform |= true;
54 break; 49 break;
55 }
56 default: 50 default:
57 break; 51 break;
58 } 52 }
59} 53}
54} // Anonymous namespace
60 55
61} // namespace 56void RescalingPass(IR::Program& program) {
62
63void RescalingPass(Environment& env, IR::Program& program) {
64 Info& info{program.info};
65 for (IR::Block* const block : program.post_order_blocks) { 57 for (IR::Block* const block : program.post_order_blocks) {
66 for (IR::Inst& inst : block->Instructions()) { 58 for (IR::Inst& inst : block->Instructions()) {
67 Visit(info, inst); 59 Visit(program, *block, inst);
68 } 60 }
69 } 61 }
70} 62}