summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/ir_opt
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2021-09-18 02:26:33 +0200
committerFernando Sahmkow <fsahmkow27@gmail.com>2021-11-16 22:11:30 +0100
commitb3a9c8f108d90234c7e5e88b41f8e4bc9c163d96 (patch)
tree7bb9f3d8b71d370c5465b0a8a736013290f2acab /src/shader_recompiler/ir_opt
parentimage_info: Mark MSAA textures as non-rescalable (diff)
downloadyuzu-b3a9c8f108d90234c7e5e88b41f8e4bc9c163d96.tar
yuzu-b3a9c8f108d90234c7e5e88b41f8e4bc9c163d96.tar.gz
yuzu-b3a9c8f108d90234c7e5e88b41f8e4bc9c163d96.tar.bz2
yuzu-b3a9c8f108d90234c7e5e88b41f8e4bc9c163d96.tar.lz
yuzu-b3a9c8f108d90234c7e5e88b41f8e4bc9c163d96.tar.xz
yuzu-b3a9c8f108d90234c7e5e88b41f8e4bc9c163d96.tar.zst
yuzu-b3a9c8f108d90234c7e5e88b41f8e4bc9c163d96.zip
Diffstat (limited to 'src/shader_recompiler/ir_opt')
-rw-r--r--src/shader_recompiler/ir_opt/rescaling_pass.cpp53
1 files changed, 52 insertions, 1 deletions
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 @@
namespace Shader::Optimization {
namespace {
+void VisitMark(const IR::Program& program, IR::Inst& inst) {
+ const bool is_fragment_shader{program.stage == Stage::Fragment};
+ switch (inst.GetOpcode()) {
+ case IR::Opcode::ShuffleIndex:
+ case IR::Opcode::ShuffleUp:
+ case IR::Opcode::ShuffleDown:
+ case IR::Opcode::ShuffleButterfly: {
+ const auto try_mark = [is_fragment_shader](IR::Inst* op) {
+ const IR::Attribute attr{op->Arg(0).Attribute()};
+ switch (attr) {
+ case IR::Attribute::PositionX:
+ case IR::Attribute::PositionY:
+ if (is_fragment_shader) {
+ op->SetFlags<u32>(0xDEADBEEF);
+ }
+ break;
+ default:
+ break;
+ }
+ };
+ const IR::Value param_1{inst.Arg(0)};
+ if (param_1.IsImmediate()) {
+ break;
+ }
+ IR::Inst* op_a{param_1.InstRecursive()};
+ if (op_a->GetOpcode() == IR::Opcode::GetAttribute) {
+ try_mark(op_a);
+ break;
+ }
+ if (op_a->GetOpcode() != IR::Opcode::BitCastF32U32) {
+ break;
+ }
+ const IR::Value param_2{op_a->Arg(0)};
+ if (param_2.IsImmediate()) {
+ break;
+ }
+ IR::Inst* op_b{param_2.InstRecursive()};
+ if (op_b->GetOpcode() == IR::Opcode::GetAttribute) {
+ try_mark(op_b);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
void PatchFragCoord(IR::Block& block, IR::Inst& inst) {
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
const IR::F32 down_factor{ir.ResolutionDownFactor()};
@@ -219,7 +265,7 @@ void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) {
switch (attr) {
case IR::Attribute::PositionX:
case IR::Attribute::PositionY:
- if (is_fragment_shader) {
+ if (is_fragment_shader && inst.Flags<u32>() != 0xDEADBEEF) {
PatchFragCoord(block, inst);
}
break;
@@ -256,6 +302,11 @@ void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) {
void RescalingPass(IR::Program& program) {
for (IR::Block* const block : program.post_order_blocks) {
for (IR::Inst& inst : block->Instructions()) {
+ VisitMark(program, inst);
+ }
+ }
+ for (IR::Block* const block : program.post_order_blocks) {
+ for (IR::Inst& inst : block->Instructions()) {
Visit(program, *block, inst);
}
}