Skip to content

Compress

Chuck Walbourn edited this page Aug 20, 2023 · 20 revisions
DirectXTex

Compresses an image or set of images to a block-compressed (BC) format.

CPU Codec

HRESULT Compress(
    const Image& srcImage,
    DXGI_FORMAT format,
    TEX_COMPRESS_FLAGS compress, float threshold,
    ScratchImage& cImage );

HRESULT Compress(
    const Image* srcImages, size_t nimages,
    const TexMetadata& metadata,
    DXGI_FORMAT format,
    TEX_COMPRESS_FLAGS compress, float threshold,
    ScratchImage& cImages );
HRESULT CompressEx(
    const Image& srcImage,
    DXGI_FORMAT format,
    const CompressOptions& options,
    ScratchImage& cImage,
    std::function<bool (size_t, size_t)> statusCallBack = nullptr);

HRESULT CompressEx(
    const Image* srcImages, size_t nimages,
    const TexMetadata& metadata,
    DXGI_FORMAT format,
    const CompressOptions& options,
    ScratchImage& cImages,
    std::function<bool (size_t, size_t)> statusCallBack = nullptr);

GPU Codec (BC6H/BC7)

HRESULT Compress(
    ID3D11Device* pDevice,
    const Image& srcImage,
    DXGI_FORMAT format,
    TEX_COMPRESS_FLAGS compress, float alphaWeight,
    ScratchImage& image );

HRESULT Compress(
    ID3D11Device* pDevice,
    const Image* srcImages, size_t nimages,
    const TexMetadata& metadata,
    DXGI_FORMAT format,
    TEX_COMPRESS_FLAGS compress, float alphaWeight,
    ScratchImage& cImages );
HRESULT CompressEx(
    ID3D11Device* pDevice,
    const Image& srcImage,
    DXGI_FORMAT format,
    const CompressOptions& options,
    ScratchImage& image, 
    std::function<bool (size_t, size_t)> statusCallBack = nullptr);

HRESULT CompressEx(
    ID3D11Device* pDevice,
    const Image* srcImages, size_t nimages,
    const TexMetadata& metadata,
    DXGI_FORMAT format,
    const CompressOptions& options,
    ScratchImage& cImages,
    std::function<bool (size_t, size_t)> statusCallBack = nullptr);

GPU compression is not yet supported for DirectX 12 devices.

Parameters

device: The DirectCompute based versions of Compress require a Direct3D 11 device with Feature Level 10.0 or greater that supports DirectCompute.

format: Format to compress to. Must be a BC compressed format (i.e. DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB - DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM_SRGB)

Note that the DirectCompute based versions of Compress only support DXGI_FORMAT_BC6H_UF16, DXGI_FORMAT_BC6H_SF16, DXGI_FORMAT_BC7_UNORM, and DXGI_FORMAT_BC7_UNORM_SRGB

compress: Compress control flags

threshold: Threshold reference value when compressing an alpha channel for BC1 formats which support 1-bit transparency. (0 to 1 range). Typically use is to pass TEX_THRESHOLD_DEFAULT (0.5).

alphaWeight: Used to weight the error metric's alpha computation for the BC7 GPU compressor. Use TEX_ALPHA_WEIGHT_DEFAULT (1.0) for default, or a larger number to improve alpha accuracy potentially at the expense of the color channels.

options: The Ex versions take the parameters compress, threshold, alphaWeight, etc. using the CompressOptions structure.

statusCallBack: This is an optional status callback invoked during processing. If the status callback returns false, then the function is exited with an E_ABORT.

Related flags

TEX_COMPRESS_DEFAULT Default flags.

Dithering

  • TEX_COMPRESS_RGB_DITHER Enables dithering RGB colors for BC1-3 compression
  • TEX_COMPRESS_A_DITHER Enables dithering alpha channel for BC1-3 compression
  • TEX_COMPRESS_DITHER Same as TEX_COMPRESS_RGB_DITHER and TEX_COMPRESS_A_DITHER

Weighting

  • TEX_COMPRESS_UNIFORM By default, BC1-3 uses a perceptual weighting. By using this flag, the perceptual weighting is disabled which can be useful when using the RGB channels for other data.

Threading

  • TEX_COMPRESS_PARALLEL This opts-in to multi-threaded compression if enabled.

Color space

  • TEX_COMPRESS_SRGB_IN Indicates the input format is the sRGB format. This is implied if using a DXGI_FORMAT_*_SRGB format
  • TEX_COMPRESS_SRGB_OUT Indicates the output format is the sRGB format. This is implied if using a DXGI_FORMAT_*_SRGB format
  • TEX_COMPRESS_SRGB This is the same as setting both TEX_COMPRESS_SRGB_IN and TEX_COMPRESS_SRGB_OUT

