This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Mali-T720 - Why doe referencing a uniform variable, cause the vertex shader to not draw anything?

Hey all,

I have this project, that has a default shader, that just draws models and textures. Recently I decided to add a second shader that does a fancy effect, and is used only on some of the objects drawn.

After compiling the project for Linux or Windows, it all works as expected. When compiling the project to Android, only on specific devices, the new shader doesn't work, while on other devices I tried, it all works.


My shaders

Below is my default vertex shader specifically made for Android devices, this one works on all devices and draws everything without any editing or effect. As far as I understand, the fragment shaders work, so I'll omit them.

#version 310 es

in vec4 position;
in vec3 colour;
in vec2 texCoord;

uniform mat4 matrix;
uniform mat4 matrixProjection;

out vec2 outTexCoord;
out vec4 outColour;

void main() {
    gl_Position = matrixProjection *matrix *position;
    outTexCoord  = texCoord;
    outColour  = vec4(colour.rgb, 1);
}


I hope this looks fairly straight-forward. `matrixProjection` is the projection matrix, and `matrix` is the model-view matrix. They both work as expected and I'm able to render a whole scene without issue.

Now here is a simplified version of my new shader:

#version 310 es

in vec4 position;
in vec3 colour; 
in vec2 texCoord;       

uniform mat4 matrix;            
uniform mat4 matrixProjection;  
uniform float animationCurrent;                 

out vec2 outTexCoord;                                   
out vec4 outColour;                                             

void main() {                                                           
    vec4 pos = matrixProjection *matrix *position;

    if (animationCurrent > 0.0) {
        pos.y += 5.0;
    }                                                                                                                                       

    gl_Position = pos;
    outColour = vec4(colour.rgb, 1.0);
    outTexCoord  = texCoord;
}


The only difference of the new shader is the new uniform `animationCurrent`, and an extra `if` statement that will modify the `gl_Position` of some vertices. On some devices, any object that is using this shader, is not drawn at all on the screen.


What I've tried

From the new shader, if I remove the entire `if` statement, it all works and it displays objects as-is. If I replace the `if` statement with `if (true)` it still works, but it just displays all vertices of objects drawn with it slightly higher. If I replace it with `if (false)` it still works as expected and draws the object without any transformations or effects.

So for some reason, just referencing `animationCurrent` causes the object to not be drawn.

I also tried replacing the `if` statement with `if (matrix[0][0] > 0.0)` and it still draws the object, it looks like there's something specifically wrong with `animationCurrent`. I tried adding another matrix uniform variable, and set its value the same way as I do `matrix`, but it would give me weird (undefined?) results.

It seems that the value of `animationCurrent` is not relevant.

I've also checked the values of `glGetShaderInfoLog` and `glGetProgramInfoLog` but got nothing.


Hardware

The problem occurs on an android phone with this hardware:

    Device: Moto E (4) Plus - 7.1.1
    Vendor graphic card: ARM
    Renderer: Mali-T720
    Version OpenGL: OpenGL ES 3.1 v1.r12p1-01alp0.62f282720426ab7712f1c6b996a6dc82
    Version GLSL: OpenGL ES GLSL ES 3.10

The problem also occurs on this android tablet with similar hardware:

    Device: Kindle Fire 8
    Vendor graphic card: ARM
    Renderer: Mali-T720
    Version GL: OpenGL ES 3.1 v1.r26p0-01rel0.526d936ea9da20486773a9aaceecd920
    Version GLSL: OpenGL ES GLSL ES 3.10

This is an android tablet where the problem does not occur:

    Device: Lenovo TB-X505F - 10
    Vendor graphic card: Qualcomm
    Renderer: Adreno (TM) 504
    Version GL: OpenGL ES 3.2 V@415.0 (GIT@f345350, I0760943699, 1580221225) (Date:01/28/20)
    Version GLSL: OpenGL ES GLSL ES 3.20

And this is a slightly older device where the problem does not occur either. I've modified the shader a bit to support an older glsl version, but the idea is the same:

    Device: Kindle Fire 7
    Vendor graphic card: ARM
    Renderer: Mali-450 MP
    Version GL: OpenGL ES 2.0
    Version GLSL: OpenGL ES GLSL ES 1.00


Question

My primary goal, is to understand what is causing this. Have I missed something very obvious? Is this a very edge-case bug related to the hardware?

I'm still learning how to support different devices with different versions of glsl, so it's very likely I've missed something.

Any information you have, let me know. I'm willing to try a few things on different devices to find more about this issue.

Parents
  • I would recommend using RenderDoc to see if the value is passed to the shader correctly.

    I took a look at `RenderDoc`, and it looks interesting. I'll give it a go sometime today and post an update here.

    Another option would be to do the if statement before launching the shader and pass something like 'deltaY' (which will be equal to 0, if the statement is false). It is a common practice to avoid conditions and loops in shaders, when it's possible.

    Avoiding loops sounds like excellent advice. Unfortunately in this case it still didn't work. I tried replacing the whole `if` statement with `pos.y += animationCurrent;`. I tested this on 2 of the devices mentioned above, one where the issue appears, and one where it doesn't, and the issue still appears on the one device (Moto E (4) Plus - 7.1.1) and objects drawn with that shader don't appear at all.

    For the sake of completeness, if I comment out the line `pos.y += animationCurrent;`, the shader draws the object without any effects on both devices (as expected).

Reply
  • I would recommend using RenderDoc to see if the value is passed to the shader correctly.

    I took a look at `RenderDoc`, and it looks interesting. I'll give it a go sometime today and post an update here.

    Another option would be to do the if statement before launching the shader and pass something like 'deltaY' (which will be equal to 0, if the statement is false). It is a common practice to avoid conditions and loops in shaders, when it's possible.

    Avoiding loops sounds like excellent advice. Unfortunately in this case it still didn't work. I tried replacing the whole `if` statement with `pos.y += animationCurrent;`. I tested this on 2 of the devices mentioned above, one where the issue appears, and one where it doesn't, and the issue still appears on the one device (Moto E (4) Plus - 7.1.1) and objects drawn with that shader don't appear at all.

    For the sake of completeness, if I comment out the line `pos.y += animationCurrent;`, the shader draws the object without any effects on both devices (as expected).

Children
No data