Today I have notice some strange performance problem in my Application.
When compiled & linked shaders are use to render something for the first time, it will be very slow.
But when the shader are use the second time (even with difference uniforms) it will run at full speed.
This give me a problem since I have a pool of forward rendering shader that support multiple light, let say 1Lightshader,2Lightshader etc… and when these shader are active for the firs time it make the program stuttering.
Since the scenario where the engine choose which shader to use is completely random (due to dynamic lighting nature), it could make my application stuttering at any time before it become stable.
If the shader programs are compiled just-in-time, then why do I get the compiler and linker error messages when I compile and link my shader programs, and why do I get the linked locations of my attribute and uniform variables when I call glGetAttribLocation() and glGetUniformLocation(), all well before rendering my first frame?
somboon, I have an ATI 5750 with Catalyst 10.8 drivers and I haven’t experienced what you have described. When you say that it “is very slow” the first time you render something, how slow do you mean? (You later wrote 5 FPS, but how may FPS is full speed after rendering your first frames?)
Did you call glGetShaderiv() with GL_COMPILE_STATUS after compiling each shader, and call glGetProgramiv() with GL_LINK_STATUS after linking each shader program, to see if the compilations and links were successful? If not, then calling them should force the shaders to be compiled and linked before you try to render your first frame.
P.S. Do you call glGetAttribLocation() and glGetUniformLocation() exactly once per variable per shader program, or do you call them before you render each frame? They should be called just once per variable per program, not once per frame.
No, pretty sure this is not generally true on an NVidia card, and definitely not true for our usage of GLSL on an NVidia card. This first-time-slowdown-after-changing-uniforms thing doesn’t (AFAIK) happen with GLSL on NVidia GPUs that are GeForce 8 or later. Been working on NVidia GPUs/drivers every work day for 8+ years, and last time I saw this odd first-use-slowdown behavior was on a GeForce 7. There have been 5 generations of GPU since then.
That said, I’m not an NVidia driver developer (hopefully one will follow-up to this thread with more conclusive info), so my experience doesn’t mean it’s not possible. For instance, it might or might not happen if you are using the very new separate shader bojects capability. I haven’t tested with that, and there was an implication dropped in the OpenGL BOF that some of the normal optimization might be deferred from link until use with separate shader objects.
Post a short GLUT test program that illustrates your problem and you’ll find lots of folks here willing to cross-test your program on lots of hardware. Here’s a starter template.
The stuttering is pretty nasty, it bring FPS down to 5fps or something when it occured.
Are you sure that there isn’t something else that just happens to be going on at the same time? Like rendering with a new mesh or something?
This first-time-slowdown-after-changing-uniforms thing
That’s not what the OP was asking about. He’s having a problem where there is a stall on the first time a shader is used. He specifically said that changing uniforms doesn’t affect this, nor does it create a slowdown later.
I faced a similar problem in my project( with cg). My application require around 40 fps display.
Whenever a state change( recreation of shader program ) was required, display stuck for a moment and then continue with new shaders.
After analysis I optimized some bad methods( for high display rate) in my application.
Avoided shader program compilation at runtime. Instead of that we created assembly code with “cgc.exe” and output file is used for compilation of shader.
Avoided file reading when during the state change. All shaders are kept as resource file of my application and avoided file I/O during shader creation. If your shader programs are different file in disk, then file I/O will consume some precious time.
If anything applicable for your program, u can implement it to increase performance.