Jump to content

  • Log In with Google      Sign In   
  • Create Account


Unused variables in uniform buffer 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.

  • You cannot reply to this topic
6 replies to this topic

#1 B_old   Members   -  Reputation: 656

Like
0Likes
Like

Posted 03 June 2013 - 11:39 AM

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.

 



Sponsor:

#2 Ashaman73   Crossbones+   -  Reputation: 7095

Like
0Likes
Like

Posted 04 June 2013 - 06:16 AM

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


#3 B_old   Members   -  Reputation: 656

Like
0Likes
Like

Posted 04 June 2013 - 06:39 AM

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?



#4 Ashaman73   Crossbones+   -  Reputation: 7095

Like
1Likes
Like

Posted 05 June 2013 - 03:30 AM

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.



#5 B_old   Members   -  Reputation: 656

Like
0Likes
Like

Posted 05 June 2013 - 05:14 AM

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. 



#6 Hodgman   Moderators   -  Reputation: 29294

Like
1Likes
Like

Posted 05 June 2013 - 05:44 AM

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



#7 B_old   Members   -  Reputation: 656

Like
0Likes
Like

Posted 05 June 2013 - 08:26 AM

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






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.



PARTNERS