Implemented TMML
This commit is contained in:
parent
0acf9b351f
commit
00131e752d
|
@ -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;
|
||||||
|
@ -685,11 +695,13 @@ public:
|
||||||
LDG, // Load from global memory
|
LDG, // Load from global memory
|
||||||
STG, // Store in global memory
|
STG, // Store in global memory
|
||||||
TEX,
|
TEX,
|
||||||
TXQ, // Texture Query
|
TXQ, // Texture Query
|
||||||
TEXS, // Texture Fetch with scalar/non-vec4 source/destinations
|
TEXS, // Texture Fetch with scalar/non-vec4 source/destinations
|
||||||
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"),
|
||||||
|
|
|
@ -1940,6 +1940,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();
|
||||||
|
|
Reference in New Issue