Every now and then, a Game Studio 3.1 customer tries something like:
spriteBatch.Begin(SpriteSortMode.Immediate); SetRenderStateFoo(); spriteBatch.Draw(...); SetRenderStateBar(); spriteBatch.Draw(...);
But this does not work! Sadness ensues.
The problem is that SpriteSortMode.Immediate did not really mean "immediate". A more accurate name would have been "inelegant hack that was added to enable drawing sprites with custom renderstates or shaders, but which still does some minimal amount of batching in the interest of having the aforementioned sprite drawing not be ridiculously slow when there are large numbers of such sprites". That’s too long to make a good enum name, though, so we just went with "immediate" 🙂
Prior to Game Studio 4.0, the way SpriteSortMode.Immediate actually worked was:
- Begin sets default states onto the graphics device
- Draw adds a sprite to the current batch
- If you call Draw with a different texture from the previous call, it flushes the current batch
- End flushes the current batch
That really only allowed one usage pattern:
- Set custom states
- Draw any number of sprites
Any time you wanted to change state, you had to End the current batch, then Begin a new one.
So, we changed SpriteSortMode.Immediate to work the way people always expected it to. Every Immediate mode SpriteBatch.Draw call now generates a separate GPU draw call, exactly like the name implies, really truly immediately with no batching whatsoever.
- If you draw many sprites in a row using SpriteSortMode.Immediate, they will not be batched, and performance will suffer as a result. You should only use Immediate sort mode if you need to change state between every Draw call. Most of the places you used to specify Immediate sort mode, Deferred is now a better choice.
- The code I posted at the start of this article now works like you would expect.