diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index 16af7be7f9..83ee484d09 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -477,6 +477,7 @@ void GenerateFragmentShader(char *buffer) { const char *texture = "texture2D"; bool highpFog = false; bool bitwiseOps = false; + bool texelFetch = false; #if defined(USING_GLES2) // Let's wait until we have a real use for this. @@ -487,10 +488,10 @@ void GenerateFragmentShader(char *buffer) { texture = "texture"; glslES30 = true; bitwiseOps = true; + texelFetch = true; } else { WRITE(p, "#version 100\n"); // GLSL ES 1.0 } - WRITE(p, "precision lowp float;\n"); // PowerVR needs highp to do the fog in MHU correctly. // Others don't, and some can't handle highp in the fragment shader. @@ -498,8 +499,10 @@ void GenerateFragmentShader(char *buffer) { // GL_NV_shader_framebuffer_fetch available on mobile platform and ES 2.0 only but not desktop if (gl_extensions.NV_shader_framebuffer_fetch) { - WRITE(p, " #extension GL_NV_shader_framebuffer_fetch : require\n"); + WRITE(p, "#extension GL_NV_shader_framebuffer_fetch : require\n"); } + + WRITE(p, "precision lowp float;\n"); #elif !defined(FORCE_OPENGL_2_0) if (gl_extensions.VersionGEThan(3, 3, 0)) { @@ -507,6 +510,7 @@ void GenerateFragmentShader(char *buffer) { texture = "texture"; glslES30 = true; bitwiseOps = true; + texelFetch = true; WRITE(p, "#version 330\n"); WRITE(p, "#define lowp\n"); WRITE(p, "#define mediump\n"); @@ -514,6 +518,7 @@ void GenerateFragmentShader(char *buffer) { } else if (gl_extensions.VersionGEThan(3, 0, 0)) { fragColor0 = "fragColor0"; bitwiseOps = true; + texelFetch = true; WRITE(p, "#version 130\n"); // Remove lowp/mediump in non-mobile non-glsl 3 implementations WRITE(p, "#define lowp\n"); @@ -560,7 +565,7 @@ void GenerateFragmentShader(char *buffer) { WRITE(p, "uniform sampler2D tex;\n"); if (!gstate.isModeClear() && useShaderBlending) { if (!gl_extensions.NV_shader_framebuffer_fetch) { - if (!gl_extensions.VersionGEThan(3, 0, 0) && !gl_extensions.GLES3) { + if (!texelFetch) { WRITE(p, "uniform vec2 u_fbotexSize;\n"); } WRITE(p, "uniform sampler2D fbotex;\n"); @@ -794,7 +799,11 @@ void GenerateFragmentShader(char *buffer) { const char *colorTestFuncs[] = { "#", "#", " != ", " == " }; if (colorTestFuncs[colorTestFunc][0] != '#') { if (bitwiseOps) { - WRITE(p, " if ((roundAndScaleTo255iv(v.rgb) & u_alphacolormask.rgb) %s (ivec3(u_alphacolorref.rgb) & u_alphacolormask.rgb)) discard;\n", colorTestFuncs[colorTestFunc]); + // Apparently GLES3 does not support vector bitwise ops. + WRITE(p, " ivec3 v_scaled = roundAndScaleTo255iv(v.rgb);"); + const char *maskedFragColor = "ivec3(v_scaled.r & u_alphacolormask.r, v_scaled.g & u_alphacolormask.g, v_scaled.b & u_alphacolormask.b)"; + const char *maskedColorRef = "ivec3(u_alphacolorref.r & u_alphacolormask.r, u_alphacolorref.g & u_alphacolormask.g, u_alphacolorref.b & u_alphacolormask.b)"; + WRITE(p, " if (%s %s %s) discard;\n", maskedFragColor, colorTestFuncs[colorTestFunc], maskedColorRef); } else if (gl_extensions.gpuVendor == GPU_VENDOR_POWERVR) { WRITE(p, " if (roundTo255thv(v.rgb) %s u_alphacolorref.rgb) discard;\n", colorTestFuncs[colorTestFunc]); } else { @@ -829,7 +838,7 @@ void GenerateFragmentShader(char *buffer) { // TODO: EXT_shader_framebuffer_fetch on iOS 6, possibly others. if (gl_extensions.NV_shader_framebuffer_fetch) { WRITE(p, " lowp vec4 destColor = gl_LastFragData[0];\n"); - } else if (!gl_extensions.VersionGEThan(3, 0, 0) && !gl_extensions.GLES3) { + } else if (!texelFetch) { WRITE(p, " lowp vec4 destColor = %s(fbotex, gl_FragCoord.xy * u_fbotexSize.xy);\n", texture); } else { WRITE(p, " lowp vec4 destColor = texelFetch(fbotex, ivec2(gl_FragCoord.x, gl_FragCoord.y), 0);\n");