mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +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 New Issue
	
	Block a user