Imagination PowerVR SDK Blog

Compile Error on SGX540

pvrshadereditor

#1

Hi forum,


I have an OpenGL ES 2.0 CG course project, the runs fine on all students laptops, on all iOS 5 devices and on Galaxy S2 (Android 2.3.4) Galaxy Note as well as on HTC Desire HD.


But it doesn’t compile on Nexus S (Android 4.0) and Galax Nexus.





With comments in the GLSL code I got compile errors in all shader. So I wrote a function that strips out the comments (// and // comments). After that most shaders compile successfully except one.





It doesn’t compile and the shader log file is empty. The shader does basically a per pixel lighting for several light sources with texture mapping. If I uncomment the bold line:


gl_FragColor *= texture2D(u_texture0, v_texCoord);


is compiles.


I’m pretty much sure the this line is correct and that the compiler has problem.


Here my specific questions.





1) Who is updating the OpenGL ES 2.0 drivers for Nexus S phones? Is it Samsung or Google?


2) Where can I see the OepnGL ES 2.0 driver version?


3) Can I somehow get more specific error messages?


4) Can I get somewhere updates for the PowerVR SGX 540?





You can get the full project with source at: http://comgr.cs.technik.fhnw.ch/


You install the project from the Android market: https://play.google.com/store/apps/details?id=ch.fhnw.comgr





Regards &Thanks for any help


Marcus Hudritsch








#ifdef GL_ES


precision mediump float;


#endif





//



varying vec3   v_P_VS;              // Interpol. point of illum. in view space (VS)

varying vec3   v_N_VS;              // Interpol. normal at v_P_VS in view space

varying vec2   v_texCoord;          // Interpol. texture coordinate in tex. space



uniform int    u_numLightsUsed;     // NO. of lights used light arrays

uniform bool   u_lightIsOn[8];      // flag if light is on

uniform vec4   u_lightPosVS[8];     // position of light in view space

uniform vec4   u_lightAmbient[8];   // ambient light intensity (Ia)

uniform vec4   u_lightDiffuse[8];   // diffuse light intensity (Id)

uniform vec4   u_lightSpecular[8]; // specular light intensity (Is)

uniform vec3   u_lightDirVS[8];     // spot direction in view space

uniform float u_lightSpotCutoff[8];// spot cutoff angle 1-180 degrees

uniform float u_lightSpotCosCut[8];// cosine of spot cutoff angle

uniform float u_lightSpotExp[8];   // spot exponent

uniform vec3   u_lightAtt[8];       // attenuation (const,linear,quadr.)

uniform bool   u_lightDoAtt[8];     // flag if att. must be calc.

uniform vec4   u_globalAmbient;     // Global ambient scene color



uniform vec4   u_matAmbient;        // ambient color reflection coefficient (ka)

uniform vec4   u_matDiffuse;        // diffuse color reflection coefficient (kd)

uniform vec4   u_matSpecular;       // specular color reflection coefficient (ks)

uniform vec4   u_matEmissive;       // emissive color for selfshining materials

uniform float u_matShininess;      // shininess exponent



uniform int    u_projection;        // type of stereo

uniform int    u_stereoEye;        // -1=left, 0=center, 1=right

uniform mat3   u_stereoColorFilter; // color filter matrix

uniform sampler2D u_texture0;       // Color map



//

void PointLight (in    int i,   // OpenGL light number

                 in    vec3 P_VS,// Point of illumination in VS

                 in    vec3 N,   // Normalized normal at v_P_VS

                 in    vec3 E,   // Normalized vector from v_P_VS to view in VS

                 inout vec4 Ia, // Ambient light intesity

                 inout vec4 Id, // Diffuse light intesity

                 inout vec4 Is) // Specular light intesity

