Could not link shader program error

Started by AeroShark333, April 30, 2017, 02:35:00 PM

Previous topic - Next topic

AeroShark333

Hello,

I have a weird crash that I can't really explain since the logs don't give me enough information nor does the error stacktrace...
Stacktrace:
java.lang.RuntimeException: [ 1493390702610 ] - ERROR: Could not link shader program:
at com.threed.jpct.Logger.log(Logger.java:206)
at com.threed.jpct.GLSLShader.createProgram(GLSLShader.java:1131)
at com.threed.jpct.GLSLShader.loadProgram(GLSLShader.java:1113)
at com.threed.jpct.GLSLShader.preInit(GLSLShader.java:301)
at com.threed.jpct.GL20.setShader(GL20.java:388)
at com.threed.jpct.GLRenderer.setShader(GLRenderer.java:567)
at com.threed.jpct.CompiledInstance.render(CompiledInstance.java:191)
at com.threed.jpct.GLRenderer.drawVertexArray(GLRenderer.java:2472)
at com.threed.jpct.World.draw(World.java:1426)
at com.threed.jpct.World.draw(World.java:1109)
at com.aeroshark333.artofearthify.lw.LiveWallpaperRenderer.onDrawFrame(LiveWallpaperRenderer.java:1188)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1524)
at android.opengl.

I am using custom shaders and they do seem to work fine on most devices...
The only device that gave me this error happens to be my brother's phone (Samsung Galaxy S3 mini).
It works fine on my phone and enough other phones, however...

Thanks in advance :)

EgonOlsen

Actually, there should be some driver output in the log as well (as long as it produces some...).

SonicBurst2

#2
Hi Aeroshark,
    If you are using android studio , then this might help you...
https://developer.android.com/studio/profile/android-monitor.html
It has a GPU monitor ... so you can give it a shot.
You can also enable GPU trace logs from your phone's developer options, if it is there...

apart from that I also found this ->
https://developer.android.com/studio/debug/am-gpu-debugger.html

But this tool is W.I.P at the moment .

AeroShark333

Quote from: EgonOlsen on April 30, 2017, 11:35:39 PM
Actually, there should be some driver output in the log as well (as long as it produces some...).
There doesn't seem to be any driver output.
The GPU is a Vivante GC1000
I'll try to give logs of the OpenGL traces...

AeroShark333

#4
http://stackoverflow.com/questions/22646581/compiling-linking-shaders-on-vivante-gc1000-gpu-galaxy-tab-3
I did some googling around... And I guess I found the issue...
I'll have to solve this myself I guess

Edit: Nevermind... I'm actually pretty sure I'm using over 8 varying variables...
I guess I'll try combining floats, vec2 and vec3's to vec4's to see if it helps :)
I'll report the results back here :)

PS: Could jPCT throw a warning or something when the varying limit is exceeded by a custom shader? So developers aren't puzzled when the GPU doesn't output anything... I'm sure there are a lot of other limits that are GPU specific (max texture size, max texture stages, max varying variables), it would be nice to have a warning by jPCT-AE when the maximum values are exceeded)... I know developers can test this themselves too but it would be nice to have added in case developers do get puzzled when the GPU doesn't report anything like in my case... It doesn't really come to my mind to check the amount of varying variables...

