mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-11 08:39:48 +12:00
Moar instructions
This commit is contained in:
parent
9ee1c3964a
commit
6c738e821d
3 changed files with 97 additions and 17 deletions
|
@ -1,10 +1,12 @@
|
|||
#pragma once
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "PICA/shader.hpp"
|
||||
#include "PICA/shader_gen_types.hpp"
|
||||
|
@ -42,9 +44,9 @@ namespace PICA::ShaderGen {
|
|||
explicit Function(u32 start, u32 end) : start(start), end(end) {}
|
||||
bool operator<(const Function& other) const { return AddressRange(start, end) < AddressRange(other.start, other.end); }
|
||||
|
||||
std::string getIdentifier() const { return "func_" + std::to_string(start) + "_to_" + std::to_string(end); }
|
||||
std::string getForwardDecl() const { return "void " + getIdentifier() + "();\n"; }
|
||||
std::string getCallStatement() const { return getIdentifier() + "()"; }
|
||||
std::string getIdentifier() const { return fmt::format("fn_{}_{}", start, end); }
|
||||
std::string getForwardDecl() const { return fmt::format("void fn_{}_{}();\n", start, end); }
|
||||
std::string getCallStatement() const { return fmt::format("fn_{}_{}()", start, end); }
|
||||
};
|
||||
|
||||
std::set<Function> functions{};
|
||||
|
|
|
@ -85,7 +85,6 @@ ExitMode ControlFlow::analyzeFunction(const PICAShader& shader, u32 start, u32 e
|
|||
}
|
||||
case ShaderOpcodes::IFU:
|
||||
case ShaderOpcodes::IFC: {
|
||||
Helpers::panic("IFC/IFU");
|
||||
const u32 num = instruction & 0xff;
|
||||
const u32 dest = getBits<10, 12>(instruction);
|
||||
|
||||
|
@ -122,7 +121,29 @@ ExitMode ControlFlow::analyzeFunction(const PICAShader& shader, u32 start, u32 e
|
|||
}
|
||||
break;
|
||||
}
|
||||
case ShaderOpcodes::CALL: Helpers::panic("Unimplemented control flow operation (CALL)"); break;
|
||||
case ShaderOpcodes::CALL: {
|
||||
const u32 num = instruction & 0xff;
|
||||
const u32 dest = getBits<10, 12>(instruction);
|
||||
const Function* calledFunction = addFunction(shader, dest, dest + num);
|
||||
|
||||
// Check if analysis of the branch taken func failed and return unknown if it did
|
||||
if (analysisFailed) {
|
||||
it->second = ExitMode::Unknown;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
if (calledFunction->exitMode == ExitMode::AlwaysEnd) {
|
||||
it->second = ExitMode::AlwaysEnd;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// Exit mode of the remainder of this function, after we return from the callee
|
||||
ExitMode postCallExitMode = analyzeFunction(shader, pc + 1, end, labels);
|
||||
ExitMode exitMode = exitSeries(postCallExitMode, calledFunction->exitMode);
|
||||
|
||||
it->second = exitMode;
|
||||
return exitMode;
|
||||
}
|
||||
case ShaderOpcodes::CALLC: Helpers::panic("Unimplemented control flow operation (CALLC)"); break;
|
||||
case ShaderOpcodes::CALLU: Helpers::panic("Unimplemented control flow operation (CALLU)"); break;
|
||||
case ShaderOpcodes::LOOP: Helpers::panic("Unimplemented control flow operation (LOOP)"); break;
|
||||
|
@ -464,14 +485,71 @@ void ShaderDecompiler::compileInstruction(u32& pc, bool& finished) {
|
|||
const uint refY = getBit<24>(instruction);
|
||||
const uint refX = getBit<25>(instruction);
|
||||
const char* condition = getCondition(condOp, refX, refY);
|
||||
|
||||
|
||||
decompiledShader += fmt::format("if ({}) {{ pc = {}u; break; }}", condition, dest);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderOpcodes::IFU:
|
||||
case ShaderOpcodes::IFC: {
|
||||
const u32 num = instruction & 0xff;
|
||||
const u32 dest = getBits<10, 12>(instruction);
|
||||
const Function* conditionalFunc = findFunction(AddressRange(pc + 1, dest));
|
||||
|
||||
if (opcode == ShaderOpcodes::IFC) {
|
||||
const u32 condOp = getBits<22, 2>(instruction);
|
||||
const uint refY = getBit<24>(instruction);
|
||||
const uint refX = getBit<25>(instruction);
|
||||
const char* condition = getCondition(condOp, refX, refY);
|
||||
|
||||
decompiledShader += fmt::format("if ({}) {{", condition);
|
||||
} else {
|
||||
const u32 bit = getBits<22, 4>(instruction); // Bit of the bool uniform to check
|
||||
const u32 mask = 1u << bit;
|
||||
|
||||
decompiledShader += fmt::format("if ((uniform_bool & {}u) != 0u) {{", mask);
|
||||
}
|
||||
|
||||
callFunction(*conditionalFunc);
|
||||
decompiledShader += "}\n";
|
||||
|
||||
pc = dest;
|
||||
if (num > 0) {
|
||||
const Function* elseFunc = findFunction(AddressRange(dest, dest + num));
|
||||
pc = dest + num;
|
||||
|
||||
decompiledShader += "else { ";
|
||||
callFunction(*elseFunc);
|
||||
decompiledShader += "}\n";
|
||||
|
||||
if (conditionalFunc->exitMode == ExitMode::AlwaysEnd && elseFunc->exitMode == ExitMode::AlwaysEnd) {
|
||||
finished = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case ShaderOpcodes::CALL: {
|
||||
const u32 num = instruction & 0xff;
|
||||
const u32 dest = getBits<10, 12>(instruction);
|
||||
const Function* calledFunc = findFunction(AddressRange(dest, dest + num));
|
||||
callFunction(*calledFunc);
|
||||
|
||||
if (opcode == ShaderOpcodes::CALL && calledFunc->exitMode == ExitMode::AlwaysEnd) {
|
||||
finished = true;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderOpcodes::END:
|
||||
decompiledShader += "return;\n";
|
||||
finished = true;
|
||||
return;
|
||||
|
||||
case ShaderOpcodes::NOP: break;
|
||||
default: Helpers::panic("GLSL recompiler: Unknown opcode: %X", opcode); break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -717,15 +717,15 @@ std::string FragmentGenerator::getVertexShaderAccelerated(const std::string& pic
|
|||
|
||||
std::string semantics = fmt::format(
|
||||
R"(
|
||||
vec4 a_coords = vec4({}, {}, {}, {});
|
||||
vec4 a_quaternion = vec4({}, {}, {}, {});
|
||||
vec4 a_vertexColour = vec4({}, {}, {}, {});
|
||||
vec2 a_texcoord0 = vec2({}, {});
|
||||
float a_texcoord0_w = {};
|
||||
vec2 a_texcoord1 = vec2({}, {});
|
||||
vec2 a_texcoord2 = vec2({}, {});
|
||||
vec3 a_view = vec3({}, {}, {});
|
||||
)",
|
||||
vec4 a_coords = vec4({}, {}, {}, {});
|
||||
vec4 a_quaternion = vec4({}, {}, {}, {});
|
||||
vec4 a_vertexColour = vec4({}, {}, {}, {});
|
||||
vec2 a_texcoord0 = vec2({}, {});
|
||||
float a_texcoord0_w = {};
|
||||
vec2 a_texcoord1 = vec2({}, {});
|
||||
vec2 a_texcoord2 = vec2({}, {});
|
||||
vec3 a_view = vec3({}, {}, {});
|
||||
)",
|
||||
getSemanticName(0), getSemanticName(1), getSemanticName(2), getSemanticName(3), getSemanticName(4), getSemanticName(5), getSemanticName(6),
|
||||
getSemanticName(7), getSemanticName(8), getSemanticName(9), getSemanticName(10), getSemanticName(11), getSemanticName(12),
|
||||
getSemanticName(13), getSemanticName(16), getSemanticName(14), getSemanticName(15), getSemanticName(22), getSemanticName(23),
|
||||
|
|
Loading…
Add table
Reference in a new issue