Jump to content
  • Advertisement
Sign in to follow this  
B_old

OpenGL Unused variables in uniform buffer optimized out

This topic is 1844 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 want to use the same uniform buffer for different shader programs, some of which might not use certain variables of the buffer at all. The way I understand this description this should be possible with the (default) shared layout description.

Unfortunately glGetUniformIndices will not give usable results if the specified variable is not used in that particular program. How should I query the buffer offset for that particular variable. Would it work to check all programs until I find one that indeed does use the variable? Or is there a better way.

I believe it would also be possible to use the std140 layout and calculate the offsets by myself using the defined rules. I'm not particularly worried about the theoretically higher storage cost, but it seems much more complicated to calculate the offset by hand instead of querying with the API.

 

Share this post


Link to post
Share on other sites
Advertisement

Write some kind of simple wrapper to the shader variable. The wrapper checks if the vairable is present (only once, after the shader has been uploaded and compiled) and just ignore unmapped variables.

 

Here's some pseudo-code:

 

class ShaderVariableLink {

private:
  int positionOfVariableInShader;

public:

ShaderVariableLink( ... idOfShaderProgram, ... variableName) 
{
   // get shader program
  ...
   // check if variable is present
   if(checkIfVariableIsPresent(variableName))
   {
     positionOfVariableInShader = getVariablePosition(variableName);
   } 
   else
   {
     // not present
     positionOfVariableInShader  = -1;
   }

}

void setFloat(float myFloat)
{
   if(positionOfVariableInShader>=0) 
  {
     loadFloatVariable(positionOfVariableInShader, myFloat);
  }
}
}



// example
myShaderId = uploadAndCompileShader(...);

// create new link
ShaderVariableLink* myAlphaVarable = new ShaderVariableLink(myShaderId, "my_shader_alpha_variable_name");

// link now
myAlphaVarable->setFloat(123.45f);

Share this post


Link to post
Share on other sites

I understand.

The problem I am having, is that I want to use the same uniform buffer/shader variable link in different programs, similar to the effect technique idea of cgfx or the (deprecated) d3dx effects. The problem starts when querying the variable position in a program that does not use that particular variable of the uniform block.

Or are you proposing to have a ShaderVariableLink for every program?

Share this post


Link to post
Share on other sites

Or are you proposing to have a ShaderVariableLink for every program?

Yep, this is the way to go. You can embed the links in a ShaderProgram-class, but eventually you are using links for every compiled shader program. The benefit is, that you can play around with the shader code without adjusting your game code. This way I can reload shaders on-the-fly, which is really helpful when testing new features or debugging a shader.

Share this post


Link to post
Share on other sites

Hm, I was looking for a more cgfx or d3dx-fx like solution. That is, an effect can contain several shader programs (what they call techniques), but the shader variables are controlled by the effect object. 

The way I understand it, this is supperted by OpenGL and the uniform buffers. As long as several programs share a buffer, writing to a variable that is not really used by the current program should do no harm because it does not overwrite other variables.

So I'm looking for a good way to get the variable offsets. The challenging part is, that a shader program might not provide a usable index for those variables. 

Share this post


Link to post
Share on other sites

You could just query every program in your "grouping" for every offset value. If you don't yet have an offset value for that variable, then store it, or if you do have one, then assert that the current program's offset value is equal to the one that you already have.

Then you'll end up with your variable->offset mapping, with only variables that aren't used by any program missing (and you'll be sure that the driver is complying and actually using the same offsets in every program).

 

Personally, I'd just use std140 though cool.png

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!