diff options
| author | 2021-09-28 21:29:17 -0400 | |
|---|---|---|
| committer | 2021-11-16 22:11:30 +0100 | |
| commit | 276565973f373b2dbf7f19a68a6d0304803dc2c3 (patch) | |
| tree | b9e37f425e3768fed4c45ad8c26a58e7e40948b9 /src/shader_recompiler | |
| parent | rescaling_pass: Enable PatchImageQueryDimensions on fragment stages (diff) | |
| download | yuzu-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.cpp | 96 |
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 | ||
| 140 | void ScaleIntegerCoord(IR::IREmitter& ir, IR::Inst& inst, const IR::U1& is_scaled) { | 140 | void 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 | ||
| 168 | void SubScaleImageFetch(IR::Block& block, IR::Inst& inst) { | 169 | void 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 | ||
| 197 | void 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 | |||
| 202 | void SubScaleImageRead(IR::Block& block, IR::Inst& inst) { | 206 | void 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 | ||
| 236 | void PatchImageFetch(IR::Block& block, IR::Inst& inst) { | 213 | void 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 | ||
| 243 | void PatchImageRead(IR::Block& block, IR::Inst& inst) { | 222 | void 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 | ||
| 250 | void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) { | 229 | void 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; |