mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 11:26:56 +02:00
129 lines
4.3 KiB
C++
129 lines
4.3 KiB
C++
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_RECOMPILER_SHADERCFG_H_
|
|
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_RECOMPILER_SHADERCFG_H_
|
|
|
|
#include "common/common.h"
|
|
#include "common/stringUtils.h"
|
|
#include "graphics/shader/recompiler/frontend/decode/ShaderDecoder.h"
|
|
|
|
#include <vector>
|
|
|
|
namespace Libs::Graphics::ShaderRecompiler::CFG {
|
|
|
|
enum class BranchCondition {
|
|
Always,
|
|
SccZero,
|
|
SccNonZero,
|
|
VccZero,
|
|
VccNonZero,
|
|
ExecZero,
|
|
ExecNonZero,
|
|
ScalarInstruction,
|
|
Expression,
|
|
Unknown
|
|
};
|
|
|
|
struct ConditionExpression {
|
|
enum class Op { Constant, Variable, Native, Not, Or };
|
|
Op op;
|
|
uint32_t lhs;
|
|
uint32_t rhs = UINT32_MAX;
|
|
};
|
|
|
|
enum class TerminatorKind { Branch, ConditionalBranch, IndirectBranch, Return, Unsupported };
|
|
|
|
enum class FailureKind {
|
|
None,
|
|
InvalidInput,
|
|
UnsupportedInstruction,
|
|
InvalidBranchTarget,
|
|
MissingFallthrough,
|
|
InvalidLabel,
|
|
IrreducibleControlFlow,
|
|
StructuredControlFlow
|
|
};
|
|
|
|
struct Terminator {
|
|
TerminatorKind kind = TerminatorKind::Return;
|
|
BranchCondition condition = BranchCondition::Always;
|
|
uint32_t true_block = UINT32_MAX;
|
|
uint32_t false_block = UINT32_MAX;
|
|
uint32_t merge_block = UINT32_MAX;
|
|
uint32_t continue_block = UINT32_MAX;
|
|
uint32_t indirect_pc_sgpr = UINT32_MAX;
|
|
uint32_t indirect_selector_code = UINT32_MAX;
|
|
std::vector<uint32_t> indirect_target_pcs;
|
|
std::vector<uint32_t> indirect_targets;
|
|
std::vector<uint32_t> indirect_selector_values;
|
|
std::vector<uint32_t> indirect_selector_targets;
|
|
uint32_t expression = UINT32_MAX;
|
|
bool loop_header = false;
|
|
};
|
|
|
|
struct BasicBlock {
|
|
uint32_t id = 0;
|
|
uint32_t start_pc = 0;
|
|
uint32_t end_pc = 0;
|
|
uint32_t inst_begin = 0;
|
|
uint32_t inst_end = 0;
|
|
struct Assignment { uint32_t variable; uint32_t expression; };
|
|
std::vector<Assignment> assignments;
|
|
std::vector<uint32_t> predecessors;
|
|
std::vector<uint32_t> successors;
|
|
std::vector<uint32_t> dominators;
|
|
Terminator terminator;
|
|
};
|
|
|
|
struct BackEdge {
|
|
uint32_t from = UINT32_MAX;
|
|
uint32_t to = UINT32_MAX;
|
|
bool natural = false;
|
|
};
|
|
|
|
struct NaturalLoop {
|
|
uint32_t header = UINT32_MAX;
|
|
uint32_t latch = UINT32_MAX;
|
|
std::vector<uint32_t> body_blocks;
|
|
};
|
|
|
|
struct StronglyConnectedComponent {
|
|
std::vector<uint32_t> blocks;
|
|
std::vector<uint32_t> entry_blocks;
|
|
bool irreducible = false;
|
|
};
|
|
|
|
struct Graph {
|
|
std::vector<BasicBlock> blocks;
|
|
std::vector<ConditionExpression> expressions;
|
|
std::vector<BackEdge> back_edges;
|
|
std::vector<NaturalLoop> natural_loops;
|
|
std::vector<StronglyConnectedComponent> components;
|
|
std::vector<uint32_t> code_table_load_pcs;
|
|
uint32_t entry_block = UINT32_MAX;
|
|
bool irreducible = false;
|
|
bool unsupported = false;
|
|
FailureKind failure_kind = FailureKind::None;
|
|
uint32_t failure_block = UINT32_MAX;
|
|
std::string unsupported_reason;
|
|
|
|
const BasicBlock* FindBlock(uint32_t id) const;
|
|
BasicBlock* FindBlock(uint32_t id);
|
|
const BasicBlock* FindBlockByPc(uint32_t pc) const;
|
|
BasicBlock* FindBlockByPc(uint32_t pc);
|
|
bool Dominates(uint32_t dominator, uint32_t block) const;
|
|
};
|
|
|
|
Graph BuildGraph(const Decoder::Program& program);
|
|
bool MayWriteScalarRegister(const Decoder::Instruction& inst, uint32_t code);
|
|
uint32_t FindScalarDefinition(const Decoder::Program& program, const Graph& graph,
|
|
uint32_t before, uint32_t code, std::vector<uint32_t>& crossed_calls);
|
|
// Returns structured control flow or failure diagnostics without changing the native graph.
|
|
// On failure, failure_block is an original block ID or UINT32_MAX.
|
|
Graph Structurize(const Graph& graph);
|
|
std::string BranchConditionToString(BranchCondition condition);
|
|
std::string FailureKindToString(FailureKind kind);
|
|
std::string GraphToString(const Graph& graph);
|
|
|
|
} // namespace Libs::Graphics::ShaderRecompiler::CFG
|
|
|
|
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_RECOMPILER_SHADERCFG_H_ */
|