Is dynamic branching ok nowadays?

Back in the early days when dynamic branching first became available on GPU’s, I was always told to avoid it because it carried a big performance hit. This always seemed counter-intuitive, because I thought the whole purpose of dynamic branching was to skip expensive calculations when they weren’t needed.

Is this no longer the case nowadays? For example, for a weapon shader, the shader recieves one static and one dynamic light values from the game engine. So the shader always calculates the lighting for two lights, no matter what, even if one of the lights is far away and doesn’t contribute much. Would it make sense to use dynamic branching to skip one or both of the lighting equations if the light is beyond a certain range, using an if statement to just return zero, for example?

Yes you should use dynamic branching if you can reduce the number of instructions by doing so.
Forget the old days :slight_smile:

Keep in mind the particulars of your shading system as well. Dynamic branching in a higher-level descriptor doesn’t necessarily equate to dynamic branching in lower-level shader code. For example, say you work in a shader system that builds its runtime versions based on a nodegraph or a custom shading language wrapper. You may end up unknowingly “building” tons of shaders or shader code snippets under the hood that end up eating your memory down the road.

Thanks for the replies. I should have mentioned that I am using directx9 and shader model 3.0.

I’ve actually found something interesting by examining the compiled assembly code. It appears the D3DX9 shader compiler is smart enough to know when branching is worthwhile. For small branches, the compiler automatically unrolls the branches and will take both paths. But…if the branch contains tons of instructions, the assembly code will indeed show an if/else statement.

So, for my particular case, it appears it’s actually quicker just to calculate both light sources for simple blinn lighting. I’m guessing if I was doing something more complex like parallax relief shading for multiple lights, then branching would be worthwhile.

The answer to all optimization questions: profile it!

I second Rob’s reply. I’ve seen some cases using dynamic branching where NVPerfHUD claims that the shader is using double the number of instructions, but the frame rate stays exactly the same. For development, it’s safe to assume that the branching will work, but be sure you test it on a variety of cards to make sure that that assumption is correct.

Back in the days the main reason to avoid branching in shader code was due to the GPU flushing all caches (even texture caches) and pipelines if a branch was hit… Thus if you hit a branch for every pixel… Your performance was pretty much toast.

As said, profile the code. Using PIX on Xbox 360 is just pure awesomeness.

SamiV.