summaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode.cpp
diff options
context:
space:
mode:
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() {
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