Forums - Issue with the Vertex Shader in Adreno320

6 posts / 0 new
Last post
Issue with the Vertex Shader in Adreno320
rd-freeware
Join Date: 13 Aug 13
Posts: 3
Posted: Tue, 2013-09-10 19:37
We currently have an issue with a portion of the Vertex Shader that come up in devices using the Adreno 320.
 
When we combined access to an array index that is not constant and nested conditional statements, it produces an indeterminate output. Even when not nested and using separate conditional statements in the same uniform, it produces the same indeterminate results.
 
In some cases, 
 
W/Adreno200-ES20( 7613): <finish_current_fbo_rendering:183>:GL_OUT_OF_MEMORY
W/Adreno200-GSL( 7613): <gsl_ldd_control:226>: ioctl code 0xc0140910 (IOCTL_KGSL_RINGBUFFER_ISSUEIBCMDS) failed: errno 35 Resource deadlock would occur W/Adreno200-EGL( 7613): <qeglDrvAPI_eglSwapBuffers:3476>: EGL_CONTEXT_LOST
 
comes out and OpenGL Context gets lost.
 
The hypothetical code should be,
 
if(A){
  result = array[index0];
}
else if(B){
  result = array[index1];
}
else{
  result = array[index2];
}
 
Or
 
if(A){
  result = array[index0];
}
if(B){
  result = array[index1];
}
 
 
There are no problems when only using just one of the conditional statements.
 
We have two devices with Adreno 320 installed on them, and the issue is occurring on both devices.
The versions of android installed are 4.1.2 and 4.2.2.
Other devices with Adreno 220 and other different GPUs are not having this issue.
 
Is this an issue with the Adreno 320 driver?
  • Up0
  • Down0
mhfeldma Moderator
Join Date: 29 Nov 12
Posts: 302
Posted: Fri, 2013-10-04 16:26

Hi...  There are some limitations with Array Indexing in GLES 2.0 .  They are listed in the following document:

http://www.khronos.org/files/opengles_shading_language.pdf  (Appendix A, section 5)

In general for array indexiing, if the support is not mandated, it's likely not implemented in our drivers. 

Without seeing your full shader, it's hard to verify..

 

thanks,

mark

 

 

 

  • Up0
  • Down0
rd-freeware
Join Date: 13 Aug 13
Posts: 3
Posted: Fri, 2013-10-11 04:16
Hi Mark,
 
Thank you for the response. 
 
We have looked into the matter based on your feedback and found that the indexing supports the uniform arrays within the vertex shader and that it supports all formats.
 
When we use the vertex shader, the vertex position and color randomly change. Also, this issue occurs quite frequently on the Galaxy S4 SC-04E. We think we may have solved the issue by doing the following three things, but is there a bug or something that is causing this to happen? 
 
1.    Remove the branching from within the getWorldMatrix function and make sure it always runs the last ‘else’.
2.    Remove the branching from within the getVertexLighting function and make sure it always calls the doOptionLighting function.
3.    Do not use the ‘_varSV_Color’ in the fragment shader.
 
