How to do batching with Effect Files???

Started by
7 comments, last by Jason Z 17 years, 9 months ago
I have been trying to figure out how to gain some improvement in rendering my GUI over the last couple of days and have kind of ran into a wall. While rendering all of the buttons in a given screen, my effect file system will sort all of the objects by type so that everything that uses the same effect get rendered together. Then the effect is started, each object is rendered during the first pass of the selected technique, each object is rendered for the second pass ... and so on until the effect is finished. Then it ends the effect and moves on to the next one. The problem comes in when rendering the objects pass by pass. In between the various objects rendering I have to call CommitChanges to update any rendering parameters that the object has changed prior to rendering itself - in particular textures. By calling CommitChanges every button that I render is calling SetTexture, giving me 30+ set texture calls that should only be 1 set texture call!!! So I am wondering what you DX experts have done to get around this problem. It would be close to impossible to keep track of what texture is set in each effect at all times - not to mention the fact that other (non-texture) parameters may change as well and I would have to keep track of those too. Is there any relatively painless way to keep objects separate but still not set EVERY parameter individually? Thanks in advance for any help or advice that someone can give!
Advertisement
I suppose I could collect all of the buttons and build them into a single draw call. The only problem with that is that there would have to be a separate draw call for each type of controls that I want to render.

If anyone has any suggestions I'm all ears [smile]
So, you have one texture for all of the buttons, and each button is doing the ID3DXEffect->SetTexture() call with that same texture file? Calling CommitChanges only finalizes any ID3DXEffect->Setxxxx calls you have done since calling BeginPass().
--------------------------Most of what I know came from Frank D. Luna's DirectX books
Yes, that is correct. At startup I build a list of the parameters that the effect requires and use their semantics to match them up to the equivalent in my renderer. Because I never find out which sampler gets used, I can't really keep track of which one is set where. So I have always been setting all of the parameters.

Most of the projects that I work on use a minimal GUI, but I would really like to be able to optimize this problem away in general.
If i get you right you are sorting the controls by effect, then drawing each control individually and setting the same effect for each control.

If this is the case, why don't you set the effect once and then render all of the required controls in individual draw calls, but with the same effect.

Dave
I think that using a custom state manager should help here (its what I'm planning to use).

You can have it monitor the state of the different samplers and if the effect attempts to set the same texture twice just ignore the command. If you then use one texture for all the buttons then CommitChanges() should result in no SetTexture().

As I said I haven't done this yet, but I think it might help.
Sorry. Forgot to mention this. See ID3DXEffectStateManager in the DX SDK for what I was rambling about.
Is there any reason why you´re not simply sorting the objects that use the same effect according to their texture?
That way you should end up with a bunch of objects that use the same texture, set that texture once, draw them all, do the same thing with the next bunch of objects that use the same texture and so on?
Quote:Original post by matches81
Is there any reason why you´re not simply sorting the objects that use the same effect according to their texture?
That way you should end up with a bunch of objects that use the same texture, set that texture once, draw them all, do the same thing with the next bunch of objects that use the same texture and so on?


That is probably how I should be doing it, but currently the list of objects to render gets sorted by object type (like regular geometry, alpha, skybox etc.), then by effect, then by textures. However, the batch rendering system only renders the batches by effect. I suppose that may be the way to fix it - make the batches break up by texture as well as effect. I was just hoping to avoid rewriting my batch rendering code if it was at all possible. This is a good suggestion though - I think it will work!

I will also investigate the custom state manager. I think there is a sample that uses it in the DXSDK that I can start out with. IIRC it was a little strange how they implemented it, but I am sure I can work with it. This may be a little bit easier to implement than rewriting my drawing code by handling the SetXXX calls in a separate layer between the effect and my renderer.

This should be enough for me to move forward on. Thanks alot for the suggestions - I really appreciate the help.

This topic is closed to new replies.

Advertisement