Current version

v1.10.4 (stable)

Navigation

Main page
Archived news
Downloads
Documentation
   Capture
   Compiling
   Processing
   Crashes
Features
Filters
Plugin SDK
Knowledge base
Contact info
 
Other projects
   Altirra

Archives

Blog Archive

The DXGI_FORMAT_R8G8_B8G8_UNORM texture format

A pet peeve of mine is underspecification, where the documentation for an API or file format doesn't tell you enough specifics about what it is describing. Instead, you get some ambiguous description of a feature that looks like it's informative, but doesn't actually tell you what you need to know.

Take, for example, this description of a texture format from Microsoft's DXGI_FORMAT enumeration (from http://msdn.microsoft.com/en-us/library/windows/desktop/bb173059%28v=vs.85%29.aspx):

DXGI_FORMAT_R8G8_B8G8_UNORM
A four-component, 32-bit unsigned-normalized integer format. [3]

I'm pretty sure this wasn't reviewed by anyone who would actually try to use said format.

Well, at least we know it's 32-bit, and the unsigned-normalized (UNORM) part described later tells us that the components are at least decoded as 0-1. From the name we could make an educated guess that the components are 8-bit and somehow relate to red, green, and blue, and that there's something strange going on with green, but that's about it. Maybe that footnote will tell us more?

3. A resource using a sub-sampled format (such as DXGI_FORMAT_R8G8_B8G8) must have a size that is a multiple of 2 in the x dimension.

That's good to know, but we still don't know enough to actually use it.

Allow me to fill in the missing information:

This format encodes pairs of RGB pixels in a 32-bit packed format, where the red and blue components are encoded at half the horizontal resolution of the green component. The byte ordering in memory is red, green0, blue, green1, where the green0 and green1 pixels are the left and right pixels of each horizontal pair, respectively. The RGB color of each pixel is the shared red and blue values of the pair combined with the corresponding green pixel. Alpha is 1.0.

Although the resource size must be an even number of pixels in the X dimension, it may have mipmaps that are not an even number of pixels across, similarly to how mipmapped DXTn/BCn textures are handled.

Apparently, this format was intended to allow for efficient decoding of UYVY format video, which encodes video in YCbCr colorspace with 4:2:2 subsampling. R8G8_B8G8_UNORM could be used to render UYVY video with an appropriate color matrix transform, if it were not for two deficiencies. First, the red and blue components are upsampled using point sampling. Bilinear interpolation can be used but will simply interpolate the result after the red and blue samples have been doubled up. Second, the shared red and blue components are positioned in the center of the pair of green samples, which is at odds with modern video formats that align it with the left sample (coalignment). The result is that the R8G8_B8G8_UNORM format gives low-quality rendering of UYVY and should not be used in a production video renderer. This might have been somewhat useful for MPEG-1 rendering, except that MPEG-1 is 4:2:0 instead of 4:2:2 and if you have hardware that supports Direct3D 10/11 you might as well use three R8 textures instead.

The G8R8_G8B8_UNORM format is a byte-swapped version that is analogous for YUY2 encoded video, and is equally useless.

Comments

This blog was originally open for comments when this entry was first posted, but was later closed and then removed due to spam and after a migration away from the original blog software. Unfortunately, it would have been a lot of work to reformat the comments to republish them. The author thanks everyone who posted comments and added to the discussion.