mirror of
https://git.h3cjp.net/H3cJP/citra.git
synced 2024-11-24 01:22:56 +00:00
shader_ir: Remove unnecessary constructors and use optional for ScanFlow result
This commit is contained in:
parent
01b21ee1e8
commit
d45fed3030
|
@ -29,10 +29,6 @@ struct ControlStack {
|
||||||
std::array<u32, stack_fixed_size> stack{};
|
std::array<u32, stack_fixed_size> stack{};
|
||||||
u32 index{};
|
u32 index{};
|
||||||
|
|
||||||
ControlStack() {}
|
|
||||||
|
|
||||||
ControlStack(const ControlStack& cp) = default;
|
|
||||||
|
|
||||||
bool Compare(const ControlStack& cs) const {
|
bool Compare(const ControlStack& cs) const {
|
||||||
if (index != cs.index) {
|
if (index != cs.index) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -75,8 +71,6 @@ struct ControlStack {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Query {
|
struct Query {
|
||||||
Query() {}
|
|
||||||
Query(const Query& q) = default;
|
|
||||||
u32 address{};
|
u32 address{};
|
||||||
ControlStack ssy_stack{};
|
ControlStack ssy_stack{};
|
||||||
ControlStack pbk_stack{};
|
ControlStack pbk_stack{};
|
||||||
|
@ -91,8 +85,6 @@ struct BlockStack {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlockBranchInfo {
|
struct BlockBranchInfo {
|
||||||
BlockBranchInfo() = default;
|
|
||||||
BlockBranchInfo(const BlockBranchInfo& b) = default;
|
|
||||||
Condition condition{};
|
Condition condition{};
|
||||||
s32 address{exit_branch};
|
s32 address{exit_branch};
|
||||||
bool kill{};
|
bool kill{};
|
||||||
|
@ -102,7 +94,6 @@ struct BlockBranchInfo {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlockInfo {
|
struct BlockInfo {
|
||||||
BlockInfo() = default;
|
|
||||||
u32 start{};
|
u32 start{};
|
||||||
u32 end{};
|
u32 end{};
|
||||||
bool visited{};
|
bool visited{};
|
||||||
|
@ -454,8 +445,8 @@ bool TryQuery(CFGRebuildState& state) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_address,
|
std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 program_size,
|
||||||
ShaderCharacteristics& result_out) {
|
u32 start_address) {
|
||||||
CFGRebuildState state{program_code, program_size};
|
CFGRebuildState state{program_code, program_size};
|
||||||
// Inspect Code and generate blocks
|
// Inspect Code and generate blocks
|
||||||
state.labels.clear();
|
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);
|
state.inspect_queries.push_back(start_address);
|
||||||
while (!state.inspect_queries.empty()) {
|
while (!state.inspect_queries.empty()) {
|
||||||
if (!TryInspectAddress(state)) {
|
if (!TryInspectAddress(state)) {
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Decompile Stacks
|
// Decompile Stacks
|
||||||
|
@ -480,7 +471,7 @@ bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_addre
|
||||||
// Sort and organize results
|
// Sort and organize results
|
||||||
std::sort(state.block_info.begin(), state.block_info.end(),
|
std::sort(state.block_info.begin(), state.block_info.end(),
|
||||||
[](const BlockInfo& a, const BlockInfo& b) -> bool { return a.start < b.start; });
|
[](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.decompilable = decompiled;
|
||||||
result_out.start = start_address;
|
result_out.start = start_address;
|
||||||
result_out.end = 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) {
|
if (result_out.decompilable) {
|
||||||
result_out.labels = std::move(state.labels);
|
result_out.labels = std::move(state.labels);
|
||||||
return true;
|
return {result_out};
|
||||||
}
|
}
|
||||||
// If it's not decompilable, merge the unlabelled blocks together
|
// If it's not decompilable, merge the unlabelled blocks together
|
||||||
auto back = result_out.blocks.begin();
|
auto back = result_out.blocks.begin();
|
||||||
|
@ -513,6 +504,6 @@ bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_addre
|
||||||
back = next;
|
back = next;
|
||||||
next++;
|
next++;
|
||||||
}
|
}
|
||||||
return true;
|
return {result_out};
|
||||||
}
|
}
|
||||||
} // namespace VideoCommon::Shader
|
} // namespace VideoCommon::Shader
|
||||||
|
|
|
@ -32,8 +32,6 @@ struct Condition {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ShaderBlock {
|
struct ShaderBlock {
|
||||||
ShaderBlock() = default;
|
|
||||||
ShaderBlock(const ShaderBlock& sb) = default;
|
|
||||||
u32 start{};
|
u32 start{};
|
||||||
u32 end{};
|
u32 end{};
|
||||||
bool ignore_branch{};
|
bool ignore_branch{};
|
||||||
|
@ -44,7 +42,7 @@ struct ShaderBlock {
|
||||||
bool operator==(const Branch& b) const {
|
bool operator==(const Branch& b) const {
|
||||||
return std::tie(cond, kills, address) == std::tie(b.cond, b.kills, b.address);
|
return std::tie(cond, kills, address) == std::tie(b.cond, b.kills, b.address);
|
||||||
}
|
}
|
||||||
} branch;
|
} branch{};
|
||||||
bool operator==(const ShaderBlock& sb) const {
|
bool operator==(const ShaderBlock& sb) const {
|
||||||
return std::tie(start, end, ignore_branch, branch) ==
|
return std::tie(start, end, ignore_branch, branch) ==
|
||||||
std::tie(sb.start, sb.end, sb.ignore_branch, sb.branch);
|
std::tie(sb.start, sb.end, sb.ignore_branch, sb.branch);
|
||||||
|
@ -52,14 +50,14 @@ struct ShaderBlock {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ShaderCharacteristics {
|
struct ShaderCharacteristics {
|
||||||
std::list<ShaderBlock> blocks;
|
std::list<ShaderBlock> blocks{};
|
||||||
bool decompilable{};
|
bool decompilable{};
|
||||||
u32 start;
|
u32 start{};
|
||||||
u32 end;
|
u32 end{};
|
||||||
std::unordered_set<u32> labels{};
|
std::unordered_set<u32> labels{};
|
||||||
};
|
};
|
||||||
|
|
||||||
bool ScanFlow(const ProgramCode& program_code, u32 program_size, u32 start_address,
|
std::optional<ShaderCharacteristics> ScanFlow(const ProgramCode& program_code, u32 program_size,
|
||||||
ShaderCharacteristics& result_out);
|
u32 start_address);
|
||||||
|
|
||||||
} // namespace VideoCommon::Shader
|
} // namespace VideoCommon::Shader
|
||||||
|
|
|
@ -39,9 +39,9 @@ void ShaderIR::Decode() {
|
||||||
std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header));
|
std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header));
|
||||||
|
|
||||||
disable_flow_stack = false;
|
disable_flow_stack = false;
|
||||||
ShaderCharacteristics shader_info{};
|
const auto info = ScanFlow(program_code, program_code.size(), main_offset);
|
||||||
bool can_proceed = ScanFlow(program_code, program_code.size(), main_offset, shader_info);
|
if (info) {
|
||||||
if (can_proceed) {
|
const auto& shader_info = *info;
|
||||||
coverage_begin = shader_info.start;
|
coverage_begin = shader_info.start;
|
||||||
coverage_end = shader_info.end;
|
coverage_end = shader_info.end;
|
||||||
if (shader_info.decompilable) {
|
if (shader_info.decompilable) {
|
||||||
|
@ -52,7 +52,7 @@ void ShaderIR::Decode() {
|
||||||
}
|
}
|
||||||
basic_blocks.insert({label, nodes});
|
basic_blocks.insert({label, nodes});
|
||||||
});
|
});
|
||||||
std::list<ShaderBlock>& blocks = shader_info.blocks;
|
const auto& blocks = shader_info.blocks;
|
||||||
NodeBlock current_block;
|
NodeBlock current_block;
|
||||||
u32 current_label = exit_branch;
|
u32 current_label = exit_branch;
|
||||||
for (auto& block : blocks) {
|
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
|
// Now we need to deal with an undecompilable shader. We need to brute force
|
||||||
// a shader that captures every position.
|
// 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));
|
const u32 shader_end = static_cast<u32>(program_size / sizeof(u64));
|
||||||
coverage_end = shader_end;
|
coverage_end = shader_end;
|
||||||
for (u32 label = main_offset; label < shader_end; label++) {
|
for (u32 label = main_offset; label < shader_end; label++) {
|
||||||
|
|
Loading…
Reference in a new issue