Shader_IR: allow else derivation to be optional.
This commit is contained in:
parent
ca9901867e
commit
2e9a810423
|
@ -1667,7 +1667,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(VideoCommon::Shader::ExprVar& expr) {
|
void operator()(VideoCommon::Shader::ExprVar& expr) {
|
||||||
current_id = decomp.Emit(decomp.OpLoad(decomp.t_bool, decomp.flow_variables.at(expr.var_index)));
|
current_id =
|
||||||
|
decomp.Emit(decomp.OpLoad(decomp.t_bool, decomp.flow_variables.at(expr.var_index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(VideoCommon::Shader::ExprBoolean& expr) {
|
void operator()(VideoCommon::Shader::ExprBoolean& expr) {
|
||||||
|
@ -1749,7 +1750,8 @@ public:
|
||||||
const Id loop_end_block = decomp.OpLabel();
|
const Id loop_end_block = decomp.OpLabel();
|
||||||
current_loop_exit = endloop_label;
|
current_loop_exit = endloop_label;
|
||||||
decomp.Emit(loop_label);
|
decomp.Emit(loop_label);
|
||||||
decomp.Emit(decomp.OpLoopMerge(endloop_label, loop_end_block, spv::LoopControlMask::MaskNone));
|
decomp.Emit(
|
||||||
|
decomp.OpLoopMerge(endloop_label, loop_end_block, spv::LoopControlMask::MaskNone));
|
||||||
decomp.Emit(decomp.OpBranch(loop_start_block));
|
decomp.Emit(decomp.OpBranch(loop_start_block));
|
||||||
decomp.Emit(loop_start_block);
|
decomp.Emit(loop_start_block);
|
||||||
ASTNode current = ast.nodes.GetFirst();
|
ASTNode current = ast.nodes.GetFirst();
|
||||||
|
|
|
@ -363,7 +363,8 @@ std::string ASTManager::Print() {
|
||||||
return printer.GetResult();
|
return printer.GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTManager::ASTManager(bool full_decompile) : full_decompile{full_decompile} {};
|
ASTManager::ASTManager(bool full_decompile, bool disable_else_derivation)
|
||||||
|
: full_decompile{full_decompile}, disable_else_derivation{disable_else_derivation} {};
|
||||||
|
|
||||||
ASTManager::~ASTManager() {
|
ASTManager::~ASTManager() {
|
||||||
Clear();
|
Clear();
|
||||||
|
@ -378,7 +379,8 @@ void ASTManager::Init() {
|
||||||
ASTManager::ASTManager(ASTManager&& other)
|
ASTManager::ASTManager(ASTManager&& other)
|
||||||
: labels_map(std::move(other.labels_map)), labels_count{other.labels_count},
|
: labels_map(std::move(other.labels_map)), labels_count{other.labels_count},
|
||||||
gotos(std::move(other.gotos)), labels(std::move(other.labels)), variables{other.variables},
|
gotos(std::move(other.gotos)), labels(std::move(other.labels)), variables{other.variables},
|
||||||
program{other.program}, main_node{other.main_node}, false_condition{other.false_condition} {
|
program{other.program}, main_node{other.main_node}, false_condition{other.false_condition},
|
||||||
|
disable_else_derivation{other.disable_else_derivation} {
|
||||||
other.main_node.reset();
|
other.main_node.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,6 +394,7 @@ ASTManager& ASTManager::operator=(ASTManager&& other) {
|
||||||
program = other.program;
|
program = other.program;
|
||||||
main_node = other.main_node;
|
main_node = other.main_node;
|
||||||
false_condition = other.false_condition;
|
false_condition = other.false_condition;
|
||||||
|
disable_else_derivation = other.disable_else_derivation;
|
||||||
|
|
||||||
other.main_node.reset();
|
other.main_node.reset();
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -641,7 +644,7 @@ void ASTManager::EncloseIfThen(ASTNode goto_node, ASTNode label) {
|
||||||
ASTNode prev = goto_node->GetPrevious();
|
ASTNode prev = goto_node->GetPrevious();
|
||||||
Expr condition = goto_node->GetGotoCondition();
|
Expr condition = goto_node->GetGotoCondition();
|
||||||
bool do_else = false;
|
bool do_else = false;
|
||||||
if (prev->IsIfThen()) {
|
if (!disable_else_derivation && prev->IsIfThen()) {
|
||||||
Expr if_condition = prev->GetIfCondition();
|
Expr if_condition = prev->GetIfCondition();
|
||||||
do_else = ExprAreEqual(if_condition, condition);
|
do_else = ExprAreEqual(if_condition, condition);
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,7 +298,7 @@ private:
|
||||||
|
|
||||||
class ASTManager final {
|
class ASTManager final {
|
||||||
public:
|
public:
|
||||||
ASTManager(bool full_decompile);
|
ASTManager(bool full_decompile, bool disable_else_derivation);
|
||||||
~ASTManager();
|
~ASTManager();
|
||||||
|
|
||||||
ASTManager(const ASTManager& o) = delete;
|
ASTManager(const ASTManager& o) = delete;
|
||||||
|
@ -378,6 +378,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool full_decompile{};
|
bool full_decompile{};
|
||||||
|
bool disable_else_derivation{};
|
||||||
std::unordered_map<u32, u32> labels_map{};
|
std::unordered_map<u32, u32> labels_map{};
|
||||||
u32 labels_count{};
|
u32 labels_count{};
|
||||||
std::vector<ASTNode> labels{};
|
std::vector<ASTNode> labels{};
|
||||||
|
|
|
@ -19,7 +19,8 @@ enum class CompileDepth : u32 {
|
||||||
std::string CompileDepthAsString(CompileDepth cd);
|
std::string CompileDepthAsString(CompileDepth cd);
|
||||||
|
|
||||||
struct CompilerSettings {
|
struct CompilerSettings {
|
||||||
CompileDepth depth;
|
CompileDepth depth{CompileDepth::NoFlowStack};
|
||||||
|
bool disable_else_derivation{true};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace VideoCommon::Shader
|
} // namespace VideoCommon::Shader
|
||||||
|
|
|
@ -516,7 +516,8 @@ std::unique_ptr<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code,
|
||||||
std::sort(state.block_info.begin(), state.block_info.end(),
|
std::sort(state.block_info.begin(), state.block_info.end(),
|
||||||
[](const BlockInfo& a, const BlockInfo& b) -> bool { return a.start < b.start; });
|
[](const BlockInfo& a, const BlockInfo& b) -> bool { return a.start < b.start; });
|
||||||
if (decompiled && settings.depth != CompileDepth::NoFlowStack) {
|
if (decompiled && settings.depth != CompileDepth::NoFlowStack) {
|
||||||
ASTManager manager{settings.depth != CompileDepth::DecompileBackwards};
|
ASTManager manager{settings.depth != CompileDepth::DecompileBackwards,
|
||||||
|
settings.disable_else_derivation};
|
||||||
state.manager = &manager;
|
state.manager = &manager;
|
||||||
DecompileShader(state);
|
DecompileShader(state);
|
||||||
decompiled = state.manager->IsFullyDecompiled();
|
decompiled = state.manager->IsFullyDecompiled();
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct ShaderCharacteristics {
|
||||||
std::set<u32> labels{};
|
std::set<u32> labels{};
|
||||||
u32 start{};
|
u32 start{};
|
||||||
u32 end{};
|
u32 end{};
|
||||||
ASTManager manager{true};
|
ASTManager manager{true, true};
|
||||||
CompilerSettings settings{};
|
CompilerSettings settings{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ using Tegra::Shader::Register;
|
||||||
ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset, const std::size_t size,
|
ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset, const std::size_t size,
|
||||||
CompilerSettings settings)
|
CompilerSettings settings)
|
||||||
: program_code{program_code}, main_offset{main_offset}, program_size{size}, basic_blocks{},
|
: program_code{program_code}, main_offset{main_offset}, program_size{size}, basic_blocks{},
|
||||||
program_manager{true}, settings{settings} {
|
program_manager{true, true}, settings{settings} {
|
||||||
Decode();
|
Decode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue