Issues with PowerVR SGX 540 fragment shaders

This topic contains 0 replies, has 1 voice, and was last updated by  madruga 6 years, 3 months ago.

Viewing 1 post (of 1 total)
  • Author
    Posts
  • #30627

    madruga
    Member

    Hello,

    I’m an Android developer, our App applies real-time effects to the camera preview, using some fairly simple GLSL shaders.

    We are getting some issues with devices that use the PowerVR SGX 540 (Galaxy S and Droid 3 among others).

    The errors don’t affect all variants of the devices equally, our Galaxy S works fine, but the ones from the American carriers don’t: some effects don’t show up, we have some error reporting features in the App, and the typical error we get is a GL_INVALID_OPERATION after either glDrawArrays or glGetUniformLocation (and the shader doesn’t work)

    We’ve tried all sorts of things with no luck: packing uniforms into vec4s, removing uniforms altogether, rearrange client code, etc…

    My questions are:
    – Do all devices use the same drivers? Different variants of the same phone seem to behave differently.

    – Are there any known bugs with these devices? should I be avoiding any particular features?

    As an example of our shaders, this is one that creates a cartoon effect:

    precision mediump float;   

    varying vec4 v_yTexCoord;
    varying vec4 v_effectTexCoord;

    uniform sampler2D effectTexture;
    uniform sampler2D effectTexture2;
    uniform sampler2D yTexture;                                                   
    uniform sampler2D uvTexture;                                                                                                                           

    uniform vec4 pvalues;
    uniform vec4 textureSize;

    float yDecode(vec2 texCoord)
    {
        return 1.164 * ( texture2D(yTexture, texCoord).r – 0.0627 );                       
    }

    vec4 yuvDecode(vec2 texCoord)
    {
        vec4 y = 1.164 * ( texture2D(yTexture, texCoord) – 0.0627 );                   
        vec4 uv = texture2D(uvTexture, texCoord) – 0.5;                                                                       
        return y + vec4( 1.596 * uv.r, – 0.813 * uv.r – 0.391 * uv.a, 2.018 * uv.a, 1.0);       
    }

    float edgeDetection(vec2 texCoords)
    {   
        vec2 xdisp = vec2(1.0/textureSize.x, 0.0);
        vec2 ydisp = vec2(0.0, 1.0/textureSize.y);
       
        //grab surrounding px colors
        float tl = yDecode(texCoords – xdisp – ydisp);
        float l =  yDecode(texCoords – xdisp);
        float bl = yDecode(texCoords – xdisp + ydisp);
        float t =  yDecode(texCoords – xdisp);
        float b =  yDecode(texCoords + ydisp);
        float tr = yDecode(texCoords + xdisp – ydisp);
        float r =  yDecode(texCoords + xdisp);
        float br = yDecode(texCoords + xdisp + ydisp);
       
        float dX = -tl – 2.0*l – bl + tr + 2.0*r + br;
        float dY = -tl – 2.0*t – tr + bl + 2.0*b + br;
       
        //compute the magnitude
        float grad = abs(dX) + abs(dY);
       
        return clamp(grad*pvalues.z, 0.0, 1.0);       
    }

    void main()
    {   
        float grad = edgeDetection(v_yTexCoord.xy);
        highp vec4 color = yuvDecode(v_yTexCoord.xy);
       
        vec3 yuv;
        yuv.r = 0.299 * color.r + 0.587 * color.g + 0.114 * color.b;   
        yuv.g = (color.b-yuv.r)*0.565;   
        yuv.b = (color.r-yuv.r)*0.713;   
        float grayscale = yuv.r;
       
        float chalk = floor((yuv.r * 5.0 ) + 0.5);
        float howmuch = 48.0;
       
        yuv.r = ceil((yuv.r * 256.0 / howmuch)-0.5);
        yuv.r *= howmuch;
        yuv.r /= 256.0;
       
        vec3 colorC;
        colorC.r = yuv.r + 1.403 * yuv.b;
        colorC.g = yuv.r – 0.344 * yuv.g – 0.714 * yuv.b;   
        colorC.b = yuv.r + 1.770 * yuv.g;
       
        grad = mix(grad, 0.5, grad);
        color.rgb = vec3(1.0 – grad);

        vec2 halfCoord = v_effectTexCoord.xy * 0.5;
        vec2 topLeft = vec2(0.0, 0.0);
        vec2 topRight = vec2(0.5, 0.0);
        vec2 bottomLeft = vec2(0.0, 0.5);
        vec2 bottomRight = vec2(0.5, 0.5);
       
        if ( chalk < 1.0 )
        {
            color.rgb -= vec3(1.0 – texture2D( effectTexture, halfCoord.xy + bottomRight  ).rgb);       
        }
        if ( (chalk >= 1.0  ) && (chalk < 2.0) )
        {
            color.rgb -= vec3(1.0 – texture2D( effectTexture, halfCoord.xy + bottomLeft ).rgb);       
        }
        if ( (chalk >= 2.0 ) && (chalk < 3.0) )
        {
            color.rgb -= vec3(1.0 – texture2D( effectTexture, halfCoord.xy + topRight ).rgb);       
        }
        if ( (chalk >= 3.0) )
        {
            color.rgb -= vec3(1.0 – texture2D( effectTexture, halfCoord.xy + topLeft ).rgb);       
        }
       
        color.rgb = mix(colorC  * vec3(229.0/255.0, 170.0/255.0, 110.0/255.0), color.rgb, 0.65);
       
        // Contrast 2*(Src*t + 0.25 – 0.5*t)   
        color.xyz = ((color.rgb – 0.5) * max(pvalues.x, 0.0)) + 0.5;
       
        // Brightness   
        color.xyz *= vec3(pvalues.y, pvalues.y, pvalues.y);
       
        gl_FragColor = color;   
    }

    madruga2011-09-09 21:19:23

Viewing 1 post (of 1 total)
You must be logged in to reply to this topic.