summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2018-11-28 02:22:10 -0300
committerGravatar ReinUsesLisp2018-11-28 23:45:53 -0300
commitab13b628d0ad07797b39499450bbb231247d2389 (patch)
treebb5c8b956ec67ad406f6496f3020a9deb6b420ab /src
parentgl_shader_decompiler: Scope GLSL variables with a scoped object (diff)
downloadyuzu-ab13b628d0ad07797b39499450bbb231247d2389.tar.gz
yuzu-ab13b628d0ad07797b39499450bbb231247d2389.tar.xz
yuzu-ab13b628d0ad07797b39499450bbb231247d2389.zip
gl_shader_decompiler: Clean up texture instructions
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp143
1 files changed, 56 insertions, 87 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 22f811ada..4ecfef071 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1337,15 +1337,7 @@ private:
1337 regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); 1337 regs.SetRegisterToInteger(dest, true, 0, result, 1, 1);
1338 } 1338 }
1339 1339
1340 void WriteTexsInstruction(const Instruction& instr, const std::string& coord, 1340 void WriteTexsInstruction(const Instruction& instr, const std::string& texture) {
1341 const std::string& texture) {
1342 // Add an extra scope and declare the texture coords inside to prevent
1343 // overwriting them in case they are used as outputs of the texs instruction.
1344 shader.AddLine('{');
1345 ++shader.scope;
1346 shader.AddLine(coord);
1347 shader.AddLine("vec4 texture_tmp = " + texture + ';');
1348
1349 // TEXS has two destination registers and a swizzle. The first two elements in the swizzle 1341 // TEXS has two destination registers and a swizzle. The first two elements in the swizzle
1350 // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 1342 // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1
1351 1343
@@ -1357,19 +1349,17 @@ private:
1357 1349
1358 if (written_components < 2) { 1350 if (written_components < 2) {
1359 // Write the first two swizzle components to gpr0 and gpr0+1 1351 // Write the first two swizzle components to gpr0 and gpr0+1
1360 regs.SetRegisterToFloat(instr.gpr0, component, "texture_tmp", 1, 4, false, 1352 regs.SetRegisterToFloat(instr.gpr0, component, texture, 1, 4, false,
1361 written_components % 2); 1353 written_components % 2);
1362 } else { 1354 } else {
1363 ASSERT(instr.texs.HasTwoDestinations()); 1355 ASSERT(instr.texs.HasTwoDestinations());
1364 // Write the rest of the swizzle components to gpr28 and gpr28+1 1356 // Write the rest of the swizzle components to gpr28 and gpr28+1
1365 regs.SetRegisterToFloat(instr.gpr28, component, "texture_tmp", 1, 4, false, 1357 regs.SetRegisterToFloat(instr.gpr28, component, texture, 1, 4, false,
1366 written_components % 2); 1358 written_components % 2);
1367 } 1359 }
1368 1360
1369 ++written_components; 1361 ++written_components;
1370 } 1362 }
1371 --shader.scope;
1372 shader.AddLine('}');
1373 } 1363 }
1374 1364
1375 static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { 1365 static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) {
@@ -2600,7 +2590,6 @@ private:
2600 } 2590 }
2601 case OpCode::Id::TEX: { 2591 case OpCode::Id::TEX: {
2602 Tegra::Shader::TextureType texture_type{instr.tex.texture_type}; 2592 Tegra::Shader::TextureType texture_type{instr.tex.texture_type};
2603 std::string coord;
2604 const bool is_array = instr.tex.array != 0; 2593 const bool is_array = instr.tex.array != 0;
2605 2594
2606 UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2595 UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
@@ -2633,21 +2622,23 @@ private:
2633 2622
2634 bool depth_compare_extra = false; 2623 bool depth_compare_extra = false;
2635 2624
2625 const auto scope = shader.Scope();
2626
2636 switch (num_coordinates) { 2627 switch (num_coordinates) {
2637 case 1: { 2628 case 1: {
2638 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index); 2629 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index);
2639 if (is_array) { 2630 if (is_array) {
2640 if (depth_compare) { 2631 if (depth_compare) {
2641 coord = "vec3 coords = vec3(" + x + ", " + depth_value + ", " + 2632 shader.AddLine("vec3 coords = vec3(" + x + ", " + depth_value + ", " +
2642 array_elem + ");"; 2633 array_elem + ");");
2643 } else { 2634 } else {
2644 coord = "vec2 coords = vec2(" + x + ", " + array_elem + ");"; 2635 shader.AddLine("vec2 coords = vec2(" + x + ", " + array_elem + ");");
2645 } 2636 }
2646 } else { 2637 } else {
2647 if (depth_compare) { 2638 if (depth_compare) {
2648 coord = "vec2 coords = vec2(" + x + ", " + depth_value + ");"; 2639 shader.AddLine("vec2 coords = vec2(" + x + ", " + depth_value + ");");
2649 } else { 2640 } else {
2650 coord = "float coords = " + x + ';'; 2641 shader.AddLine("float coords = " + x + ';');
2651 } 2642 }
2652 } 2643 }
2653 break; 2644 break;
@@ -2658,17 +2649,18 @@ private:
2658 regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1); 2649 regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1);
2659 if (is_array) { 2650 if (is_array) {
2660 if (depth_compare) { 2651 if (depth_compare) {
2661 coord = "vec4 coords = vec4(" + x + ", " + y + ", " + depth_value + 2652 shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " +
2662 ", " + array_elem + ");"; 2653 depth_value + ", " + array_elem + ");");
2663 } else { 2654 } else {
2664 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + array_elem + ");"; 2655 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " +
2656 array_elem + ");");
2665 } 2657 }
2666 } else { 2658 } else {
2667 if (depth_compare) { 2659 if (depth_compare) {
2668 coord = 2660 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " +
2669 "vec3 coords = vec3(" + x + ", " + y + ", " + depth_value + ");"; 2661 depth_value + ");");
2670 } else { 2662 } else {
2671 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 2663 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
2672 } 2664 }
2673 } 2665 }
2674 break; 2666 break;
@@ -2681,14 +2673,14 @@ private:
2681 regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 2); 2673 regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 2);
2682 if (is_array) { 2674 if (is_array) {
2683 depth_compare_extra = depth_compare; 2675 depth_compare_extra = depth_compare;
2684 coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + 2676 shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " +
2685 array_elem + ");"; 2677 array_elem + ");");
2686 } else { 2678 } else {
2687 if (depth_compare) { 2679 if (depth_compare) {
2688 coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + 2680 shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " +
2689 depth_value + ");"; 2681 depth_value + ");");
2690 } else { 2682 } else {
2691 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; 2683 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z + ");");
2692 } 2684 }
2693 } 2685 }
2694 break; 2686 break;
@@ -2700,7 +2692,7 @@ private:
2700 // Fallback to interpreting as a 2D texture for now 2692 // Fallback to interpreting as a 2D texture for now
2701 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2693 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2702 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2694 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2703 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 2695 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
2704 texture_type = Tegra::Shader::TextureType::Texture2D; 2696 texture_type = Tegra::Shader::TextureType::Texture2D;
2705 } 2697 }
2706 2698
@@ -2709,9 +2701,6 @@ private:
2709 // Add an extra scope and declare the texture coords inside to prevent 2701 // Add an extra scope and declare the texture coords inside to prevent
2710 // overwriting them in case they are used as outputs of the texs instruction. 2702 // overwriting them in case they are used as outputs of the texs instruction.
2711 2703
2712 shader.AddLine('{');
2713 ++shader.scope;
2714 shader.AddLine(coord);
2715 std::string texture; 2704 std::string texture;
2716 2705
2717 switch (instr.tex.GetTextureProcessMode()) { 2706 switch (instr.tex.GetTextureProcessMode()) {
@@ -2765,23 +2754,20 @@ private:
2765 static_cast<u32>(instr.tex.GetTextureProcessMode())); 2754 static_cast<u32>(instr.tex.GetTextureProcessMode()));
2766 } 2755 }
2767 } 2756 }
2768 if (!depth_compare) { 2757
2769 shader.AddLine("vec4 texture_tmp = " + texture + ';'); 2758 if (depth_compare) {
2759 regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false);
2760 } else {
2770 std::size_t dest_elem{}; 2761 std::size_t dest_elem{};
2771 for (std::size_t elem = 0; elem < 4; ++elem) { 2762 for (std::size_t elem = 0; elem < 4; ++elem) {
2772 if (!instr.tex.IsComponentEnabled(elem)) { 2763 if (!instr.tex.IsComponentEnabled(elem)) {
2773 // Skip disabled components 2764 // Skip disabled components
2774 continue; 2765 continue;
2775 } 2766 }
2776 regs.SetRegisterToFloat(instr.gpr0, elem, "texture_tmp", 1, 4, false, 2767 regs.SetRegisterToFloat(instr.gpr0, elem, texture, 1, 4, false, dest_elem);
2777 dest_elem);
2778 ++dest_elem; 2768 ++dest_elem;
2779 } 2769 }
2780 } else {
2781 regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false);
2782 } 2770 }
2783 --shader.scope;
2784 shader.AddLine('}');
2785 break; 2771 break;
2786 } 2772 }
2787 case OpCode::Id::TEXS: { 2773 case OpCode::Id::TEXS: {
@@ -2884,6 +2870,7 @@ private:
2884 } 2870 }
2885 const std::string sampler = 2871 const std::string sampler =
2886 GetSampler(instr.sampler, texture_type, is_array, depth_compare); 2872 GetSampler(instr.sampler, texture_type, is_array, depth_compare);
2873
2887 std::string texture; 2874 std::string texture;
2888 switch (process_mode) { 2875 switch (process_mode) {
2889 case Tegra::Shader::TextureProcessMode::None: { 2876 case Tegra::Shader::TextureProcessMode::None: {
@@ -2908,12 +2895,11 @@ private:
2908 static_cast<u32>(instr.texs.GetTextureProcessMode())); 2895 static_cast<u32>(instr.texs.GetTextureProcessMode()));
2909 } 2896 }
2910 } 2897 }
2911 if (!depth_compare) {
2912 WriteTexsInstruction(instr, coord, texture);
2913 } else {
2914 WriteTexsInstruction(instr, coord, "vec4(" + texture + ')');
2915 }
2916 2898
2899 if (depth_compare) {
2900 texture = "vec4(" + texture + ')';
2901 }
2902 WriteTexsInstruction(instr, texture);
2917 break; 2903 break;
2918 } 2904 }
2919 case OpCode::Id::TLDS: { 2905 case OpCode::Id::TLDS: {
@@ -2974,13 +2960,12 @@ private:
2974 static_cast<u32>(instr.tlds.GetTextureProcessMode())); 2960 static_cast<u32>(instr.tlds.GetTextureProcessMode()));
2975 } 2961 }
2976 } 2962 }
2977 WriteTexsInstruction(instr, coords, texture); 2963 WriteTexsInstruction(instr, texture);
2978 break; 2964 break;
2979 } 2965 }
2980 case OpCode::Id::TLD4: { 2966 case OpCode::Id::TLD4: {
2981 ASSERT(instr.tld4.texture_type == Tegra::Shader::TextureType::Texture2D); 2967 ASSERT(instr.tld4.texture_type == Tegra::Shader::TextureType::Texture2D);
2982 ASSERT(instr.tld4.array == 0); 2968 ASSERT(instr.tld4.array == 0);
2983 std::string coord;
2984 2969
2985 UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2970 UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
2986 "NODEP is not implemented"); 2971 "NODEP is not implemented");
@@ -2997,10 +2982,7 @@ private:
2997 if (depth_compare) 2982 if (depth_compare)
2998 num_coordinates += 1; 2983 num_coordinates += 1;
2999 2984
3000 // Add an extra scope and declare the texture coords inside to prevent 2985 const auto scope = shader.Scope();
3001 // overwriting them in case they are used as outputs of the texs instruction.
3002 shader.AddLine('{');
3003 ++shader.scope;
3004 2986
3005 switch (num_coordinates) { 2987 switch (num_coordinates) {
3006 case 2: { 2988 case 2: {
@@ -3031,7 +3013,9 @@ private:
3031 const std::string texture = "textureGather(" + sampler + ", coords, " + 3013 const std::string texture = "textureGather(" + sampler + ", coords, " +
3032 std::to_string(instr.tld4.component) + ')'; 3014 std::to_string(instr.tld4.component) + ')';
3033 3015
3034 if (!depth_compare) { 3016 if (depth_compare) {
3017 regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false);
3018 } else {
3035 shader.AddLine("vec4 texture_tmp = " + texture + ';'); 3019 shader.AddLine("vec4 texture_tmp = " + texture + ';');
3036 std::size_t dest_elem{}; 3020 std::size_t dest_elem{};
3037 for (std::size_t elem = 0; elem < 4; ++elem) { 3021 for (std::size_t elem = 0; elem < 4; ++elem) {
@@ -3043,11 +3027,7 @@ private:
3043 dest_elem); 3027 dest_elem);
3044 ++dest_elem; 3028 ++dest_elem;
3045 } 3029 }
3046 } else {
3047 regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false);
3048 } 3030 }
3049 --shader.scope;
3050 shader.AddLine('}');
3051 break; 3031 break;
3052 } 3032 }
3053 case OpCode::Id::TLD4S: { 3033 case OpCode::Id::TLD4S: {
@@ -3074,26 +3054,22 @@ private:
3074 const std::string op_y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 3054 const std::string op_y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
3075 shader.AddLine("vec3 coords = vec3(" + op_a + ", " + op_y + ", " + op_b + ");"); 3055 shader.AddLine("vec3 coords = vec3(" + op_a + ", " + op_y + ", " + op_b + ");");
3076 } 3056 }
3077 const std::string texture = "textureGather(" + sampler + ", coords, " +
3078 std::to_string(instr.tld4s.component) + ')';
3079 3057
3080 if (!depth_compare) { 3058 std::string texture = "textureGather(" + sampler + ", coords, " +
3081 WriteTexsInstruction(instr, coords, texture); 3059 std::to_string(instr.tld4s.component) + ')';
3082 } else { 3060 if (depth_compare) {
3083 WriteTexsInstruction(instr, coords, "vec4(" + texture + ')'); 3061 texture = "vec4(" + texture + ')';
3084 } 3062 }
3085 3063 WriteTexsInstruction(instr, texture);
3086 --shader.scope;
3087 shader.AddLine('}');
3088 break; 3064 break;
3089 } 3065 }
3090 case OpCode::Id::TXQ: { 3066 case OpCode::Id::TXQ: {
3091 UNIMPLEMENTED_IF_MSG(instr.txq.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 3067 UNIMPLEMENTED_IF_MSG(instr.txq.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
3092 "NODEP is not implemented"); 3068 "NODEP is not implemented");
3093 3069
3094 ++shader.scope; 3070 const auto scope = shader.Scope();
3095 shader.AddLine('{'); 3071
3096 // TODO: the new commits on the texture refactor, change the way samplers work. 3072 // TODO: The new commits on the texture refactor, change the way samplers work.
3097 // Sadly, not all texture instructions specify the type of texture their sampler 3073 // Sadly, not all texture instructions specify the type of texture their sampler
3098 // uses. This must be fixed at a later instance. 3074 // uses. This must be fixed at a later instance.
3099 const std::string sampler = 3075 const std::string sampler =
@@ -3104,7 +3080,8 @@ private:
3104 regs.GetRegisterAsInteger(instr.gpr8) + ')'; 3080 regs.GetRegisterAsInteger(instr.gpr8) + ')';
3105 const std::string mip_level = "textureQueryLevels(" + sampler + ')'; 3081 const std::string mip_level = "textureQueryLevels(" + sampler + ')';
3106 shader.AddLine("ivec2 sizes = " + texture + ';'); 3082 shader.AddLine("ivec2 sizes = " + texture + ';');
3107 regs.SetRegisterToInteger(instr.gpr0, true, 0, "sizes.x", 1, 1); 3083
3084 regs.SetRegisterToInteger(instr.gpr0.Value() + 0, true, 0, "sizes.x", 1, 1);
3108 regs.SetRegisterToInteger(instr.gpr0.Value() + 1, true, 0, "sizes.y", 1, 1); 3085 regs.SetRegisterToInteger(instr.gpr0.Value() + 1, true, 0, "sizes.y", 1, 1);
3109 regs.SetRegisterToInteger(instr.gpr0.Value() + 2, true, 0, "0", 1, 1); 3086 regs.SetRegisterToInteger(instr.gpr0.Value() + 2, true, 0, "0", 1, 1);
3110 regs.SetRegisterToInteger(instr.gpr0.Value() + 3, true, 0, mip_level, 1, 1); 3087 regs.SetRegisterToInteger(instr.gpr0.Value() + 3, true, 0, mip_level, 1, 1);
@@ -3115,8 +3092,6 @@ private:
3115 static_cast<u32>(instr.txq.query_type.Value())); 3092 static_cast<u32>(instr.txq.query_type.Value()));
3116 } 3093 }
3117 } 3094 }
3118 --shader.scope;
3119 shader.AddLine('}');
3120 break; 3095 break;
3121 } 3096 }
3122 case OpCode::Id::TMML: { 3097 case OpCode::Id::TMML: {
@@ -3131,17 +3106,18 @@ private:
3131 const std::string sampler = 3106 const std::string sampler =
3132 GetSampler(instr.sampler, texture_type, is_array, false); 3107 GetSampler(instr.sampler, texture_type, is_array, false);
3133 3108
3134 // TODO: add coordinates for different samplers once other texture types are 3109 const auto scope = shader.Scope();
3110
3111 // TODO: Add coordinates for different samplers once other texture types are
3135 // implemented. 3112 // implemented.
3136 std::string coord;
3137 switch (texture_type) { 3113 switch (texture_type) {
3138 case Tegra::Shader::TextureType::Texture1D: { 3114 case Tegra::Shader::TextureType::Texture1D: {
3139 coord = "float coords = " + x + ';'; 3115 shader.AddLine("float coords = " + x + ';');
3140 break; 3116 break;
3141 } 3117 }
3142 case Tegra::Shader::TextureType::Texture2D: { 3118 case Tegra::Shader::TextureType::Texture2D: {
3143 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 3119 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
3144 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 3120 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
3145 break; 3121 break;
3146 } 3122 }
3147 default: 3123 default:
@@ -3149,22 +3125,15 @@ private:
3149 3125
3150 // Fallback to interpreting as a 2D texture for now 3126 // Fallback to interpreting as a 2D texture for now
3151 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 3127 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
3152 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 3128 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
3153 texture_type = Tegra::Shader::TextureType::Texture2D; 3129 texture_type = Tegra::Shader::TextureType::Texture2D;
3154 } 3130 }
3155 // Add an extra scope and declare the texture coords inside to prevent 3131
3156 // overwriting them in case they are used as outputs of the texs instruction.
3157 shader.AddLine('{');
3158 ++shader.scope;
3159 shader.AddLine(coord);
3160 const std::string texture = "textureQueryLod(" + sampler + ", coords)"; 3132 const std::string texture = "textureQueryLod(" + sampler + ", coords)";
3161 const std::string tmp = "vec2 tmp = " + texture + "*vec2(256.0, 256.0);"; 3133 shader.AddLine("vec2 tmp = " + texture + " * vec2(256.0, 256.0);");
3162 shader.AddLine(tmp);
3163 3134
3164 regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(tmp.y)", 1, 1); 3135 regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(tmp.y)", 1, 1);
3165 regs.SetRegisterToInteger(instr.gpr0.Value() + 1, false, 0, "uint(tmp.x)", 1, 1); 3136 regs.SetRegisterToInteger(instr.gpr0.Value() + 1, false, 0, "uint(tmp.x)", 1, 1);
3166 --shader.scope;
3167 shader.AddLine('}');
3168 break; 3137 break;
3169 } 3138 }
3170 default: { 3139 default: {