Implemented Texture Processing Modes

master
FernandoS27 2018-09-07 21:09:39 +07:00
parent 1470b85af9
commit a99d9db32f
2 changed files with 43 additions and 1 deletions

@ -254,6 +254,15 @@ enum class TextureQueryType : u64 {
BorderColor = 22, BorderColor = 22,
}; };
enum class TextureProcessMode : u64 {
None = 0,
LZ = 1, // Unknown, appears to be the same as none.
LB = 2, // Load Bias.
LL = 3, // Load LOD (LevelOfDetail)
LBA = 6, // Load Bias. The A is unknown, does not appear to differ with LB
LLA = 7 // Load LOD. The A is unknown, does not appear to differ with LL
};
enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 }; enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 };
enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 }; enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 };
@ -522,6 +531,7 @@ union Instruction {
BitField<28, 1, u64> array; BitField<28, 1, u64> array;
BitField<29, 2, TextureType> texture_type; BitField<29, 2, TextureType> texture_type;
BitField<31, 4, u64> component_mask; BitField<31, 4, u64> component_mask;
BitField<55, 3, TextureProcessMode> process_mode;
bool IsComponentEnabled(size_t component) const { bool IsComponentEnabled(size_t component) const {
return ((1ull << component) & component_mask) != 0; return ((1ull << component) & component_mask) != 0;

@ -1786,15 +1786,47 @@ private:
coord = "vec2 coords = vec2(" + x + ", " + y + ");"; coord = "vec2 coords = vec2(" + x + ", " + y + ");";
texture_type = Tegra::Shader::TextureType::Texture2D; texture_type = Tegra::Shader::TextureType::Texture2D;
} }
// TODO: make sure coordinates are always indexed to gpr8 and gpr20 is always bias
// or lod.
const std::string op_c = regs.GetRegisterAsFloat(instr.gpr20);
const std::string sampler = GetSampler(instr.sampler, texture_type, false); const std::string sampler = GetSampler(instr.sampler, texture_type, false);
// Add an extra scope and declare the texture coords inside to prevent // 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. // overwriting them in case they are used as outputs of the texs instruction.
shader.AddLine("{"); shader.AddLine("{");
++shader.scope; ++shader.scope;
shader.AddLine(coord); shader.AddLine(coord);
const std::string texture = "texture(" + sampler + ", coords)"; std::string texture;
switch (instr.tex.process_mode) {
case Tegra::Shader::TextureProcessMode::None: {
texture = "texture(" + sampler + ", coords)";
break;
}
case Tegra::Shader::TextureProcessMode::LZ: {
texture = "textureLod(" + sampler + ", coords, 0.0)";
break;
}
case Tegra::Shader::TextureProcessMode::LB:
case Tegra::Shader::TextureProcessMode::LBA: {
// TODO: Figure if A suffix changes the equation at all.
texture = "texture(" + sampler + ", coords, " + op_c + ')';
break;
}
case Tegra::Shader::TextureProcessMode::LL:
case Tegra::Shader::TextureProcessMode::LLA: {
// TODO: Figure if A suffix changes the equation at all.
texture = "textureLod(" + sampler + ", coords, " + op_c + ')';
break;
}
default: {
texture = "texture(" + sampler + ", coords)";
LOG_CRITICAL(HW_GPU, "Unhandled texture process mode {}",
static_cast<u32>(instr.tex.process_mode.Value()));
UNREACHABLE();
}
}
size_t dest_elem{}; size_t dest_elem{};
for (size_t elem = 0; elem < 4; ++elem) { for (size_t elem = 0; elem < 4; ++elem) {
if (!instr.tex.IsComponentEnabled(elem)) { if (!instr.tex.IsComponentEnabled(elem)) {