diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 113 |
1 files changed, 70 insertions, 43 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 3a7e82beb..8c43f0ead 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -1261,7 +1261,15 @@ private: | |||
| 1261 | regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); | 1261 | regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); |
| 1262 | } | 1262 | } |
| 1263 | 1263 | ||
| 1264 | void WriteTexsInstruction(const Instruction& instr, const std::string& texture) { | 1264 | void WriteTexsInstruction(const Instruction& instr, const std::string& coord, |
| 1265 | const std::string& texture) { | ||
| 1266 | // Add an extra scope and declare the texture coords inside to prevent | ||
| 1267 | // overwriting them in case they are used as outputs of the texs instruction. | ||
| 1268 | shader.AddLine('{'); | ||
| 1269 | ++shader.scope; | ||
| 1270 | shader.AddLine(coord); | ||
| 1271 | shader.AddLine("vec4 texture_tmp = " + texture + ';'); | ||
| 1272 | |||
| 1265 | // TEXS has two destination registers and a swizzle. The first two elements in the swizzle | 1273 | // TEXS has two destination registers and a swizzle. The first two elements in the swizzle |
| 1266 | // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 | 1274 | // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 |
| 1267 | 1275 | ||
| @@ -1273,17 +1281,19 @@ private: | |||
| 1273 | 1281 | ||
| 1274 | if (written_components < 2) { | 1282 | if (written_components < 2) { |
| 1275 | // Write the first two swizzle components to gpr0 and gpr0+1 | 1283 | // Write the first two swizzle components to gpr0 and gpr0+1 |
| 1276 | regs.SetRegisterToFloat(instr.gpr0, component, texture, 1, 4, false, | 1284 | regs.SetRegisterToFloat(instr.gpr0, component, "texture_tmp", 1, 4, false, |
| 1277 | written_components % 2); | 1285 | written_components % 2); |
| 1278 | } else { | 1286 | } else { |
| 1279 | ASSERT(instr.texs.HasTwoDestinations()); | 1287 | ASSERT(instr.texs.HasTwoDestinations()); |
| 1280 | // Write the rest of the swizzle components to gpr28 and gpr28+1 | 1288 | // Write the rest of the swizzle components to gpr28 and gpr28+1 |
| 1281 | regs.SetRegisterToFloat(instr.gpr28, component, texture, 1, 4, false, | 1289 | regs.SetRegisterToFloat(instr.gpr28, component, "texture_tmp", 1, 4, false, |
| 1282 | written_components % 2); | 1290 | written_components % 2); |
| 1283 | } | 1291 | } |
| 1284 | 1292 | ||
| 1285 | ++written_components; | 1293 | ++written_components; |
| 1286 | } | 1294 | } |
| 1295 | --shader.scope; | ||
| 1296 | shader.AddLine('}'); | ||
| 1287 | } | 1297 | } |
| 1288 | 1298 | ||
| 1289 | static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { | 1299 | static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { |
| @@ -2505,7 +2515,7 @@ private: | |||
| 2505 | array_elem = regs.GetRegisterAsInteger(instr.gpr8); | 2515 | array_elem = regs.GetRegisterAsInteger(instr.gpr8); |
| 2506 | start_index = 1; | 2516 | start_index = 1; |
| 2507 | } | 2517 | } |
| 2508 | auto process_mode = instr.tex.GetTextureProcessMode(); | 2518 | const auto process_mode = instr.tex.GetTextureProcessMode(); |
| 2509 | u32 start_index_b = 0; | 2519 | u32 start_index_b = 0; |
| 2510 | std::string lod_value; | 2520 | std::string lod_value; |
| 2511 | if (process_mode != Tegra::Shader::TextureProcessMode::LZ && | 2521 | if (process_mode != Tegra::Shader::TextureProcessMode::LZ && |
| @@ -2563,8 +2573,10 @@ private: | |||
| 2563 | } | 2573 | } |
| 2564 | case 3: { | 2574 | case 3: { |
| 2565 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index); | 2575 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index); |
| 2566 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1); | 2576 | const std::string y = |
| 2567 | const std::string z = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 2); | 2577 | regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1); |
| 2578 | const std::string z = | ||
| 2579 | regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 2); | ||
| 2568 | if (is_array) { | 2580 | if (is_array) { |
| 2569 | depth_compare_extra = depth_compare; | 2581 | depth_compare_extra = depth_compare; |
| 2570 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + | 2582 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + |
| @@ -2595,7 +2607,7 @@ private: | |||
| 2595 | // Add an extra scope and declare the texture coords inside to prevent | 2607 | // Add an extra scope and declare the texture coords inside to prevent |
| 2596 | // overwriting them in case they are used as outputs of the texs instruction. | 2608 | // overwriting them in case they are used as outputs of the texs instruction. |
| 2597 | 2609 | ||
| 2598 | shader.AddLine("{"); | 2610 | shader.AddLine('{'); |
| 2599 | ++shader.scope; | 2611 | ++shader.scope; |
| 2600 | shader.AddLine(coord); | 2612 | shader.AddLine(coord); |
| 2601 | std::string texture; | 2613 | std::string texture; |
| @@ -2624,7 +2636,8 @@ private: | |||
| 2624 | texture = "texture(" + sampler + ", coords, " + lod_value + ')'; | 2636 | texture = "texture(" + sampler + ", coords, " + lod_value + ')'; |
| 2625 | } else { | 2637 | } else { |
| 2626 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | 2638 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; |
| 2627 | LOG_WARNING(HW_GPU, "OpenGL Limitation: can't set bias value along depth compare"); | 2639 | LOG_WARNING(HW_GPU, |
| 2640 | "OpenGL Limitation: can't set bias value along depth compare"); | ||
| 2628 | } | 2641 | } |
| 2629 | break; | 2642 | break; |
| 2630 | } | 2643 | } |
| @@ -2635,7 +2648,8 @@ private: | |||
| 2635 | texture = "textureLod(" + sampler + ", coords, " + lod_value + ')'; | 2648 | texture = "textureLod(" + sampler + ", coords, " + lod_value + ')'; |
| 2636 | } else { | 2649 | } else { |
| 2637 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | 2650 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; |
| 2638 | LOG_WARNING(HW_GPU, "OpenGL Limitation: can't set lod value along depth compare"); | 2651 | LOG_WARNING(HW_GPU, |
| 2652 | "OpenGL Limitation: can't set lod value along depth compare"); | ||
| 2639 | } | 2653 | } |
| 2640 | break; | 2654 | break; |
| 2641 | } | 2655 | } |
| @@ -2650,20 +2664,22 @@ private: | |||
| 2650 | } | 2664 | } |
| 2651 | } | 2665 | } |
| 2652 | if (!depth_compare) { | 2666 | if (!depth_compare) { |
| 2667 | shader.AddLine("vec4 texture_tmp = " + texture + ';'); | ||
| 2653 | std::size_t dest_elem{}; | 2668 | std::size_t dest_elem{}; |
| 2654 | for (std::size_t elem = 0; elem < 4; ++elem) { | 2669 | for (std::size_t elem = 0; elem < 4; ++elem) { |
| 2655 | if (!instr.tex.IsComponentEnabled(elem)) { | 2670 | if (!instr.tex.IsComponentEnabled(elem)) { |
| 2656 | // Skip disabled components | 2671 | // Skip disabled components |
| 2657 | continue; | 2672 | continue; |
| 2658 | } | 2673 | } |
| 2659 | regs.SetRegisterToFloat(instr.gpr0, elem, texture, 1, 4, false, dest_elem); | 2674 | regs.SetRegisterToFloat(instr.gpr0, elem, "texture_tmp", 1, 4, false, |
| 2675 | dest_elem); | ||
| 2660 | ++dest_elem; | 2676 | ++dest_elem; |
| 2661 | } | 2677 | } |
| 2662 | } else { | 2678 | } else { |
| 2663 | regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false); | 2679 | regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false); |
| 2664 | } | 2680 | } |
| 2665 | --shader.scope; | 2681 | --shader.scope; |
| 2666 | shader.AddLine("}"); | 2682 | shader.AddLine('}'); |
| 2667 | break; | 2683 | break; |
| 2668 | } | 2684 | } |
| 2669 | case OpCode::Id::TEXS: { | 2685 | case OpCode::Id::TEXS: { |
| @@ -2676,8 +2692,9 @@ private: | |||
| 2676 | const bool depth_compare = | 2692 | const bool depth_compare = |
| 2677 | instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | 2693 | instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |
| 2678 | u32 num_coordinates = TextureCoordinates(texture_type); | 2694 | u32 num_coordinates = TextureCoordinates(texture_type); |
| 2679 | auto process_mode = instr.texs.GetTextureProcessMode(); | 2695 | const auto process_mode = instr.texs.GetTextureProcessMode(); |
| 2680 | std::string lod_value; | 2696 | std::string lod_value; |
| 2697 | std::string coord; | ||
| 2681 | u32 lod_offset = 0; | 2698 | u32 lod_offset = 0; |
| 2682 | if (process_mode == Tegra::Shader::TextureProcessMode::LL) { | 2699 | if (process_mode == Tegra::Shader::TextureProcessMode::LL) { |
| 2683 | if (num_coordinates > 2) { | 2700 | if (num_coordinates > 2) { |
| @@ -2689,38 +2706,46 @@ private: | |||
| 2689 | } | 2706 | } |
| 2690 | } | 2707 | } |
| 2691 | 2708 | ||
| 2692 | // Scope to avoid variable name overlaps. | ||
| 2693 | shader.AddLine('{'); | ||
| 2694 | ++shader.scope; | ||
| 2695 | |||
| 2696 | switch (num_coordinates) { | 2709 | switch (num_coordinates) { |
| 2697 | case 1: { | 2710 | case 1: { |
| 2698 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2711 | coord = "float coords = " + regs.GetRegisterAsFloat(instr.gpr8) + ';'; |
| 2699 | coord = "float coords = " + x + ';'; | ||
| 2700 | break; | 2712 | break; |
| 2701 | } | 2713 | } |
| 2702 | case 2: { | 2714 | case 2: { |
| 2703 | if (is_array) { | 2715 | if (is_array) { |
| 2704 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | 2716 | if (depth_compare) { |
| 2705 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2717 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); |
| 2706 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2718 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2707 | shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"); | 2719 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 2720 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | ||
| 2721 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index + | ||
| 2722 | ");"; | ||
| 2723 | } else { | ||
| 2724 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 2725 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2726 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2727 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; | ||
| 2728 | } | ||
| 2708 | } else { | 2729 | } else { |
| 2709 | if (lod_offset != 0) { | 2730 | if (lod_offset != 0) { |
| 2710 | if (depth_compare) { | 2731 | if (depth_compare) { |
| 2711 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2732 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2712 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2733 | const std::string y = |
| 2713 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + lod_offset); | 2734 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2735 | const std::string z = | ||
| 2736 | regs.GetRegisterAsFloat(instr.gpr20.Value() + lod_offset); | ||
| 2714 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | 2737 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; |
| 2715 | } else { | 2738 | } else { |
| 2716 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2739 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2717 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2740 | const std::string y = |
| 2741 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2718 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 2742 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |
| 2719 | } | 2743 | } |
| 2720 | } else { | 2744 | } else { |
| 2721 | if (depth_compare) { | 2745 | if (depth_compare) { |
| 2722 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2746 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2723 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2747 | const std::string y = |
| 2748 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2724 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | 2749 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); |
| 2725 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | 2750 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; |
| 2726 | } else { | 2751 | } else { |
| @@ -2746,7 +2771,7 @@ private: | |||
| 2746 | // Fallback to interpreting as a 2D texture for now | 2771 | // Fallback to interpreting as a 2D texture for now |
| 2747 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2772 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2748 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2773 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 2749 | shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); | 2774 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |
| 2750 | texture_type = Tegra::Shader::TextureType::Texture2D; | 2775 | texture_type = Tegra::Shader::TextureType::Texture2D; |
| 2751 | is_array = false; | 2776 | is_array = false; |
| 2752 | } | 2777 | } |
| @@ -2760,8 +2785,7 @@ private: | |||
| 2760 | } | 2785 | } |
| 2761 | case Tegra::Shader::TextureProcessMode::LZ: { | 2786 | case Tegra::Shader::TextureProcessMode::LZ: { |
| 2762 | if (depth_compare && is_array) { | 2787 | if (depth_compare && is_array) { |
| 2763 | // Since we got an OpenGL limitation, we set bias very high to enforce mipmap 0 | 2788 | texture = "texture(" + sampler + ", coords)"; |
| 2764 | texture = "texture(" + sampler + ", coords, 1000.0)"; | ||
| 2765 | } else { | 2789 | } else { |
| 2766 | texture = "textureLod(" + sampler + ", coords, 0.0)"; | 2790 | texture = "textureLod(" + sampler + ", coords, 0.0)"; |
| 2767 | } | 2791 | } |
| @@ -2778,13 +2802,11 @@ private: | |||
| 2778 | } | 2802 | } |
| 2779 | } | 2803 | } |
| 2780 | if (!depth_compare) { | 2804 | if (!depth_compare) { |
| 2781 | WriteTexsInstruction(instr, texture); | 2805 | WriteTexsInstruction(instr, coord, texture); |
| 2782 | } else { | 2806 | } else { |
| 2783 | WriteTexsInstruction(instr, "vec4(" + texture + ')'); | 2807 | WriteTexsInstruction(instr, coord, "vec4(" + texture + ')'); |
| 2784 | } | 2808 | } |
| 2785 | 2809 | ||
| 2786 | shader.AddLine('}'); | ||
| 2787 | --shader.scope; | ||
| 2788 | break; | 2810 | break; |
| 2789 | } | 2811 | } |
| 2790 | case OpCode::Id::TLDS: { | 2812 | case OpCode::Id::TLDS: { |
| @@ -2806,11 +2828,12 @@ private: | |||
| 2806 | // Scope to avoid variable name overlaps. | 2828 | // Scope to avoid variable name overlaps. |
| 2807 | shader.AddLine('{'); | 2829 | shader.AddLine('{'); |
| 2808 | ++shader.scope; | 2830 | ++shader.scope; |
| 2831 | std::string coords; | ||
| 2809 | 2832 | ||
| 2810 | switch (texture_type) { | 2833 | switch (texture_type) { |
| 2811 | case Tegra::Shader::TextureType::Texture1D: { | 2834 | case Tegra::Shader::TextureType::Texture1D: { |
| 2812 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); | 2835 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); |
| 2813 | shader.AddLine("int coords = " + x + ';'); | 2836 | coords = "float coords = " + x + ';'; |
| 2814 | break; | 2837 | break; |
| 2815 | } | 2838 | } |
| 2816 | case Tegra::Shader::TextureType::Texture2D: { | 2839 | case Tegra::Shader::TextureType::Texture2D: { |
| @@ -2818,7 +2841,8 @@ private: | |||
| 2818 | 2841 | ||
| 2819 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); | 2842 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); |
| 2820 | const std::string y = regs.GetRegisterAsInteger(instr.gpr20); | 2843 | const std::string y = regs.GetRegisterAsInteger(instr.gpr20); |
| 2821 | shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");"); | 2844 | // shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");"); |
| 2845 | coords = "ivec2 coords = ivec2(" + x + ", " + y + ");"; | ||
| 2822 | extra_op_offset = 1; | 2846 | extra_op_offset = 1; |
| 2823 | break; | 2847 | break; |
| 2824 | } | 2848 | } |
| @@ -2846,7 +2870,7 @@ private: | |||
| 2846 | static_cast<u32>(instr.tlds.GetTextureProcessMode())); | 2870 | static_cast<u32>(instr.tlds.GetTextureProcessMode())); |
| 2847 | } | 2871 | } |
| 2848 | } | 2872 | } |
| 2849 | WriteTexsInstruction(instr, texture); | 2873 | WriteTexsInstruction(instr, coords, texture); |
| 2850 | 2874 | ||
| 2851 | --shader.scope; | 2875 | --shader.scope; |
| 2852 | shader.AddLine('}'); | 2876 | shader.AddLine('}'); |
| @@ -2905,14 +2929,17 @@ private: | |||
| 2905 | 2929 | ||
| 2906 | const std::string texture = "textureGather(" + sampler + ", coords, " + | 2930 | const std::string texture = "textureGather(" + sampler + ", coords, " + |
| 2907 | std::to_string(instr.tld4.component) + ')'; | 2931 | std::to_string(instr.tld4.component) + ')'; |
| 2932 | |||
| 2908 | if (!depth_compare) { | 2933 | if (!depth_compare) { |
| 2934 | shader.AddLine("vec4 texture_tmp = " + texture + ';'); | ||
| 2909 | std::size_t dest_elem{}; | 2935 | std::size_t dest_elem{}; |
| 2910 | for (std::size_t elem = 0; elem < 4; ++elem) { | 2936 | for (std::size_t elem = 0; elem < 4; ++elem) { |
| 2911 | if (!instr.tex.IsComponentEnabled(elem)) { | 2937 | if (!instr.tex.IsComponentEnabled(elem)) { |
| 2912 | // Skip disabled components | 2938 | // Skip disabled components |
| 2913 | continue; | 2939 | continue; |
| 2914 | } | 2940 | } |
| 2915 | regs.SetRegisterToFloat(instr.gpr0, elem, texture, 1, 4, false, dest_elem); | 2941 | regs.SetRegisterToFloat(instr.gpr0, elem, "texture_tmp", 1, 4, false, |
| 2942 | dest_elem); | ||
| 2916 | ++dest_elem; | 2943 | ++dest_elem; |
| 2917 | } | 2944 | } |
| 2918 | } else { | 2945 | } else { |
| @@ -2933,6 +2960,7 @@ private: | |||
| 2933 | // Scope to avoid variable name overlaps. | 2960 | // Scope to avoid variable name overlaps. |
| 2934 | shader.AddLine('{'); | 2961 | shader.AddLine('{'); |
| 2935 | ++shader.scope; | 2962 | ++shader.scope; |
| 2963 | std::string coords; | ||
| 2936 | 2964 | ||
| 2937 | const bool depth_compare = | 2965 | const bool depth_compare = |
| 2938 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | 2966 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |
| @@ -2942,20 +2970,19 @@ private: | |||
| 2942 | const std::string sampler = GetSampler( | 2970 | const std::string sampler = GetSampler( |
| 2943 | instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare); | 2971 | instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare); |
| 2944 | if (!depth_compare) { | 2972 | if (!depth_compare) { |
| 2945 | shader.AddLine("vec2 coords = vec2(" + op_a + ", " + op_b + ");"); | 2973 | coords = "vec2 coords = vec2(" + op_a + ", " + op_b + ");"; |
| 2946 | } else { | 2974 | } else { |
| 2947 | // Note: TLD4S coordinate encoding works just like TEXS's | 2975 | // Note: TLD4S coordinate encoding works just like TEXS's |
| 2948 | shader.AddLine( | 2976 | const std::string op_y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2949 | "float op_y = " + regs.GetRegisterAsFloat(instr.gpr8.Value() + 1) + ';'); | 2977 | coords = "vec3 coords = vec3(" + op_a + ", " + op_y + ", " + op_b + ");"; |
| 2950 | shader.AddLine("vec3 coords = vec3(" + op_a + ", op_y, " + op_b + ");"); | ||
| 2951 | } | 2978 | } |
| 2952 | const std::string texture = "textureGather(" + sampler + ", coords, " + | 2979 | const std::string texture = "textureGather(" + sampler + ", coords, " + |
| 2953 | std::to_string(instr.tld4s.component) + ')'; | 2980 | std::to_string(instr.tld4s.component) + ')'; |
| 2954 | 2981 | ||
| 2955 | if (!depth_compare) { | 2982 | if (!depth_compare) { |
| 2956 | WriteTexsInstruction(instr, texture); | 2983 | WriteTexsInstruction(instr, coords, texture); |
| 2957 | } else { | 2984 | } else { |
| 2958 | WriteTexsInstruction(instr, "vec4(" + texture + ')'); | 2985 | WriteTexsInstruction(instr, coords, "vec4(" + texture + ')'); |
| 2959 | } | 2986 | } |
| 2960 | 2987 | ||
| 2961 | --shader.scope; | 2988 | --shader.scope; |