Unused variables in uniform buffer optimized out

Started by
5 comments, last by B_old 10 years, 10 months ago

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.

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);

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?

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.

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.

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

Ok, thanks for the input. I think I can figure something out now.

This topic is closed to new replies.

Advertisement