View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

# uniforms optimized-out

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

5 replies to this topic

### #1syskrank  Members

Posted 14 August 2014 - 03:09 AM

Hi.

I'm facing the problem that GLSL optimizer eliminates my uniforms, that are actually used.

#version 120
#ifdef GL_ES
precision mediump float
#endif

attribute vec3 a_position;
attribute vec3 a_normal;
attribute vec2 a_texCoord0;

attribute vec2 a_boneWeight0;
attribute vec2 a_boneWeight1;
attribute vec2 a_boneWeight2;
attribute vec2 a_boneWeight3;
attribute vec2 a_boneWeight4;
attribute vec2 a_boneWeight5;
attribute vec2 a_boneWeight6;
attribute vec2 a_boneWeight7;

// uniforms
uniform mat4 MVP;
uniform int useBoneWeight[8]; // use numbered bone or not
uniform mat4 boneTransform[8];
uniform int useSkinning;

//// outputs
#ifdef GL_ES
varying medium vec3 normal;
varying medium vec3 worldPos;
varying medium vec2 textureCoord;
#else
varying vec3 normal;
varying vec3 worldPos;
varying vec2 textureCoord;
#endif

void main() {
textureCoord = a_texCoord0;
mat4 skinning = mat4( 0.0 );
if ( 1 == useSkinning )  {
skinning += ( ( a_boneWeight0.y ) * boneTransform[ int( a_boneWeight0.x ) ] * useBoneWeight[ 0 ] );
skinning += ( ( a_boneWeight1.y ) * boneTransform[ int( a_boneWeight1.x ) ] * useBoneWeight[ 1 ] );
skinning += ( ( a_boneWeight2.y ) * boneTransform[ int( a_boneWeight2.x ) ] * useBoneWeight[ 2 ] );
skinning += ( a_boneWeight3.y ) * boneTransform[ int( a_boneWeight3.x ) ] * useBoneWeight[ 3 ];
skinning += ( a_boneWeight4.y ) * boneTransform[ int( a_boneWeight4.x ) ] * useBoneWeight[ 4 ];
skinning += ( a_boneWeight5.y ) * boneTransform[ int( a_boneWeight5.x ) ] * useBoneWeight[ 5 ];
skinning += ( a_boneWeight6.y ) * boneTransform[ int( a_boneWeight6.x ) ] * useBoneWeight[ 6 ];
skinning += ( a_boneWeight7.y ) * boneTransform[ int( a_boneWeight7.x ) ] * useBoneWeight[ 7 ];
gl_Position = MVP * skinning * vec4( a_position, 1.0f );
normal = ( MVP * skinning * vec4( a_normal, 0.0f ) ).xyz;
worldPos = ( MVP * skinning * vec4( a_position, 1.0f ) ).xyz;
} else {
gl_Position = MVP * vec4( a_position, 1.0f );
normal = ( MVP * vec4( a_normal, 0.0f ) ).xyz;
worldPos = ( MVP * vec4( a_position, 1.0f ) ).xyz;
}
}



Uniforms 'useBoneWeights' and 'boneTransform' are erased during optimization.

I've tried to get their location with glGetUniformLocation() querying them by array name and array indexed elements.

All other parts of the shader are working fine.

I'm using Java and libgdx1.2.0 ( thus - opengl es 2.0 ) and my semi-custom shader system ( incapsulated libgdx' Shader class to give it more 'native' C/C++ interface ).

### #2Ashaman73  Members

Posted 14 August 2014 - 03:24 AM

I've tried to get their location with glGetUniformLocation() querying them by array name and array indexed elements.

Can you show the code where you query the location ?

Ashaman

### #3syskrank  Members

Posted 14 August 2014 - 03:44 AM

Ok, here it is. I'm building on top of libgdx' ShaderProgram :

import com.badlogic.gdx.Gdx;

import java.util.Map;
import java.util.HashMap;

public class Shader implements Disposable {
public Map<String, Integer> uniforms;

public static final int SHADER_OK = 0;
public static final int SHADER_ERROR = 1;

if ( program.isCompiled() ) {
} else {
}
uniforms = new HashMap<String, Integer>();
}