{

   // Vector from v_P_VS to the light in VS

   vec3 L = u_lightPosVS.xyz - v_P_VS;

      

   // Calculate attenuation over distance & normalize L

   float att = 1.0;

   if (u_lightDoAtt)

   { vec3 att_dist;

      att_dist.x = 1.0;

      att_dist.z = dot(L,L);        // = distance * distance

      att_dist.y = sqrt(att_dist.z); // = distance

      att = 1.0 / dot(att_dist, u_lightAtt);

      L /= att_dist.y;               // = normalize(L)

   } else L = normalize(L);

   

   // Normalized halfvector between N and L

   vec3 H = normalize(L+E);

   

   // Calculate diffuse & specular factors

   float diffFactor = max(dot(N,L), 0.0);

   float specFactor = 0.0;

   if (diffFactor!=0.0)

      specFactor = pow(max(dot(N,H), 0.0), u_matShininess);

   

   // Calculate spot attenuation

   if (u_lightSpotCutoff < 180.0)

   { float spotDot; // Cosine of angle between L and spotdir

      float spotAtt; // Spot attenuation

      spotDot = dot(-L, u_lightDirVS);

      if (spotDot < u_lightSpotCosCut) spotAtt = 0.0;

      else spotAtt = max(pow(spotDot, u_lightSpotExp), 0.0);

      att *= spotAtt;

   }

   

   // Accumulate light intesities

   Ia += att * u_lightAmbient;

   Id += att * u_lightDiffuse * diffFactor;

   Is += att * u_lightSpecular * specFactor;

}

//

void main()

{ vec4 Ia, Id, Is; // Accumulated light intensities at v_P_VS

   

   Ia = vec4(0.0);        // Ambient light intesity

   Id = vec4(0.0);        // Diffuse light intesity

   Is = vec4(0.0);        // Specular light intesity

   

   vec3 N = normalize(v_N_VS); // A varying normal has not anymore unit length

   vec3 E = normalize(-v_P_VS); // Vector from p to the eye

   

   // Early versions of GLSL do not allow uniforms in for loops

   for (int i=0; i<8; i++)

   { if (i < u_numLightsUsed && u_lightIsOn)

      { PointLight (i, v_P_VS, N, E, Ia, Id, Is);

      }

   }

   

   // Sum up all the reflected color components

   gl_FragColor = u_globalAmbient +

                   u_matEmissive +

                   Ia * u_matAmbient +

                   Id * u_matDiffuse;

                   

   // Componentwise multiply w. texture color

   gl_FragColor *= texture2D(u_texture0, v_texCoord);

   

   // add finally the specular RGB-part

   vec4 specColor = Is * u_matSpecular;

   gl_FragColor.rgb += specColor.rgb;



}

#2

I hit a similar problem with a shader for the Nexus S. That was the only phone that would not compile it. I spent a while commenting out sections (which would make it compile) and then trying alternate syntax to replace them which never worked – as soon as I started to add back the code it would not compile.


It turns out the problem was the total shader complexity; maybe the Nexus S has less shader program storage. I had a medium sized subroutine:
    float crawlIntensity(float intensity, float phaseOffset) …
which was called three times from main():

void main() {
  …
lowp float intensity0 = crawlIntensity(noiseMultiChannel.r, 0.0);
lowp float intensity1 = crawlIntensity(noiseMultiChannel.g, 0.333);
lowp float intensity2 = crawlIntensity(noiseMultiChannel.b, 0.667);
lowp float intensity = min(intensity0 + intensity1 + intensity2, 3.0) * (1.0 / 2.0);

Shader compilers usually in-line all function calls. I confirmed the problem was total complexity when I altered the code above to call the subroutine fewer times:

lowp float intensity0 = crawlIntensity(noiseMultiChannel.r, 0.0);
// lowp float intensity1 = crawlIntensity(noiseMultiChannel.g, 0.333);
// lowp float intensity2 = crawlIntensity(noiseMultiChannel.b, 0.667);
// lowp float intensity = min(intensity0 + intensity1 + intensity2, 3.0) * (1.0 / 2.0);
lowp float intensity = min(intensity0, 1.0) * (3.0 / 2.0);

The second version compiled, so as the syntax was unchanged I realized the shader just needed to be simpler on this phone

#3

Hi,



I’ve taken a look at your shader code in PVRShaderEditor, and it doesn’t appear to be valid GLSL. There are a lot of references to the names of arrays without an index, which is not defined to do anything in GLSL. Section 5.2 of the GLSL spec says that square brackets are the only operation valid for an array - anything else is undefined. It is possible that other vendors are allowing this and doing something, but it should not be relied upon behaviour for portability, and what the behaviour is may be undefined.



I’m not entirely sure what you were attempting to do with these arrays so I’ve been unable to fix them myself, so I can’t give any further comment on what caused your shader to fail at this time. I’d suggest using PVRShaderEditor from our SDK, as it should give you more meaningful output than the shader log alone. It will also give you an idea of cycle counts and how to optimise etc.



If you find any issues after fixing the arrays, please let us know and I’ll try to provide further help, and workarounds if appropriate.



Thanks,

Tobias