mirror of
https://git.h3cjp.net/H3cJP/citra.git
synced 2024-12-29 06:36:41 +00:00
Implemented TMML
This commit is contained in:
parent
0acf9b351f
commit
00131e752d
|
@ -533,6 +533,16 @@ union Instruction {
|
|||
BitField<31, 4, u64> component_mask;
|
||||
} 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 {
|
||||
BitField<28, 1, u64> array;
|
||||
BitField<29, 2, TextureType> texture_type;
|
||||
|
@ -685,11 +695,13 @@ public:
|
|||
LDG, // Load from global memory
|
||||
STG, // Store in global memory
|
||||
TEX,
|
||||
TXQ, // Texture Query
|
||||
TEXS, // Texture Fetch with scalar/non-vec4 source/destinations
|
||||
TLDS, // Texture Load with scalar/non-vec4 source/destinations
|
||||
TLD4, // Texture Load 4
|
||||
TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations
|
||||
TXQ, // Texture Query
|
||||
TEXS, // Texture Fetch with scalar/non-vec4 source/destinations
|
||||
TLDS, // Texture Load with scalar/non-vec4 source/destinations
|
||||
TLD4, // Texture Load 4
|
||||
TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations
|
||||
TMML_B, // Texture Mip Map Level
|
||||
TMML, // Texture Mip Map Level
|
||||
EXIT,
|
||||
IPA,
|
||||
FFMA_IMM, // Fused Multiply and Add
|
||||
|
@ -914,6 +926,8 @@ private:
|
|||
INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"),
|
||||
INST("110010----111---", Id::TLD4, Type::Memory, "TLD4"),
|
||||
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("11100000--------", Id::IPA, Type::Trivial, "IPA"),
|
||||
INST("0011001-1-------", Id::FFMA_IMM, Type::Ffma, "FFMA_IMM"),
|
||||
|
|
|
@ -1940,6 +1940,54 @@ private:
|
|||
}
|
||||
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: {
|
||||
LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName());
|
||||
UNREACHABLE();
|
||||
|
|
Loading…
Reference in a new issue