From 6fdd501113d5094f9148046c3b17cf2239e99aa5 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 28 Jun 2019 22:59:43 -0400 Subject: shader_ir: Declare Manager and pass it to appropiate programs. --- src/video_core/shader/decode.cpp | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) (limited to 'src/video_core/shader/decode.cpp') diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp index 47a9fd961..381e87415 100644 --- a/src/video_core/shader/decode.cpp +++ b/src/video_core/shader/decode.cpp @@ -39,36 +39,14 @@ void ShaderIR::Decode() { std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); disable_flow_stack = false; - const auto info = ScanFlow(program_code, program_size, main_offset); + const auto info = + ScanFlow(program_code, program_size, main_offset, program_manager); if (info) { const auto& shader_info = *info; coverage_begin = shader_info.start; coverage_end = shader_info.end; - if (shader_info.decompilable) { + if (shader_info.decompiled) { disable_flow_stack = true; - const auto insert_block = [this](NodeBlock& nodes, u32 label) { - if (label == static_cast(exit_branch)) { - return; - } - basic_blocks.insert({label, nodes}); - }; - const auto& blocks = shader_info.blocks; - NodeBlock current_block; - u32 current_label = static_cast(exit_branch); - for (auto& block : blocks) { - if (shader_info.labels.count(block.start) != 0) { - insert_block(current_block, current_label); - current_block.clear(); - current_label = block.start; - } - if (!block.ignore_branch) { - DecodeRangeInner(current_block, block.start, block.end); - InsertControlFlow(current_block, block); - } else { - DecodeRangeInner(current_block, block.start, block.end + 1); - } - } - insert_block(current_block, current_label); return; } LOG_WARNING(HW_GPU, "Flow Stack Removing Failed! Falling back to old method"); -- cgit v1.2.3 From 38fc995f6cc2c2af29abc976ddb45b72873b2cc4 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 29 Jun 2019 01:44:07 -0400 Subject: gl_shader_decompiler: Implement AST decompiling --- src/video_core/shader/decode.cpp | 70 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) (limited to 'src/video_core/shader/decode.cpp') diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp index 381e87415..e7e0903f6 100644 --- a/src/video_core/shader/decode.cpp +++ b/src/video_core/shader/decode.cpp @@ -35,10 +35,73 @@ constexpr bool IsSchedInstruction(u32 offset, u32 main_offset) { } // namespace +class ASTDecoder { +public: + ASTDecoder(ShaderIR& ir) : ir(ir) {} + + void operator()(ASTProgram& ast) { + ASTNode current = ast.nodes.GetFirst(); + while (current) { + Visit(current); + current = current->GetNext(); + } + } + + void operator()(ASTIfThen& ast) { + ASTNode current = ast.nodes.GetFirst(); + while (current) { + Visit(current); + current = current->GetNext(); + } + } + + void operator()(ASTIfElse& ast) { + ASTNode current = ast.nodes.GetFirst(); + while (current) { + Visit(current); + current = current->GetNext(); + } + } + + void operator()(ASTBlockEncoded& ast) {} + + void operator()(ASTBlockDecoded& ast) {} + + void operator()(ASTVarSet& ast) {} + + void operator()(ASTLabel& ast) {} + + void operator()(ASTGoto& ast) {} + + void operator()(ASTDoWhile& ast) { + ASTNode current = ast.nodes.GetFirst(); + while (current) { + Visit(current); + current = current->GetNext(); + } + } + + void operator()(ASTReturn& ast) {} + + void operator()(ASTBreak& ast) {} + + void Visit(ASTNode& node) { + std::visit(*this, *node->GetInnerData()); + if (node->IsBlockEncoded()) { + auto block = std::get_if(node->GetInnerData()); + NodeBlock bb = ir.DecodeRange(block->start, block->end); + node->TransformBlockEncoded(bb); + } + } + +private: + ShaderIR& ir; +}; + void ShaderIR::Decode() { std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); - disable_flow_stack = false; + decompiled = false; const auto info = ScanFlow(program_code, program_size, main_offset, program_manager); if (info) { @@ -46,7 +109,10 @@ void ShaderIR::Decode() { coverage_begin = shader_info.start; coverage_end = shader_info.end; if (shader_info.decompiled) { - disable_flow_stack = true; + decompiled = true; + ASTDecoder decoder{*this}; + ASTNode program = GetASTProgram(); + decoder.Visit(program); return; } LOG_WARNING(HW_GPU, "Flow Stack Removing Failed! Falling back to old method"); -- cgit v1.2.3 From 47e4f6a52c5eb34916e2c1f4c876e6e8624e3840 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 16 Aug 2019 16:25:02 -0400 Subject: Shader_Ir: Refactor Decompilation process and allow multiple decompilation modes. --- src/video_core/shader/decode.cpp | 86 ++++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 25 deletions(-) (limited to 'src/video_core/shader/decode.cpp') diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp index e7e0903f6..6d4359295 100644 --- a/src/video_core/shader/decode.cpp +++ b/src/video_core/shader/decode.cpp @@ -102,35 +102,71 @@ void ShaderIR::Decode() { std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); decompiled = false; - const auto info = - ScanFlow(program_code, program_size, main_offset, program_manager); - if (info) { - const auto& shader_info = *info; - coverage_begin = shader_info.start; - coverage_end = shader_info.end; - if (shader_info.decompiled) { - decompiled = true; - ASTDecoder decoder{*this}; - ASTNode program = GetASTProgram(); - decoder.Visit(program); - return; - } - LOG_WARNING(HW_GPU, "Flow Stack Removing Failed! Falling back to old method"); - // we can't decompile it, fallback to standard method + auto info = ScanFlow(program_code, program_size, main_offset, settings); + auto& shader_info = *info; + coverage_begin = shader_info.start; + coverage_end = shader_info.end; + switch (shader_info.settings.depth) { + case CompileDepth::FlowStack: { for (const auto& block : shader_info.blocks) { basic_blocks.insert({block.start, DecodeRange(block.start, block.end + 1)}); } - return; + break; + } + case CompileDepth::NoFlowStack: { + disable_flow_stack = true; + const auto insert_block = [this](NodeBlock& nodes, u32 label) { + if (label == static_cast(exit_branch)) { + return; + } + basic_blocks.insert({label, nodes}); + }; + const auto& blocks = shader_info.blocks; + NodeBlock current_block; + u32 current_label = static_cast(exit_branch); + for (auto& block : blocks) { + if (shader_info.labels.count(block.start) != 0) { + insert_block(current_block, current_label); + current_block.clear(); + current_label = block.start; + } + if (!block.ignore_branch) { + DecodeRangeInner(current_block, block.start, block.end); + InsertControlFlow(current_block, block); + } else { + DecodeRangeInner(current_block, block.start, block.end + 1); + } + } + insert_block(current_block, current_label); + break; + } + case CompileDepth::DecompileBackwards: + case CompileDepth::FullDecompile: { + program_manager = std::move(shader_info.manager); + disable_flow_stack = true; + decompiled = true; + ASTDecoder decoder{*this}; + ASTNode program = GetASTProgram(); + decoder.Visit(program); + break; + } + default: + LOG_CRITICAL(HW_GPU, "Unknown decompilation mode!"); + [[fallthrough]]; + case CompileDepth::BruteForce: { + coverage_begin = main_offset; + const u32 shader_end = static_cast(program_size / sizeof(u64)); + coverage_end = shader_end; + for (u32 label = main_offset; label < shader_end; label++) { + basic_blocks.insert({label, DecodeRange(label, label + 1)}); + } + break; + } } - LOG_WARNING(HW_GPU, "Flow Analysis Failed! Falling back to brute force compiling"); - - // Now we need to deal with an undecompilable shader. We need to brute force - // a shader that captures every position. - coverage_begin = main_offset; - const u32 shader_end = static_cast(program_size / sizeof(u64)); - coverage_end = shader_end; - for (u32 label = main_offset; label < shader_end; label++) { - basic_blocks.insert({label, DecodeRange(label, label + 1)}); + if (settings.depth != shader_info.settings.depth) { + LOG_WARNING( + HW_GPU, "Decompiling to this setting \"{}\" failed, downgrading to this setting \"{}\"", + CompileDepthAsString(settings.depth), CompileDepthAsString(shader_info.settings.depth)); } } -- cgit v1.2.3 From e6eae4b815bf4bc480d62677fdf9bdbf5d6cba82 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 4 Oct 2019 17:23:16 -0400 Subject: Shader_ir: Address feedback --- src/video_core/shader/decode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/shader/decode.cpp') diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp index 6d4359295..2626b1616 100644 --- a/src/video_core/shader/decode.cpp +++ b/src/video_core/shader/decode.cpp @@ -90,7 +90,7 @@ public: if (node->IsBlockEncoded()) { auto block = std::get_if(node->GetInnerData()); NodeBlock bb = ir.DecodeRange(block->start, block->end); - node->TransformBlockEncoded(bb); + node->TransformBlockEncoded(std::move(bb)); } } -- cgit v1.2.3