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.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/shader_recompiler/ir_opt/rescaling_pass.cpp b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
new file mode 100644
index 000000000..d3ae3f159
--- /dev/null
+++ b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
@@ -0,0 +1,72 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/alignment.h"
6#include "shader_recompiler/environment.h"
7#include "shader_recompiler/frontend/ir/modifiers.h"
8#include "shader_recompiler/frontend/ir/program.h"
9#include "shader_recompiler/frontend/ir/value.h"
10#include "shader_recompiler/ir_opt/passes.h"
11#include "shader_recompiler/shader_info.h"
12
13namespace Shader::Optimization {
14namespace {
15
16void PatchFragCoord(IR::Inst& inst) {
17 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 new_get_attribute = ir.GetAttribute(inst.Arg(0).Attribute());
20 const IR::F32 mul = ir.FMul(new_get_attribute, inv_resolution_factor);
21 const IR::U1 should_rescale = IR::U1{true};
22 const IR::F32 selection = ir.Select(should_rescale, mul, new_get_attribute);
23 inst.ReplaceUsesWith(selection);
24}
25
26void Visit(Info& info, IR::Inst& inst) {
27 info.requires_rescaling_uniform = false;
28 switch (inst.GetOpcode()) {
29 case IR::Opcode::GetAttribute: {
30 conast auto attrib = inst.Arg(0).Attribute();
31 const bool is_frag =
32 attrib == IR::Attribute::PositionX || attrib == IR::Attribute::PositionY;
33 const bool must_path = is_frag && program.stage == Stage::Fragment;
34 if (must_path) {
35 PatchFragCoord(inst);
36 info.requires_rescaling_uniform = true;
37 }
38 break;
39 }
40 case IR::Opcode::ImageQueryDimensions: {
41 info.requires_rescaling_uniform |= true;
42 break;
43 }
44 case IR::Opcode::ImageFetch: {
45 info.requires_rescaling_uniform |= true;
46 break;
47 }
48 case IR::Opcode::ImageRead: {
49 info.requires_rescaling_uniform |= true;
50 break;
51 }
52 case IR::Opcode::ImageWrite: {
53 info.requires_rescaling_uniform |= true;
54 break;
55 }
56 default:
57 break;
58 }
59}
60
61} // namespace
62
63void RescalingPass(Environment& env, IR::Program& program) {
64 Info& info{program.info};
65 for (IR::Block* const block : program.post_order_blocks) {
66 for (IR::Inst& inst : block->Instructions()) {
67 Visit(info, inst);
68 }
69 }
70}
71
72} // namespace Shader::Optimization