summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2018-11-28 01:41:06 -0300
committerGravatar ReinUsesLisp2018-11-28 23:45:51 -0300
commit6a642022ddc6eb27a56ef8f88b8590bddd3792a1 (patch)
treee2b43c8f604285fc990fe01516169909acfcf162
parentMerge pull request #1808 from Tinob/master (diff)
downloadyuzu-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.cpp104
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
204template <typename T>
205class ShaderScopedScope {
206public:
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
234private:
235 T& writer;
236 std::string end_expr;
237};
238
204class ShaderWriter { 239class ShaderWriter {
205public: 240public:
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
233private: 277private:
@@ -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) + ')';