Shader Compiler on Samsung Galaxy S, Samsung S9000, Samsung S9100

Hello,

i have very strange experience on those 3 phones. All of those should have Power SGX 540 chip but i’ve got different results compiling shaders.



Samsung S9100 - android 2.3.6 - compile ok

Samsung Galaxy S - android 4.2.1 - compile failed without reason

Samsung S9000 - android ? - compile crash



I also tested this shader in 4 shader compilers - SGX 535, 540, 543, 6xx and all went fine.



I also tested it in windows emulator - all goes fine





So, it seems to me like shader version problem, so can you, please, help me, what to do with it ?

If it compiles, everything goes fine - no artefacts seen



Best regards and thanks

Petr Sovis







Vertex shader:




#define vxIn attribute
#define vxOut varying
#line 47 2

#define VX_UNIFORMN(typeprec,type,var,tag) uniform typeprec type var
#define VX_UNIFORMDV(typeprec, type, var, tag, defaultValue) uniform typeprec type var
#define vxTex2D texture2D
#define nop

#line 4 3

VX_UNIFORMN(highp , mat4, matProjModelView, MATRIX);
VX_UNIFORMN(highp , mat4, matModelView, MATRIX);
VX_UNIFORMN(highp , mat4, matProjection, MATRIX);
VX_UNIFORMN(highp , vec3, vecCameraPos, VEC3);

VX_UNIFORMN(lowp , sampler2D, DiffuseTex, SAMPLER2D);

VX_UNIFORMN(lowp , sampler2D, SpecTex, SAMPLER2D);
VX_UNIFORMN(lowp , sampler2D, NormalTex, SAMPLER2D);
VX_UNIFORMN(lowp , vec4, AmbientCol, COLOR);

#line 2 4


const lowp vec3 globalAmbient = vec3(104.0,103.0,159.0) * (1.0 / 255.0);
const lowp vec3 globalAmbientCatcher = vec3(204.0,203.0,209.0) * (1.0 / 255.0);


const lowp vec3 lightDiff = vec3(240.0,217.0,175.0) * (1.0 / 255.0);
const lowp vec3 lightSpecColor = lightDiff;
const mediump vec3 lightPos = vec3(0.0,-3.0,1.0);



const lowp vec3 light2Diff = vec3(195.0,209.0,253.0) * (0.7 / 255.0);
const lowp vec3 light2SpecColor = light2Diff;
const lowp vec3 light2Dir = normalize(vec3(2.0,5.0,0.0));

#line 22 5

vxIn vec3 inPos;
vxIn vec3 inNormal;
vxIn vec2 inTex0;
vxIn vec3 inTangent;
vxIn vec3 inBinormal;


vxOut mediump vec2 interTex0;
vxOut mediump vec3 interLightVec;
vxOut mediump vec3 interLightVec2;
vxOut mediump vec3 interEyeVec;
vxOut mediump vec3 interHalfVec;
vxOut mediump vec3 interHalfVec2;


void saEnemyVertexFn()
{

highp vec3 outPos;

lowp mat3 mmVN = mat3(matModelView);


outPos = (matModelView * vec4(inPos,1.0)).xyz;
lowp vec3 trNormal = normalize(mmVN * inNormal);
lowp vec3 trTangent = normalize(mmVN * inTangent);
lowp vec3 trBinormal = normalize(mmVN * inBinormal);

lowp vec3 lightDir = normalize(lightPos - outPos);

interLightVec.x = dot(trTangent, lightDir);
interLightVec.y = dot(trBinormal, lightDir);
interLightVec.z = dot(trNormal, lightDir);

interLightVec2.x = dot(trTangent, light2Dir);
interLightVec2.y = dot(trBinormal, light2Dir);
interLightVec2.z = dot(trNormal, light2Dir);

mediump vec3 v, no;

no = normalize(vecCameraPos - outPos);


v.x = dot(trTangent, no);
v.y = dot(trBinormal, no);
v.z = dot(trNormal, no);
interEyeVec = normalize(v);

v = normalize(no + lightDir);
interHalfVec.x = dot(trTangent, v);
interHalfVec.y = dot(trBinormal, v);
interHalfVec.z = dot(trNormal, v);

v = normalize(no + light2Dir);
interHalfVec2.x = dot(trTangent, v);
interHalfVec2.y = dot(trBinormal, v);
interHalfVec2.z = dot(trNormal, v);

gl_Position = matProjection * vec4(outPos, 1.0);
interTex0 = inTex0;
}
#line 0 7
void main() { saEnemyVertexFn(); }


Fragmen shader:


#ifdef GL_FRAGMENT_PRECISION_HIGH
#else
#define highp mediump
#endif

#define nomeaning

#define vxIn varying
#define vxOut(x) nomeaning
#define vxPixelResult gl_FragColor