PS2: Some unrelated question, but why are 16384 resolution textures not 'officially' supported by jPCT-AE while some OpenGL2 devices might support it... (Can't this 8192 resolution limit by jPCT-AE be worked around using NPOTexture anyway..? Not sure...). I know this texture size is huge and eats a lot of RAM/VRAM but Android devices are getting more and more powerful...

EgonOlsen

But how should I know how many varying your shader uses? I would have to parse the shader for that. If a shader fails to compile, jPCT-AE will print out the error reported by the driver. Actually, this error should indicate the problem. If your driver doesn't provide such a message...well, that's another story. These Vivante chips are a piece of junk anyway. The latest jPCT-AE version provides an additional set of shaders for Vivante only, because the normal default shaders just refused to work on these chips. Make sure to use 1.31.

About the limit of 8192...it's just an artifical limit caused by some constants. I could easily extend it to 16384 or higher. But a 16384*16384 textures uses 1 GB of texture memory (without mipmaps)...what's the point of that on a mobile device?

AeroShark333

Quote from: EgonOlsen on May 01, 2017, 05:37:13 PM
But how should I know how many varying your shader uses? I would have to parse the shader for that. If a shader fails to compile, jPCT-AE will print out the error reported by the driver. Actually, this error should indicate the problem. If your driver doesn't provide such a message...well, that's another story. These Vivante chips are a piece of junk anyway. The latest jPCT-AE version provides an additional set of shaders for Vivante only, because the normal default shaders just refused to work on these chips. Make sure to use 1.31.

About the limit of 8192...it's just an artifical limit caused by some constants. I could easily extend it to 16384 or higher. But a 16384*16384 textures uses 1 GB of texture memory (without mipmaps)...what's the point of that on a mobile device?
A 16384*8192 texture would use 512MB I guess then... which high-end phones are able to support... (at least my Axon 7 can have a VM heap up to 1 GB) While it maybe has no real purpose (yet) it could be enabled for future-proofing reasons I guess :)
Or... Are there plans for a OpenGLES 3.0 (or higher) version of jPCT-AE?

EgonOlsen

I can extend the limit to 16384 or 32768 in the next version...no problem with that.

Regarding ES 3.0...there's nothing in it that I would be using ATM. But jPCT-AE itself should render fine into a 3.0 context.

AeroShark333

#8
Still couldn't solve the issue... :/

But I found something interesting maybe (which I suppose is the GPU/driver output)... (And yes, I'm catching the RuntimeException in onDrawFrame)
05-06 11:11:33.501: I/jPCT-AE(18608): Compiling shader program!
05-06 11:11:33.666: D/v_gal(18608): [tid=18725] gcmONERROR: status=-16(gcvSTATUS_OUT_OF_RESOURCES) @ gcLINKTREE_GenerateStates(11559)
05-06 11:11:33.666: D/v_gal(18608): [tid=18725] gcmERR_BREAK: status=-16(gcvSTATUS_OUT_OF_RESOURCES) @ gcLinkShaders(7848)
05-06 11:11:33.666: E/jPCT-AE(18608): [ 1494061893674 ] - ERROR: Could not link shader program:
05-06 11:11:33.666: W/System.err(18608): java.lang.RuntimeException: [ 1494061893674 ] - ERROR: Could not link shader program:
05-06 11:11:33.666: W/System.err(18608): at com.threed.jpct.Logger.log(Logger.java:206)
05-06 11:11:33.666: W/System.err(18608): at com.threed.jpct.GLSLShader.createProgram(GLSLShader.java:1131)
05-06 11:11:33.666: W/System.err(18608): at com.threed.jpct.GLSLShader.loadProgram(GLSLShader.java:1113)
05-06 11:11:33.666: W/System.err(18608): at com.threed.jpct.GLSLShader.preInit(GLSLShader.java:301)
05-06 11:11:33.666: W/System.err(18608): at com.threed.jpct.GL20.setShader(GL20.java:388)
05-06 11:11:33.666: W/System.err(18608): at com.threed.jpct.GLRenderer.setShader(GLRenderer.java:567)
05-06 11:11:33.666: W/System.err(18608): at com.threed.jpct.CompiledInstance.render(CompiledInstance.java:191)
05-06 11:11:33.666: W/System.err(18608): at com.threed.jpct.GLRenderer.drawVertexArray(GLRenderer.java:2472)
05-06 11:11:33.673: W/System.err(18608): at com.threed.jpct.World.draw(World.java:1426)
05-06 11:11:33.673: W/System.err(18608): at com.threed.jpct.World.draw(World.java:1109)
05-06 11:11:33.673: W/System.err(18608): at com.aeroshark333.artofearthify.lw.LiveWallpaperRenderer.onDrawFrame(LiveWallpaperRenderer.java:1155)
05-06 11:11:33.673: W/System.err(18608): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1524)
05-06 11:11:33.673: W/System.err(18608): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)