Please review our shader code below:
Note: The shader code been slightly modified in order to post it on the forum and therefore may not compile properly. 
 
 
precision highp float;
//! attributes
attribute vec3 Position;
attribute mediump vec3 Normal;
attribute mediump vec4 Tangent;
attribute mediump vec2 UV_Primary;
attribute mediump vec4 Joint;
attribute mediump vec3 Weight;
//! uniforms
uniform bool _vs_Weight1;
uniform bool _vs_Weight2;
uniform bool _vs_Weight3;
uniform vec4 _vs_fMatrix[96];
uniform mat4 _vs_fViewProj;
uniform vec3 _vs_fCameraPos;
uniform mediump vec4 _vs_fSHCoef[7];
uniform bool _vs_bDynamicOptionLighting;
uniform vec4 _vs_fLightPos[4];
uniform lowp vec3 _vs_fLightDiffuseColor[4];
uniform vec4 _vs_fLightDistAttn;
//! varyings
varying mediump vec2 _varSV_Texcoord;
varying lowp vec4 _varSV_Color;
struct MATERIAL_OUTPUT
{
    vec4 pos;
    mediump vec2 texcoord;
    lowp vec4 vcolor;
};
void getWorldMatrix(
    out vec4 wm0,
    out vec4 wm1,
    out vec4 wm2,
    mediump vec4 joint,
    mediump vec3 weight)
{
    if (_vs_Weight1)
        {
            int index = (int(joint.x)*3);
            wm0=_vs_fMatrix[(index+0)];
            wm1=_vs_fMatrix[(index+1)];
            wm2=_vs_fMatrix[(index+2)];
        }
    else
        if (_vs_Weight2)
            {
                int index0 = (int(joint.x)*3);
                int index1 = (int(joint.y)*3);
                wm0=mix(_vs_fMatrix[(index1+0)],_vs_fMatrix[(index0+0)],weight.x);
                wm1=mix(_vs_fMatrix[(index1+1)],_vs_fMatrix[(index0+1)],weight.x);
                wm2=mix(_vs_fMatrix[(index1+2)],_vs_fMatrix[(index0+2)],weight.x);
            }
        else
            if (_vs_Weight3)
                {
                    int index0 = (int(joint.x)*3);
                    int index1 = (int(joint.y)*3);
                    int index2 = (int(joint.z)*3);
                    mediump float w2 = (1.000000-(weight.x+weight.y));
                    wm0=(((_vs_fMatrix[(index0+0)]*weight.x)+(_vs_fMatrix[(index1+0)]*weight.y))+(_vs_fMatrix[(index2+0)]*w2));
                    wm1=(((_vs_fMatrix[(index0+1)]*weight.x)+(_vs_fMatrix[(index1+1)]*weight.y))+(_vs_fMatrix[(index2+1)]*w2));
                    wm2=(((_vs_fMatrix[(index0+2)]*weight.x)+(_vs_fMatrix[(index1+2)]*weight.y))+(_vs_fMatrix[(index2+2)]*w2));
                }
            else
                {
                    int index0 = (int(joint.x)*3);
                    int index1 = (int(joint.y)*3);
                    int index2 = (int(joint.z)*3);
                    int index3 = (int(joint.w)*3);
                    mediump float w3 = (1.000000-((weight.x+weight.y)+weight.z));
                    wm0=((((_vs_fMatrix[(index0+0)]*weight.x)+(_vs_fMatrix[(index1+0)]*weight.y))+(_vs_fMatrix[(index2+0)]*weight.z))+(_vs_fMatrix[(index3+0)]*w3));
                    wm1=((((_vs_fMatrix[(index0+1)]*weight.x)+(_vs_fMatrix[(index1+1)]*weight.y))+(_vs_fMatrix[(index2+1)]*weight.z))+(_vs_fMatrix[(index3+1)]*w3));
                    wm2=((((_vs_fMatrix[(index0+2)]*weight.x)+(_vs_fMatrix[(index1+2)]*weight.y))+(_vs_fMatrix[(index2+2)]*weight.z))+(_vs_fMatrix[(index3+2)]*w3));
                }
}
vec3 getWorldPos(
    vec4 wm0,
    vec4 wm1,
    vec4 wm2,
    vec3 local_pos)
{
    vec3 wp;
    wp.x=(dot(wm0.xyz,local_pos)+wm0.w);
    wp.y=(dot(wm1.xyz,local_pos)+wm1.w);
    wp.z=(dot(wm2.xyz,local_pos)+wm2.w);
    return wp;
}
vec4 getScreenPos(
    vec3 world_pos)
{
    vec4 wp = vec4(world_pos,1.000000);
    vec4 sp;
    sp.x=dot(wp,_vs_fViewProj[0]);
    sp.y=dot(wp,_vs_fViewProj[1]);
    sp.w=dot(wp,_vs_fViewProj[3]);
    sp.z=((2.000000*dot(wp,_vs_fViewProj[2]))-sp.w);
    return sp;
}
mediump vec3 transformDir(
    mediump vec3 axis0,
    mediump vec3 axis1,
    mediump vec3 axis2,
    mediump vec3 dir)
{
    mediump vec3 v;
    v.x=dot(axis0,dir);
    v.y=dot(axis1,dir);
    v.z=dot(axis2,dir);
    return v;
}
void getWorldNormalTangentBinormal(
    out mediump vec3 wn,
    out mediump vec3 wt,
    out mediump vec3 wb,
    vec4 wm0,
    vec4 wm1,
    vec4 wm2,
    mediump vec3 normal,
    mediump vec4 tangent)
{
    vec3 world_normal = transformDir(wm0.xyz,wm1.xyz,wm2.xyz,normal);
    wn=normalize(world_normal);
    vec3 world_tangent = transformDir(wm0.xyz,wm1.xyz,wm2.xyz,tangent.xyz);
    wt=normalize(world_tangent);
    wb=(normalize(cross(wt,wn))*tangent.w);
}
mediump vec3 getSHdiffuse(
    mediump vec3 vN)
{
    mediump vec4 vNormal = vec4(vN,1);
    mediump vec3 x1 = vec3(dot(_vs_fSHCoef[0],vNormal),dot(_vs_fSHCoef[1],vNormal),dot(_vs_fSHCoef[2],vNormal));
    mediump vec4 vB = (vNormal.xyzz*vNormal.yzzx);
    mediump vec3 x2 = vec3(dot(_vs_fSHCoef[3],vB),dot(_vs_fSHCoef[4],vB),dot(_vs_fSHCoef[5],vB));
    mediump float fC = ((vNormal.x*vNormal.x)-(vNormal.y*vNormal.y));
    mediump vec3 x3 = (_vs_fSHCoef[6].xyz*fC);
    return ((x1+x2)+x3);
}
void doOptionLighting(
    inout lowp vec3 diffuse,
    lowp vec3 nrm,
    vec3 wp)
{
    vec3 light_vec = (_vs_fLightPos[1].xyz-(wp*_vs_fLightPos[1].w));
    float dist = length(light_vec);
    lowp vec3 dir = (light_vec/dist);
    lowp vec3 col = _vs_fLightDiffuseColor[1].xyz;
    lowp float attn = max((1.000000-(dist*_vs_fLightDistAttn.y)),0.000000);
    diffuse+=(col*(max(dot(nrm,dir),0.000000)*attn));
}
lowp vec3 getVertexLighting(
    vec3 wp,
    mediump vec3 wn)
{
    lowp vec3 diffuse = getSHdiffuse(wn);
    if (_vs_bDynamicOptionLighting)
        {
            doOptionLighting(diffuse,wn,wp);
        }
    return diffuse;
}
 
 
MATERIAL_OUTPUT VS_Material(
    vec3 position,
    mediump vec3 normal,
    mediump vec4 tangent,
    mediump vec2 uv_primary,
    mediump vec4 joint,
    mediump vec3 weight)
{
    MATERIAL_OUTPUT O;
    O.texcoord=(uv_primary/1024.000000);
    vec4 wm0;
    vec4 wm1;
    vec4 wm2;
    getWorldMatrix(wm0,wm1,wm2,joint,weight);
    vec3 wp = getWorldPos(wm0,wm1,wm2,position);
    O.pos=getScreenPos(wp);
    vec3 vp = (wp-_vs_fCameraPos);
    mediump vec3 wn;
    mediump vec3 wt;
    mediump vec3 wb;
    getWorldNormalTangentBinormal(wn,wt,wb,wm0,wm1,wm2,normal,tangent);
    O.vcolor.xyz=getVertexLighting(vp,wn);
    O.vcolor.w=1.000000;
    return O;
}
 
