Bitmap block compression
CanvasBitmap
supports block compressed bitmaps. These can be loaded from a DDS file, or created with CreateFromBytes(ICanvasResourceCreator,Byte[], Int32, Int32, DirectXPixelFormat)
.
Block compressed bitmaps are great for bitmap heavy applications (such as games) because they take up less memory and can be drawn more efficiently. A block compressed bitmap uses up to 1/8th of the memory of an uncompressed bitmap. As a result, the GPU needs to access much less memory when drawing the bitmap, resulting in faster drawing.
About block compression
Block compression is different to the compression employed by PNG or JPG files. Compressed file formats are stored compressed but when they are loaded by Win2D they are decompressed into a bitmap with a format such as DirectXPixelFormat::B8G8R8A8UIntNormalized
, which uses 32 bits (4 bytes) per pixel. So a 256x256 bitmap would take up 256 * 256 * 4 = 262,144 bytes.
A block compressed bitmap uses 8 or 16 bytes (depending on the format -- more on this later) to store a block of 4x4 pixels. So in this case a 256x256 bitmap would take up 256 * 256 / (4 * 4) * 8 = 32,768 bytes, or 256 * 256 / (4 * 4) * 16 = 65,536 bytes. That's up to 8 times smaller! Since block compression is supported directly by the GPU hardware, the bitmap can be kept compressed in memory and drawn directly from the compressed format without ever having to completely uncompress it.
Win2D supports three block compressed formats. The table below describes these formats, along with an uncompressed format for comparison.
DirectXPixelFormat |
Size of 4x4 bitmap | Size of 256x256 bitmap | Alpha |
---|---|---|---|
BC1Unorm |
8 bytes | 32,768 bytes | 1 bit |
BC2Unorm |
16 bytes | 65,536 bytes | 4 bit |
BC3Unorm |
16 bytes | 65,536 bytes | ~8 bit (compressed) |
B8G8R8A8UintNormalized |
64 bytes | 262,144 bytes | 8 bit |
BC1Unorm
, BC2Unorm
and BC3Unorm
differ mostly in how they support alpha. BC1 supports only 1-bit alpha. BC2 supports each pixel in the block having a unique 4-bit alpha value. BC3 compresses the alpha values.
See Direct2D Block Compression documentation and Direct3D Block Compression documentation for more information about how block compression works.
Restrictions
- All block compressed textures must have a width and height that is a multiple of 4. This is because block compression works on blocks of 4x4 pixels.
- Any operation on a sub-rectangle of a block compressed texture (using
GetPixelBytes()
,SetPixelBytes(Byte[])
,CopyPixelsFromBitmap(CanvasBitmap, Int32, Int32)
) require that the sub-rectangle is 4-pixel aligned. - Win2D requires premultiplied alpha when using block compressed formats.
Authoring DDS files
Block compressed images can be saved in DDS files. Although these can be generated by plugins to applications such as Photoshop or Paint.NET, care must be taken to ensure that the resulting file is saved with premultiplied alpha. Win2D will load any DDS file containing a BC1Unorm
, BC2Unorm
or BC3Unorm
image and assume that it is authored with premultiplied alpha.
If you are authoring a C++ project then you can use the Image Content Pipeline to convert the image, as described on MSDN.
Alternatively, you can use texconv.exe
from https://github.com/Microsoft/DirectXTex. texconv.exe
can be built using the DirectXTex_Desktop_2015.sln solution. The following command converts "smoke.png" to a BC3Unorm
with premultiplied alpha:
texconv -pmalpha -m 1 -f BC3_UNORM smoke.png
Windows developer