- March 7, 2009 at 8:38 pm #29723
Currently I have two shaders, they are almost the same and so use
uniforms that have the same name and values. The main difference is
that one shader uses discard for 1 bit alpha. When I change shaders I
have to upload uniforms that have changed since the shader was last
used and so there is code to keep track of the current uniform value so
if it has changed it can be sent again when the shader changes.
Is there away I can aviod all this extra ‘management’ work for the CPU?
DX shaders you can have a ‘pool’ of shared varibles (uniforms) that are
shared between shaders and so for example the projection matrix only
has to be uploaded once when it changes and not for every shader.
thing you can do in DX shaders is state the constant register a varible
(uniform) is using so you can get the same effect as the pool code.
Can we do either in GLES 2.0???March 9, 2009 at 10:08 am #32799
No, OpenGL ES 2.0 has no way of explicitly sharing uniform values between programs. It should be relatively easy to encapsulate pairs of programs like this in an object that keeps track of the uniform values, though. Alternatively you could simply set the uniform values on both programs at the same time. There is some overhead to this, but it might be insignificant.March 9, 2009 at 10:48 am #32800
I did have a thought, instead of doing code to manage this could I just use ‘glGetUniform’ on the uniforms they share to get the current values, activate the new program, then set the uniforms?
What is the cost of ‘glGetUniform’?
Richard e Collins.
RichardUK 2009-03-09 10:48:47March 9, 2009 at 11:15 am #32801
You could, but it seems to me this would require just as much code as storing the values yourself. The overhead would certainly be higher.March 9, 2009 at 11:35 am #32802
Is glGetUniform doing more than just returning a copy of a local store? As the API supports a ‘get’ on uniforms I had thought that it would be coming from an internal local store and not from the chip and so my code would only be unnessarily duplicating this.
Doing the code my side off the API means every time I set a uniform I need to record it and so increasing memory bandwidth usage. Something i’ve always tried to advoid on mobile chips.
Using the glGetUniform I only add ‘work’ for the CPU when the shader changes. Read current uniforms, change shader, set uniforms. (last stage has to be done with both methods)
But if glGetUniform has to do more than just reading a local store then yes not a good idea. In DX using a “Get” function is not a good idea and so i’ve always tried to advoid it with all 3D api’s including GL.
Seems the lack of shared uniforms in the shader language is bit of an oversight, it’s causing extra work for the CPU.March 9, 2009 at 12:35 pm #32803
glGetUniform needs to at least perform error and type checking, context and program lookup, so that is an overhead comparing to accessing a local variable. But I really think you’re worrying too much about micro-optimizations. The bandwidth required for storing uniforms should be negligible, and putting a wrapper class around your shader pair that keeps those values should require only a few lines of code.March 9, 2009 at 12:47 pm #32804
That is true. The killer here is the use of discard and so splitting the shader is the bottom line, only want discard in a shader if it’s going to be used.
I’ve done the code and there is not much to it. I guess coming from the old 8bit days when writing 16 dwords was a big deal I do fall into that trap from time to time. 😉