void main()
{
    vec3 _arg0 = Position;
    mediump vec3 _arg1 = Normal;
    mediump vec4 _arg2 = Tangent;
    mediump vec2 _arg3 = UV_Primary;
    mediump vec4 _arg4 = Joint;
    mediump vec3 _arg5 = Weight;
    MATERIAL_OUTPUT _ret = VS_Material(_arg0,_arg1,_arg2,_arg3,_arg4,_arg5);
    gl_Position = _ret.pos;
    _varSV_Texcoord = _ret.texcoord;
    _varSV_Color = _ret.vcolor;
}
 
 
Many thanks.
 

 

  • Up0
  • Down0
RelativeGames
Profile picture
Join Date: 16 Apr 13
Posts: 56
Posted: Sat, 2013-10-12 16:15

@rd-freeware

Did you try removing the variable ping-pong-ing ?

What I mean is call directly

VS_Material( Position,Normal, Tangent,UV_Primary ,Joint, Weight);

And if possible remove the MATERIAL_OUTPUT return and write to outputs without the temporary _ret.

On Adreno 205 I had a similar issue where the shader compiled "ok" but because I was using a ton of temporary variables and was ping-pong-ing them in temporaries, the object wasn't looking at all as it should.

  • Up0
  • Down0
RelativeGames
Profile picture
Join Date: 16 Apr 13
Posts: 56
Posted: Sat, 2013-10-12 16:19

