Forums - Adreno 200 freezes without glFinish(), but framerate is terrible with that resolve

3 posts / 0 new
Last post
Adreno 200 freezes without glFinish(), but framerate is terrible with that resolve
Robert_Green
Join Date: 19 Oct 10
Posts: 5
Posted: Thu, 2012-03-08 10:06

We recently finished a few games using GLES 2.0 and our shaders aren't too complicated, just some basic 2D quad and 3D rendering with directional, point lights and fog.  

We have tested the code thoroughly on:

PC and Mac desktops running NV and ATI hardware

PVR SGX 530, 535 and 540, Adreno 205, Tegra 2

and we haven't had issues with any of those, but the Adreno 200-based devices are causing us serious headaches.  We can't figure out why this happens, but when we have the following shader enabled, the device locks up, affecting both Nexus One, EVO and I'm sure any other Adreno 200 device.  When I take out the point lights in the shader, it no longer crashes.  I've tried unrolling the point light array, but even when I just calculate a single point light - freeze.  I've seen much heavier-duty shaders run on these devices.  What in the world could be causing my troubles??  Any help or advice is appreciated.

Note:  On the Nexus One, commenting out point light processing made it so that the game ran for over an hour without a freeze, but on the Evo, it ran for about 5 minutes but still froze.  I feel like the issue is some sort of out-of-buffer space which accumulates in the GL context leading to a freeze eventually and somehow this shader just exacerbates it.  I can run the AdrenoProfiler on it and give numbers of calls, registers, etc if that would be helpful to anyone.

 

W/SharedBufferStack(  631): waitForCondition(LockCondition) timed out (identity=12, status=0). CPU may be pegged. trying again.

W/SharedBufferStack(  631): waitForCondition(LockCondition) timed out (identity=12, status=0). CPU may be pegged. trying again.

W/SharedBufferStack(  631): waitForCondition(LockCondition) timed out (identity=12, status=0). CPU may be pegged. trying again.

 

// Static object vertex shader

 

#define MAX_POINT_LIGHTS 5

 

struct directional_light {

vec3 direction;

vec3 halfplane;

vec4 ambient_color;

vec4 diffuse_color;

vec4 specular_color;

};

 

struct point_light {

vec3 position;

vec3 attenuations;

vec4 ambient_color;

vec4 diffuse_color;

vec4 specular_color;

};

 

struct material_properties {

vec4 ambient_color;

vec4 diffuse_color;

vec4 specular_color;

float specular_exponent;

};

 

const float c_zero = 0.0;

const float c_one = 1.0;

 

uniform material_properties material;

uniform directional_light dirLight;

uniform point_light pointLight[MAX_POINT_LIGHTS];

uniform int pointLightCount;

uniform mat4 projection_matrix;

uniform mat4 modelview_matrix;

uniform mat3 inv_matrix;

uniform float fog_near;

uniform float fog_far;

uniform vec3 cameraPos;

 

attribute vec3 vPosition;

attribute vec3 vNormal;

attribute vec3 vUV;

 

varying vec2 uvCoord;

varying vec4 vColor;

varying float fogAmount;

 

vec4 compute_directional_light(vec3 normal) {

vec4 computed_color = vec4(c_zero, c_zero, c_zero, c_zero);

float ndotl;

float ndoth;

ndotl = max(c_zero, dot(normal, dirLight.direction));

ndoth = max(c_zero, dot(normal, dirLight.halfplane));

computed_color += (dirLight.ambient_color * material.ambient_color);

computed_color += (ndotl * dirLight.diffuse_color * material.diffuse_color);

if (ndoth > c_zero) {

computed_color += (pow(ndoth, material.specular_exponent) * material.specular_color * dirLight.specular_color);

}

return computed_color;

}

 

