SSBO: GPU locks up

Hello OpenGL gurus,

I have written an Android OpenGL ES 3.1 app and I am battling with a GPU lockup. Debugging the issue, I kept removing code until I arrived at a small shader which, when run, still exhibits the issue:

Vertex shader: ( a_Position attribute is a quad [(-0.5,-0.5),(-0.5,0.5),(0.5,-0.5),(0.5,0.5)] ; u_Size is the size of the screen - 1080x1920 )

#version 310 es
precision highp float;
precision highp int;

in vec2 a_Position;
out vec2 v_Pixel;
uniform uvec2 u_Size; 

void main()
   { 
   v_Pixel      = (a_Position + 0.5) * vec2(u_Size);
   gl_Position = vec4(2.0*a_Position,1.0,1.0);
   }

Fragment shader:

#version 310 es
precision highp float;
precision highp int;

out vec4 fragColor;
in vec2 v_Pixel;
uniform uvec2 u_Size;

layout (std430,binding=1) buffer ssbo
  {
  uint u_Records[];
  }; 

void main() 
   {  
   uint index= uint(v_Pixel.x) + uint(v_Pixel.y) * u_Size.x;
   uint sum = 0u; 
   for(uint i=index+1u; i>=index; i--) sum += u_Records[i];

   fragColor = vec4(0.0,1.0,0.0,1.0);
   }

As you can see, the fragment shader uses a Shader Storage Buffer Object. First it computes a per-pixel unique index into the SSBO table, then it performs some computations (reading from the SSBO but NOT writing to it), ultimately it simply paints the whole screen green.

When I try to run this on a device with Adreno 418 GPU, it flatly refuses to run (“code would result in device lockup”). On a device with Mali T880 GPU this does run, but Mali announces

E/OpenGLRenderer: Error:glFinish::execution failed
E/OpenGLRenderer: GL error: Out of memory!

and the whole GPU turns very slow, up to a point when sometimes the whole phone reboots.

Now, what’s even more interesting, if I replace the

for(uint i=index+1u; i>=index; i--) sum += u_Records[i];

loop in the fragment shader with the seemingly identical

sum += u_Records[index+1u];
sum += u_Records[index];

then the whole thing runs just fine (on both GPUs!) and displays the expected green screen.

The SSBO for sure IS big enough to hold the 1080x1920 ints, and even if it weren’t , we are not writing to it? Could anyone shed some light on what’s going on here?

Can [var]index[/var] be equal to zero?

If [var]index==0[/var] , then this loop:


   for(uint i=index+1u; i>=index; i--)

will loop forever, as an unsigned integer is always >= 0.

When i=0, decrementing it will resulting in it wrapping around to 0xFFFFFFFF, which is still >=0.

Assuming that you don’t actually need to handle values greater than 231-1, just use a signed integer instead.

Yes, index can be 0 and then it loops forever - silly me, thanks GClements!