Shaders working fine on intel but not on ARM

Hi all,

So I have this fragment and vertex shaders for converting bayer video to RGBA (

This fragment & vertex work fine on my intel-i3(GPU: Intel Corporation 3rd Gen Core processor Graphics Controller) machine but when running those same shaders on ARM(GPU: Vivante gc2000) imx.6/Q I am getting a RGBA video stream but with green dots all over the image.

My Question is what could be the reason for such behavior ? and what is the difference between intel and ARM in dealing with those shaders ?


The CPU is irrelevant - shaders run on the GPU. What GPUs do each system use?

oh yes of course you are right.

Shader works fine on : Intel Corporation 3rd Gen Core processor Graphics Controller

Shaders don’t work properly on : Vivante gc2000

Your ARM is using OpenGL ES, not OpenGL, right?

You might post your shaders to give us something to go on.

Yes of course, my ARM is using OpenGL ES 2.0
On INTEL I have OpenGL 3.0

Fragment shader :

/** Monochrome RGBA or GL_LUMINANCE Bayer encoded texture.*/
uniform sampler2D tex;

varying vec2 v_texcoord;

varying vec4 center;
varying vec4 yCoord;
varying vec4 xCoord;

void main(void) {

    #define fetch(x, y) texture2D(tex, vec2(x, y)).r

    float C = texture2D(tex,; // ( 0, 0)
    const vec4 kC = vec4( 4.0,  6.0,  5.0,  5.0)/ 8.0;

    // Determine which of four types of pixels we are on.
    vec2 alternate = mod(floor(, 2.0);

    vec4 Dvec = vec4(
        fetch(xCoord[1], yCoord[1]),  // (-1,-1)
        fetch(xCoord[1], yCoord[2]),  // (-1, 1)
        fetch(xCoord[2], yCoord[1]),  // ( 1,-1)
        fetch(xCoord[2], yCoord[2])); // ( 1, 1)       

    vec4 PATTERN = ( * C).xyzz;

    // Can also be a dot product with (1,1,1,1) on hardware where that is
    // specially optimized.
    // Equivalent to: D = Dvec[0] + Dvec[1] + Dvec[2] + Dvec[3];
    Dvec.xy +=;
    Dvec.x  += Dvec.y;
    vec4 value = vec4(  
        fetch(center.x, yCoord[0]),   // ( 0,-2)
        fetch(center.x, yCoord[1]),   // ( 0,-1)
        fetch(xCoord[0], center.y),   // (-1, 0)
        fetch(xCoord[1], center.y));  // (-2, 0)
    vec4 temp = vec4(
        fetch(center.x, yCoord[3]),   // ( 0, 2)
        fetch(center.x, yCoord[2]),   // ( 0, 1)
        fetch(xCoord[3], center.y),   // ( 2, 0)
        fetch(xCoord[2], center.y));  // ( 1, 0)

    // Even the simplest compilers should be able to constant-fold these to avoid the division.
    // Note that on scalar processors these constants force computation of some identical products twice.
    const vec4 kA = vec4(-1.0, -1.5,  0.5, -1.0) / 8.0;
    const vec4 kB = vec4( 2.0,  0.0,  0.0,  4.0) / 8.0;
    const vec4 kD = vec4( 0.0,  2.0, -1.0, -1.0) / 8.0;  
    // Conserve constant registers and take advantage of free swizzle on load
    #define kE (kA.xywz)
    #define kF (kB.xywz)
    value += temp;
    // There are five filter patterns (identity, cross, checker,
    // theta, phi).  Precompute the terms from all of them and then
    // use swizzles to assign to color channels. 
    // Channel   Matches
    //   x       cross   (e.g., EE G)
    //   y       checker (e.g., EE B)
    //   z       theta   (e.g., EO R)
    //   w       phi     (e.g., EO R)
    #define A (value[0])
    #define B (value[1])
    #define D (Dvec.x)
    #define E (value[2])
    #define F (value[3])
    // Avoid zero elements. On a scalar processor this saves two MADDs and it has no
    // effect on a vector processor.
    PATTERN.yzw += (kD.yz * D).xyy;

    PATTERN += ( * A).xyzx + (kE.xyw * E).xyxz;
    PATTERN.xw  += kB.xw * B;
    PATTERN.xz  += kF.xz * F;

    vec3 result = (alternate.y == 0.0) ?
        ((alternate.x == 0.0) ?
            vec3(C, PATTERN.xy) :
            vec3(PATTERN.z, C, PATTERN.w)) :
        ((alternate.x == 0.0) ?
            vec3(PATTERN.w, C, PATTERN.z) :
            vec3(PATTERN.yx, C));


Vertex Shader :

    attribute vec4 a_position;
    attribute vec2 a_texcoord;
    varying vec2 v_texcoord;

    varying vec4 xCoord;
    varying vec4 yCoord;
    varying vec4 center;

    uniform float width;
    uniform float height;

    varying float width_opposite = 0.00091;
    varying float height_opposite= 0.00114;

    vec4 sourceSize = vec4(width,height,width_opposite,height_opposite);
    const vec2 firstRed = vec2(0.1,1.0);

    void main(void)

    center.xy = a_texcoord.xy; = a_texcoord.xy * sourceSize.xy + firstRed;

    vec2 invSize =;

    xCoord = center.x + vec4(-2.0 * invSize.x, -invSize.x, invSize.x, 2.0 * invSize.x);
    yCoord = center.y + vec4(-2.0 * invSize.y, -invSize.y, invSize.y, 2.0 * invSize.y);

    gl_Position= a_position;
    v_texcoord = a_texcoord;


For readability, please do surround your code blocks with [noparse]




[/noparse] blocks. Note that you can use “cpp” instead of “glsl” for the highlight tag when posting C/C++ code.

Nothing is jumping out at me here as the cause. I’d start removing code from your shaders on ARM until you identify what part is causing the green dots. Look out for differences in variable or texture component precision between the two platforms.

I can’t remove parts to observe where the problems resides because the shader should work as a whole to convert image from bayer to RGBA.

Concerning the precision, I have reduced it for INTEL GPU and I still don’t have green dots on that platform.
Besides, I have tried the shader on a 200X100 resolution images, so I will get float width_opposite=0.005 and float height_opposite=0.01.

==> I am still getting green dots even with 200X100 images


Where you stand with the status of the code?
Could you please share your code to look it up.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.