The sRGB color space overall is approximately equivalent to gamma 2.2. It's actually linear below a threshold, and gamma 2.4 beyond that.

BC7

  • TEX_COMPRESS_BC7_USE_3SUBSETS Indicates that BC7 compression should use the 3 subset modes (mode 0 and 2). Otherwise it skips these to improve compression performance. This does not usually have significant quality impacts as modes 0 & 2 are rarely selected. Also note that BC6H does not have 3-subset partition modes.

  • TEX_COMPRESS_BC7_QUICK Indicates that the BC7 compression should check the minimal number of modes (typically just mode 6). This is significantly faster compression, but is not as high-quality as standard BC7. It is better quality than using BC1/BC2/BC3 compression.

Example

ScratchImage srcImage;

...

ScratchImage bcImage;
hr = Compress( srcImage.GetImages(), srcImage.GetImageCount(),
    srcImage.GetMetadata(), DXGI_FORMAT_BC3_UNORM,
    TEX_COMPRESS_DEFAULT, TEX_THRESHOLD_DEFAULT,
    bcImage );
if ( FAILED(hr) )
    ...

CompressOptions opts = {};
opts.flags = TEX_COMPRESS_DEFAULT;
opts.threshold = TEX_THRESHOLD_DEFAULT;
opts.alphaWeight = TEX_ALPHA_WEIGHT_DEFAULT;

hr = CompressEx( srcImage.GetImages(), srcImage.GetImageCount(),
    srcImage.GetMetadata(), DXGI_FORMAT_BC3_UNORM, opts,
    bcImage,
    [&](size_t current, size_t count) -> bool
    {
        // Display status as current of count
        return true;
    });
if ( FAILED(hr) )
    ...

Remarks

By default, the BC1 - BC3 color encoding algorithms will use a perceptual weighting of the Red and Blue channels which usually gives better visual results for standard color textures. For textures that do not contain color data, you will likely want to use TEX_COMPRESS_UNIFORM to disable the perceptual weighting.

When compressing for BC4, only the RED channel in the original image is used. When compressing for BC5, only the RED and GREEN channels are used.

The DirectXTex library functions allow arbitrary sized images to handle non-power-of-2 mipmapped BC textures. Note that Direct3D will not allow a resource to be created using BC format with the top-level size set to something other than a multiple of 4 in width and height, even though it does allow the mipchain below it to not meet that requirement. In other words, the library allows some textures to be compressed that are not actually valid on Direct3D 11.

Note that on DirectX 12, there is an optional feature of the DirectX Agility SDK 1.4 / Windows 11 or later that does support the top-level of a BC texture not being a multiple of 4. See D3D12_FEATURE_DATA_D3D12_OPTIONS8.UnalignedBlockTexturesSupported.

This function cannot operate directly on a planar format image. See ConvertToSinglePlane for a method for converting planar data to a format that is supported by this routine.

Release Notes

The software based encoder for BC6H and BC7 is computationally expensive and can be quite slow. The DirectCompute based encoder which is much faster has been integrated into the DirectXTex library, but the standalone version is also available on GitHub.

Threading

The CPU-based compressor will use all cores on a system if given TEX_COMPRESS_PARALLEL for the BC6H / BC7 CPU codec.

The DirectCompute GPU-based compressor makes use of the device's immediate context.

Related Links

Compressed Texture Resources (Direct3D 9)
Block Compression (Direct3D 10)
Texture Block Compression in Direct3D 11
S3 Texture Compress
3Dc
OpenGL ARB BPTC

For Use

  • Universal Windows Platform apps
  • Windows desktop apps
  • Windows 11
  • Windows 10
  • Windows 8.1
  • Windows 7 Service Pack 1
  • Xbox One
  • Xbox Series X|S
  • Windows Subsystem for Linux

For Development

  • Visual Studio 2022
  • Visual Studio 2019 (16.11)
  • clang/LLVM v12 - v18
  • GCC 10.5, 11.4, 12.3
  • MinGW 12.2, 13.2
  • CMake 3.20

Related Projects

DirectXTex Rust bindings

DirectX Tool Kit for DirectX 11

DirectX Tool Kit for DirectX 12

DirectXMesh

DirectXMath

Tools

Test Suite

Content Exporter

DxCapsViewer

See also

DirectX Landing Page

Clone this wiki locally