Jump to content
  • Advertisement
Sign in to follow this  
xerzi

OpenGL Handling Uniform Locations?

This topic is 1420 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have some old hardware that doesn't have the explicit uniform locations extension (even though it is still good hardware), and i would like to support it. It is a pain to use glGetUniformLocation, it causes so much redundant code to be written. Also the fact that uniforms and such can get optimized out, thus return an invalid value (iirc), which you then have to check for to avoid triggering an opengl error, which just piles onto the redundant code. I was wondering if anyone had any tips or can share how they handle this elegantly?

Share this post


Link to post
Share on other sites
Advertisement

Uniform buffer objects are a third option that can simplify uniform management, but there is a good chance that won't be supported either on older hardware. As far as I know, explicit uniform locations or glGetUniformLocation are the only other options. The OpenGL wiki appears to support this.

Share this post


Link to post
Share on other sites
I never had problems in that area. glGetUniformLocation should return -1 if the named uniform does not exist (either because the shader never contained it or it was optimized out) and according to the documentation

If location is equal to -1, the data passed in will be silently ignored and the specified uniform variable will not be changed.

passing -1 to glUniform should not cause any problems except wasting a few clock cycles on a noop call.
If your driver has problems with that you might want to install a newer driver.

Share this post


Link to post
Share on other sites

I have some old hardware that doesn't have the explicit uniform locations extension (even though it is still good hardware), and i would like to support it.


A driver update should be enough. Is there a reason that makes that inviable?

Share this post


Link to post
Share on other sites

Uniform buffer objects are a third option that can simplify uniform management, but there is a good chance that won't be supported either on older hardware. As far as I know, explicit uniform locations or glGetUniformLocation are the only other options. The OpenGL wiki appears to support this.

I'll look into, but from a glance (if it does require a buffer object to hold the data) idk if that is any easier, it just adds another thing to manage.

 

I never had problems in that area. glGetUniformLocation should return -1 if the named uniform does not exist (either because the shader never contained it or it was optimized out) and according to the documentation

If location is equal to -1, the data passed in will be silently ignored and the specified uniform variable will not be changed.

passing -1 to glUniform should not cause any problems except wasting a few clock cycles on a noop call.
If your driver has problems with that you might want to install a newer driver.

 

It is the vertex attribute that i was referring to there. If you pass -1 to any of those related functions it does give an invalid value error.

 

 

I have some old hardware that doesn't have the explicit uniform locations extension (even though it is still good hardware), and i would like to support it.


A driver update should be enough. Is there a reason that makes that inviable?

 

AMD dropped support for the card a while ago. It is mobile as well, so it wasn't ever really supported well to begin with.

Share this post


Link to post
Share on other sites


AMD dropped support for the card a while ago. It is mobile as well, so it wasn't ever really supported well to begin with.

 

If the manufacturer has dropped support and it was never supported well to begin with then why are you busting your hump to support it yourself?

Share this post


Link to post
Share on other sites

Cause i need something slower as a baseline, and i don't have anything else and i'm not willing to buy new hardware for such a purpose.

Share this post


Link to post
Share on other sites

I'll look into, but from a glance (if it does require a buffer object to hold the data) idk if that is any easier, it just adds another thing to manage.

If you use the std140 layout, the uniform structure in the shader will have the same layout as the structure in your C code. This is easier to handle, since you can just update your CPU-side struct and pass it to the shader with a single call, without querying each uniform location separately.

 

 

 

 

If this is a DX10-level GPU (AMD 2xx0-4xx0 series) there is a chance that this is supported.

Share this post


Link to post
Share on other sites

I have some old hardware that doesn't have the explicit uniform locations extension (even though it is still good hardware), and i would like to support it. It is a pain to use glGetUniformLocation, it causes so much redundant code to be written. Also the fact that uniforms and such can get optimized out, thus return an invalid value (iirc), which you then have to check for to avoid triggering an opengl error, which just piles onto the redundant code. I was wondering if anyone had any tips or can share how they handle this elegantly?

Just pretend that you're using cbuffers / UBO's anyway, then emulate them using glUniform. Instead of creating actual openGL UBO instances, just malloc some memory instead to emulate them.
 
Make a struct containing a uniform location, an offset (bytes into a cbuffer structure), and the type (e.g. vec4, vec2...).  
e.g. struct VariableDesc { int location, offset, type };
 
For each shader, for each cbuffer, for each variable in the cbuffer, attempt to make one of these "VariableDesc" structures (failing if you get location of -1). You'll end up with a array of VariableDesc's per each shader per each cbuffer.
 
When you want to draw something with a particular shader (and a set of bound cbuffer/UBO instances), iterate through these arrays. For each VariableDesc item, read the data at the specified offset, call the gl function of the specified type, passing the specified location. e.g.
for i=0, i!=shader.numCBuffers; ++i
  for j=0; j!=shader.variableDescs.count; ++j
    void* data = ((char*)cbuffer[i]) + shader.variableDescs[j].offset;
    switch(shader.variableDescs[j].type)
      case TypeVec4f: glUniform4fv( shader.variableDescs[j].location, 1, data );
      ....
Now you can keep your engine simple, pretending that you're using UBOs everywhere, while emulating support for them on crappy old GL2-era GPUs without hard-coding any glUniform calls.

Share this post


Link to post
Share on other sites

From what you're describing you're using anything between the Mobility Radeon HD 2000 and 4000 series.

I've checked and seems the driver team forgot about this extension.

 

May not be exactly the same, but these cards do expose the GL_ARB_shading_language_420pack which allows you to use explicit binding points for uniform buffers.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!