public void bind() {
program.begin();
}

public void unbind() {
program.end();
}

public int addUniform( String name ) {
int location = program.getUniformLocation( name );
if ( -1 == location ) {
Gdx.app.log( SHADER_TAG, "Failed to get uniform's '" + name + "' location." );
} else {
uniforms.put( name, location );
}
}

public int setUniformInt( String name, int value ) {
Integer location = uniforms.get( name );
if ( null == location ) {
Gdx.app.log( SHADER_TAG, "Integer uniform '" + name + "' doesn't exists." );
} else {
program.setUniformi( location.intValue(), value );
}
}

public int setUniformFloat( String name, float value ) {
Integer location = uniforms.get( name );
if ( null == location ) {
Gdx.app.log( SHADER_TAG, "Float uniform '" + name + "' doesn't exists." );
} else {
program.setUniformf( location.intValue(), value );
}
}

public int setUniformVec2( String name, Vector2 value ) {
Integer location = uniforms.get( name );
if ( null == location ) {
Gdx.app.log( SHADER_TAG, "Vector2 uniform '" + name + "' doesn't exists." );
} else {
program.setUniformf( location.intValue(), value );
}
}

public int setUniformVec3( String name, Vector3 value ) {
Integer location = uniforms.get( name );
if ( null == location ) {
Gdx.app.log( SHADER_TAG, "Vector3 uniform '" + name + "' doesn't exists." );
} else {
program.setUniformf( location.intValue(), value );
}
}

public int setUniformMat4( String name, Matrix4 value ) {
Integer location = uniforms.get( name );
if ( null == location ) {
Gdx.app.log( SHADER_TAG, "Matrix4 uniform '" + name + "' doesn't exists." );
} else {
program.setUniformMatrix( location.intValue(), value );
}
}

@Override
public void dispose() {
program.dispose();
}

}

ShaderProgram, in it's turn, has the following code inside:

    private void fetchUniforms () {
params.clear();
Gdx.gl20.glGetProgramiv(program, GL20.GL_ACTIVE_UNIFORMS, params);
int numUniforms = params.get(0);

uniformNames = new String[numUniforms];

for (int i = 0; i < numUniforms; i++) {
params.clear();
params.put(0, 1);
type.clear();
String name = Gdx.gl20.glGetActiveUniform(program, i, params, type);
int location = Gdx.gl20.glGetUniformLocation(program, name);
uniforms.put(name, location);
uniformTypes.put(name, type.get(0));
uniformSizes.put(name, params.get(0));
uniformNames[i] = name;
}
}


So, yeah, basically, I'm fetching uniforms not directly from shader, but from libgdx' object, which kind of sucks.

Edited by syskrank, 14 August 2014 - 03:46 AM.

### #4Stainless  Members

Posted 14 August 2014 - 06:31 AM

do a sanity check

bump #version 120 up and recompile see if the problem persists.

From the code above it's too difficult to work out what's wrong. Maybe print out name and location in the for loop of fetchUniforms and see what that tells you.

### #5Erik Rufelt  Members

Posted 14 August 2014 - 09:03 AM

What OS/GPU do you run it on?

### #6syskrank  Members

Posted 14 August 2014 - 09:11 AM

Hi, Stainless.

What do you mean by sanity check?

I've tried playing with shader 'version' string with no luck.

Edit: I mentioned that my Java Shader object detects only the first element of the uniform array:  'useBoneWeight[0]' and 'boneTransform[0]' are located;

So, theoretically, I can use OpenGL's glUniform*() capabilities to send a whole array of data to the shader.

I will try that somehow.

What OS/GPU do you run it on?

I'm developing on two machines with Linux Mint 16 and Linux Debian 7 resp.

First system has Intel HD4000 and NV GF740M cards ( tried both ) and the last one has NV GT630. I'm using libgdx 1.2.0.

Android emulator produces same results.

Edited by syskrank, 14 August 2014 - 09:26 AM.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.