Fragment shader variables:
precision highp float;
precision highp int;
precision highp sampler2D;


uniform sampler2D textureUnit0;
uniform sampler2D textureUnit1;
uniform sampler2D textureUnit2;

uniform int textureCount;

uniform float visualizer;
uniform vec2 transparencies;
uniform float random;
uniform vec2 location;

varying vec2 texCoord[3];
varying vec2 eyeVec;
varying vec4 sunEyeData;

const vec4 BLACK = vec4(0,0,0,1);
const vec4 WHITE = vec4(1,1,1,1);
const vec3 SATURATIONFORMULA = vec3(0.2125, 0.7154, 0.0721);
const float RANDA = 12.9898;
const float RANDB = 78.233;
const float RANDC = 43758.5453;

const vec3 SATURATION = vec3(0.60,1.0,1.0);
const float ATMOSPHERE = 0.18;
const vec4 ATMOSPHEREPRIMARY = vec4(0.318, 0.341,0.741,1.0);
const vec4 ATMOSPHERESECONDARY = vec4(1.0, 1.0,1.0 ,1.0);
const vec4 ATMOSPHERETERTIARY = vec4(0.0,1.0,1.0,1.0);
const float CLOUDSSHADOW = 0.00018333;
const float SHADOW = 0.66;
const vec3 LIGHTS1 = vec3(1,1,1);
const vec3 LIGHTS2 = vec3(1,1,1);
const vec3 LOCATIONCOLOR = vec3(1.0,0.0,0.0);
const vec4 REFLECTIONCOLOR = vec4(1.0,1.0,1.0,1.0);


Any ideas?
This shader does work just fine on most devices so I don't really know... (well the only case I found it not working was with my brother's phone which has a Vivante chip)

EgonOlsen

It tells something about 'out of resources'... which ever resources these might, but I guess that's the reason. Try to simplify the shader until it compiles... Maybe that helps to find the root cause.

AeroShark333

#10
A small question about the default shaders...
I took a look at the default vertex shader you made for Vivante and the regular default vertex shaders...
Though, I don't really see much of a difference than that addColor method/function that replaces the regular color adding lines in the main method/function.
How is this a fix for Vivante chips? It does the exact same thing...

EDIT:
Well I fixed the issue I guess but it was really annoying to fix this...
But basically, I just moved some variables to the vertex shader as varying variables that would otherwise have been calculated in the fragment shader...

What wouldn't work is this for example (not my actual code but for example...):
#vertex shader

varying float angle;
varying float variable1;
varying float variable2;

void main(){
   angle = 0.5;
   variable1 = 0.1;
   variable2 = 0.2;
}


#fragment shader

varying float angle;
varying float variable1;
varying float variable2;

const vec4 col1 = vec4(1.0);
const vec4 col2 = vec4(0.75);
const vec4 col3 = vec4(0.5);

void main(){
   if(angle<0.0){
      col = mix(col1,mix(col2,mix(col3,col4,-angle),variable1),variable2);
   }else{
      col = col1;
   }
}


So my fix would basically have been this...:
#vertex shader

varying float angle;
varying float anglePos;
varying float variable1;
varying float variable2;

void main(){
   angle = 0.5;
   anglePos = -angle;
   variable1 = 0.1;
   variable2 = 0.2;
}


#fragment shader

varying float angle;
varying float anglePos;
varying float variable1;
varying float variable2;

const vec4 col1 = vec4(1.0);
const vec4 col2 = vec4(0.75);
const vec4 col3 = vec4(0.5);

void main(){
   if(angle<0.0){
      col = mix(col1,mix(col2,mix(col3,col4,anglePos),variable1),variable2);
   }else{
      col = col1;
   }
}


Something like that...

Anyway, thanks for the help!
I guess it's all sorted now

Quote from: EgonOlsen on May 04, 2017, 02:06:17 PM
I can extend the limit to 16384 or 32768 in the next version...no problem with that.
And thanks for this too if it will happen :)

EgonOlsen

Glad that you've fixed it. The default shaders' semantics for Vivante and the other ones are the same. It just doesn't work on Vivante if I won't move the calculations into the method. It would just crash.