summaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode.cpp
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-06-25 13:03:51 -0400
committerGravatar FernandoS272019-07-09 08:14:39 -0400
commitd5533b440c764093c04a4859b30fc78ddb0e0bbe (patch)
treef9fea3823e0f55787549f2f1d9fc332118449bfc /src/video_core/shader/decode.cpp
parentshader_ir: Decompile Flow Stack (diff)
downloadyuzu-d5533b440c764093c04a4859b30fc78ddb0e0bbe.tar.gz
yuzu-d5533b440c764093c04a4859b30fc78ddb0e0bbe.tar.xz
yuzu-d5533b440c764093c04a4859b30fc78ddb0e0bbe.zip
shader_ir: Unify blocks in decompiled shaders.
Diffstat (limited to 'src/video_core/shader/decode.cpp')
-rw-r--r--src/video_core/shader/decode.cpp35
1 files changed, 27 insertions, 8 deletions
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp
index 1a74b70cb..f9b1960da 100644
--- a/src/video_core/shader/decode.cpp
+++ b/src/video_core/shader/decode.cpp
@@ -38,32 +38,47 @@ constexpr bool IsSchedInstruction(u32 offset, u32 main_offset) {
38void ShaderIR::Decode() { 38void ShaderIR::Decode() {
39 std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); 39 std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header));
40 40
41 disable_flow_stack = false;
41 ShaderCharacteristics shader_info{}; 42 ShaderCharacteristics shader_info{};
42 bool can_proceed = ScanFlow(program_code, program_code.size(), main_offset, shader_info); 43 bool can_proceed = ScanFlow(program_code, program_code.size(), main_offset, shader_info);
43 if (can_proceed) { 44 if (can_proceed) {
44 coverage_begin = shader_info.start; 45 coverage_begin = shader_info.start;
45 coverage_end = shader_info.end; 46 coverage_end = shader_info.end;
46 if (shader_info.decompilable) { 47 if (shader_info.decompilable) {
48 disable_flow_stack = true;
49 auto insert_block = ([this](NodeBlock& nodes, u32 label) {
50 if (label == exit_branch) {
51 return;
52 }
53 basic_blocks.insert({label, nodes});
54 });
47 std::list<ShaderBlock>& blocks = shader_info.blocks; 55 std::list<ShaderBlock>& blocks = shader_info.blocks;
56 NodeBlock current_block;
57 u32 current_label = exit_branch;
48 for (auto& block : blocks) { 58 for (auto& block : blocks) {
49 NodeBlock nodes; 59 if (shader_info.labels.count(block.start) != 0) {
60 insert_block(current_block, current_label);
61 current_block.clear();
62 current_label = block.start;
63 }
50 if (!block.ignore_branch) { 64 if (!block.ignore_branch) {
51 nodes = DecodeRange(block.start, block.end); 65 DecodeRangeInner(current_block, block.start, block.end);
52 InsertControlFlow(nodes, block); 66 InsertControlFlow(current_block, block);
53 } else { 67 } else {
54 nodes = DecodeRange(block.start, block.end + 1); 68 DecodeRangeInner(current_block, block.start, block.end + 1);
55 } 69 }
56 basic_blocks.insert({block.start, nodes});
57 } 70 }
71 insert_block(current_block, current_label);
58 return; 72 return;
59 } 73 }
74 LOG_WARNING(HW_GPU, "Flow Stack Removing Failed! Falling back to old method");
60 // we can't decompile it, fallback to standard method 75 // we can't decompile it, fallback to standard method
61 for (const auto& block : shader_info.blocks) { 76 for (const auto& block : shader_info.blocks) {
62 basic_blocks.insert({block.start, DecodeRange(block.start, block.end + 1)}); 77 basic_blocks.insert({block.start, DecodeRange(block.start, block.end + 1)});
63 } 78 }
64 return; 79 return;
65 } 80 }
66 LOG_WARNING(HW_GPU, "Flow Analysis failed, falling back to brute force compiling"); 81 LOG_WARNING(HW_GPU, "Flow Analysis Failed! Falling back to brute force compiling");
67 82
68 // Now we need to deal with an undecompilable shader. We need to brute force 83 // Now we need to deal with an undecompilable shader. We need to brute force
69 // a shader that captures every position. 84 // a shader that captures every position.
@@ -78,10 +93,14 @@ void ShaderIR::Decode() {
78 93
79NodeBlock ShaderIR::DecodeRange(u32 begin, u32 end) { 94NodeBlock ShaderIR::DecodeRange(u32 begin, u32 end) {
80 NodeBlock basic_block; 95 NodeBlock basic_block;
96 DecodeRangeInner(basic_block, begin, end);
97 return basic_block;
98}
99
100void ShaderIR::DecodeRangeInner(NodeBlock& bb, u32 begin, u32 end) {
81 for (u32 pc = begin; pc < (begin > end ? MAX_PROGRAM_LENGTH : end);) { 101 for (u32 pc = begin; pc < (begin > end ? MAX_PROGRAM_LENGTH : end);) {
82 pc = DecodeInstr(basic_block, pc); 102 pc = DecodeInstr(bb, pc);
83 } 103 }
84 return basic_block;
85} 104}
86 105
87void ShaderIR::InsertControlFlow(NodeBlock& bb, const ShaderBlock& block) { 106void ShaderIR::InsertControlFlow(NodeBlock& bb, const ShaderBlock& block) {