vec4 compute_point_light(int lightIdx, vec3 eye, vec3 ecPosition3, vec3 normal) {

vec4 computed_color = vec4(c_zero, c_zero, c_zero, c_zero);

float nDotVP; // normal . light direction

float nDotHV; // normal . light half vec

float pf;// power factor

float attenuation;// computed attenuation factor

float d;// distance from surface to light source

vec3 VP;// direction from surface to light position

vec3 halfVector;// direction of maximum highlights

// compute vector from surface to light position (both in eye coordinates)

VP = vec3(pointLight[lightIdx].position) - ecPosition3;

// compute distance between surface and light position

d = length(VP);

// normalize the vector from surface to light position

VP = normalize(VP);

// compute attenuation (x = constant, y = linear, z = quadratic)

attenuation = 1.0 / (pointLight[lightIdx].attenuations.x +

pointLight[lightIdx].attenuations.y * d +

pointLight[lightIdx].attenuations.z * d * d);

halfVector = normalize(VP + eye);

nDotVP = max(0.0, dot(normal, VP));

nDotHV = max(0.0, dot(normal, halfVector));

if (nDotVP == 0.0)

pf = 0.0;

else

pf = pow(nDotHV, material.specular_exponent);

computed_color += pointLight[lightIdx].ambient_color * material.ambient_color * attenuation;

computed_color += pointLight[lightIdx].diffuse_color * material.diffuse_color * nDotVP * attenuation;

computed_color += pointLight[lightIdx].specular_color * material.specular_color * pf * attenuation;

return computed_color;

}

 

float compute_fog_amount(vec4 ecVert) {

// if fog_far is 0, fog is disabled, but we want to return 1,1,1,1 in that case 

// so we keep a value of 1 for fogDisable that we'll add to the fogAmt of 0.  Otherwise it will be 0 and won't affect the fog amount.

float fogDisable = 1.0-clamp(fog_far, 0.0, 1.0);

float fogAmt = clamp(1.0-(-ecVert.z / fog_far+0.001), 0.0, 1.0);

return fogAmt+fogDisable;

}

 

void main() {

// flip V

uvCoord = vec2(vUV.x, (1.0-vUV.y));

vec4 ecPosition = modelview_matrix * vec4(vPosition.xyz, 1.0);

vec3 ecNormal = normalize(inv_matrix * vNormal);

vec3 ecPos3 = (vec3(ecPosition)) / ecPosition.w;

gl_Position = projection_matrix * ecPosition;

vec3 ecCamera = (modelview_matrix * vec4(cameraPos, 1.0)).xyz;

vColor = compute_directional_light(ecNormal);

// vColor = vec4(0,0,0,0);

for (int i = 0; i < MAX_POINT_LIGHTS; i++) {

if (i < pointLightCount) {

vColor += compute_point_light(i, ecCamera, ecPos3, ecNormal);

}

}

fogAmount = compute_fog_amount(ecPosition);

fogAmount *= fogAmount;

}              

 

 

 

  • Up0
  • Down0
Mark_Feldman Moderator
Join Date: 4 Jan 12
Posts: 61
Posted: Wed, 2012-03-14 09:03

Robert - Is there any chance of a divide by zero when computing the attenuation in compute_point_light?

If you simplify compute_point_light do you still freeze (is it the function call itself, or some logic in the function that is causing the freeze?)

 

  • Up0
  • Down0
Robert_Green
Join Date: 19 Oct 10
Posts: 5
Posted: Wed, 2012-03-14 11:58

Hi Mark,

I did some testing and removed all point light computations from the shader which resulted in a much longer run time but there was still an eventual freeze on the evo.  Do divide-by-zeros in the shader cause that driver to freeze?

Either way, I'm thinking this shader exacerbates the problem but isn't the source of it.  Any other ideas of what may cause freezing on that driver?

Thanks!

  • Up0
  • Down0
or Register

Opinions expressed in the content posted here are the personal opinions of the original authors, and do not necessarily reflect those of Qualcomm Incorporated or its subsidiaries (“Qualcomm”). The content is provided for informational purposes only and is not meant to be an endorsement or representation by Qualcomm or any other party. This site may also provide links or references to non-Qualcomm sites and resources. Qualcomm makes no representations, warranties, or other commitments whatsoever about any non-Qualcomm sites or third-party resources that may be referenced, accessible from, or linked to this site.