summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h3
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp70
2 files changed, 55 insertions, 18 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 8d68156bf..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.
54static 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
54static std::string GetTopologyName(Tegra::Shader::OutputTopology topology) { 62static 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:
@@ -2766,24 +2798,27 @@ private:
2766 const bool depth_compare = 2798 const bool depth_compare =
2767 instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); 2799 instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC);
2768 const auto process_mode = instr.texs.GetTextureProcessMode(); 2800 const auto process_mode = instr.texs.GetTextureProcessMode();
2801
2769 UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2802 UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
2770 "NODEP is not implemented"); 2803 "NODEP is not implemented");
2771 2804
2772 const auto scope = shader.Scope(); 2805 const auto scope = shader.Scope();
2773 2806
2774 const auto [coord, texture] = 2807 auto [coord, texture] =
2775 GetTEXSCode(instr, texture_type, process_mode, depth_compare, is_array); 2808 GetTEXSCode(instr, texture_type, process_mode, depth_compare, is_array);
2776 2809
2777 shader.AddLine(coord); 2810 shader.AddLine(coord);
2778 2811
2779 if (!depth_compare) { 2812 if (depth_compare) {
2780 shader.AddLine("vec4 texture_tmp = " + texture + ';'); 2813 texture = "vec4(" + texture + ')';
2814 }
2815 shader.AddLine("vec4 texture_tmp = " + texture + ';');
2781 2816
2817 if (instr.texs.fp32_flag) {
2818 WriteTexsInstructionFloat(instr, "texture_tmp");
2782 } else { 2819 } else {
2783 shader.AddLine("vec4 texture_tmp = vec4(" + texture + ");"); 2820 WriteTexsInstructionHalfFloat(instr, "texture_tmp");
2784 } 2821 }
2785
2786 WriteTexsInstruction(instr, "texture_tmp");
2787 break; 2822 break;
2788 } 2823 }
2789 case OpCode::Id::TLDS: { 2824 case OpCode::Id::TLDS: {
@@ -2842,7 +2877,7 @@ private:
2842 } 2877 }
2843 }(); 2878 }();
2844 2879
2845 WriteTexsInstruction(instr, texture); 2880 WriteTexsInstructionFloat(instr, texture);
2846 break; 2881 break;
2847 } 2882 }
2848 case OpCode::Id::TLD4: { 2883 case OpCode::Id::TLD4: {
@@ -2940,7 +2975,8 @@ private:
2940 if (depth_compare) { 2975 if (depth_compare) {
2941 texture = "vec4(" + texture + ')'; 2976 texture = "vec4(" + texture + ')';
2942 } 2977 }
2943 WriteTexsInstruction(instr, texture); 2978
2979 WriteTexsInstructionFloat(instr, texture);
2944 break; 2980 break;
2945 } 2981 }
2946 case OpCode::Id::TXQ: { 2982 case OpCode::Id::TXQ: {