diff options
| author | 2021-09-18 02:26:33 +0200 | |
|---|---|---|
| committer | 2021-11-16 22:11:30 +0100 | |
| commit | b3a9c8f108d90234c7e5e88b41f8e4bc9c163d96 (patch) | |
| tree | 7bb9f3d8b71d370c5465b0a8a736013290f2acab /src | |
| parent | image_info: Mark MSAA textures as non-rescalable (diff) | |
| download | yuzu-b3a9c8f108d90234c7e5e88b41f8e4bc9c163d96.tar.gz yuzu-b3a9c8f108d90234c7e5e88b41f8e4bc9c163d96.tar.xz yuzu-b3a9c8f108d90234c7e5e88b41f8e4bc9c163d96.zip | |
Shader: Don't rescale FragCoord if used by Shuffle
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate_program.cpp | 4 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/rescaling_pass.cpp | 53 |
2 files changed, 55 insertions, 2 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp index 795f5cf08..743fb2420 100644 --- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp | |||
| @@ -178,10 +178,12 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo | |||
| 178 | Optimization::GlobalMemoryToStorageBufferPass(program); | 178 | Optimization::GlobalMemoryToStorageBufferPass(program); |
| 179 | Optimization::TexturePass(env, program); | 179 | Optimization::TexturePass(env, program); |
| 180 | 180 | ||
| 181 | Optimization::ConstantPropagationPass(program); | ||
| 182 | |||
| 181 | if (Settings::values.resolution_info.active) { | 183 | if (Settings::values.resolution_info.active) { |
| 182 | Optimization::RescalingPass(program); | 184 | Optimization::RescalingPass(program); |
| 183 | } | 185 | } |
| 184 | Optimization::ConstantPropagationPass(program); | 186 | |
| 185 | Optimization::DeadCodeEliminationPass(program); | 187 | Optimization::DeadCodeEliminationPass(program); |
| 186 | if (Settings::values.renderer_debug) { | 188 | if (Settings::values.renderer_debug) { |
| 187 | Optimization::VerificationPass(program); | 189 | Optimization::VerificationPass(program); |
diff --git a/src/shader_recompiler/ir_opt/rescaling_pass.cpp b/src/shader_recompiler/ir_opt/rescaling_pass.cpp index 71c9d9e6f..4d23b60c8 100644 --- a/src/shader_recompiler/ir_opt/rescaling_pass.cpp +++ b/src/shader_recompiler/ir_opt/rescaling_pass.cpp | |||
| @@ -14,6 +14,52 @@ | |||
| 14 | 14 | ||
| 15 | namespace Shader::Optimization { | 15 | namespace Shader::Optimization { |
| 16 | namespace { | 16 | namespace { |
| 17 | void VisitMark(const IR::Program& program, IR::Inst& inst) { | ||
| 18 | const bool is_fragment_shader{program.stage == Stage::Fragment}; | ||
| 19 | switch (inst.GetOpcode()) { | ||
| 20 | case IR::Opcode::ShuffleIndex: | ||
| 21 | case IR::Opcode::ShuffleUp: | ||
| 22 | case IR::Opcode::ShuffleDown: | ||
| 23 | case IR::Opcode::ShuffleButterfly: { | ||
| 24 | const auto try_mark = [is_fragment_shader](IR::Inst* op) { | ||
| 25 | const IR::Attribute attr{op->Arg(0).Attribute()}; | ||
| 26 | switch (attr) { | ||
| 27 | case IR::Attribute::PositionX: | ||
| 28 | case IR::Attribute::PositionY: | ||
| 29 | if (is_fragment_shader) { | ||
| 30 | op->SetFlags<u32>(0xDEADBEEF); | ||
| 31 | } | ||
| 32 | break; | ||
| 33 | default: | ||
| 34 | break; | ||
| 35 | } | ||
| 36 | }; | ||
| 37 | const IR::Value param_1{inst.Arg(0)}; | ||
| 38 | if (param_1.IsImmediate()) { | ||
| 39 | break; | ||
| 40 | } | ||
| 41 | IR::Inst* op_a{param_1.InstRecursive()}; | ||
| 42 | if (op_a->GetOpcode() == IR::Opcode::GetAttribute) { | ||
| 43 | try_mark(op_a); | ||
| 44 | break; | ||
| 45 | } | ||
| 46 | if (op_a->GetOpcode() != IR::Opcode::BitCastF32U32) { | ||
| 47 | break; | ||
| 48 | } | ||
| 49 | const IR::Value param_2{op_a->Arg(0)}; | ||
| 50 | if (param_2.IsImmediate()) { | ||
| 51 | break; | ||
| 52 | } | ||
| 53 | IR::Inst* op_b{param_2.InstRecursive()}; | ||
| 54 | if (op_b->GetOpcode() == IR::Opcode::GetAttribute) { | ||
| 55 | try_mark(op_b); | ||
| 56 | } | ||
| 57 | break; | ||
| 58 | } | ||
| 59 | default: | ||
| 60 | break; | ||
| 61 | } | ||
| 62 | } | ||
| 17 | void PatchFragCoord(IR::Block& block, IR::Inst& inst) { | 63 | void PatchFragCoord(IR::Block& block, IR::Inst& inst) { |
| 18 | IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; | 64 | IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; |
| 19 | const IR::F32 down_factor{ir.ResolutionDownFactor()}; | 65 | const IR::F32 down_factor{ir.ResolutionDownFactor()}; |
| @@ -219,7 +265,7 @@ void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) { | |||
| 219 | switch (attr) { | 265 | switch (attr) { |
| 220 | case IR::Attribute::PositionX: | 266 | case IR::Attribute::PositionX: |
| 221 | case IR::Attribute::PositionY: | 267 | case IR::Attribute::PositionY: |
| 222 | if (is_fragment_shader) { | 268 | if (is_fragment_shader && inst.Flags<u32>() != 0xDEADBEEF) { |
| 223 | PatchFragCoord(block, inst); | 269 | PatchFragCoord(block, inst); |
| 224 | } | 270 | } |
| 225 | break; | 271 | break; |
| @@ -256,6 +302,11 @@ void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) { | |||
| 256 | void RescalingPass(IR::Program& program) { | 302 | void RescalingPass(IR::Program& program) { |
| 257 | for (IR::Block* const block : program.post_order_blocks) { | 303 | for (IR::Block* const block : program.post_order_blocks) { |
| 258 | for (IR::Inst& inst : block->Instructions()) { | 304 | for (IR::Inst& inst : block->Instructions()) { |
| 305 | VisitMark(program, inst); | ||
| 306 | } | ||
| 307 | } | ||
| 308 | for (IR::Block* const block : program.post_order_blocks) { | ||
| 309 | for (IR::Inst& inst : block->Instructions()) { | ||
| 259 | Visit(program, *block, inst); | 310 | Visit(program, *block, inst); |
| 260 | } | 311 | } |
| 261 | } | 312 | } |