1
0
Fork 0
forked from suyu/suyu

Merge pull request #1268 from FernandoS27/tmml

shader_decompiler: Implemented TMML
This commit is contained in:
bunnei 2018-09-09 21:39:39 -04:00 committed by GitHub
commit e58855c7a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 5 deletions

View file

@ -533,6 +533,16 @@ union Instruction {
BitField<31, 4, u64> component_mask; BitField<31, 4, u64> component_mask;
} txq; } txq;
union {
BitField<28, 1, u64> array;
BitField<29, 2, TextureType> texture_type;
BitField<31, 4, u64> component_mask;
bool IsComponentEnabled(size_t component) const {
return ((1ull << component) & component_mask) != 0;
}
} tmml;
union { union {
BitField<28, 1, u64> array; BitField<28, 1, u64> array;
BitField<29, 2, TextureType> texture_type; BitField<29, 2, TextureType> texture_type;
@ -690,6 +700,8 @@ public:
TLDS, // Texture Load with scalar/non-vec4 source/destinations TLDS, // Texture Load with scalar/non-vec4 source/destinations
TLD4, // Texture Load 4 TLD4, // Texture Load 4
TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations
TMML_B, // Texture Mip Map Level
TMML, // Texture Mip Map Level
EXIT, EXIT,
IPA, IPA,
FFMA_IMM, // Fused Multiply and Add FFMA_IMM, // Fused Multiply and Add
@ -914,6 +926,8 @@ private:
INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"), INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"),
INST("110010----111---", Id::TLD4, Type::Memory, "TLD4"), INST("110010----111---", Id::TLD4, Type::Memory, "TLD4"),
INST("1101111100------", Id::TLD4S, Type::Memory, "TLD4S"), INST("1101111100------", Id::TLD4S, Type::Memory, "TLD4S"),
INST("110111110110----", Id::TMML_B, Type::Memory, "TMML_B"),
INST("1101111101011---", Id::TMML, Type::Memory, "TMML"),
INST("111000110000----", Id::EXIT, Type::Trivial, "EXIT"), INST("111000110000----", Id::EXIT, Type::Trivial, "EXIT"),
INST("11100000--------", Id::IPA, Type::Trivial, "IPA"), INST("11100000--------", Id::IPA, Type::Trivial, "IPA"),
INST("0011001-1-------", Id::FFMA_IMM, Type::Ffma, "FFMA_IMM"), INST("0011001-1-------", Id::FFMA_IMM, Type::Ffma, "FFMA_IMM"),

View file

@ -1945,6 +1945,54 @@ private:
} }
break; break;
} }
case OpCode::Id::TMML: {
const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
const std::string op_b = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
const bool is_array = instr.tmml.array != 0;
auto texture_type = instr.tmml.texture_type.Value();
const std::string sampler = GetSampler(instr.sampler, texture_type, is_array);
// TODO: add coordinates for different samplers once other texture types are
// implemented.
std::string coord;
switch (texture_type) {
case Tegra::Shader::TextureType::Texture1D: {
std::string x = regs.GetRegisterAsFloat(instr.gpr8);
coord = "float coords = " + x + ';';
break;
}
case Tegra::Shader::TextureType::Texture2D: {
std::string x = regs.GetRegisterAsFloat(instr.gpr8);
std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
coord = "vec2 coords = vec2(" + x + ", " + y + ");";
break;
}
default:
LOG_CRITICAL(HW_GPU, "Unhandled texture type {}",
static_cast<u32>(texture_type));
UNREACHABLE();
// Fallback to interpreting as a 2D texture for now
std::string x = regs.GetRegisterAsFloat(instr.gpr8);
std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
coord = "vec2 coords = vec2(" + x + ", " + y + ");";
texture_type = Tegra::Shader::TextureType::Texture2D;
}
// Add an extra scope and declare the texture coords inside to prevent
// overwriting them in case they are used as outputs of the texs instruction.
shader.AddLine('{');
++shader.scope;
shader.AddLine(coord);
const std::string texture = "textureQueryLod(" + sampler + ", coords)";
const std::string tmp = "vec2 tmp = " + texture + "*vec2(256.0, 256.0);";
shader.AddLine(tmp);
regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(tmp.y)", 1, 1);
regs.SetRegisterToInteger(instr.gpr0.Value() + 1, false, 0, "uint(tmp.x)", 1, 1);
--shader.scope;
shader.AddLine('}');
break;
}
default: { default: {
LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName()); LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName());
UNREACHABLE(); UNREACHABLE();