Shaders: Implement CAL and RET, and increase program size.

This commit is contained in:
Fernando Sahmkow
2021-01-02 22:16:14 +01:00
committed by Morph
parent faec16a0ce
commit 7b779b26d2
3 changed files with 22 additions and 9 deletions

View File

@@ -1785,6 +1785,8 @@ public:
SSY, SSY,
SYNC, SYNC,
BRK, BRK,
CAL,
RET,
DEPBAR, DEPBAR,
VOTE, VOTE,
VOTE_VTG, VOTE_VTG,
@@ -2108,6 +2110,8 @@ private:
INST("1111000011111---", Id::SYNC, Type::Flow, "SYNC"), INST("1111000011111---", Id::SYNC, Type::Flow, "SYNC"),
INST("111000110100----", Id::BRK, Type::Flow, "BRK"), INST("111000110100----", Id::BRK, Type::Flow, "BRK"),
INST("111000110000----", Id::EXIT, Type::Flow, "EXIT"), INST("111000110000----", Id::EXIT, Type::Flow, "EXIT"),
INST("111000100110----", Id::CAL, Type::Flow, "CAL"),
INST("111000110010----", Id::RET, Type::Flow, "RET"),
INST("1111000011110---", Id::DEPBAR, Type::Synch, "DEPBAR"), INST("1111000011110---", Id::DEPBAR, Type::Synch, "DEPBAR"),
INST("0101000011011---", Id::VOTE, Type::Warp, "VOTE"), INST("0101000011011---", Id::VOTE, Type::Warp, "VOTE"),
INST("0101000011100---", Id::VOTE_VTG, Type::Warp, "VOTE_VTG"), INST("0101000011100---", Id::VOTE_VTG, Type::Warp, "VOTE_VTG"),

View File

@@ -93,13 +93,15 @@ struct ProgramControl {
struct CFGRebuildState { struct CFGRebuildState {
explicit CFGRebuildState(ProgramControl& control, const ProgramCode& program_code_, u32 start_, explicit CFGRebuildState(ProgramControl& control, const ProgramCode& program_code_, u32 start_,
Registry& registry_) u32 base_start_, Registry& registry_)
: control{control}, program_code{program_code_}, registry{registry_}, start{start_} {} : control{control}, program_code{program_code_}, registry{registry_}, start{start_},
base_start{base_start_} {}
ProgramControl& control; ProgramControl& control;
const ProgramCode& program_code; const ProgramCode& program_code;
Registry& registry; Registry& registry;
u32 start{}; u32 start{};
u32 base_start{};
std::vector<BlockInfo> block_info; std::vector<BlockInfo> block_info;
std::list<u32> inspect_queries; std::list<u32> inspect_queries;
std::list<Query> queries; std::list<Query> queries;
@@ -180,7 +182,7 @@ template <typename Result, typename TestCallable, typename PackCallable>
std::optional<Result> TrackInstruction(const CFGRebuildState& state, u32& pos, TestCallable test, std::optional<Result> TrackInstruction(const CFGRebuildState& state, u32& pos, TestCallable test,
PackCallable pack) { PackCallable pack) {
for (; pos >= state.start; --pos) { for (; pos >= state.start; --pos) {
if (IsSchedInstruction(pos, state.start)) { if (IsSchedInstruction(pos, state.base_start)) {
continue; continue;
} }
const Instruction instr = state.program_code[pos]; const Instruction instr = state.program_code[pos];
@@ -287,7 +289,7 @@ std::pair<ParseResult, ParseInfo> ParseCode(CFGRebuildState& state, u32 address)
single_branch.ignore = true; single_branch.ignore = true;
break; break;
} }
if (IsSchedInstruction(offset, state.start)) { if (IsSchedInstruction(offset, state.base_start)) {
offset++; offset++;
continue; continue;
} }
@@ -299,6 +301,7 @@ std::pair<ParseResult, ParseInfo> ParseCode(CFGRebuildState& state, u32 address)
} }
switch (opcode->get().GetId()) { switch (opcode->get().GetId()) {
case OpCode::Id::RET:
case OpCode::Id::EXIT: { case OpCode::Id::EXIT: {
const auto pred_index = static_cast<u32>(instr.pred.pred_index); const auto pred_index = static_cast<u32>(instr.pred.pred_index);
single_branch.condition.predicate = GetPredicate(pred_index, instr.negate_pred != 0); single_branch.condition.predicate = GetPredicate(pred_index, instr.negate_pred != 0);
@@ -447,6 +450,11 @@ std::pair<ParseResult, ParseInfo> ParseCode(CFGRebuildState& state, u32 address)
state.jump_labels.emplace(offset, it); state.jump_labels.emplace(offset, it);
break; break;
} }
case OpCode::Id::CAL: {
const u32 target = offset + instr.bra.GetBranchTarget();
state.control.RegisterFunction(target);
break;
}
case OpCode::Id::BRX: { case OpCode::Id::BRX: {
const auto tmp = TrackBranchIndirectInfo(state, offset); const auto tmp = TrackBranchIndirectInfo(state, offset);
if (!tmp) { if (!tmp) {
@@ -681,7 +689,7 @@ void DecompileShader(CFGRebuildState& state) {
} // Anonymous namespace } // Anonymous namespace
ShaderFunction ScanFunction(ProgramControl& control, const ProgramCode& program_code, ShaderFunction ScanFunction(ProgramControl& control, const ProgramCode& program_code,
u32 start_address, const CompilerSettings& settings, u32 start_address, u32 base_start, const CompilerSettings& settings,
Registry& registry) { Registry& registry) {
ShaderFunction result_out{}; ShaderFunction result_out{};
if (settings.depth == CompileDepth::BruteForce) { if (settings.depth == CompileDepth::BruteForce) {
@@ -689,7 +697,7 @@ ShaderFunction ScanFunction(ProgramControl& control, const ProgramCode& program_
return result_out; return result_out;
} }
CFGRebuildState state{control, program_code, start_address, registry}; CFGRebuildState state{control, program_code, start_address, base_start, registry};
// Inspect Code and generate blocks // Inspect Code and generate blocks
state.labels.clear(); state.labels.clear();
state.labels.emplace(start_address); state.labels.emplace(start_address);
@@ -784,10 +792,11 @@ std::unique_ptr<ShaderProgram> ScanFlow(const ProgramCode& program_code, u32 sta
const CompilerSettings& settings, Registry& registry) { const CompilerSettings& settings, Registry& registry) {
ProgramControl control{}; ProgramControl control{};
auto result_out = std::make_unique<ShaderProgram>(); auto result_out = std::make_unique<ShaderProgram>();
result_out->main = ScanFunction(control, program_code, start_address, settings, registry); result_out->main =
ScanFunction(control, program_code, start_address, start_address, settings, registry);
while (!control.pending_functions.empty()) { while (!control.pending_functions.empty()) {
u32 address = control.pending_functions.front(); u32 address = control.pending_functions.front();
auto fun = ScanFunction(control, program_code, address, settings, registry); auto fun = ScanFunction(control, program_code, address, start_address, settings, registry);
result_out->subfunctions.emplace(address, std::move(fun)); result_out->subfunctions.emplace(address, std::move(fun));
control.pending_functions.pop_front(); control.pending_functions.pop_front();
} }

View File

@@ -26,7 +26,7 @@ namespace VideoCommon::Shader {
struct ShaderBlock; struct ShaderBlock;
constexpr u32 MAX_PROGRAM_LENGTH = 0x1000; constexpr u32 MAX_PROGRAM_LENGTH = 0x8000;
struct ConstBuffer { struct ConstBuffer {
constexpr explicit ConstBuffer(u32 max_offset_, bool is_indirect_) constexpr explicit ConstBuffer(u32 max_offset_, bool is_indirect_)