diff options
| author | Fernando Sahmkow <fsahmkow27@gmail.com> | 2021-11-01 22:26:17 +0100 | 
|---|---|---|
| committer | Fernando Sahmkow <fsahmkow27@gmail.com> | 2021-11-01 22:26:17 +0100 | 
| commit | 194579bc4f409ba9a232afc54f19d0610102954e (patch) | |
| tree | b386d44d63d28fccd5464df29e4c5434e7341403 | |
| parent | c50ad56bf59169bd0fc808ebecfb4a69376f10df (diff) | |
ShaderCache: Fix Phi Nodes Type on OGL.
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_glsl_special.cpp | 4 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/microinstruction.cpp | 4 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | 24 | 
3 files changed, 30 insertions, 2 deletions
| diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp index 9b866f889..67f9dad68 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp @@ -68,7 +68,7 @@ void EmitPhi(EmitContext& ctx, IR::Inst& phi) {      }      if (!phi.Definition<Id>().is_valid) {          // The phi node wasn't forward defined -        ctx.var_alloc.PhiDefine(phi, phi.Arg(0).Type()); +        ctx.var_alloc.PhiDefine(phi, phi.Type());      }  } @@ -80,7 +80,7 @@ void EmitReference(EmitContext& ctx, const IR::Value& value) {  void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) {      IR::Inst& phi{*phi_value.InstRecursive()}; -    const auto phi_type{phi.Arg(0).Type()}; +    const auto phi_type{phi.Type()};      if (!phi.Definition<Id>().is_valid) {          // The phi node wasn't forward defined          ctx.var_alloc.PhiDefine(phi, phi_type); diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index e563b4022..30b470bdd 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp @@ -254,6 +254,10 @@ Inst* Inst::GetAssociatedPseudoOperation(IR::Opcode opcode) {  }  IR::Type Inst::Type() const { +    if (op == IR::Opcode::Phi) { +        // The type of a phi node is stored in its flags +        return Flags<IR::Type>(); +    }      return TypeOf(op);  } diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp index 5545f8197..87aa09358 100644 --- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp +++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp @@ -14,6 +14,7 @@  //      https://link.springer.com/chapter/10.1007/978-3-642-37051-9_6  // +#include <deque>  #include <span>  #include <variant>  #include <vector> @@ -370,6 +371,26 @@ void VisitBlock(Pass& pass, IR::Block* block) {      }      pass.SealBlock(block);  } + +IR::Type GetConcreteType(IR::Inst* inst) { +    std::deque<IR::Inst*> queue; +    queue.push_back(inst); +    while (!queue.empty()) { +        IR::Inst* current = queue.front(); +        queue.pop_front(); +        const size_t num_args{current->NumArgs()}; +        for (size_t i = 0; i < num_args; ++i) { +            const auto set_type = current->Arg(i).Type(); +            if (set_type != IR::Type::Opaque) { +                return set_type; +            } +            if (!current->Arg(i).IsImmediate()) { +                queue.push_back(current->Arg(i).Inst()); +            } +        } +    } +    return IR::Type::Opaque; +}  } // Anonymous namespace  void SsaRewritePass(IR::Program& program) { @@ -381,6 +402,9 @@ void SsaRewritePass(IR::Program& program) {      for (auto block = program.post_order_blocks.rbegin(); block != end; ++block) {          for (IR::Inst& inst : (*block)->Instructions()) {              if (inst.GetOpcode() == IR::Opcode::Phi) { +                if (inst.Type() == IR::Type::Opaque) { +                    inst.SetFlags(GetConcreteType(&inst)); +                }                  inst.OrderPhiArgs();              }          } | 
