summaryrefslogtreecommitdiff
path: root/src/shader_recompiler
diff options
context:
space:
mode:
authorGravatar ameerj2021-09-28 21:29:17 -0400
committerGravatar Fernando Sahmkow2021-11-16 22:11:30 +0100
commit276565973f373b2dbf7f19a68a6d0304803dc2c3 (patch)
treeb9e37f425e3768fed4c45ad8c26a58e7e40948b9 /src/shader_recompiler
parentrescaling_pass: Enable PatchImageQueryDimensions on fragment stages (diff)
downloadyuzu-276565973f373b2dbf7f19a68a6d0304803dc2c3.tar.gz
yuzu-276565973f373b2dbf7f19a68a6d0304803dc2c3.tar.xz
yuzu-276565973f373b2dbf7f19a68a6d0304803dc2c3.zip
rescaling_pass: Scale ImageFetch offset if it exists
Plus some code deduplication
Diffstat (limited to 'src/shader_recompiler')
-rw-r--r--src/shader_recompiler/ir_opt/rescaling_pass.cpp96
1 files changed, 37 insertions, 59 deletions
diff --git a/src/shader_recompiler/ir_opt/rescaling_pass.cpp b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
index 51125f45a..2aa9c31dc 100644
--- a/src/shader_recompiler/ir_opt/rescaling_pass.cpp
+++ b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
@@ -137,21 +137,22 @@ void PatchImageQueryDimensions(IR::Block& block, IR::Inst& inst) {
137 } 137 }
138} 138}
139 139
140void ScaleIntegerCoord(IR::IREmitter& ir, IR::Inst& inst, const IR::U1& is_scaled) { 140void ScaleIntegerComposite(IR::IREmitter& ir, IR::Inst& inst, const IR::U1& is_scaled,
141 size_t index) {
142 const IR::Value composite{inst.Arg(index)};
143 if (composite.IsEmpty()) {
144 return;
145 }
141 const auto info{inst.Flags<IR::TextureInstInfo>()}; 146 const auto info{inst.Flags<IR::TextureInstInfo>()};
142 const IR::Value coord{inst.Arg(1)}; 147 const IR::U32 x{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(composite, 0)})};
148 const IR::U32 y{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(composite, 1)})};
143 switch (info.type) { 149 switch (info.type) {
144 case TextureType::Color2D: { 150 case TextureType::Color2D:
145 const IR::U32 x{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 0)})}; 151 inst.SetArg(index, ir.CompositeConstruct(x, y));
146 const IR::U32 y{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 1)})};
147 inst.SetArg(1, ir.CompositeConstruct(x, y));
148 break; 152 break;
149 }
150 case TextureType::ColorArray2D: { 153 case TextureType::ColorArray2D: {
151 const IR::U32 x{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 0)})}; 154 const IR::U32 z{ir.CompositeExtract(composite, 2)};
152 const IR::U32 y{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 1)})}; 155 inst.SetArg(index, ir.CompositeConstruct(x, y, z));
153 const IR::U32 z{ir.CompositeExtract(coord, 2)};
154 inst.SetArg(1, ir.CompositeConstruct(x, y, z));
155 break; 156 break;
156 } 157 }
157 case TextureType::Color1D: 158 case TextureType::Color1D:
@@ -165,27 +166,21 @@ void ScaleIntegerCoord(IR::IREmitter& ir, IR::Inst& inst, const IR::U1& is_scale
165 } 166 }
166} 167}
167 168
168void SubScaleImageFetch(IR::Block& block, IR::Inst& inst) { 169void SubScaleCoord(IR::IREmitter& ir, IR::Inst& inst, const IR::U1& is_scaled) {
169 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
170 const auto info{inst.Flags<IR::TextureInstInfo>()}; 170 const auto info{inst.Flags<IR::TextureInstInfo>()};
171 const IR::U1 is_scaled{ir.IsTextureScaled(ir.Imm32(info.descriptor_index))};
172 const IR::Value coord{inst.Arg(1)}; 171 const IR::Value coord{inst.Arg(1)};
172 const IR::U32 coord_x{ir.CompositeExtract(coord, 0)};
173 const IR::U32 coord_y{ir.CompositeExtract(coord, 1)};
174
175 const IR::U32 scaled_x{SubScale(ir, is_scaled, coord_x, IR::Attribute::PositionX)};
176 const IR::U32 scaled_y{SubScale(ir, is_scaled, coord_y, IR::Attribute::PositionY)};
173 switch (info.type) { 177 switch (info.type) {
174 case TextureType::Color2D: { 178 case TextureType::Color2D:
175 const IR::U32 x{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 0)}, 179 inst.SetArg(1, ir.CompositeConstruct(scaled_x, scaled_y));
176 IR::Attribute::PositionX)};
177 const IR::U32 y{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 1)},
178 IR::Attribute::PositionY)};
179 inst.SetArg(1, ir.CompositeConstruct(x, y));
180 break; 180 break;
181 }
182 case TextureType::ColorArray2D: { 181 case TextureType::ColorArray2D: {
183 const IR::U32 x{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 0)},
184 IR::Attribute::PositionX)};
185 const IR::U32 y{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 1)},
186 IR::Attribute::PositionY)};
187 const IR::U32 z{ir.CompositeExtract(coord, 2)}; 182 const IR::U32 z{ir.CompositeExtract(coord, 2)};
188 inst.SetArg(1, ir.CompositeConstruct(x, y, z)); 183 inst.SetArg(1, ir.CompositeConstruct(scaled_x, scaled_y, z));
189 break; 184 break;
190 } 185 }
191 case TextureType::Color1D: 186 case TextureType::Color1D:
@@ -199,57 +194,40 @@ void SubScaleImageFetch(IR::Block& block, IR::Inst& inst) {
199 } 194 }
200} 195}
201 196
197void SubScaleImageFetch(IR::Block& block, IR::Inst& inst) {
198 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
199 const auto info{inst.Flags<IR::TextureInstInfo>()};
200 const IR::U1 is_scaled{ir.IsTextureScaled(ir.Imm32(info.descriptor_index))};
201 SubScaleCoord(ir, inst, is_scaled);
202 // Scale ImageFetch offset
203 ScaleIntegerComposite(ir, inst, is_scaled, 2);
204}
205
202void SubScaleImageRead(IR::Block& block, IR::Inst& inst) { 206void SubScaleImageRead(IR::Block& block, IR::Inst& inst) {
203 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; 207 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
204 const auto info{inst.Flags<IR::TextureInstInfo>()}; 208 const auto info{inst.Flags<IR::TextureInstInfo>()};
205 const IR::U1 is_scaled{ir.IsImageScaled(ir.Imm32(info.descriptor_index))}; 209 const IR::U1 is_scaled{ir.IsImageScaled(ir.Imm32(info.descriptor_index))};
206 const IR::Value coord{inst.Arg(1)}; 210 SubScaleCoord(ir, inst, is_scaled);
207 switch (info.type) {
208 case TextureType::Color2D: {
209 const IR::U32 x{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 0)},
210 IR::Attribute::PositionX)};
211 const IR::U32 y{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 1)},
212 IR::Attribute::PositionY)};
213 inst.SetArg(1, ir.CompositeConstruct(x, y));
214 break;
215 }
216 case TextureType::ColorArray2D: {
217 const IR::U32 x{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 0)},
218 IR::Attribute::PositionX)};
219 const IR::U32 y{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 1)},
220 IR::Attribute::PositionY)};
221 const IR::U32 z{ir.CompositeExtract(coord, 2)};
222 inst.SetArg(1, ir.CompositeConstruct(x, y, z));
223 break;
224 }
225 case TextureType::Color1D:
226 case TextureType::ColorArray1D:
227 case TextureType::Color3D:
228 case TextureType::ColorCube:
229 case TextureType::ColorArrayCube:
230 case TextureType::Buffer:
231 // Nothing to patch here
232 break;
233 }
234} 211}
235 212
236void PatchImageFetch(IR::Block& block, IR::Inst& inst) { 213void PatchImageFetch(IR::Block& block, IR::Inst& inst) {
237 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; 214 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
238 const auto info{inst.Flags<IR::TextureInstInfo>()}; 215 const auto info{inst.Flags<IR::TextureInstInfo>()};
239 const IR::U1 is_scaled{ir.IsTextureScaled(ir.Imm32(info.descriptor_index))}; 216 const IR::U1 is_scaled{ir.IsTextureScaled(ir.Imm32(info.descriptor_index))};
240 ScaleIntegerCoord(ir, inst, is_scaled); 217 ScaleIntegerComposite(ir, inst, is_scaled, 1);
218 // Scale ImageFetch offset
219 ScaleIntegerComposite(ir, inst, is_scaled, 2);
241} 220}
242 221
243void PatchImageRead(IR::Block& block, IR::Inst& inst) { 222void PatchImageRead(IR::Block& block, IR::Inst& inst) {
244 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; 223 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
245 const auto info{inst.Flags<IR::TextureInstInfo>()}; 224 const auto info{inst.Flags<IR::TextureInstInfo>()};
246 const IR::U1 is_scaled{ir.IsImageScaled(ir.Imm32(info.descriptor_index))}; 225 const IR::U1 is_scaled{ir.IsImageScaled(ir.Imm32(info.descriptor_index))};
247 ScaleIntegerCoord(ir, inst, is_scaled); 226 ScaleIntegerComposite(ir, inst, is_scaled, 1);
248} 227}
249 228
250void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) { 229void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) {
251 const bool is_fragment_shader{program.stage == Stage::Fragment}; 230 const bool is_fragment_shader{program.stage == Stage::Fragment};
252 const bool is_compute_shader{program.stage == Stage::Compute};
253 switch (inst.GetOpcode()) { 231 switch (inst.GetOpcode()) {
254 case IR::Opcode::GetAttribute: { 232 case IR::Opcode::GetAttribute: {
255 const IR::Attribute attr{inst.Arg(0).Attribute()}; 233 const IR::Attribute attr{inst.Arg(0).Attribute()};
@@ -271,14 +249,14 @@ void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) {
271 case IR::Opcode::ImageFetch: 249 case IR::Opcode::ImageFetch:
272 if (is_fragment_shader) { 250 if (is_fragment_shader) {
273 SubScaleImageFetch(block, inst); 251 SubScaleImageFetch(block, inst);
274 } else if (is_compute_shader) { 252 } else {
275 PatchImageFetch(block, inst); 253 PatchImageFetch(block, inst);
276 } 254 }
277 break; 255 break;
278 case IR::Opcode::ImageRead: 256 case IR::Opcode::ImageRead:
279 if (is_fragment_shader) { 257 if (is_fragment_shader) {
280 SubScaleImageRead(block, inst); 258 SubScaleImageRead(block, inst);
281 } else if (is_compute_shader) { 259 } else {
282 PatchImageRead(block, inst); 260 PatchImageRead(block, inst);
283 } 261 }
284 break; 262 break;