Unbinding or directly binding a new shader

Hi there.

Simple question: Is it a bad habit to first unbind an old shader and then bind the new shader?

Might it be better to directly bind the new shader?

I just thought, this might be better, since the other way round this might be equal to binding 2 different shaders, without using the first (fixed pipe).

Jan.

I would not expect drivers to help me optimize my code.

This is what I do

//variable declarations
GLhandleARB currentProgramHandle=0;


if ( currentProgramHandle != Doom3BadGuy_ProgramHandle )
{
   currentProgramHandle = Doom3BadGuy_ProgramHandle;

   glUseProgramObjectARB(currentProgramHandle);
}

I would recommend doing like V-man suggests. The drivers may or may not optimize here, but you shouldn’t rely on it too much. I see no reason why you should switch to fixed function in between, unless that’s a consequence of the way you have structured your code. I did a similar thing for VBOs before, switching back to regular VAs after using a VBO, but I’ve fixed that in a new framework I’m working on.

Yeah, i´ll do so.

And another thing: If i change the value of a uniform, how much does that impact performance?

In the most naive case, i would think, that a driver might take the shader and insert a constant for the uniform. If it was this way, changing the value of a uniform would be as heavy-weighting, as a complete shader-switch.

Well, i hope this is not the case, is it?

Jan.

uniform = constant = parameter = register

I hope I have not misunderstood something.
By constant, you mean an immediate value?

I have assumed the shaders consume a register and don’t actually compile into the instruction, otherwise, we would have very large instructions.
Instead, I think the instruction just refers to a register address in the GPU.

From another thread, I think it was evanGLizer that said changing uniforms can be costly on NV because it sets up the shader (assembly shader have the same issue)

Shaders consume registers. I don’t know all the dirty details of the hardware, but I would be very surprised if any hardware supported inlining of immediate values in the command string, except perhaps for a few special cases like 0 and 1 and -1.

Whenever you set a uniform, you’re uploading a value to a shader constant register. It’s much cheaper than switching shaders, but it has a cost as well of course. In practice however I would think it’s pretty uncommon to be limited by uniform updates.

Thanks, that answers my question.

Jan.

Whenever you set a uniform, you’re uploading a value to a shader constant register. It’s much cheaper than switching shaders, but it has a cost as well of course. In practice however I would think it’s pretty uncommon to be limited by uniform updates.

on my gffx using a unifrom in a shader makes the shader one instruction more than using a constant

thus
uniform float material_shininess;
col = pow( specular_amount, material_shininess );
is one longer instruction than
col = pow( specular_amount, 16.0 );

now im betting in a real world app changing a shader to using a more streamlined shader is gonna run quicker than a generic shader (provided youre drawing pixels onscreen with it, cause each pixel is gonna execute quicker) and changing uniforms

(i do the first version btw, as im not SUCH a performance junkie)
hmmm but then again its got me thinking, do i need to use any uniforms at all!

Originally posted by zed:
on my gffx using a unifrom in a shader makes the shader one instruction more than using a constant

How do you know it’s one instruction less for the second version?

Remember that the hw can do something different than what is indicated by the disassembly.

except perhaps for a few special cases like 0 and 1 and -1.

It’s possible to have special FPU instructions, in which case they won’t actually store the -1, 0, or, 1 in the instruction.
I think it’s safe to assume the instructions are 32 bit, and possibly less in some cases.

>>How do you know it’s one instruction less for the second version>>

from loooking at the asm output

>>Remember that the hw can do something different than what is indicated by the disassembly.>>

i would think it would interperate the asm literally ((but i dont now the inner workings)
hmm i might chuck together a test case of the two and see what the performance difference is (if any)

ok tested, oddly enuf i now cant see any difference in instruction length between using unifroms + hardcoded values. im sure i saw this before. so in that case unifroms are better
(my testing wasn’t exactly thorough though)

There are cases where knowing the value at compile time allows for certain optimizations. You can bake together constants. In the pow(x, 16.0) case it’s still going to be three instructions, but for instance pow(16.0, x) can be reduced to two instructions.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.