DDSWithoutD3DX Sample Updatedds
Originally posted to Chuck Walbourn's Blog on MSDN,
Over the past few releases of the DirectX SDK, I’ve been working on updating our documentation for the
DDS file format. The DDSWithoutD3DX and DDSWithoutD3DX11 samples in the DirectX SDK (June 2010) release demonstrate the details of interpreting the DDS file format for basic 2D textures and 2D texture arrays for Direct3D 9, Direct3D 10.x, and Direct3D 11. Since the June release, I’ve been expanding the sample to support cubemaps, volume textures, and 1D textures. In the process I also found a number of minor issues with the DDSTextureLoader code and the
UPDATE: The latest version of DDSTextureLoader for Direct3D 9, Direct3D 11, and Direct3D 12 can be found on GitHub
Attached to this post is a ZIP containing an updated DDS.H, DDSTextureLoader.cpp, and DDSTextureLoader.h which you can drop into the DDSWithoutD3DX11 sample code in the DirectX SDK (June 2010). Note that the DDSWithoutD3DX sample is very similar if you are looking to use it with Direct3D 10.x instead of Direct3D 11, although there are some additional complexities when dealing with cubemap arrays which are supported by the Direct3D 10.1 API with
D3D10_FEATURE_LEVEL_10_1hardware, but not the Direct3D 10.0 API or
Update: A recent inquiry about the
DDS file format has brought up an area of common confusion when parsing these files w.r.t. to the pitch alignment of uncompressed pixel data (there are different rules for computing the sizes of block compressed DXT/BC formats and the packed R8G8_B8G8/G8R8_G8B8 pixel formats). The DDS file format always uses
byte alignment for the pitch of uncompressed data, but the original DrawDraw structures used to define the format document that the pitch should be
DWORD aligned. With many common texture formats and sizes, these computations yield the same results but for 16-bit and 24-bit per pixel formats, these results do not agree. This is further complicated by the fact that many DDS writers (including D3DX) do not set a PITCH value in the header, so DDS readers have to compute one from assumptions.
The recommendation is to use byte-alignment (which is what the DDSWithoutD3DX samples do), but you may want to support a legacy compatibility flag on your DDS reader that will compute DWORD aligned pitch values should you encounter content that uses the incorrect “DWORD” alignment. You can also side-step this issue by preferring the use of block compressed (DXT/BC) or 32-bit per pixel formats–16-bit and 24-bit per pixel formats are not supported by Direct3D 10.x or 11 in any case. It is also important than when copying the data from the DDS structure into a Direct3D resource that you do not assume the pitch values will match, so you must support copying line-by-line (or use initData for Direct3D 10.x & 11 which is what the DDSWithoutD3DX sample demonstrates).
Update 2: I found a minor problem with legacy cubemap DDS files. I was over-validating legacy volume map DDS files for having the ‘right’ flags set in dwCaps2, which are often missing.
Update 3: Minor issue, but BC4 formats should be 4 BitsPerPixel. Doesn’t affect the functionality because GetSurfaceInfo has special handling for BC4 formats already, but in the interest of avoiding future cut & paste issues I’ve fixed it in another refresh of the source.
See also The DDS File Format Lives and DDS Update and 10:10:10:2 problems
Update 4: For Direct3D 11 only applications, consider using the DDSTextureLoader included in DirectX Tool Kit for DX11 instead. There is also a DDSTextureLoader for DirectX 12 included in DirectX Tool Kit for DX12.