summaryrefslogtreecommitdiffstats
path: root/src/video_core/shader/decode.cpp
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2019-06-25 19:03:51 +0200
committerFernandoS27 <fsahmkow27@gmail.com>2019-07-09 14:14:39 +0200
commitd5533b440c764093c04a4859b30fc78ddb0e0bbe (patch)
treef9fea3823e0f55787549f2f1d9fc332118449bfc /src/video_core/shader/decode.cpp
parentshader_ir: Decompile Flow Stack (diff)
downloadyuzu-d5533b440c764093c04a4859b30fc78ddb0e0bbe.tar
yuzu-d5533b440c764093c04a4859b30fc78ddb0e0bbe.tar.gz
yuzu-d5533b440c764093c04a4859b30fc78ddb0e0bbe.tar.bz2
yuzu-d5533b440c764093c04a4859b30fc78ddb0e0bbe.tar.lz
yuzu-d5533b440c764093c04a4859b30fc78ddb0e0bbe.tar.xz
yuzu-d5533b440c764093c04a4859b30fc78ddb0e0bbe.tar.zst
yuzu-d5533b440c764093c04a4859b30fc78ddb0e0bbe.zip
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) {
void ShaderIR::Decode() {
std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header));
+ disable_flow_stack = false;
ShaderCharacteristics shader_info{};
bool can_proceed = ScanFlow(program_code, program_code.size(), main_offset, shader_info);
if (can_proceed) {
coverage_begin = shader_info.start;
coverage_end = shader_info.end;
if (shader_info.decompilable) {
+ disable_flow_stack = true;
+ auto insert_block = ([this](NodeBlock& nodes, u32 label) {
+ if (label == exit_branch) {
+ return;
+ }
+ basic_blocks.insert({label, nodes});
+ });
std::list<ShaderBlock>& blocks = shader_info.blocks;
+ NodeBlock current_block;
+ u32 current_label = exit_branch;
for (auto& block : blocks) {
- NodeBlock nodes;
+ 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) {
- nodes = DecodeRange(block.start, block.end);
- InsertControlFlow(nodes, block);
+ DecodeRangeInner(current_block, block.start, block.end);
+ InsertControlFlow(current_block, block);
} else {
- nodes = DecodeRange(block.start, block.end + 1);
+ DecodeRangeInner(current_block, block.start, block.end + 1);
}
- basic_blocks.insert({block.start, nodes});
}
+ insert_block(current_block, current_label);
return;
}
+ LOG_WARNING(HW_GPU, "Flow Stack Removing Failed! Falling back to old method");
// we can't decompile it, fallback to standard method
for (const auto& block : shader_info.blocks) {
basic_blocks.insert({block.start, DecodeRange(block.start, block.end + 1)});
}
return;
}
- LOG_WARNING(HW_GPU, "Flow Analysis failed, falling back to brute force compiling");
+ 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.
@@ -78,10 +93,14 @@ void ShaderIR::Decode() {
NodeBlock ShaderIR::DecodeRange(u32 begin, u32 end) {
NodeBlock basic_block;
+ DecodeRangeInner(basic_block, begin, end);
+ return basic_block;
+}
+
+void ShaderIR::DecodeRangeInner(NodeBlock& bb, u32 begin, u32 end) {
for (u32 pc = begin; pc < (begin > end ? MAX_PROGRAM_LENGTH : end);) {
- pc = DecodeInstr(basic_block, pc);
+ pc = DecodeInstr(bb, pc);
}
- return basic_block;
}
void ShaderIR::InsertControlFlow(NodeBlock& bb, const ShaderBlock& block) {