2
1
Fork 0
mirror of https://github.com/yuzu-emu/yuzu.git synced 2024-07-04 23:31:19 +01:00

shader: Fix resolution scaling pass

This commit is contained in:
ReinUsesLisp 2021-07-21 22:25:34 -03:00 committed by Fernando Sahmkow
parent fb924ea85c
commit 1672e9ba09
5 changed files with 32 additions and 35 deletions

View file

@ -221,6 +221,7 @@ add_library(shader_recompiler STATIC
ir_opt/lower_fp16_to_fp32.cpp ir_opt/lower_fp16_to_fp32.cpp
ir_opt/lower_int64_to_int32.cpp ir_opt/lower_int64_to_int32.cpp
ir_opt/passes.h ir_opt/passes.h
ir_opt/rescaling_pass.cpp
ir_opt/ssa_rewrite_pass.cpp ir_opt/ssa_rewrite_pass.cpp
ir_opt/texture_pass.cpp ir_opt/texture_pass.cpp
ir_opt/verification_pass.cpp ir_opt/verification_pass.cpp

View file

@ -430,6 +430,9 @@ void VisitUsages(Info& info, IR::Inst& inst) {
case IR::Opcode::IsHelperInvocation: case IR::Opcode::IsHelperInvocation:
info.uses_is_helper_invocation = true; info.uses_is_helper_invocation = true;
break; break;
case IR::Opcode::ResolutionDownFactor:
info.uses_rescaling_uniform = true;
break;
case IR::Opcode::LaneId: case IR::Opcode::LaneId:
info.uses_subgroup_invocation_id = true; info.uses_subgroup_invocation_id = true;
break; break;

View file

@ -19,6 +19,7 @@ void GlobalMemoryToStorageBufferPass(IR::Program& program);
void IdentityRemovalPass(IR::Program& program); void IdentityRemovalPass(IR::Program& program);
void LowerFp16ToFp32(IR::Program& program); void LowerFp16ToFp32(IR::Program& program);
void LowerInt64ToInt32(IR::Program& program); void LowerInt64ToInt32(IR::Program& program);
void RescalingPass(IR::Program& program);
void SsaRewritePass(IR::Program& program); void SsaRewritePass(IR::Program& program);
void TexturePass(Environment& env, IR::Program& program); void TexturePass(Environment& env, IR::Program& program);
void VerificationPass(const IR::Program& program); void VerificationPass(const IR::Program& program);

View file

@ -3,7 +3,9 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "common/alignment.h" #include "common/alignment.h"
#include "common/settings.h"
#include "shader_recompiler/environment.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/modifiers.h"
#include "shader_recompiler/frontend/ir/program.h" #include "shader_recompiler/frontend/ir/program.h"
#include "shader_recompiler/frontend/ir/value.h" #include "shader_recompiler/frontend/ir/value.h"
@ -12,59 +14,49 @@
namespace Shader::Optimization { namespace Shader::Optimization {
namespace { namespace {
void PatchFragCoord(IR::Block& block, IR::Inst& inst) {
void PatchFragCoord(IR::Inst& inst) {
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(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 down_factor{ir.ResolutionDownFactor()};
const IR::F32 new_get_attribute = ir.GetAttribute(inst.Arg(0).Attribute()); const IR::F32 frag_coord{&inst};
const IR::F32 mul = ir.FMul(new_get_attribute, inv_resolution_factor); const IR::F32 downscaled_frag_coord{ir.FPMul(frag_coord, down_factor)};
const IR::U1 should_rescale = IR::U1{true}; inst.ReplaceUsesWith(downscaled_frag_coord);
const IR::F32 selection = ir.Select(should_rescale, mul, new_get_attribute);
inst.ReplaceUsesWith(selection);
} }
void Visit(Info& info, IR::Inst& inst) { void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) {
info.requires_rescaling_uniform = false; const bool is_fragment_shader{program.stage == Stage::Fragment};
switch (inst.GetOpcode()) { switch (inst.GetOpcode()) {
case IR::Opcode::GetAttribute: { case IR::Opcode::GetAttribute: {
conast auto attrib = inst.Arg(0).Attribute(); const IR::Attribute attr{inst.Arg(0).Attribute()};
const bool is_frag = switch (attr) {
attrib == IR::Attribute::PositionX || attrib == IR::Attribute::PositionY; case IR::Attribute::PositionX:
const bool must_path = is_frag && program.stage == Stage::Fragment; case IR::Attribute::PositionY:
if (must_path) { if (is_fragment_shader) {
PatchFragCoord(inst); PatchFragCoord(block, inst);
info.requires_rescaling_uniform = true; }
break;
default:
break;
} }
break; break;
} }
case IR::Opcode::ImageQueryDimensions: { case IR::Opcode::ImageQueryDimensions:
info.requires_rescaling_uniform |= true;
break; break;
} case IR::Opcode::ImageFetch:
case IR::Opcode::ImageFetch: {
info.requires_rescaling_uniform |= true;
break; break;
} case IR::Opcode::ImageRead:
case IR::Opcode::ImageRead: {
info.requires_rescaling_uniform |= true;
break; break;
} case IR::Opcode::ImageWrite:
case IR::Opcode::ImageWrite: {
info.requires_rescaling_uniform |= true;
break; break;
}
default: default:
break; break;
} }
} }
} // Anonymous namespace
} // namespace void RescalingPass(IR::Program& program) {
void RescalingPass(Environment& env, IR::Program& program) {
Info& info{program.info};
for (IR::Block* const block : program.post_order_blocks) { for (IR::Block* const block : program.post_order_blocks) {
for (IR::Inst& inst : block->Instructions()) { for (IR::Inst& inst : block->Instructions()) {
Visit(info, inst); Visit(program, *block, inst);
} }
} }
} }

View file

@ -172,7 +172,7 @@ struct Info {
bool uses_global_memory{}; bool uses_global_memory{};
bool uses_atomic_image_u32{}; bool uses_atomic_image_u32{};
bool uses_shadow_lod{}; bool uses_shadow_lod{};
bool requires_rescaling_uniform{}; bool uses_rescaling_uniform{};
IR::Type used_constant_buffer_types{}; IR::Type used_constant_buffer_types{};
IR::Type used_storage_buffer_types{}; IR::Type used_storage_buffer_types{};