Adreno 510 GPU: 'deadlock would occur' when trying to use UBO in fragment shader

Hello there,

Open GL ES 3.1 here. When I load uniforms to the fragment shader the ‘old way’

Fragment shader:

#version 310 es

//…
uniform ivec4 properties[100];
//…

CPU:

propertiesL = glGetUniformLocation( mProgramH, “properties”);
int[] array = new int[100];
// …
glUniform4iv( propertiesL , array, 100 , 0);

Then everything works on every GPU I’ve tried. If I however change that to an UBO

#version 310 es
// …
layout (std140) uniform fUniformProperties
{
ivec4 properties[100];
};

CPU:

propBufferIndex = glGetUniformBlockIndex( mProgramH, “fUniformProperties”);
// …
// declare a UNIFORM BUFFER ‘mUBP’, upload it…
// …
int index = mUBP.getIndex();
glBindBufferBase(GL_UNIFORM_BUFFER, PROP_FRAG_UBO_BINDING, index);
glUniformBlockBinding(programH, propBufferIndex , PROP_FRAG_UBO_BINDING);

then everything works on almost all GPUs, but on the Adreno 510 GPU I get

W/Adreno-GSL(30978): <gsl_ldd_control:475>: ioctl fd 26 code 0x400c0907 (IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID) failed: errno 35 Resource deadlock would occur
W/Adreno-GSL(30978): <log_gpu_snapshot:384>: panel.gpuSnapshotPath is not set.not generating user snapshot
W/Adreno-GSL(30978): <gsl_ldd_control:475>: ioctl fd 26 code 0xc0200933 (IOCTL_KGSL_TIMESTAMP_EVENT) failed: errno 22 Invalid argument
W/Adreno-GSL(30978): <ioctl_kgsl_syncobj_create:2979>: (1b, b, 2112) fail 22 Invalid argument
W/Adreno-GSL(30978): <gsl_ldd_control:475>: ioctl fd 26 code 0xc040094a (IOCTL_KGSL_GPU_COMMAND) failed: errno 35 Resource deadlock would occur
W/Adreno-GSL(30978): <log_gpu_snapshot:384>: panel.gpuSnapshotPath is not set.not generating user snapshot

and my app dies.

Yes, I have made sure that PROP_FRAG_UBO_BINDING ( =6) is less than GL_MAX_FRAGMENT_UNIFORM_BLOCKS (=14 on this GPU).

I use 3 different UBOs in my vertex shader, on the CPU side prepared and uploaded in the very same way like the one that’s giving me trouble, and everything works everywhere including the problematic GPU. So it’s really looking like the problem is only in the fragment shader.

The problem manifests itself for sure on the Adreno 510 and - according to a bug report I’ve got - on a device using Adreno 506. I’ve tried this on some 20 different platforms running other GPUs (including some later Adrenos) and it’s working there with no visible problems at all.

The GPU driver identifies itself as

I/Adreno  (30978): QUALCOMM build                   : a7823f5, I59a6815413
I/Adreno  (30978): Build Date                       : 09/23/16
I/Adreno  (30978): OpenGL ES Shader Compiler Version: XE031.07.00.00
I/Adreno  (30978): Local Branch                     : mybranch22028469
I/Adreno  (30978): Remote Branch                    : quic/LA.BR.1.3.3_rb2.26
I/Adreno  (30978): Remote Branch                    : NONE
I/Adreno  (30978): Reconstruct Branch               : NOTHING

Any advice?

This is pretty standard for a graphics driver crash that triggers an app crash on Adreno drivers (have hit this kind of thing before with their drivers).

It could be caused by a graphics driver bug, or by your application violating the spec or exceeding some advertised limit in the graphics driver.

(FWIW KGSL is the kernel graphics driver (kernel graphics support layer) which talks to the usermode graphics driver linked into your app.)

I would post about your problem in the following Qualcomm developer forum, with specific repro details. Sometimes they respond; sometimes not:

Thanks Photon,

I’m trying to post something there but I have never seen such a broken forum - as soon as I try to paste anything into the text I try to post, I get ‘submission failed: we can only accept posts written in English’. So I need to type everything by hand, including the logs…

That’s definitely annoying.

A few other limits you might check against:

  • GL_MAX_COMBINED_UNIFORM_BLOCKS
  • GL_MAX_VERTEX_UNIFORM_BLOCKS
  • GL_MAX_UNIFORM_BLOCK_SIZE
  • GL_MAX_UNIFORM_BUFFER_BINDINGS

I think GL_MAX_UNIFORM_BUFFER_BINDINGS is the limit you want to check against here. GL_MAX_FRAGMENT_UNIFORM_BLOCKS (and GL_MAX_VERTEX_UNIFORM_BLOCKS and GL_MAX_COMBINED_UNIFORM_BLOCKS) are for the totals bindings allowed for vertex, fragment, and all stages.

Also, pretty sure this goes without saying, but you are Checking for OpenGL Errors, right? And making sure your GLSL program compiles and links successfully?

Good luck!

The GLSL program does compile and link successfully.

I don’t check if that particular part (preparing and uploading the UBO to the fragemnt shader) does not generate any OpenGL errors, good point.

I highly doubt the problem is that I exceed some limits, as this runs on many much older GPUs, including a few older Adrenos ( 320 for one ) - and it’s hard to imagine 510 and 506 would have lower limits than all of those (much!) older chipsets?

Also, I don’t really know how widesperead the problem is, but it cannot be very widesperead, because a day after a release of the faulty version of my app I only got 2 complaints out of roughly 55k active users, one from someone running this on a Xiaomi Redmi Note 3 ( Adreno 510 ) and another - Redmi Note 4 (Adreno 506). Then I managed to reproduce it on the Adreno 510.

I managed to type everything and ask a question in the Qualcomm forum:

So far - no answer.

For now I’ve worked around the problem by simply removing the UBO from the fragment shader and reverting back to glUniform4iv(). A move to UBO was part of the plan to try and increase the number of available uniforms in the vertex and fragment shaders, but for now I really need it only in the vertex shader, where fortunately it does work - in fragment shader I can still live with the old way for a while.

That’s interesting. So if it’s a driver bug, that begs the question whether most folks are just running ARM or Imagination Tech GPUs (e.g. Mali, PowerVR) instead of Qualcomm (Adreno). That would explain it. Otherwise it suggests an app bug.

I will say, in the short time I worked with Adreno drivers, I wasn’t impressed with their driver or dev-tech quality. In short order, I hit a driver crash. And like you, posted about it on those forums, getting no help from dev-tech. Some folks do get help there though, so it’s worth a shot.

Makes sense.

On using UBO vs. global-scope uniforms, one performance warning. Make sure you know what the behavior of your GL-ES driver(s) is when there is buffer object resource contention.

For instance, when you update a buffer object from the CPU for which a GPU read from that buffer object has been queued. Many drivers internally will just block the CPU update (and the app draw thread) until the GPU “catches up”. This is often not the behavior you want. Double- or triple-buffering can help here. This is especially a problem on mobile GPUs, which depend on deep pipelining for best performance (e.g. GPU rasterizing a frame 1-3 frames after CPU submission).

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.