From 59a8df1b14b8632a3e35091dfd8279f228fd511c Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 5 Dec 2018 01:33:36 -0300 Subject: gl_shader_decompiler: Implement TEXS.F16 --- .../renderer_opengl/gl_shader_decompiler.cpp | 61 +++++++++++++++++----- 1 file changed, 49 insertions(+), 12 deletions(-) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index d3a5d2f12..4fc09cac6 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -50,6 +50,14 @@ public: 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 static std::string GetTopologyName(Tegra::Shader::OutputTopology 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& declarations; std::vector regs; @@ -1343,7 +1343,7 @@ private: 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 // 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 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) { switch (texture_type) { case Tegra::Shader::TextureType::Texture1D: @@ -2782,7 +2814,11 @@ private: } 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; } case OpCode::Id::TLDS: { @@ -2841,7 +2877,7 @@ private: } }(); - WriteTexsInstruction(instr, texture); + WriteTexsInstructionFloat(instr, texture); break; } case OpCode::Id::TLD4: { @@ -2939,7 +2975,8 @@ private: if (depth_compare) { texture = "vec4(" + texture + ')'; } - WriteTexsInstruction(instr, texture); + + WriteTexsInstructionFloat(instr, texture); break; } case OpCode::Id::TXQ: { -- cgit v1.2.3