summaryrefslogtreecommitdiffstats
path: root/src/video_core/shader/decode.cpp
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2019-08-16 22:25:02 +0200
committerFernandoS27 <fsahmkow27@gmail.com>2019-10-05 00:52:50 +0200
commit47e4f6a52c5eb34916e2c1f4c876e6e8624e3840 (patch)
tree60ca95508197ceb868b004791caf81a042b22842 /src/video_core/shader/decode.cpp
parentgl_shader_decompiler: Implement AST decompiling (diff)
downloadyuzu-47e4f6a52c5eb34916e2c1f4c876e6e8624e3840.tar
yuzu-47e4f6a52c5eb34916e2c1f4c876e6e8624e3840.tar.gz
yuzu-47e4f6a52c5eb34916e2c1f4c876e6e8624e3840.tar.bz2
yuzu-47e4f6a52c5eb34916e2c1f4c876e6e8624e3840.tar.lz
yuzu-47e4f6a52c5eb34916e2c1f4c876e6e8624e3840.tar.xz
yuzu-47e4f6a52c5eb34916e2c1f4c876e6e8624e3840.tar.zst
yuzu-47e4f6a52c5eb34916e2c1f4c876e6e8624e3840.zip
Diffstat (limited to 'src/video_core/shader/decode.cpp')
-rw-r--r--src/video_core/shader/decode.cpp86
1 files changed, 61 insertions, 25 deletions
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<u32>(exit_branch)) {
+ return;
+ }
+ basic_blocks.insert({label, nodes});
+ };
+ const auto& blocks = shader_info.blocks;
+ NodeBlock current_block;
+ u32 current_label = static_cast<u32>(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<u32>(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<u32>(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));
}
}