diff options
Diffstat (limited to 'src/video_core/shader/decode.cpp')
| -rw-r--r-- | src/video_core/shader/decode.cpp | 86 |
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() { | |||
| 102 | std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); | 102 | std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); |
| 103 | 103 | ||
| 104 | decompiled = false; | 104 | decompiled = false; |
| 105 | const auto info = | 105 | auto info = ScanFlow(program_code, program_size, main_offset, settings); |
| 106 | ScanFlow(program_code, program_size, main_offset, program_manager); | 106 | auto& shader_info = *info; |
| 107 | if (info) { | 107 | coverage_begin = shader_info.start; |
| 108 | const auto& shader_info = *info; | 108 | coverage_end = shader_info.end; |
| 109 | coverage_begin = shader_info.start; | 109 | switch (shader_info.settings.depth) { |
| 110 | coverage_end = shader_info.end; | 110 | case CompileDepth::FlowStack: { |
| 111 | if (shader_info.decompiled) { | ||
| 112 | decompiled = true; | ||
| 113 | ASTDecoder decoder{*this}; | ||
| 114 | ASTNode program = GetASTProgram(); | ||
| 115 | decoder.Visit(program); | ||
| 116 | return; | ||
| 117 | } | ||
| 118 | LOG_WARNING(HW_GPU, "Flow Stack Removing Failed! Falling back to old method"); | ||
| 119 | // we can't decompile it, fallback to standard method | ||
| 120 | for (const auto& block : shader_info.blocks) { | 111 | for (const auto& block : shader_info.blocks) { |
| 121 | basic_blocks.insert({block.start, DecodeRange(block.start, block.end + 1)}); | 112 | basic_blocks.insert({block.start, DecodeRange(block.start, block.end + 1)}); |
| 122 | } | 113 | } |
| 123 | return; | 114 | break; |
| 115 | } | ||
| 116 | case CompileDepth::NoFlowStack: { | ||
| 117 | disable_flow_stack = true; | ||
| 118 | const auto insert_block = [this](NodeBlock& nodes, u32 label) { | ||
| 119 | if (label == static_cast<u32>(exit_branch)) { | ||
| 120 | return; | ||
| 121 | } | ||
| 122 | basic_blocks.insert({label, nodes}); | ||
| 123 | }; | ||
| 124 | const auto& blocks = shader_info.blocks; | ||
| 125 | NodeBlock current_block; | ||
| 126 | u32 current_label = static_cast<u32>(exit_branch); | ||
| 127 | for (auto& block : blocks) { | ||
| 128 | if (shader_info.labels.count(block.start) != 0) { | ||
| 129 | insert_block(current_block, current_label); | ||
| 130 | current_block.clear(); | ||
| 131 | current_label = block.start; | ||
| 132 | } | ||
| 133 | if (!block.ignore_branch) { | ||
| 134 | DecodeRangeInner(current_block, block.start, block.end); | ||
| 135 | InsertControlFlow(current_block, block); | ||
| 136 | } else { | ||
| 137 | DecodeRangeInner(current_block, block.start, block.end + 1); | ||
| 138 | } | ||
| 139 | } | ||
| 140 | insert_block(current_block, current_label); | ||
| 141 | break; | ||
| 142 | } | ||
| 143 | case CompileDepth::DecompileBackwards: | ||
| 144 | case CompileDepth::FullDecompile: { | ||
| 145 | program_manager = std::move(shader_info.manager); | ||
| 146 | disable_flow_stack = true; | ||
| 147 | decompiled = true; | ||
| 148 | ASTDecoder decoder{*this}; | ||
| 149 | ASTNode program = GetASTProgram(); | ||
| 150 | decoder.Visit(program); | ||
| 151 | break; | ||
| 152 | } | ||
| 153 | default: | ||
| 154 | LOG_CRITICAL(HW_GPU, "Unknown decompilation mode!"); | ||
| 155 | [[fallthrough]]; | ||
| 156 | case CompileDepth::BruteForce: { | ||
| 157 | coverage_begin = main_offset; | ||
| 158 | const u32 shader_end = static_cast<u32>(program_size / sizeof(u64)); | ||
| 159 | coverage_end = shader_end; | ||
| 160 | for (u32 label = main_offset; label < shader_end; label++) { | ||
| 161 | basic_blocks.insert({label, DecodeRange(label, label + 1)}); | ||
| 162 | } | ||
| 163 | break; | ||
| 164 | } | ||
| 124 | } | 165 | } |
| 125 | LOG_WARNING(HW_GPU, "Flow Analysis Failed! Falling back to brute force compiling"); | 166 | if (settings.depth != shader_info.settings.depth) { |
| 126 | 167 | LOG_WARNING( | |
| 127 | // Now we need to deal with an undecompilable shader. We need to brute force | 168 | HW_GPU, "Decompiling to this setting \"{}\" failed, downgrading to this setting \"{}\"", |
| 128 | // a shader that captures every position. | 169 | CompileDepthAsString(settings.depth), CompileDepthAsString(shader_info.settings.depth)); |
| 129 | coverage_begin = main_offset; | ||
| 130 | const u32 shader_end = static_cast<u32>(program_size / sizeof(u64)); | ||
| 131 | coverage_end = shader_end; | ||
| 132 | for (u32 label = main_offset; label < shader_end; label++) { | ||
| 133 | basic_blocks.insert({label, DecodeRange(label, label + 1)}); | ||
| 134 | } | 170 | } |
| 135 | } | 171 | } |
| 136 | 172 | ||