Browse Source

shader: Fix branches to visited virtual blocks

nce_cpp
ReinUsesLisp 5 years ago
committed by ameerj
parent
commit
b64bf653a4
  1. 2
      src/shader_recompiler/backend/spirv/emit_spirv.cpp
  2. 10
      src/shader_recompiler/frontend/maxwell/control_flow.cpp

2
src/shader_recompiler/backend/spirv/emit_spirv.cpp

@ -56,6 +56,8 @@ ArgType Arg(EmitContext& ctx, const IR::Value& arg) {
return arg.Label(); return arg.Label();
} else if constexpr (std::is_same_v<ArgType, IR::Attribute>) { } else if constexpr (std::is_same_v<ArgType, IR::Attribute>) {
return arg.Attribute(); return arg.Attribute();
} else if constexpr (std::is_same_v<ArgType, IR::Reg>) {
return arg.Reg();
} }
} }

10
src/shader_recompiler/frontend/maxwell/control_flow.cpp

@ -486,6 +486,16 @@ Block* CFG::AddLabel(Block* block, Stack stack, Location pc, FunctionId function
} }
if (const auto it{function.blocks.find(pc, Compare{})}; it != function.blocks.end()) { if (const auto it{function.blocks.find(pc, Compare{})}; it != function.blocks.end()) {
// Block already exists and it has been visited // Block already exists and it has been visited
if (function.blocks.begin() != it) {
// Check if the previous node is the virtual variant of the label
// This won't exist if a virtual node is not needed or it hasn't been visited
// If it hasn't been visited and a virtual node is needed, this will still behave as
// expected because the node impersonated with its virtual node.
const auto prev{std::prev(it)};
if (it->begin.Virtual() == prev->begin) {
return &*prev;
}
}
return &*it; return &*it;
} }
Block* const new_block{block_pool.Create(Block{ Block* const new_block{block_pool.Create(Block{

Loading…
Cancel
Save