Sign in to follow this  
AlexKappner

Memory footprint of compiled shader in graphics memory

Recommended Posts

I am currently in the process of optimizing a DirectX 3d graphics engine that uses shaders that are compiled at run-time from .fx files. Currently, the engine creates a new DirectX Effect instance for every possible variation of shader parameters, even if they are based on the same .fx file. So, for example, if I have a water shader that comes in 2 variants, say "clear water" and "muddy water", both based on the same code, but with different index of refraction and reflectivities, the engine will compile the .fx twice. Would you consider that a significant waste of GPU memory, or is the compiled effect so small that rewriting the engine to re-use compiled Effects whereever possible would be a waste of developer time? Best regards & happy holidays Alexander

Share this post


Link to post
Share on other sites

In this kind of scenario the cost of switching shaders is likely to be significantly higher than the cost of having multiple shaders, so your focus should be on shader changes rather than on memory usage.  In the example you gave you could easily combine the two and have the variable factors as uniforms or even per-vertex attributes.

Share this post


Link to post
Share on other sites
I did not consider that. Makes sense - even though the compiled shaders themselves are small, both the GPU and the host still waste cycles loading and unloading their code several times per frame. Thanks for your answer! Best regards Alexander

Share this post


Link to post
Share on other sites

GPU's do not "load and unload" shader code mid-frame, and won't waste cycles doing that. Any associated cost with switching shaders typically come from hidden state changes, flushes of the GPU pipeline, and/or extra work that needs to be done by the shader behind the scenes.

When it comes to compiling multiple versions of the same shader code, it depends on what the differences are. If the only difference is that one shader a parameter has a value of "4" and the other one has a value of "4.5", then it's probably not worth it. However in some cases a hard-coded parameter can allow the compiler to make significant optimizations. For instance imagine a simple pixel shader with lighting that has a albedo map and an albedo tint color, where the output is basically lighting * albedoMap * albedoTint. If you were set albedoTint to 0.0, then the compiler would optimize out the albedo map texture fetch as well as all of the lighting calculations since they would end up having no effect on the output. In that case it may be worth having multiple versions of the shader, rather than relying on passing the parameters as shader constants.

Share this post


Link to post
Share on other sites
GPU's do not "load and unload" shader code mid-frame, and won't waste cycles doing that. Any associated cost with switching shaders typically come from hidden state changes, flushes of the GPU pipeline, and/or extra work that needs to be done by the shader behind the scenes.

 

Switching shaders also means having to break a draw call batch (same as any other state change) which - while not such a big deal on D3D11 as it was on 9 - is still not a free operation.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this