summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2019-06-26 02:40:38 +0200
committerFernandoS27 <fsahmkow27@gmail.com>2019-07-09 14:14:40 +0200
commitd45fed303055fa699377bedcc3a7973bd03b7870 (patch)
tree1a21fe83b7ad852021f886cb2494ad5467ad5c66 /src
parentshader_ir: Corrections, documenting and asserting control_flow (diff)
downloadyuzu-d45fed303055fa699377bedcc3a7973bd03b7870.tar
yuzu-d45fed303055fa699377bedcc3a7973bd03b7870.tar.gz
yuzu-d45fed303055fa699377bedcc3a7973bd03b7870.tar.bz2
yuzu-d45fed303055fa699377bedcc3a7973bd03b7870.tar.lz
yuzu-d45fed303055fa699377bedcc3a7973bd03b7870.tar.xz
yuzu-d45fed303055fa699377bedcc3a7973bd03b7870.tar.zst
yuzu-d45fed303055fa699377bedcc3a7973bd03b7870.zip
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/control_flow.cpp21
-rw-r--r--src/video_core/shader/control_flow.h14
-rw-r--r--src/video_core/shader/decode.cpp10
3 files changed, 17 insertions, 28 deletions
diff --git a/src/video_core/shader/control_flow.cpp b/src/video_core/shader/control_flow.cpp
index deef0cd3a..6259ad594 100644
--- a/src/video_core/shader/control_flow.cpp
+++ b/src/video_core/shader/control_flow.cpp
@@ -29,10 +29,6 @@ struct ControlStack {
std::array<u32, stack_fixed_size> stack{};
u32 index{};
- ControlStack() {}
-
- ControlStack(const ControlStack& cp) = default;
-
bool Compare(const ControlStack& cs) const {
if (index != cs.index) {
return false;
@@ -75,8 +71,6 @@ struct ControlStack {
};
struct Query {
- Query() {}
- Query(const Query& q) = default;
u32 address{};
ControlStack ssy_stack{};
ControlStack pbk_stack{};
@@ -91,8 +85,6 @@ struct BlockStack {
};
struct BlockBranchInfo {
- BlockBranchInfo() = default;
- BlockBranchInfo(const BlockBranchInfo& b) = default;
Condition condition{};
s32 address{exit_branch};
bool kill{};
@@ -102,7 +94,6 @@ struct BlockBranchInfo {
};
struct BlockInfo {
- BlockInfo() = default;
u32 start{};
u32 end{};
bool visited{};
@@ -454,8 +445,8 @@ bool TryQuery(CFGRebuildState& state) {
return true;
}
-bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_address,
- ShaderCharacteristics& result_out) {
+std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 program_size,
+ u32 start_address) {
CFGRebuildState state{program_code, program_size};
// Inspect Code and generate blocks
state.labels.clear();
@@ -463,7 +454,7 @@ bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_addre
state.inspect_queries.push_back(start_address);
while (!state.inspect_queries.empty()) {
if (!TryInspectAddress(state)) {
- return false;
+ return {};
}
}
// Decompile Stacks
@@ -480,7 +471,7 @@ bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_addre
// Sort and organize results
std::sort(state.block_info.begin(), state.block_info.end(),
[](const BlockInfo& a, const BlockInfo& b) -> bool { return a.start < b.start; });
- result_out.blocks.clear();
+ ShaderCharacteristics result_out{};
result_out.decompilable = decompiled;
result_out.start = start_address;
result_out.end = start_address;
@@ -499,7 +490,7 @@ bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_addre
}
if (result_out.decompilable) {
result_out.labels = std::move(state.labels);
- return true;
+ return {result_out};
}
// If it's not decompilable, merge the unlabelled blocks together
auto back = result_out.blocks.begin();
@@ -513,6 +504,6 @@ bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_addre
back = next;
next++;
}
- return true;
+ return {result_out};
}
} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/control_flow.h b/src/video_core/shader/control_flow.h
index 4689b0c10..5e8ea3271 100644
--- a/src/video_core/shader/control_flow.h
+++ b/src/video_core/shader/control_flow.h
@@ -32,8 +32,6 @@ struct Condition {
};
struct ShaderBlock {
- ShaderBlock() = default;
- ShaderBlock(const ShaderBlock& sb) = default;
u32 start{};
u32 end{};
bool ignore_branch{};
@@ -44,7 +42,7 @@ struct ShaderBlock {
bool operator==(const Branch& b) const {
return std::tie(cond, kills, address) == std::tie(b.cond, b.kills, b.address);
}
- } branch;
+ } branch{};
bool operator==(const ShaderBlock& sb) const {
return std::tie(start, end, ignore_branch, branch) ==
std::tie(sb.start, sb.end, sb.ignore_branch, sb.branch);
@@ -52,14 +50,14 @@ struct ShaderBlock {
};
struct ShaderCharacteristics {
- std::list<ShaderBlock> blocks;
+ std::list<ShaderBlock> blocks{};
bool decompilable{};
- u32 start;
- u32 end;
+ u32 start{};
+ u32 end{};
std::unordered_set<u32> labels{};
};
-bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_address,
- ShaderCharacteristics& result_out);
+std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 program_size,
+ u32 start_address);
} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp
index b4a282cbd..15cb33bbf 100644
--- a/src/video_core/shader/decode.cpp
+++ b/src/video_core/shader/decode.cpp
@@ -39,9 +39,9 @@ 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) {
+ const auto info = ScanFlow(program_code, program_code.size(), main_offset);
+ if (info) {
+ const auto& shader_info = *info;
coverage_begin = shader_info.start;
coverage_end = shader_info.end;
if (shader_info.decompilable) {
@@ -52,7 +52,7 @@ void ShaderIR::Decode() {
}
basic_blocks.insert({label, nodes});
});
- std::list<ShaderBlock>& blocks = shader_info.blocks;
+ const auto& blocks = shader_info.blocks;
NodeBlock current_block;
u32 current_label = exit_branch;
for (auto& block : blocks) {
@@ -82,7 +82,7 @@ void ShaderIR::Decode() {
// Now we need to deal with an undecompilable shader. We need to brute force
// a shader that captures every position.
- coverage_begin = shader_info.start;
+ 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++) {