diff options
| author | 2018-11-28 01:41:06 -0300 | |
|---|---|---|
| committer | 2018-11-28 23:45:51 -0300 | |
| commit | 6a642022ddc6eb27a56ef8f88b8590bddd3792a1 (patch) | |
| tree | e2b43c8f604285fc990fe01516169909acfcf162 | |
| parent | Merge pull request #1808 from Tinob/master (diff) | |
| download | yuzu-6a642022ddc6eb27a56ef8f88b8590bddd3792a1.tar.gz yuzu-6a642022ddc6eb27a56ef8f88b8590bddd3792a1.tar.xz yuzu-6a642022ddc6eb27a56ef8f88b8590bddd3792a1.zip | |
gl_shader_decompiler: Scope GLSL variables with a scoped object
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 104 |
1 files changed, 72 insertions, 32 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 0c4524d5c..22f811ada 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -201,14 +201,53 @@ private: | |||
| 201 | } | 201 | } |
| 202 | }; | 202 | }; |
| 203 | 203 | ||
| 204 | template <typename T> | ||
| 205 | class ShaderScopedScope { | ||
| 206 | public: | ||
| 207 | explicit ShaderScopedScope(T& writer, std::string_view begin_expr, std::string end_expr) | ||
| 208 | : writer(writer), end_expr(std::move(end_expr)) { | ||
| 209 | |||
| 210 | if (begin_expr.empty()) { | ||
| 211 | writer.AddLine('{'); | ||
| 212 | } else { | ||
| 213 | writer.AddExpression(begin_expr); | ||
| 214 | writer.AddLine(" {"); | ||
| 215 | } | ||
| 216 | ++writer.scope; | ||
| 217 | } | ||
| 218 | |||
| 219 | ShaderScopedScope(const ShaderScopedScope&) = delete; | ||
| 220 | |||
| 221 | ~ShaderScopedScope() { | ||
| 222 | --writer.scope; | ||
| 223 | if (end_expr.empty()) { | ||
| 224 | writer.AddLine('}'); | ||
| 225 | } else { | ||
| 226 | writer.AddExpression("} "); | ||
| 227 | writer.AddExpression(end_expr); | ||
| 228 | writer.AddLine(';'); | ||
| 229 | } | ||
| 230 | } | ||
| 231 | |||
| 232 | ShaderScopedScope& operator=(const ShaderScopedScope&) = delete; | ||
| 233 | |||
| 234 | private: | ||
| 235 | T& writer; | ||
| 236 | std::string end_expr; | ||
| 237 | }; | ||
| 238 | |||
| 204 | class ShaderWriter { | 239 | class ShaderWriter { |
| 205 | public: | 240 | public: |
| 206 | void AddLine(std::string_view text) { | 241 | void AddExpression(std::string_view text) { |
| 207 | DEBUG_ASSERT(scope >= 0); | 242 | DEBUG_ASSERT(scope >= 0); |
| 208 | if (!text.empty()) { | 243 | if (!text.empty()) { |
| 209 | AppendIndentation(); | 244 | AppendIndentation(); |
| 210 | } | 245 | } |
| 211 | shader_source += text; | 246 | shader_source += text; |
| 247 | } | ||
| 248 | |||
| 249 | void AddLine(std::string_view text) { | ||
| 250 | AddExpression(text); | ||
| 212 | AddNewLine(); | 251 | AddNewLine(); |
| 213 | } | 252 | } |
| 214 | 253 | ||
| @@ -228,6 +267,11 @@ public: | |||
| 228 | return std::move(shader_source); | 267 | return std::move(shader_source); |
| 229 | } | 268 | } |
| 230 | 269 | ||
| 270 | ShaderScopedScope<ShaderWriter> Scope(std::string_view begin_expr = {}, | ||
| 271 | std::string end_expr = {}) { | ||
| 272 | return ShaderScopedScope(*this, begin_expr, end_expr); | ||
| 273 | } | ||
| 274 | |||
| 231 | int scope = 0; | 275 | int scope = 0; |
| 232 | 276 | ||
| 233 | private: | 277 | private: |
| @@ -311,7 +355,7 @@ public: | |||
| 311 | // Default - do nothing | 355 | // Default - do nothing |
| 312 | return value; | 356 | return value; |
| 313 | default: | 357 | default: |
| 314 | UNIMPLEMENTED_MSG("Unimplemented conversion size: {}", static_cast<u32>(size)); | 358 | UNREACHABLE_MSG("Unimplemented conversion size: {}", static_cast<u32>(size)); |
| 315 | } | 359 | } |
| 316 | } | 360 | } |
| 317 | 361 | ||
| @@ -2747,26 +2791,28 @@ private: | |||
| 2747 | UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), | 2791 | UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), |
| 2748 | "NODEP is not implemented"); | 2792 | "NODEP is not implemented"); |
| 2749 | 2793 | ||
| 2794 | const auto scope = shader.Scope(); | ||
| 2795 | |||
| 2750 | const bool depth_compare = | 2796 | const bool depth_compare = |
| 2751 | instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | 2797 | instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |
| 2752 | u32 num_coordinates = TextureCoordinates(texture_type); | 2798 | u32 num_coordinates = TextureCoordinates(texture_type); |
| 2753 | const auto process_mode = instr.texs.GetTextureProcessMode(); | 2799 | const auto process_mode = instr.texs.GetTextureProcessMode(); |
| 2754 | std::string lod_value; | ||
| 2755 | std::string coord; | ||
| 2756 | u32 lod_offset = 0; | 2800 | u32 lod_offset = 0; |
| 2757 | if (process_mode == Tegra::Shader::TextureProcessMode::LL) { | 2801 | if (process_mode == Tegra::Shader::TextureProcessMode::LL) { |
| 2758 | if (num_coordinates > 2) { | 2802 | if (num_coordinates > 2) { |
| 2759 | lod_value = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | 2803 | shader.AddLine("float lod_value = " + |
| 2804 | regs.GetRegisterAsFloat(instr.gpr20.Value() + 1) + ';'); | ||
| 2760 | lod_offset = 2; | 2805 | lod_offset = 2; |
| 2761 | } else { | 2806 | } else { |
| 2762 | lod_value = regs.GetRegisterAsFloat(instr.gpr20); | 2807 | shader.AddLine("float lod_value = " + regs.GetRegisterAsFloat(instr.gpr20) + |
| 2808 | ';'); | ||
| 2763 | lod_offset = 1; | 2809 | lod_offset = 1; |
| 2764 | } | 2810 | } |
| 2765 | } | 2811 | } |
| 2766 | 2812 | ||
| 2767 | switch (num_coordinates) { | 2813 | switch (num_coordinates) { |
| 2768 | case 1: { | 2814 | case 1: { |
| 2769 | coord = "float coords = " + regs.GetRegisterAsFloat(instr.gpr8) + ';'; | 2815 | shader.AddLine("float coords = " + regs.GetRegisterAsFloat(instr.gpr8) + ';'); |
| 2770 | break; | 2816 | break; |
| 2771 | } | 2817 | } |
| 2772 | case 2: { | 2818 | case 2: { |
| @@ -2776,13 +2822,14 @@ private: | |||
| 2776 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2822 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2777 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2823 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 2778 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | 2824 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); |
| 2779 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index + | 2825 | shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + |
| 2780 | ");"; | 2826 | index + ");"); |
| 2781 | } else { | 2827 | } else { |
| 2782 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | 2828 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); |
| 2783 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2829 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2784 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2830 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 2785 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; | 2831 | shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + index + |
| 2832 | ");"); | ||
| 2786 | } | 2833 | } |
| 2787 | } else { | 2834 | } else { |
| 2788 | if (lod_offset != 0) { | 2835 | if (lod_offset != 0) { |
| @@ -2792,12 +2839,13 @@ private: | |||
| 2792 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2839 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2793 | const std::string z = | 2840 | const std::string z = |
| 2794 | regs.GetRegisterAsFloat(instr.gpr20.Value() + lod_offset); | 2841 | regs.GetRegisterAsFloat(instr.gpr20.Value() + lod_offset); |
| 2795 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | 2842 | shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z + |
| 2843 | ");"); | ||
| 2796 | } else { | 2844 | } else { |
| 2797 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2845 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2798 | const std::string y = | 2846 | const std::string y = |
| 2799 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2847 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2800 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 2848 | shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); |
| 2801 | } | 2849 | } |
| 2802 | } else { | 2850 | } else { |
| 2803 | if (depth_compare) { | 2851 | if (depth_compare) { |
| @@ -2805,11 +2853,12 @@ private: | |||
| 2805 | const std::string y = | 2853 | const std::string y = |
| 2806 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2854 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2807 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | 2855 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); |
| 2808 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | 2856 | shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z + |
| 2857 | ");"); | ||
| 2809 | } else { | 2858 | } else { |
| 2810 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2859 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2811 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2860 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 2812 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 2861 | shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); |
| 2813 | } | 2862 | } |
| 2814 | } | 2863 | } |
| 2815 | } | 2864 | } |
| @@ -2819,7 +2868,7 @@ private: | |||
| 2819 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2868 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2820 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2869 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2821 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | 2870 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); |
| 2822 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | 2871 | shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"); |
| 2823 | break; | 2872 | break; |
| 2824 | } | 2873 | } |
| 2825 | default: | 2874 | default: |
| @@ -2829,7 +2878,7 @@ private: | |||
| 2829 | // Fallback to interpreting as a 2D texture for now | 2878 | // Fallback to interpreting as a 2D texture for now |
| 2830 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2879 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2831 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2880 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 2832 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 2881 | shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); |
| 2833 | texture_type = Tegra::Shader::TextureType::Texture2D; | 2882 | texture_type = Tegra::Shader::TextureType::Texture2D; |
| 2834 | is_array = false; | 2883 | is_array = false; |
| 2835 | } | 2884 | } |
| @@ -2850,7 +2899,7 @@ private: | |||
| 2850 | break; | 2899 | break; |
| 2851 | } | 2900 | } |
| 2852 | case Tegra::Shader::TextureProcessMode::LL: { | 2901 | case Tegra::Shader::TextureProcessMode::LL: { |
| 2853 | texture = "textureLod(" + sampler + ", coords, " + lod_value + ')'; | 2902 | texture = "textureLod(" + sampler + ", coords, lod_value)"; |
| 2854 | break; | 2903 | break; |
| 2855 | } | 2904 | } |
| 2856 | default: { | 2905 | default: { |
| @@ -2883,15 +2932,12 @@ private: | |||
| 2883 | 2932 | ||
| 2884 | u32 extra_op_offset = 0; | 2933 | u32 extra_op_offset = 0; |
| 2885 | 2934 | ||
| 2886 | // Scope to avoid variable name overlaps. | 2935 | ShaderScopedScope scope = shader.Scope(); |
| 2887 | shader.AddLine('{'); | ||
| 2888 | ++shader.scope; | ||
| 2889 | std::string coords; | ||
| 2890 | 2936 | ||
| 2891 | switch (texture_type) { | 2937 | switch (texture_type) { |
| 2892 | case Tegra::Shader::TextureType::Texture1D: { | 2938 | case Tegra::Shader::TextureType::Texture1D: { |
| 2893 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); | 2939 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); |
| 2894 | coords = "float coords = " + x + ';'; | 2940 | shader.AddLine("float coords = " + x + ';'); |
| 2895 | break; | 2941 | break; |
| 2896 | } | 2942 | } |
| 2897 | case Tegra::Shader::TextureType::Texture2D: { | 2943 | case Tegra::Shader::TextureType::Texture2D: { |
| @@ -2900,7 +2946,7 @@ private: | |||
| 2900 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); | 2946 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); |
| 2901 | const std::string y = regs.GetRegisterAsInteger(instr.gpr20); | 2947 | const std::string y = regs.GetRegisterAsInteger(instr.gpr20); |
| 2902 | // shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");"); | 2948 | // shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");"); |
| 2903 | coords = "ivec2 coords = ivec2(" + x + ", " + y + ");"; | 2949 | shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");"); |
| 2904 | extra_op_offset = 1; | 2950 | extra_op_offset = 1; |
| 2905 | break; | 2951 | break; |
| 2906 | } | 2952 | } |
| @@ -2929,9 +2975,6 @@ private: | |||
| 2929 | } | 2975 | } |
| 2930 | } | 2976 | } |
| 2931 | WriteTexsInstruction(instr, coords, texture); | 2977 | WriteTexsInstruction(instr, coords, texture); |
| 2932 | |||
| 2933 | --shader.scope; | ||
| 2934 | shader.AddLine('}'); | ||
| 2935 | break; | 2978 | break; |
| 2936 | } | 2979 | } |
| 2937 | case OpCode::Id::TLD4: { | 2980 | case OpCode::Id::TLD4: { |
| @@ -3015,10 +3058,7 @@ private: | |||
| 3015 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), | 3058 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), |
| 3016 | "AOFFI is not implemented"); | 3059 | "AOFFI is not implemented"); |
| 3017 | 3060 | ||
| 3018 | // Scope to avoid variable name overlaps. | 3061 | const auto scope = shader.Scope(); |
| 3019 | shader.AddLine('{'); | ||
| 3020 | ++shader.scope; | ||
| 3021 | std::string coords; | ||
| 3022 | 3062 | ||
| 3023 | const bool depth_compare = | 3063 | const bool depth_compare = |
| 3024 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | 3064 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |
| @@ -3028,11 +3068,11 @@ private: | |||
| 3028 | const std::string sampler = GetSampler( | 3068 | const std::string sampler = GetSampler( |
| 3029 | instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare); | 3069 | instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare); |
| 3030 | if (!depth_compare) { | 3070 | if (!depth_compare) { |
| 3031 | coords = "vec2 coords = vec2(" + op_a + ", " + op_b + ");"; | 3071 | shader.AddLine("vec2 coords = vec2(" + op_a + ", " + op_b + ");"); |
| 3032 | } else { | 3072 | } else { |
| 3033 | // Note: TLD4S coordinate encoding works just like TEXS's | 3073 | // Note: TLD4S coordinate encoding works just like TEXS's |
| 3034 | const std::string op_y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 3074 | const std::string op_y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 3035 | coords = "vec3 coords = vec3(" + op_a + ", " + op_y + ", " + op_b + ");"; | 3075 | shader.AddLine("vec3 coords = vec3(" + op_a + ", " + op_y + ", " + op_b + ");"); |
| 3036 | } | 3076 | } |
| 3037 | const std::string texture = "textureGather(" + sampler + ", coords, " + | 3077 | const std::string texture = "textureGather(" + sampler + ", coords, " + |
| 3038 | std::to_string(instr.tld4s.component) + ')'; | 3078 | std::to_string(instr.tld4s.component) + ')'; |