Forums - Adreno 330 GLES3 [email protected] compiler issue - unable to access array of structs from non-main function

2 posts / 0 new
Last post
Adreno 330 GLES3 [email protected] compiler issue - unable to access array of structs from non-main function
sinisterchipmunk
Join Date: 3 Oct 14
Posts: 2
Posted: Fri, 2014-10-03 14:39

I'm testing code that runs fine on a Samsung Galaxy Note 10.1" 2014 (Mali-T628) on a Samsung Galaxy S5 (Adreno 330) for the first time and am experiencing a few GLSL (ES 3.0) issues. I'll post different issues to different topics. Note that these are up-to-date production devices I am testing on; I'm unaware if these issues have been resolved in unreleased drivers.

This one's a little complicated; please bear with me.

Background

I have a struct representing light source data. The engine's side of this is not yet finished, so I have mocked up the light source information inside of the shader at the beginning of the main() function for now. Also, the light data is represented as an array of structs so that I can apply multiple lights in a single pass. Due to issues on other devices, I can't use a "for" loop and I can't pass the Light into the function directly. So instead I just pass the array index into the function, and index into the array of structs within the function. To demonstrate, a truncated version of of my source code follows:

struct Light {
  bool enabled;
  int type;
  float spotInnerCos, spotOuterCos;
  float energy, falloffDistance;
  vec3 ambientColor, diffuseColor, specularColor;
  // Direction and position of light in eye space
  vec3 direction;
  vec3 position;
};

// eventually this will be in a uniform block and contain more
// than one element
Light uLights[1];

void accumulateLighting(in int i) {
  if (uLights[i].enabled) {
    // lighting computations here
  }
}

void main(void) {
  // mock data
  uLights[0].enabled = true;
  uLights[0].type = DIRECTIONAL_LIGHT;
  uLights[0].spotInnerCos = -1.0;
  uLights[0].spotOuterCos = -1.0;
  uLights[0].ambientColor = vec3(0.1, 0.1, 0.1);
  uLights[0].diffuseColor = vec3(1.0, 1.0, 1.0);
  uLights[0].specularColor = vec3(1.0, 1.0, 1.0);
  uLights[0].direction = vec3(1.0, -1.0, 0.0);
  uLights[0].energy = 1.0;
  uLights[0].falloffDistance = 3.0;
  uLights[0].position = vec3(0.0, 0.0, 0.0);

  // some other stuff here

  accumulateLighting(0);
}

The Issue

About 50% of the time, the app crashes during linking without any compile, link or android log info. The rest of the time, the result seems to be corrupted. I got slightly different (but still unacceptable, actually worse) results when I commented out the conditionals in the accumulateLight function. This leads me to suspect this issue may be related to a combination of both [1] and [2] but I can't establish exactly what is going on and there may be more at play here than I can guess at.

Workaround

I was able to work around this issue by indexing into the array of structs only in main() and then passing its values directly into the function. The result looks like this:

struct Light {
  bool enabled;
  int type;
  float spotInnerCos, spotOuterCos;
  float energy, falloffDistance;
  vec3 ambientColor, diffuseColor, specularColor;
  // Direction and position of light in eye space
  vec3 direction;
  vec3 position;
};

Light uLights[1];

void accumulateLighting(bool uLightEnabled, int uLightType,
                        float uLightSpotInnerCos, float uLightSpotOuterCos,
                        float uLightEnergy, float uLightFalloffDistance,
                        vec3 uLightAmbientColor, vec3 uLightDiffuseColor,
                        vec3 uLightSpecularColor, vec3 uLightDirection,
                        vec3 uLightPosition) {
  if (uLightEnabled) {
    // lighting computations here
  }
}

void main(void) {
  // mock data
  uLights[0].enabled = true;
  uLights[0].type = DIRECTIONAL_LIGHT;
  uLights[0].spotInnerCos = -1.0;
  uLights[0].spotOuterCos = -1.0;
  uLights[0].ambientColor = vec3(0.1, 0.1, 0.1);
  uLights[0].diffuseColor = vec3(1.0, 1.0, 1.0);
  uLights[0].specularColor = vec3(1.0, 1.0, 1.0);
  uLights[0].direction = vec3(1.0, -1.0, 0.0);
  uLights[0].energy = 1.0;
  uLights[0].falloffDistance = 3.0;
  uLights[0].position = vec3(0.0, 0.0, 0.0);

  // some other stuff here

  accumulateLighting(uLights[0].enabled, uLights[0].type,
                     uLights[0].spotInnerCos, uLights[0].spotOuterCos,
                     uLights[0].energy, uLights[0].falloffDistance,
                     uLights[0].ambientColor, uLights[0].diffuseColor,
                     uLights[0].specularColor, uLights[0].direction,
                     uLights[0].position);
}

While obviously not ideal, this does allow me to preserve the array-of-structs interface, which I expect to become important for my application in the near future. The workaround produces the correct result and allows me to continue development.

[1] https://developer.qualcomm.com/forum/qdn-forums/maximize-hardware/mobile...

[2] https://developer.qualcomm.com/forum/qdn-forums/maximize-hardware/mobile...

  • Up0
  • Down0
mhfeldma Moderator
Join Date: 29 Nov 12
Posts: 310
Posted: Mon, 2014-10-13 14:24

We took a look at trying to reproduce this shader in a test apk, but were unable to get the app to crash on our device.

We were using a Galaxys S5 (4.4.2 kernel 5/8/2014, Build KOT49H).

Let us know the build you're running on, and if you have an apk you can share with us..

 

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.