summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-07-25 22:20:56 -0300
committerGravatar Fernando Sahmkow2021-11-16 22:11:28 +0100
commit01379c5e3cd1181c7c7d37a672364fbcad627fb0 (patch)
tree9dfc52e3e4793f24cdc1d0c1d071f21605cb2bac
parentshader: Add IsTextureScaled opcode (diff)
downloadyuzu-01379c5e3cd1181c7c7d37a672364fbcad627fb0.tar.gz
yuzu-01379c5e3cd1181c7c7d37a672364fbcad627fb0.tar.xz
yuzu-01379c5e3cd1181c7c7d37a672364fbcad627fb0.zip
shader/rescaling_pass: Patch more instructions
-rw-r--r--src/shader_recompiler/ir_opt/rescaling_pass.cpp105
1 files changed, 101 insertions, 4 deletions
diff --git a/src/shader_recompiler/ir_opt/rescaling_pass.cpp b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
index f8d04b6e3..d5b98ae6e 100644
--- a/src/shader_recompiler/ir_opt/rescaling_pass.cpp
+++ b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
@@ -22,6 +22,105 @@ void PatchFragCoord(IR::Block& block, IR::Inst& inst) {
22 inst.ReplaceUsesWith(downscaled_frag_coord); 22 inst.ReplaceUsesWith(downscaled_frag_coord);
23} 23}
24 24
25[[nodiscard]] IR::U32 Scale(IR::IREmitter& ir, const IR::U1& is_scaled, const IR::U32& value) {
26 IR::U32 scaled_value{value};
27 bool changed{};
28 if (const u32 up_scale = Settings::values.resolution_info.up_scale; up_scale != 1) {
29 scaled_value = ir.IMul(value, ir.Imm32(up_scale));
30 changed = true;
31 }
32 if (const u32 down_shift = Settings::values.resolution_info.down_shift; down_shift != 0) {
33 scaled_value = ir.ShiftRightArithmetic(value, ir.Imm32(down_shift));
34 changed = true;
35 }
36 if (changed) {
37 return IR::U32{ir.Select(is_scaled, scaled_value, value)};
38 } else {
39 return value;
40 }
41}
42
43[[nodiscard]] IR::U32 DownScale(IR::IREmitter& ir, IR::U32 value) {
44 if (const u32 down_shift = Settings::values.resolution_info.down_shift; down_shift != 0) {
45 value = ir.ShiftLeftLogical(value, ir.Imm32(down_shift));
46 }
47 if (const u32 up_scale = Settings::values.resolution_info.up_scale; up_scale != 1) {
48 value = ir.IDiv(value, ir.Imm32(up_scale));
49 }
50 return value;
51}
52
53void PatchImageQueryDimensions(IR::Block& block, IR::Inst& inst) {
54 const auto it{IR::Block::InstructionList::s_iterator_to(inst)};
55 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
56 const auto info{inst.Flags<IR::TextureInstInfo>()};
57 switch (info.type) {
58 case TextureType::Color1D:
59 case TextureType::ColorArray1D: {
60 const IR::Value new_inst{&*block.PrependNewInst(it, inst)};
61 const IR::U32 width{DownScale(ir, IR::U32{ir.CompositeExtract(new_inst, 0)})};
62 const IR::Value replacement{ir.CompositeConstruct(width, ir.CompositeExtract(new_inst, 1),
63 ir.CompositeExtract(new_inst, 2),
64 ir.CompositeExtract(new_inst, 3))};
65 inst.ReplaceUsesWith(replacement);
66 break;
67 }
68 case TextureType::Color2D:
69 case TextureType::ColorArray2D: {
70 const IR::Value new_inst{&*block.PrependNewInst(it, inst)};
71 const IR::U32 width{DownScale(ir, IR::U32{ir.CompositeExtract(new_inst, 0)})};
72 const IR::U32 height{DownScale(ir, IR::U32{ir.CompositeExtract(new_inst, 1)})};
73 const IR::Value replacement{ir.CompositeConstruct(
74 width, height, ir.CompositeExtract(new_inst, 2), ir.CompositeExtract(new_inst, 3))};
75 inst.ReplaceUsesWith(replacement);
76 break;
77 }
78 case TextureType::Color3D:
79 case TextureType::ColorCube:
80 case TextureType::ColorArrayCube:
81 case TextureType::Buffer:
82 // Nothing to patch here
83 break;
84 }
85}
86
87void PatchImageFetch(IR::Block& block, IR::Inst& inst) {
88 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
89 const auto info{inst.Flags<IR::TextureInstInfo>()};
90 const IR::U1 is_scaled{ir.IsTextureScaled(ir.Imm32(info.descriptor_index))};
91 const IR::Value coord{inst.Arg(1)};
92 switch (info.type) {
93 case TextureType::Color1D:
94 inst.SetArg(1, Scale(ir, is_scaled, IR::U32{coord}));
95 break;
96 case TextureType::ColorArray1D: {
97 const IR::U32 x{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 0)})};
98 const IR::U32 y{ir.CompositeExtract(coord, 1)};
99 inst.SetArg(1, ir.CompositeConstruct(x, y));
100 break;
101 }
102 case TextureType::Color2D: {
103 const IR::U32 x{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 0)})};
104 const IR::U32 y{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 1)})};
105 inst.SetArg(1, ir.CompositeConstruct(x, y));
106 break;
107 }
108 case TextureType::ColorArray2D: {
109 const IR::U32 x{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 0)})};
110 const IR::U32 y{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 1)})};
111 const IR::U32 z{ir.CompositeExtract(coord, 2)};
112 inst.SetArg(1, ir.CompositeConstruct(x, y, z));
113 break;
114 }
115 case TextureType::Color3D:
116 case TextureType::ColorCube:
117 case TextureType::ColorArrayCube:
118 case TextureType::Buffer:
119 // Nothing to patch here
120 break;
121 }
122}
123
25void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) { 124void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) {
26 const bool is_fragment_shader{program.stage == Stage::Fragment}; 125 const bool is_fragment_shader{program.stage == Stage::Fragment};
27 switch (inst.GetOpcode()) { 126 switch (inst.GetOpcode()) {
@@ -40,12 +139,10 @@ void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) {
40 break; 139 break;
41 } 140 }
42 case IR::Opcode::ImageQueryDimensions: 141 case IR::Opcode::ImageQueryDimensions:
142 PatchImageQueryDimensions(block, inst);
43 break; 143 break;
44 case IR::Opcode::ImageFetch: 144 case IR::Opcode::ImageFetch:
45 break; 145 PatchImageFetch(block, inst);
46 case IR::Opcode::ImageRead:
47 break;
48 case IR::Opcode::ImageWrite:
49 break; 146 break;
50 default: 147 default:
51 break; 148 break;