Imagination PowerVR SDK Blog

Shader failing only in PowerVR SGX540 (used in Samsung Galaxy S i9000)

pvrshadereditor

#1

Hello.

I’m having trouble with this specific GPU, the PowerVR SGX540, which is used in the Samsung Galaxy S i9000 device.

The problem is the next shader which works fine in all my other test devices with different GPUs, but fails to compile on this one.

For this specific GPU I only get a “Compile Failed.” and nothing else. Makes no sense as the shader works perectly in all other GPUs.

Please let me know if there is an issue with this GPU drivers, and if there is any workaround I can apply to the shader.



Thanks





variant v_texcoord;

uniform sampler2D u_texture;



vec3 processMatrix(vec3 color, mat3 matrix, float scaleFactor)

{

vec3 colorSum = color * matrix[1][1];



float left = v_texcoord.x - scaleFactor;

float right = v_texcoord.x + scaleFactor;

float top = v_texcoord.y - scaleFactor;

float bottom = v_texcoord.y + scaleFactor;



vec3 temp_color = texture2D(u_texture, vec2(left, top)).rgb;

colorSum = colorSum + matrix[0][0] * temp_color;



temp_color = texture2D(u_texture, vec2(right, top)).rgb;

colorSum = colorSum + matrix[0][2] * temp_color;



temp_color = texture2D(u_texture, vec2(left, v_texcoord.y)).rgb;

colorSum = colorSum + matrix[1][0] * temp_color;



temp_color = texture2D(u_texture, vec2(right, v_texcoord.y)).rgb;

colorSum = colorSum + matrix[1][2] * temp_color;



temp_color = texture2D(u_texture, vec2(left, bottom)).rgb;

colorSum = colorSum + matrix[2][0] * temp_color;



temp_color = texture2D(u_texture, vec2(right, bottom)).rgb;

colorSum = colorSum + matrix[2][2] * temp_color;



temp_color = texture2D(u_texture, vec2(v_texcoord.x, top)).rgb;

colorSum = colorSum + matrix[0][1] * temp_color;



temp_color = texture2D(u_texture, vec2(v_texcoord.x, bottom)).rgb;

colorSum = colorSum + matrix[2][1] * temp_color;



return clamp(colorSum, 0.0, 1.0);

}



void main()

{

float scaleUnsharp = 0.009;

float scaleBlur = 0.0;



mat3 matrixBlur = mat3(0.045, 0.122, 0.045, 0.122, 0.332, 0.122, 0.045, 0.122, 0.045);

mat3 matrixUnsharp = mat3(-1.0, -1.0, -1.0, -1.0, 9.0, -1.0, -1.0, -1.0, -1.0);



vec3 color = texture2D(u_texture, v_texcoord).rgb;



color = processMatrix(color, matrixUnsharp, scaleUnsharp);

color = processMatrix(color, matrixBlur, scaleBlur);



gl_FragColor = vec4(color, 1.0);

}


#2

Hi,



Have you tried using our PVRShaderEditor tool to investigate the issues? I’ve copied the shader code to it and spotted a few errors:


  1. variant: This should be 'varying'

  2. v_texcoord: You haven't specified a type for this variable. Based on your code, it looks like this should be a vec2

  3. precision qualifiers: Your shader is missing precision qualifiers. A simple solution is to set a default precision, e.g. precision highp float; at the top of the shader. For best performance though, you should choose appropriate precisions per-variable



The changes I've mentioned above ensure your shader conforms to the GLSL ES 1.00 specification. The compilers of other GPUs should also produce errors in these cases. In more recent PowerVR compilers (such as those packaged with PVRShaderEditor), we've improved our output to better describe errors and warnings.

Thanks,
Joe

#3

Hi Joe, my apologies for the typo. Instead of copy/paste everthing from my code, when I placed the question I realized that I missed the top variables, and I wrote them quick by hand, of course wrongly. Next you will find the exact copy/paste code which includes also the precision.



