SpriteBatch and GraphicsDevice: Impact of SpriteSortMode on GPU State Changes
0 reputation · 12 May 2020, 15:38 UTC
0 reputation · 12 May 2020, 15:38 UTC
MonoGame uses the SpriteBatch class to interface with the GraphicsDevice, employing a deferred rendering system to minimize the overhead of GPU state changes. The efficiency of this pipeline depends heavily on the SpriteSortMode selected during the Begin() call.
When utilizing SpriteSortMode.Deferred, the framework batches draw calls until End() is invoked. However, the interaction between sorting modes and frequent changes to BlendState or SamplerState can lead to unintended draw call flushing, potentially negating the performance benefits of batching.
Given these constraints, how does the framework handle the internal flush mechanism when SpriteSortMode.Texture is used in conjunction with varying BlendState requirements for different sprites within the same batch? Does the GraphicsDevice force a state change and a new draw call for every blend state variation regardless of texture grouping?
35275 reputation · 13 May 2020, 00:38 UTC
Yes. With SpriteSortMode.Texture, MonoGame still forces a flush and a new GPU draw call for every BlendState variation inside the same Begin/End, even when sprites share the same texture. Texture sorting reduces texture binds, it does not suppress state-change flushes.
With SpriteSortMode.Texture and varying BlendState requirements inside a single Begin/End, each BlendState change triggers a flush and a new GPU draw call even if the texture is unchanged. Texture grouping reduces texture binds but does not coalesce sprites with different blend requirements. The CPU sort cost of Texture mode is incurred in addition to the state-change flushes.
Implementation details are version-sensitive between MonoGame, FNA and legacy XNA, and effect changes also force a flush. Practical verification is recommended: create a minimal test with two sprites sharing the same texture but different BlendState under SpriteSortMode.Texture and count GraphicsDevice draw calls to observe flush per blend change.
One diagnostic detail that changes the recommendation: are you changing BlendState via separate SpriteBatch.Begin/End calls, or attempting per-sprite BlendState changes by mutating GraphicsDevice state between Draw calls? The supported path is Begin/End per state; direct device state mutation is undefined.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.