2021-07-18 23:06:12 +02:00
|
|
|
// Copyright 2021 yuzu Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#include "common/alignment.h"
|
2021-07-22 03:25:34 +02:00
|
|
|
#include "common/settings.h"
|
2021-07-18 23:06:12 +02:00
|
|
|
#include "shader_recompiler/environment.h"
|
2021-07-22 03:25:34 +02:00
|
|
|
#include "shader_recompiler/frontend/ir/ir_emitter.h"
|
2021-07-18 23:06:12 +02:00
|
|
|
#include "shader_recompiler/frontend/ir/modifiers.h"
|
|
|
|
#include "shader_recompiler/frontend/ir/program.h"
|
|
|
|
#include "shader_recompiler/frontend/ir/value.h"
|
|
|
|
#include "shader_recompiler/ir_opt/passes.h"
|
|
|
|
#include "shader_recompiler/shader_info.h"
|
|
|
|
|
|
|
|
namespace Shader::Optimization {
|
|
|
|
namespace {
|
2021-07-22 03:25:34 +02:00
|
|
|
void PatchFragCoord(IR::Block& block, IR::Inst& inst) {
|
2021-07-18 23:06:12 +02:00
|
|
|
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
|
2021-07-22 03:25:34 +02:00
|
|
|
const IR::F32 down_factor{ir.ResolutionDownFactor()};
|
2021-07-22 09:29:00 +02:00
|
|
|
const IR::F32 frag_coord{ir.GetAttribute(inst.Arg(0).Attribute())};
|
2021-07-22 03:25:34 +02:00
|
|
|
const IR::F32 downscaled_frag_coord{ir.FPMul(frag_coord, down_factor)};
|
|
|
|
inst.ReplaceUsesWith(downscaled_frag_coord);
|
2021-07-18 23:06:12 +02:00
|
|
|
}
|
|
|
|
|
2021-07-22 03:25:34 +02:00
|
|
|
void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) {
|
|
|
|
const bool is_fragment_shader{program.stage == Stage::Fragment};
|
2021-07-18 23:06:12 +02:00
|
|
|
switch (inst.GetOpcode()) {
|
|
|
|
case IR::Opcode::GetAttribute: {
|
2021-07-22 03:25:34 +02:00
|
|
|
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;
|
2021-07-18 23:06:12 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2021-07-22 03:25:34 +02:00
|
|
|
case IR::Opcode::ImageQueryDimensions:
|
2021-07-18 23:06:12 +02:00
|
|
|
break;
|
2021-07-22 03:25:34 +02:00
|
|
|
case IR::Opcode::ImageFetch:
|
2021-07-18 23:06:12 +02:00
|
|
|
break;
|
2021-07-22 03:25:34 +02:00
|
|
|
case IR::Opcode::ImageRead:
|
2021-07-18 23:06:12 +02:00
|
|
|
break;
|
2021-07-22 03:25:34 +02:00
|
|
|
case IR::Opcode::ImageWrite:
|
2021-07-18 23:06:12 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-07-22 03:25:34 +02:00
|
|
|
} // Anonymous namespace
|
2021-07-18 23:06:12 +02:00
|
|
|
|
2021-07-22 03:25:34 +02:00
|
|
|
void RescalingPass(IR::Program& program) {
|
2021-07-18 23:06:12 +02:00
|
|
|
for (IR::Block* const block : program.post_order_blocks) {
|
|
|
|
for (IR::Inst& inst : block->Instructions()) {
|
2021-07-22 03:25:34 +02:00
|
|
|
Visit(program, *block, inst);
|
2021-07-18 23:06:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Shader::Optimization
|