Also I did some more tests with a different test device which uses the same GPU, and also with PVRShaderEditor.



On the PVRShaderEditor, using the compiler SGX540 rev 130 version 1.9@939827. Result is no errors at all, the shader compiles perfectly.



On the different device Samsung Nexus S, but which uses the same GPU also compiles correctly, which makes it even more strange. Only fails on the Samsung Galaxy S I9000.



Here are the GL strings for both devices with the same GPU:



Samsung Nexus S (works correctly):



GL_RENDER: PowerVR SGX 540

GL_VERSION: OpenGL ES 2.0 build 1.8.GOOGLENEXUS.ED945322@2112805

GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 1.00 build 1.8.GOOGLENEXUS.ED945322@2112805



Samsung Galaxy S i9000 (Affected device):



GL_RENDER: PowerVR SGX 540

GL_VERSION: OpenGL ES 2.0

GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 1.00



UPDATED CODE:





precision mediump float;

varying vec2 v_texcoord;

uniform sampler2D u_texture;



vec3 processMatrix(vec3 color, mat3 matrix, float scaleFactor)

{

vec3 colorSum = color * matrix[1][1];



float left = v_texcoord.x - scaleFactor;

float right = v_texcoord.x + scaleFactor;

float top = v_texcoord.y - scaleFactor;

float bottom = v_texcoord.y + scaleFactor;



vec3 temp_color = texture2D(u_texture, vec2(left, top)).rgb;

colorSum = colorSum + matrix[0][0] * temp_color;



temp_color = texture2D(u_texture, vec2(right, top)).rgb;

colorSum = colorSum + matrix[0][2] * temp_color;



temp_color = texture2D(u_texture, vec2(left, v_texcoord.y)).rgb;

colorSum = colorSum + matrix[1][0] * temp_color;



temp_color = texture2D(u_texture, vec2(right, v_texcoord.y)).rgb;

colorSum = colorSum + matrix[1][2] * temp_color;



temp_color = texture2D(u_texture, vec2(left, bottom)).rgb;

colorSum = colorSum + matrix[2][0] * temp_color;



temp_color = texture2D(u_texture, vec2(right, bottom)).rgb;

colorSum = colorSum + matrix[2][2] * temp_color;



temp_color = texture2D(u_texture, vec2(v_texcoord.x, top)).rgb;

colorSum = colorSum + matrix[0][1] * temp_color;



temp_color = texture2D(u_texture, vec2(v_texcoord.x, bottom)).rgb;

colorSum = colorSum + matrix[2][1] * temp_color;



return clamp(colorSum, 0.0, 1.0);

}



void main()

{

float scaleUnsharp = 0.009;

float scaleBlur = 0.0;



mat3 matrixBlur = mat3(0.045, 0.122, 0.045, 0.122, 0.332, 0.122, 0.045, 0.122, 0.045);

mat3 matrixUnsharp = mat3(-1.0, -1.0, -1.0, -1.0, 9.0, -1.0, -1.0, -1.0, -1.0);



vec3 color = texture2D(u_texture, v_texcoord).rgb;



color = processMatrix(color, matrixUnsharp, scaleUnsharp);

color = processMatrix(color, matrixBlur, scaleBlur);



gl_FragColor = vec4(color, 1.0);

}



#4

I see the PVRShaderEditor tool also allows to use custom compilers, is there anywhere I can download the specific shader compiler version used in that device? Maybe that will help me to find out what’s wrong. Thanks


#5

The Galaxy S uses a much older graphics driver than the Nexus S. I suspect this is the reason behind the difference you’re seeing. I’ve uploaded a few legacy compilers to our support portal for you: https://pvrsupport.imgtec.com/downloads/9-offline-compilers



The 1.6@3924 package is based on the same reference graphics driver as the Galaxy S.



Thanks,

Joe