#line 47 2

#define VX_UNIFORMN(typeprec,type,var,tag) uniform typeprec type var
#define VX_UNIFORMDV(typeprec, type, var, tag, defaultValue) uniform typeprec type var
#define vxTex2D texture2D
#define nop

#line 4 3

VX_UNIFORMN(highp , mat4, matProjModelView, MATRIX);
VX_UNIFORMN(highp , mat4, matModelView, MATRIX);
VX_UNIFORMN(highp , mat4, matProjection, MATRIX);
VX_UNIFORMN(highp , vec3, vecCameraPos, VEC3);

VX_UNIFORMN(lowp , sampler2D, DiffuseTex, SAMPLER2D);

VX_UNIFORMN(lowp , sampler2D, SpecTex, SAMPLER2D);
VX_UNIFORMN(lowp , sampler2D, NormalTex, SAMPLER2D);
VX_UNIFORMN(lowp , vec4, AmbientCol, COLOR);

#line 2 4


const lowp vec3 globalAmbient = vec3(104.0,103.0,159.0) * (1.0 / 255.0);
const lowp vec3 globalAmbientCatcher = vec3(204.0,203.0,209.0) * (1.0 / 255.0);


const lowp vec3 lightDiff = vec3(240.0,217.0,175.0) * (1.0 / 255.0);
const lowp vec3 lightSpecColor = lightDiff;
const mediump vec3 lightPos = vec3(0.0,-3.0,1.0);



const lowp vec3 light2Diff = vec3(195.0,209.0,253.0) * (0.7 / 255.0);
const lowp vec3 light2SpecColor = light2Diff;
const lowp vec3 light2Dir = (vec3(2.0,5.0,0.0));

#line 88 6

vxIn mediump vec2 interTex0;

vxIn mediump vec3 interLightVec;
vxIn mediump vec3 interLightVec2;
vxIn mediump vec3 interEyeVec;
vxIn mediump vec3 interHalfVec;
vxIn mediump vec3 interHalfVec2;

vxOut( vec4 vxPixelResult)


lowp vec3 specLighting(lowp vec3 bumpVec, lowp vec3 texDiffuse, lowp float texSpec, lowp vec3 lightDiffuse, lowp vec3 lightSpec, lowp vec3 pILD, lowp vec3 eyeVec, lowp vec3 halfVec)
{
lowp float diffFact = max(dot(pILD, bumpVec), 0.0);


lowp vec3 baseColor = texDiffuse * (lightDiffuse * diffFact);



if (diffFact > 0.0)
{
mediump float shininess = pow (max (dot (halfVec, bumpVec), 0.0), 1.0);
baseColor += lightSpec * (texSpec * shininess);
};

return baseColor;
}


void saEnemyPixelFn()
{
mediump vec3 bumpVec = vxTex2D(NormalTex, interTex0).xyz * 2.0 - 1.0;
lowp vec4 texDiffuse = vxTex2D(DiffuseTex, interTex0);

bumpVec.x = -bumpVec.x;


vxPixelResult.xyz = texDiffuse.xyz * globalAmbient;
vxPixelResult.xyz += specLighting(bumpVec, texDiffuse.xyz, texDiffuse.a, lightDiff, lightSpecColor, interLightVec, interEyeVec, interHalfVec);
vxPixelResult.xyz += specLighting(bumpVec, texDiffuse.xyz, texDiffuse.a, light2Diff, light2SpecColor, interLightVec2, interEyeVec, interHalfVec2);




vxPixelResult.a = 1.0;
}
#line 0 8
void main() { saEnemyPixelFn(); }






One more thing

It’s working file on all other devices (Adreno, Mali, Tegra)



PS

Hi,



Can you query the graphics driver version of the 3 devices and share this information with us? This FAQ item describes how to query the driver version number.


Samsung Galaxy S - android 4.2.1

I believe Android 2.3 was the last official OS released for this device. Are your devices running custom ROMs?

Joe

Samsung Galaxy S, clean android 4.2.1



Output:



Screen size: 1196 x 720

GLES:


Renderer PowerVR SGX 540
Version OpenGL ES 2.0 build 1.8@905891
Vendor Imagination Technologies
Shading Language OpenGL ES GLSL ES 1.00 build 1.8@905891
GLES:

Shader compilation message:

11-22 14:28:25.224: I/vxappbinary(9908): Loading AHRock.shader shader
11-22 14:28:25.287: E/vxappbinary(9908): Pixel shader:
11-22 14:28:25.287: E/vxappbinary(9908): No Filename(0) : Compile failed.
11-22 14:28:25.287: E/vxappbinary(9908): AHRock.shader error compiling shader file - pass 0

