diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 505e49570..72fbc69c4 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp @@ -1667,7 +1667,8 @@ public: } 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) { @@ -1749,7 +1750,8 @@ public: const Id loop_end_block = decomp.OpLabel(); current_loop_exit = endloop_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(loop_start_block); ASTNode current = ast.nodes.GetFirst(); diff --git a/src/video_core/shader/ast.cpp b/src/video_core/shader/ast.cpp index 74b9a8f9a..7e5e916ab 100644 --- a/src/video_core/shader/ast.cpp +++ b/src/video_core/shader/ast.cpp @@ -363,7 +363,8 @@ std::string ASTManager::Print() { 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() { Clear(); @@ -378,7 +379,8 @@ void ASTManager::Init() { ASTManager::ASTManager(ASTManager&& other) : 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}, - 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(); } @@ -392,6 +394,7 @@ ASTManager& ASTManager::operator=(ASTManager&& other) { program = other.program; main_node = other.main_node; false_condition = other.false_condition; + disable_else_derivation = other.disable_else_derivation; other.main_node.reset(); return *this; @@ -641,7 +644,7 @@ void ASTManager::EncloseIfThen(ASTNode goto_node, ASTNode label) { ASTNode prev = goto_node->GetPrevious(); Expr condition = goto_node->GetGotoCondition(); bool do_else = false; - if (prev->IsIfThen()) { + if (!disable_else_derivation && prev->IsIfThen()) { Expr if_condition = prev->GetIfCondition(); do_else = ExprAreEqual(if_condition, condition); } diff --git a/src/video_core/shader/ast.h b/src/video_core/shader/ast.h index 12db336df..1b73f301f 100644 --- a/src/video_core/shader/ast.h +++ b/src/video_core/shader/ast.h @@ -298,7 +298,7 @@ private: class ASTManager final { public: - ASTManager(bool full_decompile); + ASTManager(bool full_decompile, bool disable_else_derivation); ~ASTManager(); ASTManager(const ASTManager& o) = delete; @@ -378,6 +378,7 @@ private: } bool full_decompile{}; + bool disable_else_derivation{}; std::unordered_map labels_map{}; u32 labels_count{}; std::vector labels{}; diff --git a/src/video_core/shader/compiler_settings.h b/src/video_core/shader/compiler_settings.h index e1fb5bc3a..916018c01 100644 --- a/src/video_core/shader/compiler_settings.h +++ b/src/video_core/shader/compiler_settings.h @@ -19,7 +19,8 @@ enum class CompileDepth : u32 { std::string CompileDepthAsString(CompileDepth cd); struct CompilerSettings { - CompileDepth depth; + CompileDepth depth{CompileDepth::NoFlowStack}; + bool disable_else_derivation{true}; }; } // namespace VideoCommon::Shader diff --git a/src/video_core/shader/control_flow.cpp b/src/video_core/shader/control_flow.cpp index c4351969b..c2fa734e7 100644 --- a/src/video_core/shader/control_flow.cpp +++ b/src/video_core/shader/control_flow.cpp @@ -516,7 +516,8 @@ std::unique_ptr ScanFlow(const ProgramCode& program_code, std::sort(state.block_info.begin(), state.block_info.end(), [](const BlockInfo& a, const BlockInfo& b) -> bool { return a.start < b.start; }); 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; DecompileShader(state); decompiled = state.manager->IsFullyDecompiled(); diff --git a/src/video_core/shader/control_flow.h b/src/video_core/shader/control_flow.h index 8d0d08422..74e54a5c7 100644 --- a/src/video_core/shader/control_flow.h +++ b/src/video_core/shader/control_flow.h @@ -72,7 +72,7 @@ struct ShaderCharacteristics { std::set labels{}; u32 start{}; u32 end{}; - ASTManager manager{true}; + ASTManager manager{true, true}; CompilerSettings settings{}; }; diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index 04e364634..c1f2b88c8 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp @@ -25,7 +25,7 @@ using Tegra::Shader::Register; ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset, const std::size_t size, CompilerSettings settings) : 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(); }