Shader_IR: allow else derivation to be optional.

This commit is contained in:
Fernando Sahmkow 2019-09-20 21:12:06 -04:00 committed by FernandoS27
parent ca9901867e
commit 2e9a810423
7 changed files with 18 additions and 10 deletions

View file

@ -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();

View file

@ -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);
} }

View file

@ -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{};

View file

@ -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

View file

@ -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();

View file

@ -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{};
}; };

View file

@ -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();
} }