diff options
| author | 2018-12-05 01:33:36 -0300 | |
|---|---|---|
| committer | 2018-12-05 02:06:34 -0300 | |
| commit | 59a8df1b14b8632a3e35091dfd8279f228fd511c (patch) | |
| tree | cdf912aef254cefc7c4f8b2459675db9fa44f4d2 /src | |
| parent | gl_shader_decompiler: Fixup inverted if (diff) | |
| download | yuzu-59a8df1b14b8632a3e35091dfd8279f228fd511c.tar.gz yuzu-59a8df1b14b8632a3e35091dfd8279f228fd511c.tar.xz yuzu-59a8df1b14b8632a3e35091dfd8279f228fd511c.zip | |
gl_shader_decompiler: Implement TEXS.F16
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 61 |
2 files changed, 51 insertions, 13 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index b9faaf8e0..5ea094e64 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -1049,6 +1049,7 @@ union Instruction { | |||
| 1049 | BitField<49, 1, u64> nodep_flag; | 1049 | BitField<49, 1, u64> nodep_flag; |
| 1050 | BitField<50, 3, u64> component_mask_selector; | 1050 | BitField<50, 3, u64> component_mask_selector; |
| 1051 | BitField<53, 4, u64> texture_info; | 1051 | BitField<53, 4, u64> texture_info; |
| 1052 | BitField<60, 1, u64> fp32_flag; | ||
| 1052 | 1053 | ||
| 1053 | TextureType GetTextureType() const { | 1054 | TextureType GetTextureType() const { |
| 1054 | // The TEXS instruction has a weird encoding for the texture type. | 1055 | // The TEXS instruction has a weird encoding for the texture type. |
| @@ -1549,7 +1550,7 @@ private: | |||
| 1549 | INST("1110111011011---", Id::STG, Type::Memory, "STG"), | 1550 | INST("1110111011011---", Id::STG, Type::Memory, "STG"), |
| 1550 | INST("110000----111---", Id::TEX, Type::Memory, "TEX"), | 1551 | INST("110000----111---", Id::TEX, Type::Memory, "TEX"), |
| 1551 | INST("1101111101001---", Id::TXQ, Type::Memory, "TXQ"), | 1552 | INST("1101111101001---", Id::TXQ, Type::Memory, "TXQ"), |
| 1552 | INST("1101100---------", Id::TEXS, Type::Memory, "TEXS"), | 1553 | INST("1101-00---------", Id::TEXS, Type::Memory, "TEXS"), |
| 1553 | INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"), | 1554 | INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"), |
| 1554 | INST("110010----111---", Id::TLD4, Type::Memory, "TLD4"), | 1555 | INST("110010----111---", Id::TLD4, Type::Memory, "TLD4"), |
| 1555 | INST("1101111100------", Id::TLD4S, Type::Memory, "TLD4S"), | 1556 | INST("1101111100------", Id::TLD4S, Type::Memory, "TLD4S"), |
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: | |||
| 50 | using std::runtime_error::runtime_error; | 50 | using std::runtime_error::runtime_error; |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | /// Generates code to use for a swizzle operation. | ||
| 54 | static std::string GetSwizzle(u64 elem) { | ||
| 55 | ASSERT(elem <= 3); | ||
| 56 | std::string swizzle = "."; | ||
| 57 | swizzle += "xyzw"[elem]; | ||
| 58 | return swizzle; | ||
| 59 | } | ||
| 60 | |||
| 53 | /// Translate topology | 61 | /// Translate topology |
| 54 | static std::string GetTopologyName(Tegra::Shader::OutputTopology topology) { | 62 | static std::string GetTopologyName(Tegra::Shader::OutputTopology topology) { |
| 55 | switch (topology) { | 63 | switch (topology) { |
| @@ -1004,14 +1012,6 @@ private: | |||
| 1004 | } | 1012 | } |
| 1005 | } | 1013 | } |
| 1006 | 1014 | ||
| 1007 | /// Generates code to use for a swizzle operation. | ||
| 1008 | static std::string GetSwizzle(u64 elem) { | ||
| 1009 | ASSERT(elem <= 3); | ||
| 1010 | std::string swizzle = "."; | ||
| 1011 | swizzle += "xyzw"[elem]; | ||
| 1012 | return swizzle; | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | ShaderWriter& shader; | 1015 | ShaderWriter& shader; |
| 1016 | ShaderWriter& declarations; | 1016 | ShaderWriter& declarations; |
| 1017 | std::vector<GLSLRegister> regs; | 1017 | std::vector<GLSLRegister> regs; |
| @@ -1343,7 +1343,7 @@ private: | |||
| 1343 | regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); | 1343 | regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); |
| 1344 | } | 1344 | } |
| 1345 | 1345 | ||
| 1346 | void WriteTexsInstruction(const Instruction& instr, const std::string& texture) { | 1346 | void WriteTexsInstructionFloat(const Instruction& instr, const std::string& texture) { |
| 1347 | // TEXS has two destination registers and a swizzle. The first two elements in the swizzle | 1347 | // TEXS has two destination registers and a swizzle. The first two elements in the swizzle |
| 1348 | // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 | 1348 | // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 |
| 1349 | 1349 | ||
| @@ -1368,6 +1368,38 @@ private: | |||
| 1368 | } | 1368 | } |
| 1369 | } | 1369 | } |
| 1370 | 1370 | ||
| 1371 | void WriteTexsInstructionHalfFloat(const Instruction& instr, const std::string& texture) { | ||
| 1372 | // TEXS.F16 destionation registers are packed in two registers in pairs (just like any half | ||
| 1373 | // float instruction). | ||
| 1374 | |||
| 1375 | std::array<std::string, 4> components; | ||
| 1376 | u32 written_components = 0; | ||
| 1377 | |||
| 1378 | for (u32 component = 0; component < 4; ++component) { | ||
| 1379 | if (!instr.texs.IsComponentEnabled(component)) | ||
| 1380 | continue; | ||
| 1381 | components[written_components++] = texture + GetSwizzle(component); | ||
| 1382 | } | ||
| 1383 | if (written_components == 0) | ||
| 1384 | return; | ||
| 1385 | |||
| 1386 | const auto BuildComponent = [&](std::string low, std::string high, bool high_enabled) { | ||
| 1387 | return "vec2(" + low + ", " + (high_enabled ? high : "0") + ')'; | ||
| 1388 | }; | ||
| 1389 | |||
| 1390 | regs.SetRegisterToHalfFloat( | ||
| 1391 | instr.gpr0, 0, BuildComponent(components[0], components[1], written_components > 1), | ||
| 1392 | Tegra::Shader::HalfMerge::H0_H1, 1, 1); | ||
| 1393 | |||
| 1394 | if (written_components > 2) { | ||
| 1395 | ASSERT(instr.texs.HasTwoDestinations()); | ||
| 1396 | regs.SetRegisterToHalfFloat( | ||
| 1397 | instr.gpr28, 0, | ||
| 1398 | BuildComponent(components[2], components[3], written_components > 3), | ||
| 1399 | Tegra::Shader::HalfMerge::H0_H1, 1, 1); | ||
| 1400 | } | ||
| 1401 | } | ||
| 1402 | |||
| 1371 | static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { | 1403 | static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { |
| 1372 | switch (texture_type) { | 1404 | switch (texture_type) { |
| 1373 | case Tegra::Shader::TextureType::Texture1D: | 1405 | case Tegra::Shader::TextureType::Texture1D: |
| @@ -2782,7 +2814,11 @@ private: | |||
| 2782 | } | 2814 | } |
| 2783 | shader.AddLine("vec4 texture_tmp = " + texture + ';'); | 2815 | shader.AddLine("vec4 texture_tmp = " + texture + ';'); |
| 2784 | 2816 | ||
| 2785 | WriteTexsInstruction(instr, "texture_tmp"); | 2817 | if (instr.texs.fp32_flag) { |
| 2818 | WriteTexsInstructionFloat(instr, "texture_tmp"); | ||
| 2819 | } else { | ||
| 2820 | WriteTexsInstructionHalfFloat(instr, "texture_tmp"); | ||
| 2821 | } | ||
| 2786 | break; | 2822 | break; |
| 2787 | } | 2823 | } |
| 2788 | case OpCode::Id::TLDS: { | 2824 | case OpCode::Id::TLDS: { |
| @@ -2841,7 +2877,7 @@ private: | |||
| 2841 | } | 2877 | } |
| 2842 | }(); | 2878 | }(); |
| 2843 | 2879 | ||
| 2844 | WriteTexsInstruction(instr, texture); | 2880 | WriteTexsInstructionFloat(instr, texture); |
| 2845 | break; | 2881 | break; |
| 2846 | } | 2882 | } |
| 2847 | case OpCode::Id::TLD4: { | 2883 | case OpCode::Id::TLD4: { |
| @@ -2939,7 +2975,8 @@ private: | |||
| 2939 | if (depth_compare) { | 2975 | if (depth_compare) { |
| 2940 | texture = "vec4(" + texture + ')'; | 2976 | texture = "vec4(" + texture + ')'; |
| 2941 | } | 2977 | } |
| 2942 | WriteTexsInstruction(instr, texture); | 2978 | |
| 2979 | WriteTexsInstructionFloat(instr, texture); | ||
| 2943 | break; | 2980 | break; |
| 2944 | } | 2981 | } |
| 2945 | case OpCode::Id::TXQ: { | 2982 | case OpCode::Id::TXQ: { |