mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-06-08 20:11:39 +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
|
#pragma once
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "PICA/shader.hpp"
|
#include "PICA/shader.hpp"
|
||||||
#include "PICA/shader_gen_types.hpp"
|
#include "PICA/shader_gen_types.hpp"
|
||||||
|
@ -42,9 +44,9 @@ namespace PICA::ShaderGen {
|
||||||
explicit Function(u32 start, u32 end) : start(start), end(end) {}
|
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); }
|
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 getIdentifier() const { return fmt::format("fn_{}_{}", start, end); }
|
||||||
std::string getForwardDecl() const { return "void " + getIdentifier() + "();\n"; }
|
std::string getForwardDecl() const { return fmt::format("void fn_{}_{}();\n", start, end); }
|
||||||
std::string getCallStatement() const { return getIdentifier() + "()"; }
|
std::string getCallStatement() const { return fmt::format("fn_{}_{}()", start, end); }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::set<Function> functions{};
|
std::set<Function> functions{};
|
||||||
|
|
|
@ -85,7 +85,6 @@ ExitMode ControlFlow::analyzeFunction(const PICAShader& shader, u32 start, u32 e
|
||||||
}
|
}
|
||||||
case ShaderOpcodes::IFU:
|
case ShaderOpcodes::IFU:
|
||||||
case ShaderOpcodes::IFC: {
|
case ShaderOpcodes::IFC: {
|
||||||
Helpers::panic("IFC/IFU");
|
|
||||||
const u32 num = instruction & 0xff;
|
const u32 num = instruction & 0xff;
|
||||||
const u32 dest = getBits<10, 12>(instruction);
|
const u32 dest = getBits<10, 12>(instruction);
|
||||||
|
|
||||||
|
@ -122,7 +121,29 @@ ExitMode ControlFlow::analyzeFunction(const PICAShader& shader, u32 start, u32 e
|
||||||
}
|
}
|
||||||
break;
|
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::CALLC: Helpers::panic("Unimplemented control flow operation (CALLC)"); break;
|
||||||
case ShaderOpcodes::CALLU: Helpers::panic("Unimplemented control flow operation (CALLU)"); break;
|
case ShaderOpcodes::CALLU: Helpers::panic("Unimplemented control flow operation (CALLU)"); break;
|
||||||
case ShaderOpcodes::LOOP: Helpers::panic("Unimplemented control flow operation (LOOP)"); break;
|
case ShaderOpcodes::LOOP: Helpers::panic("Unimplemented control flow operation (LOOP)"); break;
|
||||||
|
@ -468,10 +489,67 @@ void ShaderDecompiler::compileInstruction(u32& pc, bool& finished) {
|
||||||
decompiledShader += fmt::format("if ({}) {{ pc = {}u; break; }}", condition, dest);
|
decompiledShader += fmt::format("if ({}) {{ pc = {}u; break; }}", condition, dest);
|
||||||
break;
|
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:
|
case ShaderOpcodes::END:
|
||||||
decompiledShader += "return;\n";
|
decompiledShader += "return;\n";
|
||||||
finished = true;
|
finished = true;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case ShaderOpcodes::NOP: break;
|
||||||
default: Helpers::panic("GLSL recompiler: Unknown opcode: %X", opcode); break;
|
default: Helpers::panic("GLSL recompiler: Unknown opcode: %X", opcode); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -725,7 +725,7 @@ std::string FragmentGenerator::getVertexShaderAccelerated(const std::string& pic
|
||||||
vec2 a_texcoord1 = vec2({}, {});
|
vec2 a_texcoord1 = vec2({}, {});
|
||||||
vec2 a_texcoord2 = vec2({}, {});
|
vec2 a_texcoord2 = vec2({}, {});
|
||||||
vec3 a_view = vec3({}, {}, {});
|
vec3 a_view = vec3({}, {}, {});
|
||||||
)",
|
)",
|
||||||
getSemanticName(0), getSemanticName(1), getSemanticName(2), getSemanticName(3), getSemanticName(4), getSemanticName(5), getSemanticName(6),
|
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(7), getSemanticName(8), getSemanticName(9), getSemanticName(10), getSemanticName(11), getSemanticName(12),
|
||||||
getSemanticName(13), getSemanticName(16), getSemanticName(14), getSemanticName(15), getSemanticName(22), getSemanticName(23),
|
getSemanticName(13), getSemanticName(16), getSemanticName(14), getSemanticName(15), getSemanticName(22), getSemanticName(23),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue