speeding up shader pass state changes

Started by
4 comments, last by Dragon_Strike 15 years, 10 months ago
im using direct3d10... what ways are there to speed up shader state changes? just as a test im rendering several hundred of boxes... and all i change between each box is the world matrix... even soo.. the "GetTech()->GetPassByIndex(n)->Apply(0);" takes as much as 60% of the cpu time... for each box effect->set world matrix effect->pass->apply // SLOW! render box is there any way i can speed up this? ive been looking a bit in the documentation and i saw something about state_block_masks... would that be relevant? i know i should use instancing but ill do that later
Advertisement
Not totally sure how you have things set up but some things to keep in mind:

1. When you load your effect cache the pass pointers so you dont have to call "GetTech()->GetPassByIndex(n) (unless for some reason you are doing multipass)

2. Use constant buffers and group them based on update frequency (per frame, per material, per object etc...) Otherwise all shader constants are thrown into a single default constant buffer and each time pass->Apply() is called it will send everything to the gpu again even if only one constant was updated.

3. Sort everything by material/effect pass before rendering to reduce state changes.

4. Since you are rendering so many boxes just the sheer number of draw calls is going to slow things down some. I know you said you will look into it later, but if you are rendering several hundred of the same mesh and you want to reduce the CPU time, instancing is probably the only thing that's going to do a whole lot in this case.
ive been googling constant buffers for a while... just to make sure ive understood correctly..

its enough to just place the constants in different buffers and then the API will manage the update frequency automatically.. i dont have to do something more?

EDIT:

also does this work between shaders? for example id only have to set the modelviewmatrix once for all shaders?

[Edited by - Dragon_Strike on May 29, 2008 6:45:47 AM]
Yup all you have to do is divide things into the cbuffers in your shader and it will take care of the rest. I'm not totally sure about sharing between shaders but I would assume that if you have it set up with an effect pool and shared variables it would work just the same with or without cbuffers
Quote:Original post by Dragon_Strike
for each box
effect->set world matrix
effect->pass->apply // SLOW!
render box


Ideally this would be written giving the material presidence.

for each material material->Apply() for each box_that_uses_this_material  material->SetAttribute(WORLD_MATRIX, box.Transform)  render(box)
Quote:Original post by bzroom
Quote:Original post by Dragon_Strike
for each box
effect->set world matrix
effect->pass->apply // SLOW!
render box


Ideally this would be written giving the material presidence.

for each material material->Apply() for each box_that_uses_this_material  material->SetAttribute(WORLD_MATRIX, box.Transform)  render(box)


as far as ive understood the WORLD_MATRIX wont be changed until u Apply the shader?

This topic is closed to new replies.

Advertisement