Sign in to follow this  
JohnHardy

Expert advice about render order

Recommended Posts

Hey Folks,

I have a question about how to optimally draw things in light of how the video driver works. I had a quick poke around and found a few conflicting examples (most are suited to cases where scalability is not a denominating issue) so figured this would be a good place for a definitive answer. [img]http://public.gamedev.net/public/style_emoticons/default/smile.gif[/img]



In our game we are using lots of models in the same scene which have large texture files and high poly meshes - enough to fill the texture memory of most cards. Should we draw them like this:

[b]Method A:[/b]
[code]
Begin()
BeginPass(1)
RenderModelA_TextureA
RenderModelA_TextureB
RenderModelB_TextureA
RenderModelB_TextureB
BeginPass(2)
RenderModelA_TextureA
RenderModelA_TextureB
RenderModelB_TextureA
RenderModelB_TextureB
End()
[/code]

[b]or Method B:[/b]
[code]
Begin()
BeginPass(1)
RenderModelA_TextureA
BeginPass(2)
RenderModelA_TextureA

BeginPass(1)
RenderModelA_TextureB
BeginPass(2)
RenderModelA_TextureB

BeginPass(1)
RenderModelB_TextureA
BeginPass(2)
RenderModelB_TextureA

BeginPass(1)
RenderModelB_TextureB
BeginPass(2)
RenderModelB_TextureB
End()
[/code]

My current feeling is that Method B will be best since seems cheaper to change a pointer in the shaders than it is to hit a cache limit and end up sending another 2048x2048x32x5 texture set to the card. However the other argument is that once it is in memory, we cannot really code for the caching policy and at by changing the texture set we are just effectively swapping pointers and there is no large data transfer going on - this suggests we should avoid the render state switches instead.

Looking forward to hearing what your answers are!

Best,

John

Share this post


Link to post
Share on other sites
What is considered a 'pass'? Because if it involves a different shader then that is the most expensive change you can make on the GPU and is FAR more than just 'changing a pointer'.

Same thing with textures; far more goes on than just 'changing a pointer'.

In short; changing shader is the most expensive thing you can do, followed up by constants and textures in about that order.

Share this post


Link to post
Share on other sites
Thanks for your reply!
Why is changing a shader so expensive? Is it clearing all the caches' and video memory?

As for what I am defining as a pass:
[code]technique SomeTechnique
{
pass p0
{
...blah...
VertexShader = compile vs_3_0 VS_Model();
PixelShader = compile ps_3_0 PS_Model();
}
pass p1
{
...blah...
VertexShader = compile vs_3_0 VS_Model();
PixelShader = compile ps_3_0 PS_Detail();
}
}[/code]
[font="courier new"][size="1"][font="arial, verdana, tahoma, sans-serif"] [/font][/size][/font]
In this case, p0 and p1 are the different passes within the same technique. Does this change your answer?

Share this post


Link to post
Share on other sites
The shaders have to be loaded into the GPU, various states need to be set, variables uploaded into registers, caches cleared/reset and a whole heap of other work needs to be done to get the GPU into the correct 'state' to use the program.

As to the above code, it very much depends on what 'blah' is doing as to what the driver might do, also it depends on what the effect runtime is doing; if it doesn't recognise that the two passes use the same shader then it might be setting the shader anyway.

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