Merge pull request #1863 from ReinUsesLisp/texs-f16
gl_shader_decompiler: Implement TEXS.F16
This commit is contained in:
commit
7fbd484f0e
@ -1049,6 +1049,7 @@ union Instruction {
|
|||||||
BitField<49, 1, u64> nodep_flag;
|
BitField<49, 1, u64> nodep_flag;
|
||||||
BitField<50, 3, u64> component_mask_selector;
|
BitField<50, 3, u64> component_mask_selector;
|
||||||
BitField<53, 4, u64> texture_info;
|
BitField<53, 4, u64> texture_info;
|
||||||
|
BitField<60, 1, u64> fp32_flag;
|
||||||
|
|
||||||
TextureType GetTextureType() const {
|
TextureType GetTextureType() const {
|
||||||
// The TEXS instruction has a weird encoding for the texture type.
|
// The TEXS instruction has a weird encoding for the texture type.
|
||||||
@ -1549,7 +1550,7 @@ private:
|
|||||||
INST("1110111011011---", Id::STG, Type::Memory, "STG"),
|
INST("1110111011011---", Id::STG, Type::Memory, "STG"),
|
||||||
INST("110000----111---", Id::TEX, Type::Memory, "TEX"),
|
INST("110000----111---", Id::TEX, Type::Memory, "TEX"),
|
||||||
INST("1101111101001---", Id::TXQ, Type::Memory, "TXQ"),
|
INST("1101111101001---", Id::TXQ, Type::Memory, "TXQ"),
|
||||||
INST("1101100---------", Id::TEXS, Type::Memory, "TEXS"),
|
INST("1101-00---------", Id::TEXS, Type::Memory, "TEXS"),
|
||||||
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"),
|
||||||
|
@ -50,6 +50,14 @@ public:
|
|||||||
using std::runtime_error::runtime_error;
|
using std::runtime_error::runtime_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Generates code to use for a swizzle operation.
|
||||||
|
static std::string GetSwizzle(u64 elem) {
|
||||||
|
ASSERT(elem <= 3);
|
||||||
|
std::string swizzle = ".";
|
||||||
|
swizzle += "xyzw"[elem];
|
||||||
|
return swizzle;
|
||||||
|
}
|
||||||
|
|
||||||
/// Translate topology
|
/// Translate topology
|
||||||
static std::string GetTopologyName(Tegra::Shader::OutputTopology topology) {
|
static std::string GetTopologyName(Tegra::Shader::OutputTopology topology) {
|
||||||
switch (topology) {
|
switch (topology) {
|
||||||
@ -1004,14 +1012,6 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates code to use for a swizzle operation.
|
|
||||||
static std::string GetSwizzle(u64 elem) {
|
|
||||||
ASSERT(elem <= 3);
|
|
||||||
std::string swizzle = ".";
|
|
||||||
swizzle += "xyzw"[elem];
|
|
||||||
return swizzle;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShaderWriter& shader;
|
ShaderWriter& shader;
|
||||||
ShaderWriter& declarations;
|
ShaderWriter& declarations;
|
||||||
std::vector<GLSLRegister> regs;
|
std::vector<GLSLRegister> regs;
|
||||||
@ -1343,7 +1343,7 @@ private:
|
|||||||
regs.SetRegisterToInteger(dest, true, 0, result, 1, 1);
|
regs.SetRegisterToInteger(dest, true, 0, result, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteTexsInstruction(const Instruction& instr, const std::string& texture) {
|
void WriteTexsInstructionFloat(const Instruction& instr, const std::string& texture) {
|
||||||
// TEXS has two destination registers and a swizzle. The first two elements in the swizzle
|
// TEXS has two destination registers and a swizzle. The first two elements in the swizzle
|
||||||
// go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1
|
// go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1
|
||||||
|
|
||||||
@ -1368,6 +1368,38 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WriteTexsInstructionHalfFloat(const Instruction& instr, const std::string& texture) {
|
||||||
|
// TEXS.F16 destionation registers are packed in two registers in pairs (just like any half
|
||||||
|
// float instruction).
|
||||||
|
|
||||||
|
std::array<std::string, 4> components;
|
||||||
|
u32 written_components = 0;
|
||||||
|
|
||||||
|
for (u32 component = 0; component < 4; ++component) {
|
||||||
|
if (!instr.texs.IsComponentEnabled(component))
|
||||||
|
continue;
|
||||||
|
components[written_components++] = texture + GetSwizzle(component);
|
||||||
|
}
|
||||||
|
if (written_components == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto BuildComponent = [&](std::string low, std::string high, bool high_enabled) {
|
||||||
|
return "vec2(" + low + ", " + (high_enabled ? high : "0") + ')';
|
||||||
|
};
|
||||||
|
|
||||||
|
regs.SetRegisterToHalfFloat(
|
||||||
|
instr.gpr0, 0, BuildComponent(components[0], components[1], written_components > 1),
|
||||||
|
Tegra::Shader::HalfMerge::H0_H1, 1, 1);
|
||||||
|
|
||||||
|
if (written_components > 2) {
|
||||||
|
ASSERT(instr.texs.HasTwoDestinations());
|
||||||
|
regs.SetRegisterToHalfFloat(
|
||||||
|
instr.gpr28, 0,
|
||||||
|
BuildComponent(components[2], components[3], written_components > 3),
|
||||||
|
Tegra::Shader::HalfMerge::H0_H1, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) {
|
static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) {
|
||||||
switch (texture_type) {
|
switch (texture_type) {
|
||||||
case Tegra::Shader::TextureType::Texture1D:
|
case Tegra::Shader::TextureType::Texture1D:
|
||||||
@ -2766,24 +2798,27 @@ private:
|
|||||||
const bool depth_compare =
|
const bool depth_compare =
|
||||||
instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC);
|
instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC);
|
||||||
const auto process_mode = instr.texs.GetTextureProcessMode();
|
const auto process_mode = instr.texs.GetTextureProcessMode();
|
||||||
|
|
||||||
UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
|
UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
|
||||||
"NODEP is not implemented");
|
"NODEP is not implemented");
|
||||||
|
|
||||||
const auto scope = shader.Scope();
|
const auto scope = shader.Scope();
|
||||||
|
|
||||||
const auto [coord, texture] =
|
auto [coord, texture] =
|
||||||
GetTEXSCode(instr, texture_type, process_mode, depth_compare, is_array);
|
GetTEXSCode(instr, texture_type, process_mode, depth_compare, is_array);
|
||||||
|
|
||||||
shader.AddLine(coord);
|
shader.AddLine(coord);
|
||||||
|
|
||||||
if (!depth_compare) {
|
if (depth_compare) {
|
||||||
shader.AddLine("vec4 texture_tmp = " + texture + ';');
|
texture = "vec4(" + texture + ')';
|
||||||
|
|
||||||
} else {
|
|
||||||
shader.AddLine("vec4 texture_tmp = vec4(" + texture + ");");
|
|
||||||
}
|
}
|
||||||
|
shader.AddLine("vec4 texture_tmp = " + texture + ';');
|
||||||
|
|
||||||
WriteTexsInstruction(instr, "texture_tmp");
|
if (instr.texs.fp32_flag) {
|
||||||
|
WriteTexsInstructionFloat(instr, "texture_tmp");
|
||||||
|
} else {
|
||||||
|
WriteTexsInstructionHalfFloat(instr, "texture_tmp");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OpCode::Id::TLDS: {
|
case OpCode::Id::TLDS: {
|
||||||
@ -2842,7 +2877,7 @@ private:
|
|||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
WriteTexsInstruction(instr, texture);
|
WriteTexsInstructionFloat(instr, texture);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OpCode::Id::TLD4: {
|
case OpCode::Id::TLD4: {
|
||||||
@ -2940,7 +2975,8 @@ private:
|
|||||||
if (depth_compare) {
|
if (depth_compare) {
|
||||||
texture = "vec4(" + texture + ')';
|
texture = "vec4(" + texture + ')';
|
||||||
}
|
}
|
||||||
WriteTexsInstruction(instr, texture);
|
|
||||||
|
WriteTexsInstructionFloat(instr, texture);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OpCode::Id::TXQ: {
|
case OpCode::Id::TXQ: {
|
||||||
|
Loading…
Reference in New Issue
Block a user