no compilation message sent - fragment shader is not compiled - on other devices i usually get the error message - but formatting can be the issue I dont receive anything.


FYI: I had "similar" error on Samsung SII - in another shader - I removed function call:

lowp float mixOverlay(lowp float bottom, lowp float top)
{
mediump float a0 = 2.0 * top * bottom;
mediump float a1 = 1.0 - 2.0 * (1.0 - top) * (1.0 - bottom);

lowp float q = step(0.5, bottom);

return a0 * (1.0 - q) + a1 * q;
}

lowp vec3 dt;
dt.r = mixOverlay(bk.r, ov.r);
dt.g = mixOverlay(bk.g, ov.g) - 0.02;
dt.b = mixOverlay(bk.b, ov.b);



and changed it to direct computation -

lowp vec3 dt;

{
mediump float a0 = 2.0 * bk.r * ov.r;
mediump float a1 = 1.0 - 2.0 * (1.0 - bk.r ) * (1.0 - ov.r);
lowp float q = step(0.5, bk.r);
dt.r = a0 * (1.0 - q) + a1 * q;
};

same for dt.g, dt.b

and no problems anymore -
but again, on all emulators/ smoe other 540 devices, shader was compiled OK

Thank
P.S.

Hi,



I’ve found a workaround just by changing the function:



lowp vec3 specLighting(lowp vec3 bumpVec, lowp vec3 texDiffuse, mediump float texSpec, lowp vec3 lightDiffuse, lowp vec3 lightSpec, lowp vec3 pILD, lowp vec3 eyeVec, lowp vec3 halfVec)

{

lowp float diffFact = max(dot(pILD, bumpVec), 0.0);





lowp vec3 baseColor = texDiffuse * (lightDiffuse * diffFact);





if (diffFact > 0.0)

{

mediump float shininess = pow (max (dot (halfVec, bumpVec), 0.0), 1.0);

baseColor += lightSpec * (texSpec * shininess);

}



return baseColor;



}



Cheers,

Guillem

Thanks a LOT! Otherwise I would be forced to rewrite shader to the point it compiles and then again add lines - I did it so many times I dont want to do it again. And I dont have the actual device, so sending builds to friend can be very slow.



I’ll test it tomorrow.



A) have you tested it on the device ?

B) will it work everywhere ?

C) So can you specify, whats wrong ?

I can see - multiplying mediump float / vec3 by lowp float in both cases. (2nd case - mixoverlay)

but this should be ok and probably is on most of the devices

D) can you suggest some general rule what do to in these cases. To avoid this situation next time.



Thanks Again



P.S.

Message To Immagination: :slight_smile:

Whats another thing to say is that I’m very uncomfortable with situation where everything goes fine in emultator / compilers but doesn’t work in real world case. I cannot get every device ant test it. And the situation where your first customer fails to see it right and immediately writes 1.0 rating (happened today) is very disappointing.


































Hello,



I will reply inline:



A) have you tested it on the device ?

Unfortunately not, I am happy to test it for you in some of our devices if you send me a test .apk.



B) will it work everywhere ?

I assume it will but I cannot guarantee anything :frowning:



C) So can you specify, whats wrong ?

I can see - multiplying mediump float / vec3 by lowp float in both cases. (2nd case - mixoverlay)

but this should be ok and probably is on most of the devices


It looks to me like a bug on our compiler :wink:

It must have got fixed on later DDKs, that is why you cannot reproduce with the compilers we ship with PVRShader.



D) can you suggest some general rule what do to in these cases. To avoid this situation next time.

Yes, drop us an email (devtech@imgtec.com) and I’ll look into providing you some older compilers (like from the last 2/3yrs) that you can use as custom compilers in your PVRShader editor. Unfortunately I’ve just been able to fish the Windows version.



We are aware on the fragmentation on our compilers, I’ve raised the issue with the rest of the team and what we will do is release in the next couple of weeks a “Legacy Shader Compilers” pack including the compilers for older (and relevant) devices as they were released.



Cheers,

Guillem



PS: I completely understand and share the frustration of getting your apps 1* :frowning:

Hello again,

I tested it and it seems to be working fine, at least on devices I could get my hands on (2 of them).

I posted fix on google store, so we’ll see the reports.

Additional testing you proposed is always nice opportunity and I would be VERY gratefull.

(can I post a link here ? for now I have only release build - but it logs everything as debug build). And of course, I can prepare special debug build for you.



The idea with legacy compilers is very good and will be really helpful, from my point of view - I can alter some things as long as I know where is the problem. And I understand that fixing bugs is better than backward compatibility. So solution with legacy compilers is almost perfect.





I have to admit, that apart from problems compiling shader, the application runs very smoothly on all your chips.

Thanks again for the immediate support from your side. I really appreciate it.

Petr Sovis