diff options
| author | 2018-11-23 08:49:37 -0800 | |
|---|---|---|
| committer | 2018-11-23 08:49:37 -0800 | |
| commit | c4b5319446803aeebbdf63089a89045a79cd7d05 (patch) | |
| tree | 01edf16f26e2dcac748fbb22fab8868c46fa7a12 /src | |
| parent | Merge pull request #1766 from FernandoS27/fix-txq (diff) | |
| parent | gl_shader_decompiler: Fix register overwriting on texture calls (diff) | |
| download | yuzu-c4b5319446803aeebbdf63089a89045a79cd7d05.tar.gz yuzu-c4b5319446803aeebbdf63089a89045a79cd7d05.tar.xz yuzu-c4b5319446803aeebbdf63089a89045a79cd7d05.zip | |
Merge pull request #1756 from ReinUsesLisp/fix-textures
gl_shader_decompiler: Fix register overwriting on texture calls
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 138 |
1 files changed, 78 insertions, 60 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 7d7df0712..dd406b132 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -1243,14 +1243,7 @@ private: | |||
| 1243 | regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); | 1243 | regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); |
| 1244 | } | 1244 | } |
| 1245 | 1245 | ||
| 1246 | void WriteTexsInstruction(const Instruction& instr, const std::string& coord, | 1246 | void WriteTexsInstruction(const Instruction& instr, const std::string& texture) { |
| 1247 | const std::string& texture) { | ||
| 1248 | // Add an extra scope and declare the texture coords inside to prevent | ||
| 1249 | // overwriting them in case they are used as outputs of the texs instruction. | ||
| 1250 | shader.AddLine('{'); | ||
| 1251 | ++shader.scope; | ||
| 1252 | shader.AddLine(coord); | ||
| 1253 | |||
| 1254 | // TEXS has two destination registers and a swizzle. The first two elements in the swizzle | 1247 | // TEXS has two destination registers and a swizzle. The first two elements in the swizzle |
| 1255 | // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 | 1248 | // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 |
| 1256 | 1249 | ||
| @@ -1273,9 +1266,6 @@ private: | |||
| 1273 | 1266 | ||
| 1274 | ++written_components; | 1267 | ++written_components; |
| 1275 | } | 1268 | } |
| 1276 | |||
| 1277 | --shader.scope; | ||
| 1278 | shader.AddLine('}'); | ||
| 1279 | } | 1269 | } |
| 1280 | 1270 | ||
| 1281 | static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { | 1271 | static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { |
| @@ -2563,7 +2553,6 @@ private: | |||
| 2563 | } | 2553 | } |
| 2564 | // TODO: make sure coordinates are always indexed to gpr8 and gpr20 is always bias | 2554 | // TODO: make sure coordinates are always indexed to gpr8 and gpr20 is always bias |
| 2565 | // or lod. | 2555 | // or lod. |
| 2566 | std::string op_c; | ||
| 2567 | 2556 | ||
| 2568 | const std::string sampler = | 2557 | const std::string sampler = |
| 2569 | GetSampler(instr.sampler, texture_type, is_array, depth_compare); | 2558 | GetSampler(instr.sampler, texture_type, is_array, depth_compare); |
| @@ -2586,27 +2575,35 @@ private: | |||
| 2586 | } | 2575 | } |
| 2587 | case Tegra::Shader::TextureProcessMode::LB: | 2576 | case Tegra::Shader::TextureProcessMode::LB: |
| 2588 | case Tegra::Shader::TextureProcessMode::LBA: { | 2577 | case Tegra::Shader::TextureProcessMode::LBA: { |
| 2589 | if (depth_compare) { | 2578 | const std::string bias = [&]() { |
| 2590 | if (is_array) | 2579 | if (depth_compare) { |
| 2591 | op_c = regs.GetRegisterAsFloat(instr.gpr20.Value() + 2); | 2580 | if (is_array) |
| 2592 | else | 2581 | return regs.GetRegisterAsFloat(instr.gpr20.Value() + 2); |
| 2593 | op_c = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | 2582 | else |
| 2594 | } else { | 2583 | return regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); |
| 2595 | op_c = regs.GetRegisterAsFloat(instr.gpr20); | 2584 | } else { |
| 2596 | } | 2585 | return regs.GetRegisterAsFloat(instr.gpr20); |
| 2586 | } | ||
| 2587 | }(); | ||
| 2588 | shader.AddLine("float bias = " + bias + ';'); | ||
| 2589 | |||
| 2597 | // TODO: Figure if A suffix changes the equation at all. | 2590 | // TODO: Figure if A suffix changes the equation at all. |
| 2598 | texture = "texture(" + sampler + ", coords, " + op_c + ')'; | 2591 | texture = "texture(" + sampler + ", coords, bias)"; |
| 2599 | break; | 2592 | break; |
| 2600 | } | 2593 | } |
| 2601 | case Tegra::Shader::TextureProcessMode::LL: | 2594 | case Tegra::Shader::TextureProcessMode::LL: |
| 2602 | case Tegra::Shader::TextureProcessMode::LLA: { | 2595 | case Tegra::Shader::TextureProcessMode::LLA: { |
| 2603 | if (num_coordinates <= 2) { | 2596 | const std::string lod = [&]() { |
| 2604 | op_c = regs.GetRegisterAsFloat(instr.gpr20); | 2597 | if (num_coordinates <= 2) { |
| 2605 | } else { | 2598 | return regs.GetRegisterAsFloat(instr.gpr20); |
| 2606 | op_c = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | 2599 | } else { |
| 2607 | } | 2600 | return regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); |
| 2601 | } | ||
| 2602 | }(); | ||
| 2603 | shader.AddLine("float lod = " + lod + ';'); | ||
| 2604 | |||
| 2608 | // TODO: Figure if A suffix changes the equation at all. | 2605 | // TODO: Figure if A suffix changes the equation at all. |
| 2609 | texture = "textureLod(" + sampler + ", coords, " + op_c + ')'; | 2606 | texture = "textureLod(" + sampler + ", coords, lod)"; |
| 2610 | break; | 2607 | break; |
| 2611 | } | 2608 | } |
| 2612 | default: { | 2609 | default: { |
| @@ -2633,7 +2630,6 @@ private: | |||
| 2633 | break; | 2630 | break; |
| 2634 | } | 2631 | } |
| 2635 | case OpCode::Id::TEXS: { | 2632 | case OpCode::Id::TEXS: { |
| 2636 | std::string coord; | ||
| 2637 | Tegra::Shader::TextureType texture_type{instr.texs.GetTextureType()}; | 2633 | Tegra::Shader::TextureType texture_type{instr.texs.GetTextureType()}; |
| 2638 | bool is_array{instr.texs.IsArrayTexture()}; | 2634 | bool is_array{instr.texs.IsArrayTexture()}; |
| 2639 | 2635 | ||
| @@ -2646,17 +2642,21 @@ private: | |||
| 2646 | if (depth_compare) | 2642 | if (depth_compare) |
| 2647 | num_coordinates += 1; | 2643 | num_coordinates += 1; |
| 2648 | 2644 | ||
| 2645 | // Scope to avoid variable name overlaps. | ||
| 2646 | shader.AddLine('{'); | ||
| 2647 | ++shader.scope; | ||
| 2648 | |||
| 2649 | switch (num_coordinates) { | 2649 | switch (num_coordinates) { |
| 2650 | case 2: { | 2650 | case 2: { |
| 2651 | if (is_array) { | 2651 | if (is_array) { |
| 2652 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | 2652 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); |
| 2653 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2653 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2654 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2654 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 2655 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; | 2655 | shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"); |
| 2656 | } else { | 2656 | } else { |
| 2657 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2657 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2658 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2658 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 2659 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 2659 | shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); |
| 2660 | } | 2660 | } |
| 2661 | break; | 2661 | break; |
| 2662 | } | 2662 | } |
| @@ -2666,13 +2666,13 @@ private: | |||
| 2666 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2666 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2667 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); | 2667 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); |
| 2668 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | 2668 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); |
| 2669 | coord = | 2669 | shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + |
| 2670 | "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index + ");"; | 2670 | index + ");"); |
| 2671 | } else { | 2671 | } else { |
| 2672 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2672 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2673 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2673 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2674 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | 2674 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); |
| 2675 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | 2675 | shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"); |
| 2676 | } | 2676 | } |
| 2677 | break; | 2677 | break; |
| 2678 | } | 2678 | } |
| @@ -2683,7 +2683,7 @@ private: | |||
| 2683 | // Fallback to interpreting as a 2D texture for now | 2683 | // Fallback to interpreting as a 2D texture for now |
| 2684 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2684 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2685 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2685 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 2686 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 2686 | shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); |
| 2687 | texture_type = Tegra::Shader::TextureType::Texture2D; | 2687 | texture_type = Tegra::Shader::TextureType::Texture2D; |
| 2688 | is_array = false; | 2688 | is_array = false; |
| 2689 | } | 2689 | } |
| @@ -2715,14 +2715,16 @@ private: | |||
| 2715 | } | 2715 | } |
| 2716 | } | 2716 | } |
| 2717 | if (!depth_compare) { | 2717 | if (!depth_compare) { |
| 2718 | WriteTexsInstruction(instr, coord, texture); | 2718 | WriteTexsInstruction(instr, texture); |
| 2719 | } else { | 2719 | } else { |
| 2720 | WriteTexsInstruction(instr, coord, "vec4(" + texture + ')'); | 2720 | WriteTexsInstruction(instr, "vec4(" + texture + ')'); |
| 2721 | } | 2721 | } |
| 2722 | |||
| 2723 | shader.AddLine('}'); | ||
| 2724 | --shader.scope; | ||
| 2722 | break; | 2725 | break; |
| 2723 | } | 2726 | } |
| 2724 | case OpCode::Id::TLDS: { | 2727 | case OpCode::Id::TLDS: { |
| 2725 | std::string coord; | ||
| 2726 | const Tegra::Shader::TextureType texture_type{instr.tlds.GetTextureType()}; | 2728 | const Tegra::Shader::TextureType texture_type{instr.tlds.GetTextureType()}; |
| 2727 | const bool is_array{instr.tlds.IsArrayTexture()}; | 2729 | const bool is_array{instr.tlds.IsArrayTexture()}; |
| 2728 | 2730 | ||
| @@ -2736,12 +2738,16 @@ private: | |||
| 2736 | UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::MZ), | 2738 | UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::MZ), |
| 2737 | "MZ is not implemented"); | 2739 | "MZ is not implemented"); |
| 2738 | 2740 | ||
| 2739 | u32 op_c_offset = 0; | 2741 | u32 extra_op_offset = 0; |
| 2742 | |||
| 2743 | // Scope to avoid variable name overlaps. | ||
| 2744 | shader.AddLine('{'); | ||
| 2745 | ++shader.scope; | ||
| 2740 | 2746 | ||
| 2741 | switch (texture_type) { | 2747 | switch (texture_type) { |
| 2742 | case Tegra::Shader::TextureType::Texture1D: { | 2748 | case Tegra::Shader::TextureType::Texture1D: { |
| 2743 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); | 2749 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); |
| 2744 | coord = "int coords = " + x + ';'; | 2750 | shader.AddLine("int coords = " + x + ';'); |
| 2745 | break; | 2751 | break; |
| 2746 | } | 2752 | } |
| 2747 | case Tegra::Shader::TextureType::Texture2D: { | 2753 | case Tegra::Shader::TextureType::Texture2D: { |
| @@ -2749,8 +2755,8 @@ private: | |||
| 2749 | 2755 | ||
| 2750 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); | 2756 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); |
| 2751 | const std::string y = regs.GetRegisterAsInteger(instr.gpr20); | 2757 | const std::string y = regs.GetRegisterAsInteger(instr.gpr20); |
| 2752 | coord = "ivec2 coords = ivec2(" + x + ", " + y + ");"; | 2758 | shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");"); |
| 2753 | op_c_offset = 1; | 2759 | extra_op_offset = 1; |
| 2754 | break; | 2760 | break; |
| 2755 | } | 2761 | } |
| 2756 | default: | 2762 | default: |
| @@ -2765,9 +2771,10 @@ private: | |||
| 2765 | break; | 2771 | break; |
| 2766 | } | 2772 | } |
| 2767 | case Tegra::Shader::TextureProcessMode::LL: { | 2773 | case Tegra::Shader::TextureProcessMode::LL: { |
| 2768 | const std::string op_c = | 2774 | shader.AddLine( |
| 2769 | regs.GetRegisterAsInteger(instr.gpr20.Value() + op_c_offset); | 2775 | "float lod = " + |
| 2770 | texture = "texelFetch(" + sampler + ", coords, " + op_c + ')'; | 2776 | regs.GetRegisterAsInteger(instr.gpr20.Value() + extra_op_offset) + ';'); |
| 2777 | texture = "texelFetch(" + sampler + ", coords, lod)"; | ||
| 2771 | break; | 2778 | break; |
| 2772 | } | 2779 | } |
| 2773 | default: { | 2780 | default: { |
| @@ -2776,7 +2783,10 @@ private: | |||
| 2776 | static_cast<u32>(instr.tlds.GetTextureProcessMode())); | 2783 | static_cast<u32>(instr.tlds.GetTextureProcessMode())); |
| 2777 | } | 2784 | } |
| 2778 | } | 2785 | } |
| 2779 | WriteTexsInstruction(instr, coord, texture); | 2786 | WriteTexsInstruction(instr, texture); |
| 2787 | |||
| 2788 | --shader.scope; | ||
| 2789 | shader.AddLine('}'); | ||
| 2780 | break; | 2790 | break; |
| 2781 | } | 2791 | } |
| 2782 | case OpCode::Id::TLD4: { | 2792 | case OpCode::Id::TLD4: { |
| @@ -2799,18 +2809,23 @@ private: | |||
| 2799 | if (depth_compare) | 2809 | if (depth_compare) |
| 2800 | num_coordinates += 1; | 2810 | num_coordinates += 1; |
| 2801 | 2811 | ||
| 2812 | // Add an extra scope and declare the texture coords inside to prevent | ||
| 2813 | // overwriting them in case they are used as outputs of the texs instruction. | ||
| 2814 | shader.AddLine('{'); | ||
| 2815 | ++shader.scope; | ||
| 2816 | |||
| 2802 | switch (num_coordinates) { | 2817 | switch (num_coordinates) { |
| 2803 | case 2: { | 2818 | case 2: { |
| 2804 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2819 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2805 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2820 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2806 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 2821 | shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); |
| 2807 | break; | 2822 | break; |
| 2808 | } | 2823 | } |
| 2809 | case 3: { | 2824 | case 3: { |
| 2810 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2825 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2811 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2826 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2812 | const std::string z = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); | 2827 | const std::string z = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); |
| 2813 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | 2828 | shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"); |
| 2814 | break; | 2829 | break; |
| 2815 | } | 2830 | } |
| 2816 | default: | 2831 | default: |
| @@ -2818,17 +2833,13 @@ private: | |||
| 2818 | static_cast<u32>(num_coordinates)); | 2833 | static_cast<u32>(num_coordinates)); |
| 2819 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2834 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2820 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2835 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2821 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 2836 | shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); |
| 2822 | texture_type = Tegra::Shader::TextureType::Texture2D; | 2837 | texture_type = Tegra::Shader::TextureType::Texture2D; |
| 2823 | } | 2838 | } |
| 2824 | 2839 | ||
| 2825 | const std::string sampler = | 2840 | const std::string sampler = |
| 2826 | GetSampler(instr.sampler, texture_type, false, depth_compare); | 2841 | GetSampler(instr.sampler, texture_type, false, depth_compare); |
| 2827 | // Add an extra scope and declare the texture coords inside to prevent | 2842 | |
| 2828 | // overwriting them in case they are used as outputs of the texs instruction. | ||
| 2829 | shader.AddLine("{"); | ||
| 2830 | ++shader.scope; | ||
| 2831 | shader.AddLine(coord); | ||
| 2832 | const std::string texture = "textureGather(" + sampler + ", coords, " + | 2843 | const std::string texture = "textureGather(" + sampler + ", coords, " + |
| 2833 | std::to_string(instr.tld4.component) + ')'; | 2844 | std::to_string(instr.tld4.component) + ')'; |
| 2834 | if (!depth_compare) { | 2845 | if (!depth_compare) { |
| @@ -2845,7 +2856,7 @@ private: | |||
| 2845 | regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false); | 2856 | regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false); |
| 2846 | } | 2857 | } |
| 2847 | --shader.scope; | 2858 | --shader.scope; |
| 2848 | shader.AddLine("}"); | 2859 | shader.AddLine('}'); |
| 2849 | break; | 2860 | break; |
| 2850 | } | 2861 | } |
| 2851 | case OpCode::Id::TLD4S: { | 2862 | case OpCode::Id::TLD4S: { |
| @@ -2856,6 +2867,10 @@ private: | |||
| 2856 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), | 2867 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), |
| 2857 | "AOFFI is not implemented"); | 2868 | "AOFFI is not implemented"); |
| 2858 | 2869 | ||
| 2870 | // Scope to avoid variable name overlaps. | ||
| 2871 | shader.AddLine('{'); | ||
| 2872 | ++shader.scope; | ||
| 2873 | |||
| 2859 | const bool depth_compare = | 2874 | const bool depth_compare = |
| 2860 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | 2875 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |
| 2861 | const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); | 2876 | const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); |
| @@ -2863,22 +2878,25 @@ private: | |||
| 2863 | // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction. | 2878 | // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction. |
| 2864 | const std::string sampler = GetSampler( | 2879 | const std::string sampler = GetSampler( |
| 2865 | instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare); | 2880 | instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare); |
| 2866 | std::string coord; | ||
| 2867 | if (!depth_compare) { | 2881 | if (!depth_compare) { |
| 2868 | coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");"; | 2882 | shader.AddLine("vec2 coords = vec2(" + op_a + ", " + op_b + ");"); |
| 2869 | } else { | 2883 | } else { |
| 2870 | // Note: TLD4S coordinate encoding works just like TEXS's | 2884 | // Note: TLD4S coordinate encoding works just like TEXS's |
| 2871 | const std::string op_c = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2885 | shader.AddLine( |
| 2872 | coord = "vec3 coords = vec3(" + op_a + ", " + op_c + ", " + op_b + ");"; | 2886 | "float op_y = " + regs.GetRegisterAsFloat(instr.gpr8.Value() + 1) + ';'); |
| 2887 | shader.AddLine("vec3 coords = vec3(" + op_a + ", op_y, " + op_b + ");"); | ||
| 2873 | } | 2888 | } |
| 2874 | const std::string texture = "textureGather(" + sampler + ", coords, " + | 2889 | const std::string texture = "textureGather(" + sampler + ", coords, " + |
| 2875 | std::to_string(instr.tld4s.component) + ')'; | 2890 | std::to_string(instr.tld4s.component) + ')'; |
| 2876 | 2891 | ||
| 2877 | if (!depth_compare) { | 2892 | if (!depth_compare) { |
| 2878 | WriteTexsInstruction(instr, coord, texture); | 2893 | WriteTexsInstruction(instr, texture); |
| 2879 | } else { | 2894 | } else { |
| 2880 | WriteTexsInstruction(instr, coord, "vec4(" + texture + ')'); | 2895 | WriteTexsInstruction(instr, "vec4(" + texture + ')'); |
| 2881 | } | 2896 | } |
| 2897 | |||
| 2898 | --shader.scope; | ||
| 2899 | shader.AddLine('}'); | ||
| 2882 | break; | 2900 | break; |
| 2883 | } | 2901 | } |
| 2884 | case OpCode::Id::TXQ: { | 2902 | case OpCode::Id::TXQ: { |