Rendertarget formats are one of the few things Game Studio 4.0 allows to vary across different platforms and hardware, even within a single graphics profile.
How it works
Anywhere you specify a backbuffer or rendertarget format, or a depth/stencil format, or a multisample count:
- via the GraphicsDeviceManager.Preferred* properties
- via PresentationParameters
- when calling a RenderTarget constructor
this is just a request rather than an absolute requirement. If the format you asked for is not supported, the call will not fail, but will automatically fall back to the closest supported settings. This design gives you several options:
- Don’t worry, be happy, and let the fallback do its stuff. If you want high quality multisampling you can ask for 4 samples, without bothering to check whether the current hardware supports that. If it does not, you will get 2 samples instead, or none if multisampling is not supported at all. This means most games will ‘just work’ ™ without needing any explicit format checks.
- If you need to know which format was selected, you can go ahead and ask for whatever you would ideally like, then look at the properties on the resulting objects to see what you actually got.
- If you need to check what formats are supported before creating any objects, use GraphicsAdapter.QueryBackBufferFormat and QueryRenderTargetFormat. I do not expect these methods to be used often, but they are there if you need them.
If you do not specify a backbuffer format, GraphicsDeviceManager defaults to Color on Windows and Xbox, or Bgr565 on Windows Phone.
If we did not allow any variation in rendertarget formats, we would be left with Color as the only universally available option, since Xbox does not support 16 bit rendertargets. But 16 bit formats are important on phone hardware:
- Only use half as much memory
- Half the memory bandwidth, which saves both time and battery
- Rendering requires fewer tiling passes, which reduces vertex shading cost
So we had to consider, how much compatibility pain would it cause if we allowed 16 bit formats on the phone, while not having them on Xbox?
This is where the fallback mechanism comes in. It would be bad if you could write a game on the phone, using a 16 bit rendertarget, but then it crashes on Xbox where that format is not available. With automatic fallbacks your game can ask for Bgra5551, get back a Color surface instead, and continue to render without (in most cases) even noticing the substitution.
Rendertargets are somewhat unique in this regard. For instance when you create a texture, you are most likely going to SetData on it immediately after. If we substituted one texture format for another, this SetData call would fail because you would be providing data in a different format to what the texture was actually using. Not good, so we do not allow any variation in what texture formats are supported within a profile.
Aside: we sometimes emulate formats that are not supported by the underlying hardware. For instance some older DX9 cards only support BGRA., not RGBA, for 32 bit color data. We only do such emulation where it is a trivial and lossless conversion (swapping RGB <-> BGR can be done for free while the data is copied into the GPU resource), so as far as the user is concerned, these emulated formats behave and perform the same as if they were directly implemented in silicon.
Of course it is possible to create a rendertarget, then SetData on it, in which case you would run into the same problem as with textures. If you need to do this, you must check the format after creating the rendertarget, or use GraphicsAdapter.QueryRenderTargetFormat. But most people never do such things, so rendertarget format fallbacks work well most of the time.
What can I count on for sure?
These formats are guaranteed across all devices that support a given profile:
Backbuffer formats Rendertarget formats Reach Color Color HiDef Color Color, HdrBlendable
These formats are supported by specific target platforms:
Backbuffer formats Rendertarget formats
Color, Bgr565, Bgra5551, Bgra4444
Color, Rgba1010102, Single, Vector2, HalfVector2, HalfVector4, HdrBlendable
Color, maybe others (Bgr565 and Rgba1010102 are most likely)
Color, HdrBlendable, others are possible but not guaranteed
I will write more about HdrBlendable in my next post.