@mhfeldma

Is there anything wrong with indexing a huge array from an uniform buffer in OpenGL ES 3 ? I get a compiler crash when doing that on Adreno 320 and I'm thinking this issue is related.

VS->


#version 300 es
//Inputs
in vec4 POSITION;
in vec2 TEXCOORD;

//Outputs
out vec2 TexCoordVarying;

uniform sampler2D Texture0;
uniform mat4 modelViewProjectionMatrix;
uniform vec3 ExtraTranslate;//z = Alpha

struct VertexData
{
    vec4 POS;
    vec4 TEX;
};
uniform VertexBufferData
{
    VertexData Vertices[ 16 ];
};
uniform IndexBufferData
{
    uint Indices[ 16 ];
};
uniform BaryCoordsBuffer
{
    vec4 BaryCoords[ 200 ];
};

vec4 interpolate4(in vec4 v0, in vec4 v1, in vec4 v2, vec4 BaryCoord)
{
    return v0 * BaryCoord.x + v1 * BaryCoord.y + v2 * BaryCoord.z;
}

void main()
{
    int PolygonID = gl_VertexID / 3;
    int VertexIndex = gl_VertexID % 3;
    int PolygonIndices[3];
    PolygonIndices[0] = PolygonID * 3 + 0;
    PolygonIndices[1] = PolygonID * 3 + 1;
    PolygonIndices[2] = PolygonID * 3 + 2;

    vec4 Bary = BaryCoords[ VertexIndex + gl_InstanceID * 3 ];
    
    vec4 CurrentVertex;
    CurrentVertex = interpolate4( Vertices[ Indices[ PolygonIndices[ 0 ] ]].POS, Vertices[ Indices[ PolygonIndices[ 1 ] ]].POS,
            Vertices[ Indices[ PolygonIndices[ 2 ] ]].POS, Bary );
    
    vec4 CurrentTexcoord;
    CurrentTexcoord = interpolate4( Vertices[ Indices[ PolygonIndices[ 0 ] ]].TEX, Vertices[ Indices[ PolygonIndices[ 1 ] ]].TEX,
            Vertices[ Indices[ PolygonIndices[ 2 ] ]].TEX, Bary );
         
    vec4 ModifiedPos = CurrentVertex;
    ModifiedPos.xy += ExtraTranslate.xy;
    
    gl_Position = modelViewProjectionMatrix * ModifiedPos;
    
    TexCoordVarying = CurrentTexcoord.xy;    
}
 

 

PS->

 

#version 300 es

precision highp float;

layout(location = 0) out vec4 FragColor;

//Inputs
in vec2 TexCoordVarying;

uniform sampler2D   Texture0;
uniform float Time;
uniform vec4 AtlasInfo;
uniform vec4 TextureInfo;
uniform vec3 ExtraTranslate;
uniform vec4 MaterialColor;

void main()
{
    vec2 FinalTexcoord = TexCoordVarying;
    vec4 Texel;
    Texel = texture( Texture0, FinalTexcoord );
    
    Texel.a *= ExtraTranslate.z;
    Texel.rgb *= MaterialColor.rgb;
    
    FragColor = Texel;
}
 

  • Up0
  • Down0
rd-freeware
Join Date: 13 Aug 13
Posts: 3
Posted: Tue, 2013-11-12 02:41
Hi mhfeldma and RelativeGames,
 
Thank you for all of the advice. I have been able to work around the issue.
 
Many 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.