From 1672e9ba092f6bc268ece7619c4bae793c00c580 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 21 Jul 2021 22:25:34 -0300 Subject: [PATCH] shader: Fix resolution scaling pass --- src/shader_recompiler/CMakeLists.txt | 1 + .../ir_opt/collect_shader_info_pass.cpp | 3 + src/shader_recompiler/ir_opt/passes.h | 1 + .../ir_opt/rescaling_pass.cpp | 60 ++++++++----------- src/shader_recompiler/shader_info.h | 2 +- 5 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index b5b7e5e83..bc3df80c8 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt @@ -221,6 +221,7 @@ add_library(shader_recompiler STATIC ir_opt/lower_fp16_to_fp32.cpp ir_opt/lower_int64_to_int32.cpp ir_opt/passes.h + ir_opt/rescaling_pass.cpp ir_opt/ssa_rewrite_pass.cpp ir_opt/texture_pass.cpp ir_opt/verification_pass.cpp diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp index f69e1c9cc..ef918f4d4 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp @@ -430,6 +430,9 @@ void VisitUsages(Info& info, IR::Inst& inst) { case IR::Opcode::IsHelperInvocation: info.uses_is_helper_invocation = true; break; + case IR::Opcode::ResolutionDownFactor: + info.uses_rescaling_uniform = true; + break; case IR::Opcode::LaneId: info.uses_subgroup_invocation_id = true; break; diff --git a/src/shader_recompiler/ir_opt/passes.h b/src/shader_recompiler/ir_opt/passes.h index 2f89b1ea0..f877c7ba0 100644 --- a/src/shader_recompiler/ir_opt/passes.h +++ b/src/shader_recompiler/ir_opt/passes.h @@ -19,6 +19,7 @@ void GlobalMemoryToStorageBufferPass(IR::Program& program); void IdentityRemovalPass(IR::Program& program); void LowerFp16ToFp32(IR::Program& program); void LowerInt64ToInt32(IR::Program& program); +void RescalingPass(IR::Program& program); void SsaRewritePass(IR::Program& program); void TexturePass(Environment& env, IR::Program& program); void VerificationPass(const IR::Program& program); diff --git a/src/shader_recompiler/ir_opt/rescaling_pass.cpp b/src/shader_recompiler/ir_opt/rescaling_pass.cpp index d3ae3f159..293593c78 100644 --- a/src/shader_recompiler/ir_opt/rescaling_pass.cpp +++ b/src/shader_recompiler/ir_opt/rescaling_pass.cpp @@ -3,7 +3,9 @@ // Refer to the license.txt file included. #include "common/alignment.h" +#include "common/settings.h" #include "shader_recompiler/environment.h" +#include "shader_recompiler/frontend/ir/ir_emitter.h" #include "shader_recompiler/frontend/ir/modifiers.h" #include "shader_recompiler/frontend/ir/program.h" #include "shader_recompiler/frontend/ir/value.h" @@ -12,59 +14,49 @@ namespace Shader::Optimization { namespace { - -void PatchFragCoord(IR::Inst& inst) { +void PatchFragCoord(IR::Block& block, IR::Inst& inst) { IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; - const IR::F32 inv_resolution_factor = IR::F32{Settings::values.resolution_info.down_factor}; - const IR::F32 new_get_attribute = ir.GetAttribute(inst.Arg(0).Attribute()); - const IR::F32 mul = ir.FMul(new_get_attribute, inv_resolution_factor); - const IR::U1 should_rescale = IR::U1{true}; - const IR::F32 selection = ir.Select(should_rescale, mul, new_get_attribute); - inst.ReplaceUsesWith(selection); + const IR::F32 down_factor{ir.ResolutionDownFactor()}; + const IR::F32 frag_coord{&inst}; + const IR::F32 downscaled_frag_coord{ir.FPMul(frag_coord, down_factor)}; + inst.ReplaceUsesWith(downscaled_frag_coord); } -void Visit(Info& info, IR::Inst& inst) { - info.requires_rescaling_uniform = false; +void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) { + const bool is_fragment_shader{program.stage == Stage::Fragment}; switch (inst.GetOpcode()) { case IR::Opcode::GetAttribute: { - conast auto attrib = inst.Arg(0).Attribute(); - const bool is_frag = - attrib == IR::Attribute::PositionX || attrib == IR::Attribute::PositionY; - const bool must_path = is_frag && program.stage == Stage::Fragment; - if (must_path) { - PatchFragCoord(inst); - info.requires_rescaling_uniform = true; + const IR::Attribute attr{inst.Arg(0).Attribute()}; + switch (attr) { + case IR::Attribute::PositionX: + case IR::Attribute::PositionY: + if (is_fragment_shader) { + PatchFragCoord(block, inst); + } + break; + default: + break; } break; } - case IR::Opcode::ImageQueryDimensions: { - info.requires_rescaling_uniform |= true; + case IR::Opcode::ImageQueryDimensions: break; - } - case IR::Opcode::ImageFetch: { - info.requires_rescaling_uniform |= true; + case IR::Opcode::ImageFetch: break; - } - case IR::Opcode::ImageRead: { - info.requires_rescaling_uniform |= true; + case IR::Opcode::ImageRead: break; - } - case IR::Opcode::ImageWrite: { - info.requires_rescaling_uniform |= true; + case IR::Opcode::ImageWrite: break; - } default: break; } } +} // Anonymous namespace -} // namespace - -void RescalingPass(Environment& env, IR::Program& program) { - Info& info{program.info}; +void RescalingPass(IR::Program& program) { for (IR::Block* const block : program.post_order_blocks) { for (IR::Inst& inst : block->Instructions()) { - Visit(info, inst); + Visit(program, *block, inst); } } } diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h index e7981a08c..7bac9e2cd 100644 --- a/src/shader_recompiler/shader_info.h +++ b/src/shader_recompiler/shader_info.h @@ -172,7 +172,7 @@ struct Info { bool uses_global_memory{}; bool uses_atomic_image_u32{}; bool uses_shadow_lod{}; - bool requires_rescaling_uniform{}; + bool uses_rescaling_uniform{}; IR::Type used_constant_buffer_types{}; IR::Type used_storage_buffer_types{};