Format Version: 2.0

Document Revision: 3

Editor: Mark Callow (Edgewise Consulting)

Abstract

KTX™️ (Khronos TeXture) is an efficient lightweight container file format for reliably distributing GPU textures to diverse platforms and applications. It is distinguished by the simplicity of the loader required to instantiate texture objects from the file contents. The contents of a KTX file can range from a simple base-level 2D texture to a cubemap array texture with mipmaps. KTX files hold all the parameters needed for efficient texture loading into 3D APIs such as OpenGL® and Vulkan®

Version 2 extends the functionality of version 1 with easier loading of Vulkan textures, easier use by non-OpenGL and non-Vulkan applications, the possibility of streaming, through sending small mip levels first, universal textures using Basis Universal technology and supercompression. Providing this new functionality requires a significantly different file structure from version 1.

Status of this document

KTX 2.0 ratified by the Khronos Board of Promoters Aug 14th, 2020.

Document Revision 1 approved by the 3D Formats WG Dec 7th, 2022.

Document Revision 2 approved by the 3D Formats WG Sep 6th, 2023.

Document Revision 3 approved by the 3D Formats WG Feb 14th, 2024.

1. Introduction

This document describes the KTX™️ file format version 2.0, hereafter KTX, unless disambiguation is necessary. KTX files are used for storing textures for use with GPU APIs such as OpenGL®, OpenGL ES™️, Vulkan® and WebGL™️.

The canonical version of the specification is available in the Khronos Registry (https://registry.khronos.org/KTX). The source files used to generate the specification are stored in the KTX-Specification Repository (https://github.com/KhronosGroup/KTX-Specification). The source repository has a public issue tracker and allows the submission of pull requests that improve the specification.

KTX files can contain almost any of the wide variety of image formats supported by GPUs. Other specifications wishing to refer to KTX as a container may wish to restrict the range of image formats or other items that can be used. Such referrers must establish a way to identify that given KTX files are compliant with their subsets such as by adding a metadata item.

1.1. Document Conventions

The KTX specification is intended for use by both creators and consumers of KTX files forming a contract between these parties. Specification text may address either party; typically the intended audience can be inferred from context

1.1.1. Normative Terminology

Within this specification, the key words must, required, should, recommended, may and optional are to be interpreted as described in Key words for use in RFCs to Indicate Requirement Levels [RFC2119]. In text addressing creators, their use expresses requirements that apply to the files produced. In text addressing consumers, their use expresses requirements that must be followed when, e.g, uploading the textures via a 3D API.

1.1.2. Admonitions

Notes are non-normative and give further background information such as rationales.
Tips are non-normative and give helpful suggestions for implementers or users.
Importants are normative and give directions for implementers.
Cautions are normative and give restrictions that must be followed.

2. File Structure

Basic Structure
Byte[12] identifier
UInt32 vkFormat
UInt32 typeSize
UInt32 pixelWidth
UInt32 pixelHeight
UInt32 pixelDepth
UInt32 layerCount
UInt32 faceCount
UInt32 levelCount
UInt32 supercompressionScheme

// Index (1)
UInt32 dfdByteOffset
UInt32 dfdByteLength
UInt32 kvdByteOffset
UInt32 kvdByteLength
UInt64 sgdByteOffset
UInt64 sgdByteLength
// Level Index (2)
struct {
    UInt64 byteOffset
    UInt64 byteLength
    UInt64 uncompressedByteLength
} levels[max(1, levelCount)]

// Data Format Descriptor (3)
UInt32 dfdTotalSize
continue
    dfDescriptorBlock dfdBlock
          
until dfdTotalSize read

// Key/Value Data (4)
continue
    UInt32   keyAndValueByteLength
    Byte     keyAndValue[keyAndValueByteLength]
    align(4) valuePadding (5)
                    
until kvdByteLength read
if (sgdByteLength > 0)
    align(8) sgdPadding

// Supercompression Global Data (6)
Byte supercompressionGlobalData[sgdByteLength]

// Mip Level Array (7)
for each mip_level in levelCount (8)
    Byte     levelImages[bytesOfLevelImages] (9)
end
1 Required. See Section 3.9, “Index”.
2 Required. See Section 3.9.7, “Level Index”.
3 Required. See Section 3.10, “Data Format Descriptor”.
4 Not required. See Section 3.11, “Key/Value Data”.
5 align(n) is pseudo function that inserts the minimum number of 0-filled bytes of padding required to align the following item on an n-byte boundary. where n is the function parameter.
6 Not required. See Section 3.12, “Supercompression Global Data”.
7 Required. See Section 3.13, “Mip Level Array”.
8 Replace with 1 if levelCount is 0
9 See the levelImages structure below.

After inflation from supercompression or when supercompressionScheme == 0, levelImages looks like the following:

Mip levels are supercompressed independently so do not contain mipPadding. Applications inflating levels may choose to restore the alignment caused by mipPadding.
levelImages Structure
align( lcm(texel_block_size, 4) ) mipPadding (1)
for each layer in max(1, layerCount)
   for each face in faceCount
       for each z_slice_of_blocks in num_blocks_z (2)
           for each row_of_blocks in num_blocks_y (2)
               for each block in num_blocks_x (2)
                   Byte data[format_specific_number_of_bytes] (3)
               end
           end
       end
   end
end
1 See Section 3.13.2, “mipPadding”.
2 See the definitions below.
3 Rows of uncompressed texture images must be tightly packed, equivalent to a GL_UNPACK_ALIGNMENT of 1.

In the levelImages loops above,

\[num\_blocks\_z = \max\left(1, \left\lceil{\frac{\left\lfloor{{pixelDepth}*{2^{-p}}}\right\rfloor}{block\_depth}}\right\rceil\right)\]
\[num\_blocks\_y = \max\left(1, \left\lceil{\frac{\left\lfloor{{pixelHeight}*{2^{-p}}}\right\rfloor}{block\_height}}\right\rceil\right)\]
\[num\_blocks\_x = \max\left(1, \left\lceil{\frac{\left\lfloor{{pixelWidth}*{2^{-p}}}\right\rfloor}{block\_width}}\right\rceil\right)\]

where p is the level index (see Section 3.7, “levelCount”) and block_depth, block_height and block_width are 1 for uncompressed formats and the block size in that dimension for block compressed formats as given in the format’s section of the Khronos Data Format specification [KDF13].

A block is a single pixel for uncompressed formats and \(block\_width \times block\_height \times block\_depth\) pixels for block compressed formats.

For formats whose Vulkan names have _422_, block_depth and block_height are 1, and block_width is 2.

3. Field Descriptions

3.1. identifier

The file identifier is a unique set of bytes that will differentiate the file from other types of files. It consists of 12 bytes, as follows:

Byte[12] FileIdentifier = {
  0xAB, 0x4B, 0x54, 0x58, 0x20, 0x32, 0x30, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
}

This can also be expressed using C-style character definitions as:

Byte[12] FileIdentifier = {
  '«', 'K', 'T', 'X', ' ', '2', '0', '»', '\r', '\n', '\x1A', '\n'
}

The rationale behind the choice of values in the identifier is based on the rationale for the identifier in the PNG specification. This identifier both identifies the file as a KTX version 2 file and provides for immediate detection of common file-transfer problems.

  • Byte [0] is chosen as a non-ASCII value to reduce the probability that a text file may be misrecognized as a KTX file.

  • Byte [0] also catches bad file transfers that clear bit 7.

  • Bytes [1..6] identify the format, and are the ASCII values for the string “KTX 20”.

  • Byte [7] is for aesthetic balance with byte [0] (they are a matching pair of double-angle quotation marks).

  • Bytes [8..9] form a CR-LF sequence which catches bad file transfers that alter newline sequences.

  • Byte [10] is a control-Z character, which stops file display under MS-DOS, and further reduces the chance that a text file will be falsely recognized.

  • Byte [11] is a final line feed, which checks for the inverse of the CR-LF translation problem.

3.2. vkFormat

vkFormat specifies the image format using Vulkan VkFormat enum values. It can be any value defined in core Vulkan 1.2 [VULKAN12], future core versions or registered Vulkan extensions, except for values listed in Table 1, “Prohibited Formats” and any *SCALED* or *[2-9]PLANE* formats added in future. Values defined by core Vulkan 1.2 are given in section 33.1 Format Definition of [VULKAN12]. The list of registered extensions is provided in the Khronos Vulkan Registry. A complete list of values defined by both core Vulkan 1.2 and extensions can be found in section 43.1 Format Definition of [VULKAN12EXT].

The section number given for [VULKAN12EXT] is as of this writing (Vulkan 1.2.175). It is subject to change as future extensions are added to the document but the link should remain valid as it is to an internal anchor.

Use of the value VK_FORMAT_UNDEFINED (0) is only permissible when the format of the data is a not a recognized Vulkan format, such as in the case of the universal texture formats. In this case information about the format must be provided by the Data Format Descriptor and, in cases where the format is known to another GPU API, the KTX writer must include one or more of the metadata items described in Section 5.3, “Format Mapping”. Some permissible uses are outlined within this specification and summarized in Section 4.2, “Use of VK_FORMAT_UNDEFINED.

The table in Appendix B, Mapping of vkFormat values gives the mapping for all VkFormat enum values in Vulkan 1.2 core and the extensions known at the time of writing, to the equivalent OpenGL format (internal format, format and type values), DXGI_FORMAT and MTLPixelFormat. Applications must use these mappings. If Appendix B, Mapping of vkFormat values does not have an entry for the value of vkFormat and a mapping to one or more of the other APIs exists then, even if the value is not VK_FORMAT_UNDEFINED, the KTX writer must provide that mapping using one or more of the metadata items described in Section 5.3, “Format Mapping”.

Before loading any image, Vulkan loaders should confirm via vkGetPhysicalDeviceFormatProperties that the Vulkan physical device (VkDevice) supports the intended use of the format.

Vulkan applications using a core Vulkan format whose name has the _BLOCK suffix must ensure they enable the corresponding textureCompression* physical device feature at VkDevice creation time. Those using formats defined by extensions must ensure they enable the defining extension at VkDevice creation time.

Vulkan applications handling textures whose formats are not known at VkDevice creation time are recommended to enable all available texture compression features and format defining extensions when creating a device.

Packed A8B8G8R8 Formats

The A8B8G8R8*PACK32 formats are supported but the end result is the same regardless of whether the data is treated as packed into 32 bits or as the equivalent R8G8B8A8 format, i.e., as an array of 4 bytes; a Data Format Descriptor cannot distinguish between these cases.

Table 1. Prohibited Formats
Format Name Value

VK_FORMAT_R8_USCALED

11

VK_FORMAT_R8_SSCALED

12

VK_FORMAT_R8G8_USCALED

18

VK_FORMAT_R8G8_SSCALED

19

VK_FORMAT_R8G8B8_USCALED

25

VK_FORMAT_R8G8B8_SSCALED

26

VK_FORMAT_B8G8R8_USCALED

32

VK_FORMAT_B8G8R8_SSCALED

33

VK_FORMAT_R8G8B8A8_USCALED

39

VK_FORMAT_R8G8B8A8_SSCALED

40

VK_FORMAT_B8G8R8A8_USCALED

46

VK_FORMAT_B8G8R8A8_SSCALED

47

VK_FORMAT_A8B8G8R8_USCALED_PACK32

53

VK_FORMAT_A8B8G8R8_SSCALED_PACK32

54

VK_FORMAT_A2R10G10B10_USCALED_PACK32

60

VK_FORMAT_A2R10G10B10_SSCALED_PACK32

61

VK_FORMAT_A2B10G10R10_USCALED_PACK32

66

VK_FORMAT_A2B10G10R10_SSCALED_PACK32

67

VK_FORMAT_R16_USCALED

72

VK_FORMAT_R16_SSCALED

73

VK_FORMAT_R16G16_USCALED

79

VK_FORMAT_R16G16_SSCALED

80

VK_FORMAT_R16G16B16_USCALED

86

VK_FORMAT_R16G16B16_SSCALED

87

VK_FORMAT_R16G16B16A16_USCALED

93

VK_FORMAT_R16G16B16A16_SSCALED

94

VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM

1000156002

VK_FORMAT_G8_B8R8_2PLANE_420_UNORM

1000156003

VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM

1000156004

VK_FORMAT_G8_B8R8_2PLANE_422_UNORM

1000156005

VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM

1000156006

VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16

1000156012

VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16

1000156013

VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16

1000156014

VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16

1000156015

VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16

1000156016

VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16

1000156022

VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16

1000156023

VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16

1000156024

VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16

1000156025

VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16

1000156026

VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM

1000156029

VK_FORMAT_G16_B16R16_2PLANE_420_UNORM

1000156030

VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM

1000156031

VK_FORMAT_G16_B16R16_2PLANE_422_UNORM

1000156032

VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM

1000156033

VK_FORMAT_G8_B8R8_2PLANE_444_UNORM

1000330000

VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16

1000330001

VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16

1000330002

VK_FORMAT_G16_B16R16_2PLANE_444_UNORM

1000330003

Rationale

The *SCALED* formats are prohibited because they are intended for vertex data, very few, if any, implementations support using them for texturing and a Data Format Descriptor cannot distinguish these from int values having the same bit pattern.

The *[2-9]PLANE* formats are prohibited because multiplanar formats are not supported.

Legacy Formats

The legacy OpenGL & OpenGL ES formats specified by the following extensions, do not have equivalent Vulkan formats and are not supported.

  • OES_compressed_paletted_texture

  • AMD_compressed_3DC_texture

  • AMD_compressed_ATC_texture

  • 3DFX_texture_compression_FXT1

  • EXT_texture_compression_latc

Only a few of these formats can be described without an extended Data Format Descriptor so VK_FORMAT_UNDEFINED must not be used as a workaround.

This is felt to be an acceptable trade-off for simplifying this specification as the formats are not in wide use and applications needing them can use KTX version 1.

3.2.1. Depth and Stencil Formats

Despite Vulkan requiring separate uploads of depth and stencil components, combined depth/stencil pixel formats can be used with KTX.

Rationale

Other GPU APIs support combined uploads and given KTX data alignment it’s trivial to upload components separately in Vulkan.

VK_FORMAT_D16_UNORM_S8_UINT is defined as two 16-bit words per texel. The first word contains the D16 value. The second word contains the S8 value in the eight LSBs and zeros in the eight MSBs.

VK_FORMAT_D24_UNORM_S8_UINT is defined as one 32-bit word per texel with the S8 value in the eight LSBs of the word and the D24 value in the MSBs.

This layout matches OpenGL’s GL_UNSIGNED_INT_24_8 type. Uploading such data via other GPU APIs, such as Direct3D 11 or Metal, usually requires swapping the components, i.e., performing right rotation by 8 bits.

VK_FORMAT_X8_D24_UNORM_PACK32 is defined as one 32-bit word per texel with the D24 value in the LSBs of the word and zeros in the eight MSBs.

VK_FORMAT_D32_SFLOAT_S8_UINT is defined as two 32-bit words per texel. The first word contains the floating-point D32 value. The second word contains the S8 value in the eight LSBs and zeros in the MSBs.

VK_FORMAT_S8_UINT, VK_FORMAT_D16_UNORM and VK_FORMAT_D32_SFLOAT are defined as in [VULKAN12EXT].

3.3. typeSize

typeSize specifies the size of the data type in bytes used to upload the data to a graphics API. When typeSize is greater than 1, software on big-endian systems must endian convert all image data since it is little-endian. When format is VK_FORMAT_UNDEFINED, typeSize must equal 1. For formats whose Vulkan names have the suffix _BLOCK it must equal 1. For formats with the suffix _PACKxx or _nPACKxx it must equal the value of \(xx / 8\). For unpacked formats, except combined depth/stencil formats, it must equal the number of bytes needed for a single component which can be derived from the format name. E.g for VK_FORMAT_R16G16B16_UNORM it will be \(16 / 8\). This means it will equal 1 for any format with 8-bit components. For VK_FORMAT_D16_UNORM_S8_UINT, using the layout defined in this specification, the value will be 2 and for the other combined depth/stencil formats the value will be 4.

Rationale

Although typeSize can be calculated from the Data Format Descriptor and big-endian machines are in the minority we have chosen to provide a useful piece of data instead of the 4 bytes of padding that would otherwise be needed for proper alignment of sgdByteOffset.

3.4. pixelWidth, pixelHeight, pixelDepth

The size of the texture image for level 0, in pixels.

These properties combined with faceCount and layerCount determine the type of the texture as understood by graphics APIs. See Section 4.1, “Texture Type” for more details.

pixelWidth must not be 0.

If faceCount is equal to 6, pixelHeight must be equal to pixelWidth, and pixelDepth must be 0.

pixelHeight must not be 0 for block-compressed formats, including BasisLZ/ETC1S and UASTC.

pixelDepth must not be 0 for block-compressed formats that have block depth greater than 1.

pixelDepth must be 0 for depth or stencil formats.

While the KTX format does not impose any image size restrictions, beyond those above, producers of KTX files need to be aware that some APIs and formats have specific requirements including, but not limited to, the following:

  • Partial texture uploads of all block-compressed formats except PVRTC1 can be performed only along block boundaries. Textures of PVRTC1 formats support only full-image replacement.

  • Vulkan requires the width of texture images using _422_ formats to be a multiple of 2.

  • Direct3D 11 and earlier require the width and height of level 0 texture images using BCn formats to be multiples of 4.

  • WebGL 1.0 requires the width and height of all non-base mip levels to be powers of 2.

  • PVRTC1 formats require the width and height of all images to be powers of 2. Transcoders from universal formats to PVRTC1 may have the same requirement.

3.5. layerCount

layerCount specifies the number of array elements. If the texture is not an array texture, layerCount must equal 0.

Although current graphics APIs do not support 3D array textures, KTX files can be used to store them.

Refer to Section 4.1, “Texture Type” for more details about valid values.

3.6. faceCount

faceCount specifies the number of cubemap faces. For cubemaps and cubemap arrays this must be 6. For non cubemaps this must be 1. Cubemap faces are stored in the order: +X, -X, +Y, -Y, +Z, -Z in a left-handed coordinate system with +Y up and, with the +Z face forward, +X on the on the right. All faces must have the same orientation which must be rd (top-left origin) which is assumed in the absence of Section 5.2, “KTXorientation” metadata. See Appendix A, Cubemap Orientation for details.

Applications wanting to store incomplete cubemaps should flatten faces into a 2D array and use the metadata described in Section 5.1, “KTXcubemapIncomplete” to signal which faces are present.

3.7. levelCount

levelCount specifies the number of levels in the Mip Level Array and, by extension, the number of indices in the Level Index array. A KTX file does not need to contain a complete mipmap pyramid. Mip level data is ordered from the level with the smallest size images, \(level_p\) to that with the largest size images, \(level_{base}\) where \(p = levelCount - 1\) and \(base = 0\). \(level_p\) must not be greater than the maximum possible, \(level_{max}\), where

\[max = \lfloor\log _2\left(\max\left(pixelWidth, pixelHeight, pixelDepth\right)\right)\rfloor\]

\(levelCount = 1\) means that a file contains only the base level and the texture isn’t meant to have other levels. E.g., this could be a LUT rather than a natural image.

\(levelCount = 0\) is allowed, except for block-compressed formats, and means that a file contains only the base level and consumers, particularly loaders, should generate other levels if needed.

3.8. supercompressionScheme

supercompressionScheme indicates if a supercompression scheme has been applied to the data in levelImages. It must be one of the unreserved values from Table 2, “Supercompression Schemes” or Table 3, “Vendor Supercompression Schemes1. A value of 0 indicates no supercompression.

Table 2. Supercompression Schemes
Scheme Id Scheme Name Level Data Format Global Data Format

0

None

n/a

n/a

1

BasisLZ

ETC1S Slice Decoding

BasisLZ Global Data

2

Zstandard

[RFC8478]

n/a

3

ZLIB

[RFC1950]

n/a

4・・・0xffff

Reserved1

0x10000・・・0x1ffff

Reserved2

0x20000・・・0xffffffff

Reserved3

  1. Reserved for KTX use.

  2. Reserved for vendor compression schemes. See Table 3, “Vendor Supercompression Schemes1.

  3. Reserved. Do not use.

The supercompression scheme is applied independently to each mip level to permit streaming and random access to the levels. The format of the data in levelImages for a scheme is specified in the reference given in the Level Data Format column of Table 2, “Supercompression Schemes”.

Schemes that require data global to all levels can store it as described in Section 3.12.1, “supercompressionGlobalData”. Currently only BasisLZ uses global data. The format of the global data for a scheme is specified in the reference given in the Global Data Format column of Table 2, “Supercompression Schemes”.

When a supercompression scheme is used, the image data must be inflated from the scheme prior to GPU sampling.

LZW-style lossless supercompression, e.g, scheme 2, is generally ineffective on the block-compressed data of GPU texture formats. It is best reserved for use with uncompressed texture formats or with block-compressed data that has been specially conditioned for LZW compression such as by Rate-distortion Optimization [RDO].

BasisLZ internally uses a universal block-compressed texture format and Rate-distortion Optimization. Encoding to the RDO-conditioned internal format is combined with supercompression. Therefore it is applicable only to uncompressed images.

Table 3. Vendor Supercompression Schemes1
Scheme Id Scheme Name Token Author Contact Level Data Format Global Data Format

0x10000

Asobo

KTX_SS_PROPRIETARY_ASOBO

Asobo Studio

Julien Vernay jvernay@asobostudio.com

Proprietary

Required

0x10001・・・0x1ffff

Reserved2

  1. For information on registering schemes see Section 4.3.4.2, “Supercompression Schemes”. Readers and writers may, but are not required, to support these schemes.

  2. Reserved for schemes yet to come.

3.8.1. Scheme Notes (Normative)

BasisLZ
Rationale

The BasisLZ encoder combines encoding to a universal format with deflation. The transcoder combines inflation back to the universal format with transcoding to one of the many GPU-specific block compressed formats. There is therefore no visible common pre- and post-supercompression format.

The effective uncompressed byte length is dependent on the which transcode target format is selected.

Zstandard
ZLIB

3.8.2. Vendor Scheme Notes (Normative)

Asobo

3.9. Index

An index giving the byte offsets from the start of the file and byte sizes of the various sections of the KTX file.

3.9.1. dfdByteOffset

The offset from the start of the file of the dfdTotalSize field of the Data Format Descriptor.

3.9.2. dfdByteLength

The total number of bytes in the Data Format Descriptor including the dfdTotalSize field. dfdByteLength must equal dfdTotalSize.

This field is not necessary. Since no padding is needed for DFDs the value is easily calculated from the offsets. However, if it is removed, we would need 4 bytes of padding instead for proper alignment of supercompressionGlobalData. Retaining it means all sections of the file can be handled uniformly.

3.9.3. kvdByteOffset

An arbitrary number of key/value pairs may follow the Index. These can be used to encode any arbitrary data. The kvdByteOffset field gives the offset of this data, i.e. that of first key/value pair, from the start of the file. The value must be 0 when kvdByteLength = 0.

3.9.4. kvdByteLength

The total number of bytes of key/value data including all keyAndValueByteLength fields, all keyAndValue fields and all valuePadding fields.

3.9.5. sgdByteOffset

The offset from the start of the file of supercompressionGlobalData. The value must be 0 when sgdByteLength = 0.

3.9.6. sgdByteLength

The number of bytes of supercompressionGlobalData. For supercompression schemes for which no reference is provided in the Global Data Format column of Table 2, “Supercompression Schemes”. the value must be 0.

3.9.7. Level Index

An array, levels, giving the offset from the start of the file and compressed and uncompressed byte sizes of the image data for each mip level within the Mip Level Array The array is ordered starting with \(level_{base}\) (the level with the largest size images) at index 0. Image for \(level_p\) will be found at index p.

levels[p].byteOffset

The offset from the start of the file of the first byte of image data for mip level p. It is the offset of the first byte after any mipPadding.

levels[p].byteLength

The total size of the data for supercompressed mip level p.

levels[p].byteLength is the number of bytes of pixel data in LOD \(level_p\). This includes all layers, all z slices, all faces, all rows (or rows of blocks) and all pixels (or blocks) in each row for the mip level.

The total size of the image data from \(levels[numLevels-1].byteOffset\) (i.e., after the first mipPadding, if any) until the end of the file is:

\[levels[0].byteLength + \sum_{p=1}^{numLevels-1} \left\lceil{\frac{levels[p].byteLength}{requiredAlignment}}\right\rceil \times requiredAlignment\]

where

\[numLevels = \max\left(1, levelCount\right)\]

and

\[requiredAlignment = \begin{cases} lcm(texel\_block\_size, 4) & (\text{supercompressionScheme} = 0) \\ 1 & (\text{supercompressionScheme} \neq 0) \end{cases}\]

texel_block_size is defined in Section 3.13.2, “mipPadding”.

levels[p].uncompressedByteLength

levels[p].uncompressedByteLength is the number of bytes of pixel data in LOD \(level_p\) after reflation from supercompression. This includes all layers, all z slices, all faces, all rows (or rows of blocks) and all pixels (or blocks) in each row for the mip level. When supercompressionScheme == 0, levels[p].byteLength must have the same value as this. When supercompressionScheme == 1, BasisLZ, the value must be 0.

The value of a level’s uncompressedByteLength must satisfy the following condition:

uncompressedByteLength % (faceCount * max(1, layerCount)) == 0

Writers should be aware that block-compressed formats require the byte length of encoded levels be a multiple of the block size, i.e. the data is always a whole number of blocks regardless of the size in texels. The PVRTC1 format has extra restrictions. See Chapter 24 PVRTC Compressed Texture Image Formats in [KDF13].

In versions of OpenGL < 4.5 and in OpenGL ES, faces of non-array cubemap textures (any texture where faceCount is 6 and layerCount is 0) must be uploaded individually. Loaders wishing to minimize the size of their intermediate buffers may want to read the faces individually rather than as a block of size level[n].uncompressedByteLength.

3.10. Data Format Descriptor

The Data Format Descriptor (dfDescriptor) describes the layout of the texel blocks in data. The full specification for this is is Part 2, Chapters 2 to 11, of the Khronos Data Format Specification version 1.3 [KDF13].

The dfDescriptor is partially expanded in this specification in order to provide sufficient information for a KTX file to be parsed without having to refer to [KDF13]. It consists of a total size field and one or more Descriptor Blocks (dfDescriptorBlock) described below.

Rationale

A dfDescriptor is useful in the following cases:

  • wise choice of transcode target format when the data is in one of the universal formats by providing information about the components present;

  • precise color management using the descriptor’s color space information;

  • use of pre-multiplied alpha by providing indication of pre-multiplication.

  • easier use of the images by non-OpenGL and non-Vulkan applications. There will be no need for large tables to interpret format enums.

3.10.1. Restrictions

The following restrictions must be obeyed when setting the fields of a dfDescriptorBlock.

  • If vkFormat is not VK_FORMAT_UNDEFINED, the DFD’s texelBlockDimension*, bytesPlane* and sample information fields must match the format’s definition. The colorModel must be KHR_DF_MODEL_RGBSDA, KHR_DF_MODEL_YUVSDA or the matching block compressed color model listed in [KDF13] Section 5.6 or its successors, currently KHR_DF_MODEL_BC1A to KHR_DF_MODEL_UASTC. KHR_DF_MODEL_YUVSDA should be used for all non-prohibited *_422_* formats.

  • If vkFormat is one of the *_SRGB{,_*} formats, transferFunction must be KHR_DF_TRANSFER_SRGB.

  • If vkFormat is not one of the *_SRGB{,_*} formats and an sRGB variant of that format exists, transferFunction should not be KHR_DF_TRANSFER_SRGB.

  • If formats for other transfer functions are added to GPU APIs in the future similar restrictions to those just described apply. For example, if formats for the HLG transfer function which have the the suffix _HLG are added then

    • If vkFormat is one of the *_HLG{,_*} formats transferFunction must be KHR_DF_TRANSFER_HLG.

    • If vkFormat is not one of the *_HLG{,_*} formats and an HLG variant of that format exists, transferFunction should not be KHR_DF_TRANSFER_HLG.

For example, VK_FORMAT_R8G8B8A8_UNORM should not be used with KHR_DF_TRANSFER_SRGB because there is VK_FORMAT_R8G8B8A8_SRGB.

On the other hand, VK_FORMAT_A2B10G10R10_UNORM_PACK32 may be used with KHR_DF_TRANSFER_SRGB because there is no sRGB variant of this format.

When vkFormat is not one of the *_SRGB{,_*} formats and the transfer function is not linear, the KTX file may be much less portable due to limited hardware support of such inputs.

colorPrimaries may be any of the available values since conversion of the selected primaries and white point to a display’s can be done simply with a 3x3 matrix multiply.

Still, KHR_DF_PRIMARIES_BT709 / KHR_DF_PRIMARIES_SRGB is recommended for standard dynamic range, standard gamut images.

3.10.2. Providing additional information

There are several cases where the dfDescriptorBlock is used to provide information beyond that given by vkFormat.

Premultiplied Alpha

KHR_DF_FLAG_ALPHA_PREMULTIPLIED (= 1) can be set in the flags field if the images' RGB components have been multiplied by their alpha components, otherwise it must be 0.

Basis Universal UASTC Format

The Universal ASTC image format (UASTC) is indicated by colorModel KHR_DF_MODEL_UASTC (= 166) together with vkFormat VK_FORMAT_UNDEFINED (= 0). The DFD must be as described in Section 5.6.14 KHR_DF_MODEL_UASTC of [KDF13]. Images in this format must be transcoded to a GPU-supported block-compressed format or decoded to a GPU-supported uncompressed format before being uploaded to and sampled by a GPU. UASTC images can be supercompressed with Zstandard (supercompressionScheme = 2) with or without first conditioning the data with Rate-distortion Optimization. If supercompression is used, the DFD’s bytesPlane[0-7] must be set to 0 as described in the next subsection.

This color model provides channel Ids, e.g. KHR_DF_CHANNEL_UASTC_RGB that must be used to indicate the effective number of components in the data. Consumers use this information to help select a transcode target. The following ids are valid and must be used for the type of data indicated.

Id Value Type

KHR_DF_CHANNEL_UASTC_RGB

0

3 component: opaque color. RGB components in the rgb channels.

KHR_DF_CHANNEL_UASTC_RGBA

3

4 component: color + alpha. RGB components in the rgb channels, alpha in the alpha channel.

KHR_DF_CHANNEL_UASTC_RRR

4

1 component: R component replicated in all 3 rgb channels for better compression results.

KHR_DF_CHANNEL_UASTC_RRRG

5

2 independent components: R component replicated in all 3 rgb channels and G moved to alpha for better compression results.

KHR_DF_CHANNEL_UASTC_RG

6

2 independent components. Blue & alpha should not be sampled.

_UASTC_RRRG cannot be transcoded to the RG channels of an ASTC or BC7 texture. Applications using this channel id will have to use swizzles or have shaders that understand this channel layout.

The bitstream of the UASTC data is described in Chapter 25 UASTC Compressed Texture Image Format of [KDF13].

Basis Universal ETC1S Format

The ETC1S image format is indicated by colorModel KHR_DF_MODEL_ETC1S (= 163) together with vkFormat VK_FORMAT_UNDEFINED (= 0). The DFD must be as described in Section 5.6.11 KHR_DF_MODEL_ETC1S of [KDF13]. Because ETC1S does not support an alpha component, Basis Universal uses 2 slices, (planes in DFD-speak) to represent RGBA images. This color model provides the following channel ids that must be used to indicate the use of a slice.

Id Value Type

KHR_DF_CHANNEL_ETC1S_RGB

0

3 components: opaque color. RGB components in the slice’s rgb components.

KHR_DF_CHANNEL_ETC1S_RRR

3

1 component: R component in the slice’s r component.

KHR_DF_CHANNEL_ETC1S_GGG

4

1 component: G component in the slice’s r component. Not used independently.

KHR_DF_CHANNEL_ETC1S_AAA

15

1 component: Alpha component in the slice’s r component. Not used independently.

For better compression results, non-RGB slices may have the same value replicated in all 3 slice components.

Whether there are 1 or 2 slices depends on the pre-deflation components as detailed in the following table of valid channel id combinations.

Combination Description

KHR_DF_CHANNEL_ETC1S_RGB

One slice, opaque color.

KHR_DF_CHANNEL_ETC1S_RGB + KHR_DF_CHANNEL_ETC1S_AAA

Two slices, color + alpha

KHR_DF_CHANNEL_ETC1S_RRR

One slice, 1 component encoded as greyscale.

KHR_DF_CHANNEL_ETC1S_RRR + KHR_DF_CHANNEL_ETC1S_GGG

Two slices, 2 independent components each encoded as greyscale.

KTX writers may map components of their original input images into the RGB and A components of the supercompressed image in any way they choose. They may also offer an option to apply KTXswizzle metadata prior to supercompressing an uncompressed KTX file.

Images in this format are always supercompressed with BasisLZ and must be inflated and transcoded to a GPU-supported block-compressed format or decoded to a GPU-supported uncompressed format before being uploaded to and sampled by a GPU. Because ETC1S images are supercompressed, the DFD’s bytesPlane[0-7] must be set to 0 as described in the next subsection.

Whether the image has 1 or 2 slices can be determined from the DFD’s sample count.

The bitstream of the ETC1S data pre LZ deflation is described in Chapter 21.1 ETC1S of [KDF13].

since inflation and transcoding are typically combined in a single operation, this bitstream is not visible to applications.

The DFD for UASTC and ETC1S must reflect the components provided as input to the Basis encoders not those of the source image. Therefore, for example, if the software checks for and removes from source image(s) alpha channel(s) that are all opaque (1.0) before submitting the data to a Basis encoder then the DFD must not have a sample with a channelType that indicates it is alpha.

DFD for Supercompressed Data

When supercompressionScheme is not 0 the dfDescriptorBlock must preserve the colorModel, transferFunction, colorPrimaries, flags and texelBlockDimension[0-3] of the pre-deflation images along with each sample’s channelType, qualifiers, bitlength, bitOffset, sampleLower and sampleUpper. bytesPlane[0-7] must be set to 0 to indicate an unsized format, as described in Section 5.19 Unsized Formats of [KDF13].

In the event that a block-compressed format is supercompressed the DFD will reflect the color model of the block-compressed format most of which have only one or two components.

Table 4, “Example Unsigned R + G descriptor for BasisLZ/ETC1S” shows a DFD for images that were VK_FORMAT_R8G8_UNORM, before encoding and deflation, i.e. they have two unsigned 8-bit components.

Table 4. Example Unsigned R + G descriptor for BasisLZ/ETC1S

~uint32_t bit~

31

30

29

28

27

26

25

24

23

22

21

20

19

18

17

16

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

totalSize: 60

descriptorType: 0

vendorId: 0

descriptorBlockSize: 24 + (16 {times} 2) = 56

versionNumber: 2

flags: ALPHA_STRAIGHT

transferFunction: LINEAR

colorPrimaries: BT709

colorModel: ETC1S

texelBlockDimension3

texelBlockDimension2

texelBlockDimension1

texelBlockDimension0

0

0

3 (= ``4'')

3 (= ``4'')

bytesPlane3: 0

bytesPlane2: 0

bytesPlane1: 0

bytesPlane0: 0

bytesPlane7: 0

bytesPlane6: 0

bytesPlane5: 0

bytesPlane4: 0

F

S

E

L

channelType

~Red sample information~

0

0

0

0

RRR

bitLength: 63 (= ``64'')

bitOffset: 0

samplePosition3

samplePosition2

samplePosition1

samplePosition0

0

0

0

0

sampleLower: 0

sampleUpper: UINT32_MAX

F

S

E

L

channelType

~Green sample information~

0

0

0

0

GGG

bitLength: 63 (= ``64'')

bitOffset: 64

samplePosition3

samplePosition2

samplePosition1

samplePosition0

0

0

0

0

sampleLower: 0

sampleUpper: UINT32_MAX

Table 5, “Example Signed RGB descriptor for Zstandard/ZLIB” shows a DFD for images that were VK_FORMAT_R8G8B8_SNORM, before deflation, i.e. have 3 signed 8-bit components.

Table 5. Example Signed RGB descriptor for Zstandard/ZLIB

~uint32_t bit~

31

30

29

28

27

26

25

24

23

22

21

20

19

18

17

16

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

totalSize: 76

descriptorType: 0

vendorId: 0

descriptorBlockSize: \(24 + (16 \times 3) = 72\)

versionNumber: 2

flags: ALPHA_STRAIGHT

transferFunction: LINEAR

colorPrimaries: BT709

colorModel: RGBSDA

texelBlockDimension3

texelBlockDimension2

texelBlockDimension1

texelBlockDimension0

0

0

0

0

bytesPlane3: 0

bytesPlane2: 0

bytesPlane1: 0

bytesPlane0: 0

bytesPlane7: 0

bytesPlane6: 0

bytesPlane5: 0

bytesPlane4: 0

F

S

E

L

channelType

~Red sample information~

0

1

0

0

RED

bitLength: 7

bitOffset: 0

samplePosition3

samplePosition2

samplePosition1

samplePosition0

0

0

0

0

sampleLower: -127

sampleUpper: 127

F

S

E

L

channelType

~Green sample information~

0

1

0

0

GREEN

bitLength: 7

bitOffset: 8

samplePosition3

samplePosition2

samplePosition1

samplePosition0

0

0

0

0

sampleLower: -127

sampleUpper: 127

F

S

E

L

channelType

~Blue sample information~

0

1

0

0

BLUE

bitLength: 7

bitOffset: 16

samplePosition3

samplePosition2

samplePosition1

samplePosition0

0

0

0

0

sampleLower: -127

sampleUpper: 127

3.10.3. dfdTotalSize

Called total_size in [KDF13], dfdTotalSize indicates the total number of bytes in the dfDescriptor including dfdTotalSize and all dfdBlock fields. dfdByteLength must equal dfdTotalSize.

If

\[dfdTotalSize \neq kvdByteOffset - dfdByteOffset\]

the file is invalid.

dfdTotalSize is included so that the KTX file contains a complete descriptor as defined in Chapter 4 “Khronos Data Format Descriptor” of [KDF13].

3.10.4. dfdBlock

A Descriptor Block as defined in Section 4.1 of [KDF13]. The high-order 16 bits of its first UInt32 are the descriptor_type and the high-order 16 bits of the second UInt32 are the descriptor_block_size. descriptor_block_size is mandated to be a multiple of 4 which guarantees that the following keyAndValueByteLength will be aligned in a 32-bit word.

3.11. Key/Value Data

Key/Value data consists of a set of key/value pairs. The number of pairs is such that

\[\sum_{i=0}^{n-1} \left\lceil{\frac{keyAndValueByteLength[i]}{4}}\right\rceil \times 4 + n \times 4 = kvdByteLength.\]

Any file that does not meet the above condition is invalid.

KTX tools must update any key/value data affected by their operations. For example, a tool that supports xflip or yflip operations must update existing KTXorientation data to reflect the result of performing one of these. Tools must, preserve any key/value data not affected by their operations and not modified by the user or that they do not understand.

Key/value data must be written to the file sorted by the Unicode code points of the keys starting from a key’s first character.

Keys must not appear more than once.

3.11.1. keyAndValueByteLength

The number of bytes of combined key and value data in one key/value pair. This includes the size of the key, the required NUL byte terminating the key and all the bytes of data in the value. If the value is a UTF-8 string it should be NUL terminated and keyAndValueByteLength must include the NUL character (but code that reads KTX files must not assume that value fields are NUL terminated). keyAndValueByteLength does not include the bytes in valuePadding.

keyAndValueByteLength must be at least 2, that is a 1 byte key plus its NUL terminator.

3.11.2. keyAndValue

keyAndValue contains 2 separate sections. First it contains a key encoded in UTF-8 without a byte order mark (BOM). The key must be terminated by a NUL character (a single 0x00 byte). Keys that begin with the 3 ASCII characters KTX or ktx are reserved and must not be used except as described by this specification (this version of the KTX spec. defines eight keys). Immediately following the NUL character that terminates the key is the Value data.

The Value data may consist of any arbitrary data bytes. Any byte value is allowed. It is encouraged that the value be a NUL terminated UTF-8 string without a BOM, but this is not required.

If the Value data is binary, it is a sequence of bytes rather than of words. It is up to the vendor defining the key to specify how those bytes are to be interpreted. If any bytes encode multi-byte numbers they must be in little-endian order and, if such a number appears at the start of the Value data, the key length including its terminating NUL must be a multiple of the number of bytes in the number so that the number will be properly aligned.

If the Value data is a string then the NUL termination, if present, must be included in keyAndValueByteLength (but programs that read KTX files must not rely on NUL termination).

3.11.3. valuePadding

Contains between 0 and 3 bytes of value 0x00 to ensure that the byte following the last byte in valuePadding is at a file offset that is a multiple of 4. This ensures that every keyAndValueByteLength field is 4-byte aligned. This padding is included in the kvdByteLength field but not the individual keyAndValueByteLength fields.

3.12. Supercompression Global Data

3.12.1. supercompressionGlobalData

An array of data used by certain supercompression schemes that must be available before any mip level can be inflated. Must start on the next 8-byte boundary following the key/value data.

The specification of this data block for the BasisLZ scheme is given in Appendix C, BasisLZ Global Data.

3.13. Mip Level Array

Mip levels in the array are ordered from the level with the smallest size images, \(level_p\) to that with the largest size images, \(level_{base}\).

Rationale

When streaming a KTX file, sending smaller mip levels first can be used together with, e.g., the GL_TEXTURE_MAX_LEVEL and GL_TEXTURE_BASE_LEVEL texture parameters or appropriate region setting in a VkCmdCopyBufferToImage, to display a low resolution image quickly without waiting for the entire texture data.

3.13.1. levelImages

levelImages is an array of Bytes holding all the image data for a level. The offset of a level’s levelImages is provided by the Level Index. Images are concatenated in the order layer, face, slice.

When supercompressionScheme != 0 these bytes are formatted as specified in the scheme documentation.

3.13.2. mipPadding

mipPadding is between 0 and \(lcm(texel\_block\_size, 4) - 1\) bytes of value 0x00. \(lcm\) is least common multiple. This is only required when supercompressionScheme == 0.

Texel block size is as given for the vkFormat value in section 40.1.6 Format Compatibility Classes of [VULKAN12EXT] for all vkFormat values except the following three:

VkFormat Texel Block Size

VK_FORMAT_UNDEFINED

Derived from DFD

VK_FORMAT_D16_UNORM_S8_UINT

4

VK_FORMAT_D32_SFLOAT_S8_UINT

8

Padding Rationale

mipPadding ensures that data for each mip level is aligned on a boundary that enables data to be uploaded to a graphics API in bulk without having to shuffle it around. Among other things, this enables memory mapped files to be used with some APIs. Vulkan requires data to be aligned to a texel block size boundary and to a 4-byte boundary hence the least common multiple requirement.

Since levels after the first will be naturally aligned to their texel block size, in block-compressed formats because an integral number of blocks is required regardless of the image size, the majority of formats will have 0 bytes of padding between levels. The exception is formats whose texel block size is not a multiple of 4. Depending on the image size, these may require some mipPadding bytes between levels to meet the alignment requirement.

4. General comments

4.1. Texture Type

The type of texture can be determined from the following table. Any other combination of these parameters makes the KTX file invalid.

Type pixelWidth pixelHeight pixelDepth layerCount faceCount

1D

> 0

0

0

0

1

2D

> 0

> 0

0

0

1

3D

> 0

> 0

> 0

0

1

Cubemap

> 0

> 0

0

0

6

1D Array

> 0

0

0

> 0

1

2D Array

> 0

> 0

0

> 0

1

3D Array

> 0

> 0

> 0

> 0

1

Cubemap Array

> 0

> 0

0

> 0

6

4.2. Use of VK_FORMAT_UNDEFINED

VK_FORMAT_UNDEFINED can be used

  • For custom formats that do not have any equivalent in GPU APIs.

  • For BasisLZ supercompressed data.

  • For compressed color models in [KDF13] or successors that do not have corresponding Vulkan formats. If the format corresponds to a format in DirectX or Metal then at least one format mapping metadata item is required. One such format exists now, the transcodable format with colorModel KHR_DF_MODEL_UASTC (= 166). This does not correspond to a DirectX or Metal format.

  • For formats from Metal or DirectX that do not have Vulkan equivalents. In this case at least one API’s format must be recorded in a format metadata item.

4.3. Extending KTX

The following sections describe ways to extend what can be contained in a KTX file. It covers three categories: formats, supercompression schemes and metadata. This specification can be periodically updated to incorporate officially recognized additions and the Document Revision incremented. Since the KTX format itself would not change the KTX version and file identifier would not change. This document serves as the registry for both official and vendor extensions.

The document revision can be used as a parameter for validators to guide validation.

Consumers of KTX files must fail gracefully when encountering formats or supercompression schemes they are not prepared to handle. They must ignore or report metadata items they are not prepared to handle.

In the following, vendor encompasses independent software and hardware vendors and open source developers.

4.3.1. Carrying New Formats

Formats are identified by one or more of the following:

  • A Vulkan VkFormat enum value.

  • A color model value from the Khronos Data Format Specification [KDF13].

New transcodable formats can be added by:

  • Creating a new color model and format specification in the Khronos Data format specification [KDF13] (as was done with UASTC).

  • Creating a new color model and format specification as above and providing a specification for a new supercompression scheme that incorporates this transcodable format (à la BasisLZ/ETC1S).

New Vulkan formats are created via Vulkan extensions.

New DXGI or Metal formats can be carried by using VK_FORMAT_UNDEFINED together with a Data Format Descriptor, which may or may not need a new color model, and format mapping metadata giving the DXGI or Metal format value.

4.3.2. Supercompression Schemes

Supercompression schemes are identified by supercompressionScheme in the KTX header. New official schemes can be documented in updates to this specification.

Vendors can create their own supercompression schemes. To avoid conflicts in the Scheme Id name space, those doing so must register them with Khronos as described in Section 4.3.4, “Registering Extensions”.

4.3.3. Adding Metadata Items

New official metadata items (i.e, KTX prefixed) can be documented in updates to this specification.

Vendors can register their own metadata items (key/value pairs) as described in Section 4.3.4, “Registering Extensions” and are strongly encouraged to do so to avoid potential collisions in the key name space (prefix).

4.3.4. Registering Extensions

General Procedures

Supercompression schemes and metadata items are registered by proposing a pull-request (PR) against the default branch (currently main) of the KTX-Specification repository on GitHub. See the sections below for the specific information required.

The vendor will need to create a GitHub account, if it doesn’t have one. Register the vendor’s FQDN to that account. A GitHub account handle is the preferred way of providing the required registration contact information.

Choose a short tag name to identify the vendor. Use the same tag the vendor uses for Vulkan, glTF, OpenGL etcetera extensions, if there is one. The sections below explain how the tag will be used. As a matter of courtesy and respect, please do not try to use tags which clearly belong to an existing company or project which may wish to develop extensions in the future. Khronos may decline to register extensions that are not requested in good faith.

Registration is not complete until the repository maintainer has validated and merged the PR.

Supercompression Schemes

Submit requests for scheme ids by proposing a pull request (PR) against ktxspec.adoc. The PR must add a row to Table 3, “Vendor Supercompression Schemes1, that uses the next available id, and a note to Section 3.8.2, “Vendor Scheme Notes (Normative)”. Follow the instructions in the comments at those locations. Required information for the first includes the scheme name, author, contact information and a token name that must incorporate the chosen tag name. The token can be used by readers and writers to identify the scheme and vendor in enumerations, etc. Required information for the second includes whether to retain post compression the vkFormat value and the Data Format Descriptor’s color space information.

Vendors are strongly encouraged to provide the bitstream and, if applicable, global data specifications but they are not required. When provided, they must be put in appendices to this document and contain anchors linked from the added row. Create an AsciiDoc file for each in the appendices directory named using the template

KTX_<TAG>_<name>_{bitstream,gdata}.adoc

Replace <TAG> with the vendor’s identifying tag and <name> with the scheme name. Use AsciiDoc’s include:: directive to include these appendices after the last similar include currently in this document. Add the new files to the PR as well as edits to Makefile that add the new files to the ktx_sources variable.

The registration process can be split into several steps to accommodate scheme id assignment prior to scheme publication:

  • Acquire a scheme id. This is done by proposing a PR against ktxspec.adoc. The id will be reserved only once this request is accepted into the default branch.

  • Develop and test the scheme using the registered id.

  • Publish the bit stream specifications to Khronos with a PR that updates the row in the table for the previously registered id and adds the scheme documentation.

4.3.5. Metadata

Register items by proposing a pull request (PR) against appendices/vendor_metadata.adoc, the source file for Appendix E, Registered Vendor Key/Value Pairs. Add the metadata item(s) following the instructions in the comment there.

Use the tag described in Section 4.3.4, “Registering Extensions” as the key prefix.

4.4. Animation Sequence

The images of any array texture can be indicated to be the frames of a short animation sequence by including KTXanimData metadata. Valid animation files must have the combination of parameters outlined in Section 4.1, “Texture Type” for Array textures in addition to KTXanimData metadata. layerCount is the number of frames in the video, i.e. layers become the temporal axis.

Use of uncompressed images for an animation sequence will not be memory efficient. Animation sequences should be limited to block-compressed or, preferably, BasisLZ compressed textures.

4.5. Endianness

KTX files are little endian. All header fields and the data for all uncompressed texture formats are stored in little endian order. Readers on big-endian machines must endian convert all header UInt32s and UInt64s and, when typeSize is greater than 1, all data to big endian. The data of block compressed formats, those ending in *_BLOCK, does not need endian converting.

If an application on a big-endian machine intends to use the sample information in the Data Format Descriptor, the DFD must be rewritten for the endian-converted data as the samples describe the data as laid out in memory.

Writers must endian convert these items to little endian on writing the file.

4.6. Packing

Rows of uncompressed pixel data are tightly packed. Each row in memory immediately follows the end of the preceding row. I.e the data must be packed according to the rules described in section 8.4.4.1 Unpacking of the OpenGL 4.6 specification [OPENGL46] with GL_UNPACK_ROW_LENGTH = 0 and GL_UNPACK_ALIGNMENT = 1.

5. Predefined Key/Value Pairs

5.1. KTXcubemapIncomplete

A KTX file can be used to store an incomplete cubemap or an array of incomplete cubemaps. In such a case, faceCount must be 1 and layerCount must be equal to the number of faces present (in case of a single cubemap) or to the number of faces present times the number of cubemaps (in case of a cubemap array). The faces that are present must be indicated using the metadata key

  • KTXcubemapIncomplete

The value is a one-byte bitfield defined as:

00xxxxx1 - +X is present
00xxxx1x - -X is present
00xxx1xx - +Y is present
00xx1xxx - -Y is present
00x1xxxx - +Z is present
001xxxxx - -Z is present

Any value, not matching the mask above is invalid.

At least one face must be present, i.e., the value must not be 0.

Within the levelImages structure structure, faces must be written in the same order as with complete cubemaps: +X, -X, +Y, -Y, +Z, -Z.

When a texture is a cubemap array, missing/present faces must be the same for each element.

As with complete cubemaps, pixelHeight must be equal to pixelWidth, and pixelDepth must be 0.

This metadata entry must not be used together with KTXanimData.

5.2. KTXorientation

Texture data in a KTX file are arranged so that the first pixel in the data stream for each face and/or array element is closest to the origin of the texture coordinate system. In OpenGL that origin is conventionally described as being at the lower left, but this convention is not shared by all image file formats and content creation tools, so there is abundant room for confusion.

The desired texture axis orientation is often predetermined by, e.g. a content creation tool’s or existing application’s use of the image. Therefore it is strongly recommended that tools for generating and manipulating KTX files clearly describe their behaviour, and provide an option to specify the texture axis origin and orientation relative to the logical orientation of the source image. At minimum they should provide a choice between top-left and bottom-left as origin for 2D source images, with the positive S axis pointing right. Where possible, the preferred default is to use the logical upper-left corner of the image as the texture origin. Note that this is contrary to the standard interpretation of GL texture coordinates. However, most other APIs and the majority of texture compression tools use this convention.

When writing the logical orientation to the KTX file’s metadata, image manipulation tools and viewers must use the key

  • KTXorientation

Note that this metadata affects only the logical interpretation of the data and has no effect on the mapping from pixels in the file byte stream to texture coordinates.

The value is a NUL-terminated string formatted depending on the texture type.

Type Format ([REGEXP])

1D

/^[rl]$/

2D or Cubemap

/^[rl][du]$/

3D

/^[rl][du][oi]$/

where

  • r indicates S values increasing to the right

  • l indicates S values increasing to the left

  • d indicates T values increasing downwards

  • u indicates T values increasing upwards

  • o indicates R values increasing out from the screen (moving towards viewer)

  • i indicates R values increasing in towards the screen (moving away from viewer)

When a texture is an array, all its elements have the same orientation and when it is a cubemap, all faces have the same orientation.

Values not matching the table above are invalid.

It is recommended that viewing and editing tools support at least the following values:

  • rd

  • ru

  • rdi

  • ruo

Although other orientations can be represented, it is recommended that tools that create KTX files use only the values listed above as other values may not be widely supported by other tools.

5.3. Format Mapping

The vkFormat field is the primary way of describing the format of the texture data stored in a KTX file. However when there is no matching Vulkan format, KTX writers may use the following key-value pairs to provide alternative API-specific enum values.

These metadata entries must not be used when the vkFormat is not VK_FORMAT_UNDEFINED.

5.3.1. KTXglFormat

For OpenGL {,ES} the mapping is specified with the key

  • KTXglFormat

The value is 12 bytes representing 3 Uint32 values:

UInt32 glInternalformat
UInt32 glFormat
UInt32 glType

For compressed formats, glFormat and glType must be set to zero; and glInternalformat must be used for providing mapping.

5.3.2. KTXdxgiFormat__

For Direct3D the mapping is specified with the key

  • KTXdxgiFormat__

The value is a UInt32 (4 bytes) giving the format enum value.

5.3.3. KTXmetalPixelFormat

For Metal, the mapping is specified with the key

  • KTXmetalPixelFormat

The value is a UInt32 (4 bytes) giving the format enum value.

5.4. KTXswizzle

Desired component mapping for a texture can be indicated with the key

  • KTXswizzle

The value is a four-byte NUL-terminated string formatted as ([REGEXP]):

  • /^[rgba01]{4}$/

where each symbol represents source component (or fixed value) that is used for red, green, blue and alpha values, thus rgba being a default swizzling state.

For example, rg01 means:

  • the red and green channels are sampled from the red and green texture components respectively;

  • the blue channel is set to zero, ignoring texture data;

  • the alpha channel is set to one (fully saturated), ignoring texture data.

When a channel is not present in the texture, a value of 0 must be used for colors (red, green and blue) and a value of 1 (fully saturated) must be used for alpha.

This metadata has no effect on depth or stencil texture formats.

5.4.1. Common Mappings

Use the following formats and swizzles to map alpha-only, luminance and luminance-alpha formats.

Alpha8

vkFormat: VK_FORMAT_R8_UNORM (9)
KTXswizzle: 000r

Luminance8

vkFormat: VK_FORMAT_R8_UNORM (9)
KTXswizzle: rrr1

Luminance8Alpha8

vkFormat: VK_FORMAT_R8G8_UNORM (16)
KTXswizzle: rrrg

Loaders may opt to detect these cases and use API-provided enums when available, e.g. for the first case GL_ALPHA8 (when using compatibility profile), MTLPixelFormatA8Unorm or DXGI_FORMAT_A8_UNORM.

5.5. KTXwriter

KTX file writers may, and are strongly encouraged to, identify themselves by including a value with the key

  • KTXwriter

The value is a NUL-terminated UTF-8 string that will uniquely identify the tool writing the file, for example:

  • AcmeCo TexTool v1.0

Only the most recent writer should be identified. Editing tools must overwrite this value when rewriting a file originally written by a different tool.

5.6. KTXwriterScParams

KTX file writers may, and are strongly encouraged to, identify any non-default Basis Universal, ASTC & other block-compression encoding and supercompression options specified when the file is created by including a value with the key

  • KTXwriterScParams

The value is a NUL-terminated UTF-8 string that shows the command-line or other options used when writing the file, for example:

  • --uastc --uastc_rdo_l 2 --zcmp 5

If KTXwriterScParams is present, KTXwriter must also be present.

In general only the most recent writer and most recently used options should be identified unless the writer is building on operations done previously. For example if a writer is adding Zstd supercompression to a file it previously encoded in UASTC, it should append the additional options to those previously used.

5.7. KTXastcDecodeMode

By default, ASTC decoders produce pixel values with half-float precision for HDR and linear LDR blocks. KTX file writers may indicate that the data is compatible with more compact decoding modes (as defined in [VULKAN12EXT], VK_EXT_astc_decode_mode) by using the key

  • KTXastcDecodeMode

The value is a NUL-terminated string.

rgb9e5 means that pixel values can be decoded with RGB9E5 mode.

unorm8 (valid only for LDR formats) means that pixel values can be decoded with UNORM8 mode.

Other values are not allowed.

This metadata entry has no effect on and should not be present in KTX files that use sRGB transfer function.

This metadata entry has no effect on and should not be present in KTX files that use non-ASTC formats.

5.8. KTXanimData

The images of an array texture can be indicated to be the frames of a short animation by using the key

  • KTXanimData

The value is 12 bytes representing 3 Uint32 values:

UInt32 duration
UInt32 timescale
UInt32 loopCount

duration is the number of time units per frame. timescale is the number of time units per 1 second. Thus the duration of a frame in seconds is \(duration / timescale\).

loopCount indicates how many times to loop the animation. Values are:

  • 0 - loops infinitely

  • 1 - plays once

  • n - plays n times

This metadata entry must not be used together with KTXcubemapIncomplete.

6. An example KTX version 2 file:

// Header
0xAB, 0x4B, 0x54, 0x58, // first four bytes of Byte[12] identifier
0x20, 0x32, 0x30, 0xBB, // next four bytes of Byte[12] identifier
0x0D, 0x0A, 0x1A, 0x0A, // final four bytes of Byte[12] identifier
0x00, 0x00, 0x00, 0x00, // UInt32 vkFormat = VK_FORMAT_UNDEFINED (0)
0x01, 0x00, 0x00, 0x00, // UInt32 typeSize = 1
0x08, 0x00, 0x00, 0x00, // UInt32 pixelWidth = 8
0x08, 0x00, 0x00, 0x00, // UInt32 pixelHeight = 8
0x00, 0x00, 0x00, 0x00, // UInt32 pixelDepth = 0
0x00, 0x00, 0x00, 0x00, // UInt32 layerCount = 0
0x01, 0x00, 0x00, 0x00, // UInt32 faceCount = 0
0x01, 0x00, 0x00, 0x00, // UInt32 levelCount = 0
0x01, 0x00, 0x00, 0x00, // UInt32 supercompressionScheme = 1 (BASISLZ)
// Index
0x68, 0x00, 0x00, 0x00, // Uint32 dfdByteOffset = 0x00000068
0x3C, 0x00, 0x00, 0x00, // UInt32 dfdByteLength = 0x0000003C
0xC4, 0x00, 0x00, 0x00, // UInt32 kvdByteOffset = 0x000000C4
0x58, 0x00, 0x00, 0x00, // UInt32 kvdByteLength = 0x00000058
0x20, 0x01, 0x00, 0x00, // UInt64 sgdByteOffset = 0x0000000000000120
0x00, 0x00, 0x00, 0x00,
0x90, 0x00, 0x00, 0x00, // UInt64 sgdByteLength = 0x0000000000000090
0x00, 0x00, 0x00, 0x00,
// Level Index
0xB0, 0x01, 0x00, 0x00, // UInt64 level[0].byteOffset = 0x00000000000001B0
0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, // UInt64 level[0].byteLength = 0x0000000000000003
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // UInt64 level[0].uncompressedByteLength = 0
0x00, 0x00, 0x00, 0x00,
// DFD
0x3C, 0x00, 0x00, 0x00, // UInt32 dfdTotalSize = 0x3C (60)
0x00, 0x00, 0x00, 0x00, // vendorId = 0 (17 bits), descriptorType = 0
0x02, 0x00, 0x38, 0x00, // versionNumber = 2, descriptorBlockSize = 0x38 (56)
0xA3, 0x01, 0x02, 0x00, // colorModel = ETC1S (163), primaries = BT709 (1)
                        // transferFunction = SRGB (2), flags = 0
0x03, 0x03, 0x00, 0x00, // texelBlockDimension[[0-3] = 3, 3, 0, 0
0x00, 0x00, 0x00, 0x00, // bytesPlane[0-3] = 0
0x00, 0x00, 0x00, 0x00, // bytesPlane[4-7] = 0
// DFD sample information, sample 0
0x00, 0x00, 0x3F, 0x00, // bitOffset = 0 bitLength = 0x3F (63),
                        // channelType = RGB (0), qualifiers = 0
0x00, 0x00, 0x00, 0x00, // samplePosition[0-3] = 0
0x00, 0x00, 0x00, 0x00, // sampleLower = 0
0xFF, 0xFF, 0xFF, 0xFF, // sampleUpper = 0xFFFFFFFF (UINT_MAX)
// Sample 1
0x40, 0x00, 0x3F, 0x0F, // bitOffset = 0x40 (64) bitLength = 0x3F (63),
                        // channelType = AAA (0x0F), qualifiers = 0
0x00, 0x00, 0x00, 0x00, // samplePosition[0-3] = 0
0x00, 0x00, 0x00, 0x00, // sampleLower = 0
0xFF, 0xFF, 0xFF, 0xFF, // sampleUpper = 0xFFFFFFFF (UINT_MAX)
// Key/Value Data
0x12, 0x00, 0x00, 0x00, // keyAndValueByteLength = 18 (0x12)
0x4B, 0x54, 0x58, 0x6F, // KTXo
0x72, 0x69, 0x65, 0x6E, // rien
0x74, 0x61, 0x74, 0x69, // tati
0x6F, 0x6E, 0x00, 0x72, // on NUL r
0x64, 0x00, 0x00, 0x00, // d  <3 bytes of valuePadding>
0x3B, 0x00, 0x00, 0x00, // keyAndValueByteLength = 59 (0x3B)
0x4B, 0x54, 0x58, 0x77, // KTXw
0x72, 0x69, 0x74, 0x65, // rite
0x72, 0x00, 0x74, 0x6F, // r NUL to
0x6B, 0x74, 0x78, 0x20, // ktx SPACE
0x76, 0x34, 0x2E, 0x30, // v4.0
0x2E, 0x5F, 0x5F, 0x64, // .__d
0x65, 0x66, 0x61, 0x75, // efau
0x6C, 0x74, 0x5F, 0x5F, // lt__
0x20, 0x2F, 0x20, 0x6C, // SPACE / SPACE l
0x69, 0x62, 0x6B, 0x74, // ibkt
0x78, 0x20, 0x76, 0x34, // x v4
0x2E, 0x30, 0x2E, 0x5F, // .0._
0x5F, 0x64, 0x65, 0x66, // _def
0x61, 0x75, 0x6C, 0x74, // ault
0x5F, 0x5F, 0x00, 0x00, // __ <2 bytes of valuePadding>
0x00, 0x00, 0x00, 0x00, // 4 bytes of padding.
// Supercompression Global Data
0x02, 0x00, 0x02, 0x00, // UInt16 endpointCount = 2, UInt16 selectorCount = 2
0x2D, 0x00, 0x00, 0x00, // UInt32 endpointsByteLength = 0x2D
0x09, 0x00, 0x00, 0x00, // UInt32 selectorsByteLength = 0x09
0x2E, 0x00, 0x00, 0x00, // Uint32 tablesByteLength = 0x2E
0x00, 0x00, 0x00, 0x00, // Uint32 extendedByteLength = 0
// imageDesc[0]
0x00, 0x00, 0x00, 0x00, // UInt32 flags = 0
0x00, 0x00, 0x00, 0x00, // UInt32 rgbSliceByteOffset = 0
0x02, 0x00, 0x00, 0x00, // UInt32 rgbSliceByteLength = 2
0x02, 0x00, 0x00, 0x00, // UInt32 alphaSliceByteOffset = 0x02
0x01, 0x00, 0x00, 0x00, // UInt32 alphaSliceByteLength = 1
// endpointsData
0x01, 0xC0, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x04, 0x98,
0x1B, 0x20, 0x00, 0x00,
0x00, 0x08, 0xC3, 0x36,
0x91, 0x3E, 0x91, 0x00,
0x60, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x81, 0x00, 0x4C, 0x01,
0x10, 0x00, 0x00, 0x00,
0x00, 0x20, 0x59, 0xC0,
0x3D,
// selectorsData
      0x54, 0x55, 0x55,
0x55, 0xAD, 0xAA, 0xAA,
0xAA, 0x02,
// tablesData
            0x14, 0xC0,
0x44, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x12,
0x41, 0x00, 0x98, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x18, 0x02,
0xA2, 0x04, 0x0C, 0x00,
0x00, 0x00, 0x83, 0x76,
0x7B, 0x49, 0x04, 0xA2,
0x20, 0x00, 0x4C, 0x00,
0x08, 0x00, 0x00, 0x00,
0x00, 0x20, 0x02, 0x01,
// Level 0 image data
0x4E, 0x0E, 0x04

7. IANA Media-Type Registration Information

Type name: Image

Subtype name: ktx2

Required parameters: none

Optional parameters: none

Encoding considerations: binary

Security considerations:

The ktx2 type is a binary data stream which contains no executable code that could disrupt a client processor. There is no provision in the type specification that would allow authors to insert executable code that would present any security risk to a client machine. The only effect associated with this data is to cause an image to be rendered on the recipient’s display.

Because every item’s length is available at its beginning, there is robust defense against corrupted or fraudulent data that might overflow a decoder’s buffer. Also the signature bytes provide early detection of common file transmission errors.

The image payload may be uncompressed or block-compressed. The payload may be further supercompressed with variable-rate compression.

Block compression schemes are designed so small blocks of data (typically 64 to 128 bits) can be decompressed in real time into a small block of pixels (typically 4x4) during texel fetch. In such schemes it is not possible for a small amount of data to expand enormously because the level of compression is limited; the compressed size is related directly to the number of pixels in the uncompressed image and not to the content of the data.

When variable-rate compression is used, the format includes information as to the expected size of the uncompressed data. However applications must not rely on this and must guard against buffer overflow and ultra large memory allocation.

The ktx2 type does not provide encryption of the data payload. Users or applications wishing or needing to keep their images confidential must overlay their own encryption on the ktx data during transmission.

Interoperability considerations:

The ktx2 type is a container capable of holding a payload in one of a large number of formats, potentially supercompressed with one of a number of schemes. While the container format will not change, new payload formats and supercompression schemes may be added over time. Consumers of this media-type must fail gracefully in the face of unrecognized formats and schemes. Since formats and schemes are identified in the ktx2 header, applications can quickly reject those they do not support.

Published specification:

The KTX v2 file format specification can be found at

Applications Usage:

The tools in the KTX Software repo (https://github.com/KhronosGroup/KTX-Software) - ktx2check, ktx2ktx2, ktxinfo, ktxsc, toktx - and gltfpack. The KHR_texture_basisu glTF extension. Loaders are available in THREE.js and Babylon.js. It is anticipated that it will be widely used by applications using glTF content and by applications built on top of OpenGl, Vulkan, WebGL and other 3D API standards as the means of delivering texture data. Since image/ktx2 supports universal textures (textures that can be transcoded to any GPU block-compressed format) uptake is expected to be nearly, er, universal.

Fragment Identifier Considerations:

The syntax and semantics for identifying fragments in the payload of a KTX file, is as specified in KTX Fragments URI.

Restrictions on Usage: none

Provisional registration? No

Additional information:

Magic number(s): 12 octets
                 { 0xAB,0x4B,0x54,0x58,0x20,0x32,0x30,0xBB,0x0D,0x0A,0x1A,0x0A }
File extension(s): .ktx2
Macintosh file type code(s): n/a
Macintosh Uniform Type Identifier: public.ktx2, conforms to public.image

Intended usage: COMMON

Restrictions on usage: none

Other Information & Comments:

Relationship to image/ktx: image/ktx shares the purpose of being a container for texture data for use with 3D APIs. image/ktx2 offers a significant increase in functionality, including universal textures and supercompression, that required incompatible changes to the container format hence this new registration request.

Contact Person:

Mark Callow (khronos at callow.im)

Authors:

Mark Callow, Alexey Knyazev

Change controller:

The Khronos Group (www.khronos.org), the industry consortium responsible for standards such as OpenGL, OpenGL ES, WebGL and Vulkan. For change requests contact <iana at khronos.org>.

8. Issues

  1. How to refer to the DF descriptor block?

    Discussion: There is no such data type as dfDesriptorBlock but using primitive types would effectively mean repeating the definition of a descriptor block here which we do not want to do.

    Resolved: Show that dfDescriptorBlock is used as a shorthand for [KDF13]'s Descriptor block.

  2. How to handle endianness of the DF descriptor block?

    Discussion: The DF spec says data structures are assumed to be little-endian for purposes of data transfer. This is incompatible with the net which is big-endian and incompatible with endianness. What should we do?

    _Resolved._All fields and data in KTX files will be little endian as that is the endianness of the vast majority of machines.

  3. Can we guarantee the DF descriptor blocks are always a multiple of 4 bytes?

    Discussion The Khronos Basic Data Format Descriptor Block is a multiple of 4 bytes (24 + 16 x number of samples). Is there anything to require that extensions' block sizes be a multiple of 4 bytes? Need to maintain alignment.

    Resolved: The Data Format Specification has been updated to recommend but not require padding. This spec. will require padding.

  4. Should KTX support level sizes > 4GB?

    Discussion: Users have reported having base levels > 4GB for 3D textures. For this the imageSize field needs to be 64-bits. Loaders on 32-bit systems will have to ensure correct handling of this and check that imageSize <= 4GB, before loading.

    Resolved: Be future proof and make all image-size related fields 64 bits.

  5. Should KTX provide a way to distinguish between rectangle and regular 2D textures?

    Discussion: The difference is that unnormalized texel coordinates are used for sampling via a special sampler type in GLSL and, in the case of OpenGL {,ES}, the special TEXTURE_RECTANGLE target is used. If needed this could be supported by a metadata item instructing to use unnormalized texel coordinates.

    Resolved: Not at this time. Should the need emerge, a metadata item can be added.

  6. Should KTX provide a way to distinguish between 1D textures and buffer textures?

    Discussion: The difference is how you use the data in OpenGL. With buffer textures the image data is stored in a buffer object. Note that a TextureView can be used to give a different view of the data so supporting buffer textures probably requires metadata to indicate a preferred view as well as metadata to indicate the data should be loaded in a buffer.

    Resolved: Not at this time. Should the need emerge, metadata items can be added.

  7. Should KTX drop the gl* fields?

    Discussion: Narrowing down and enforcing the valid combinations of glFormat, glInternalFormat and glType is fraught with issues. The spec. could be simplified by dropping them and having only vkFormat. The spec can include a table showing a standard mapping from the vkFormat value to a glInternalFormat, glFormat and glType combination.

    Resolved: Drop the gl* fields. OpenGL and OpenGL ES loaders can include code to do the mapping based on table which has been added to the spec. Such code is estimated to be about 6 kbytes.

  8. Use alphanumeric characters or binary values for component swizzles?

    Discussion: Values in the swizzle metadata could be either a character from the set [01rgba] or numeric values corresponding to the VkComponentSwizzle enum values from 0 to 6. In the latter case values could be expressed in binary or as numeric characters. The GL token values have been eliminated from this choice because they are not user friendly.

    Resolved: Use alphanumeric characters from the set [01rgba].

  9. Is anything needed to support sparse textures?

    Discussion: Sparse textures are provided by the GL_ARB_sparse_textures extension and are a standard feature of Vulkan. Are any additional KTX features needed to support them?

    Resolved: No. Nothing is seen to be required.

  10. Should KTX support metadata for effective use of Vulkan SCALED formats?

    Discussion: Vulkan SCALED formats convert int (or uint) values to unnormalized floating point values, equivalent to specifying a value of GL_FALSE for the normalized parameter to glVertexAttribFormat. Generally when using such data, associated scale and bias values are folded into the transformation matrix. Should KTX specify standard metadata for these?

    Resolved: No. These formats will not be supported. They are primarily for vertex data and several Vulkan vendors have said they can’t support them as texture formats. Also a DFD cannot distinguish these from int values having the same bit pattern.

  11. Should the supercompression scheme be applied per-mip-level?

    Discussion: Should each mip level be supercompressed independently or should the scheme, zlib, zstd, etc., be applied to all levels as a unit? The latter may result in slightly smaller size though that is unclear. However it would also mean levels could not be streamed or randomly accessed.

    Resolved: Yes. The benefits of streaming and random access outweigh what is expected to be a small increase in size.

  12. Should we remove row padding from uncompressed image data?

    Discussion: Row padding was added to KTX so that data would have the default GL_UNPACK_ALIGNMENT of 4, which was chosen to help speed up DMA of rows by the GPU. Modern architectures are apparently not sensitive to this as evidenced by Vulkan deliberately omitting any equivalent of GL_UNPACK_ALIGNMENT. Thus an annoying chunk of code is required to upload row-padded images to Vulkan.

    Resolved: Remove this and cube padding. Formats that would need padding have texel sizes that are less than 4 bytes so no benefit is obtained by starting cube faces or rows of such images at 4-byte multiples.

  13. Should we require content checksums anywhere?

    Discussion: Modern transmission mechanisms, e.g, HTTP2, provide good robustness so checksums are less important than they used to be. Some supercompressions schemes have checksum which may be optional.

    Resolved: No. We can rely on modern transmission mechanisms. However if the supercompression scheme includes a checksum readers should verify it.

  14. Should we use the DFD to indicate the number of components in Basis Universal supercompressed data?

    Discussion: Basis Universal compressed data may have 1, 2, 3 or 4 components. The number of components affects the choice of transcode target format. The information could be provided within the supercompression global data or by the DFD. Currently presence of alpha slices, but not necessarily an alpha component, is indicated by a flag in the global data. The number of components is needed by applications that may have no knowledge of the original images.

    Resolved: Yes. The supercompression global data gives information about the Basis Universal compressed data not about the images. The DFD contains this information prior to supercompression. It makes sense to preserve it. Implementations will then have a consistent place to query this information.

9. References

Normative References

The Vulkan 1.2 references are living documents that are updated weekly with corrections, clarifications and, in the case of [VULKAN12EXT], newly released extensions. References to the specifications do not imply that KTX header field values are limited solely to those in the referenced sections or tables. These values may be supplemented by extensions or new versions. They also do not imply that all of the texture types can be loaded in any particular version of OpenGL {,ES} or Vulkan.

Non-Normative References

Appendix A: Cubemap Orientation

The KTX cubemap coordinate system in Section 3.6, “faceCount” is directly compatible with the Vulkan and OpenGL cube samplers described by the face selection tables and equations for calculating (s, t) in section 16.5.3 Cube Map Face Selection and Transformations of [VULKAN12] and section 8.13 Cube Map Texture Selection of [OPENGL46].

Figure 1, “Cubemap Coordinate System” shows graphically how the cubemap images should be arranged.

cubemap coord system
Figure 1. Cubemap Coordinate System

If the face orientation is not rd, maintaining compatibility with the cube samplers may require changing the relative positions of faces, e.g. swapping +Y and -Y faces. To keep things simple rd must always be used.

If using a skybox to render the cubemap, the (s, t, r) coordinates passed to the cubemap sampler need to match the KTX cubemap coordinate system, that is left-handed with +Y up, +Z forward and +X on the right.

If using OpenGL’s default object space, which is right-handed, you can transform your skybox cube coordinates to the necessary left-handed system by multiplying either the X or the Z coordinate by -1. The former places the +Z face in the +Z direction so, if using OpenGL’s default view, that face will be behind you. The latter places the +Z face in the -Z direction so it will be in front of you. Failure to do one of these things will result in the skybox scene being a mirror image of reality, a common error in samples found on the web.

While Vulkan defaults to a left-handed coordinate system it has +Y down, with +Z out of the screen (behind the default view) and +X to the right. To transform these skybox coordinates to the cubemap’s coordinate system, either

  • multiply both Y and Z by -1 to keep +Y up and place the +Z face in -Z direction, or

  • multiply both Y and X by -1 to keep +Y up and place the +Z face in +Z direction.

Failure to do one of these will result in the cubemap top and bottom faces being swapped.

Appendix B: Mapping of vkFormat values

This appendix is non-normative.
Provided mappings for BGR(A) formats are based on non-ES OpenGL specifications. See the relevant OpenGL ES extensions for more options.
On OpenGL ES 2.0 and WebGL 1.0, half-float data type is provided via GL_OES_texture_half_float extension that defines different enum name (GL_HALF_FLOAT_OES) and value (0x8D61) than other GL APIs.
Some vendor-specific extensions (e.g. GL_NV_depth_buffer_float) define custom enum values for symbols used in the ratified specifications.
Mapping of vkFormat values to OpenGL, Direct3D and Metal
VK_FORMAT_R4G4_UNORM_PACK8
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R4G4B4A4_UNORM_PACK16
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA4.

  • glFormat: GL_RGBA.

  • glType: GL_UNSIGNED_SHORT_4_4_4_4.

    OpenGL Support
    • Core 1.2+.

    • GL_EXT_packed_pixels.

    OpenGL ES Support
    • Core 1.0+.

    WebGL Support
    • Core 1.0+.

Direct3D
  • No mapping available.

Metal
VK_FORMAT_B4G4R4A4_UNORM_PACK16
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA4.

  • glFormat: GL_BGRA.

  • glType: GL_UNSIGNED_SHORT_4_4_4_4.

    OpenGL Support
    • Core 1.2+.

    • GL_EXT_bgra + GL_EXT_packed_pixels.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R5G6B5_UNORM_PACK16
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB565.

  • glFormat: GL_RGB.

  • glType: GL_UNSIGNED_SHORT_5_6_5.

    OpenGL Support
    • Core 1.2+.

    OpenGL ES Support
    • Core 1.0+.

    WebGL Support
    • Core 1.0+.

Direct3D
Metal
VK_FORMAT_B5G6R5_UNORM_PACK16
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB565.

  • glFormat: GL_RGB.

  • glType: GL_UNSIGNED_SHORT_5_6_5_REV.

    OpenGL Support
    • Core 1.2+.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R5G5B5A1_UNORM_PACK16
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB5_A1.

  • glFormat: GL_RGBA.

  • glType: GL_UNSIGNED_SHORT_5_5_5_1.

    OpenGL Support
    • Core 1.2+.

    • GL_EXT_packed_pixels.

    OpenGL ES Support
    • Core 1.0+.

    WebGL Support
    • Core 1.0+.

Direct3D
  • No mapping available.

Metal
VK_FORMAT_B5G5R5A1_UNORM_PACK16
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB5_A1.

  • glFormat: GL_BGRA.

  • glType: GL_UNSIGNED_SHORT_5_5_5_1.

    OpenGL Support
    • Core 1.2+.

    • GL_EXT_bgra + GL_EXT_packed_pixels.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_A1R5G5B5_UNORM_PACK16
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB5_A1.

  • glFormat: GL_BGRA.

  • glType: GL_UNSIGNED_SHORT_1_5_5_5_REV.

    OpenGL Support
    • Core 1.2+.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
Metal
VK_FORMAT_R8_UNORM
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_R8.

  • glFormat: GL_RED.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg.

    OpenGL ES Support
    • Core 3.0+.

    • GL_EXT_texture_rg.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R8_SNORM
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_R8_SNORM.

  • glFormat: GL_RED.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.1+.

    • GL_EXT_texture_snorm.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R8_UINT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_R8UI.

  • glFormat: GL_RED_INTEGER.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg + GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R8_SINT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_R8I.

  • glFormat: GL_RED_INTEGER.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg + GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R8_SRGB
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_SR8_EXT.

  • glFormat: GL_RED.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • GL_EXT_texture_sRGB_R8.

    OpenGL ES Support
    • GL_EXT_texture_sRGB_R8.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
VK_FORMAT_R8G8_UNORM
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RG8.

  • glFormat: GL_RG.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg.

    OpenGL ES Support
    • Core 3.0+.

    • GL_EXT_texture_rg.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R8G8_SNORM
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RG8_SNORM.

  • glFormat: GL_RG.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.1+.

    • GL_EXT_texture_snorm.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R8G8_UINT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RG8UI.

  • glFormat: GL_RG_INTEGER.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg + GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R8G8_SINT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RG8I.

  • glFormat: GL_RG_INTEGER.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg + GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R8G8_SRGB
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_SRG8_EXT.

  • glFormat: GL_RG.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • GL_EXT_texture_sRGB_RG8.

    OpenGL ES Support
    • GL_EXT_texture_sRGB_RG8.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
VK_FORMAT_R8G8B8_UNORM
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB8.

  • glFormat: GL_RGB.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 1.0+.

    OpenGL ES Support
    • Core 1.0+.

    WebGL Support
    • Core 1.0+.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R8G8B8_SNORM
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB8_SNORM.

  • glFormat: GL_RGB.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.1+.

    • GL_EXT_texture_snorm.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R8G8B8_UINT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB8UI.

  • glFormat: GL_RGB_INTEGER.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R8G8B8_SINT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB8I.

  • glFormat: GL_RGB_INTEGER.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R8G8B8_SRGB
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_SRGB8.

  • glFormat: GL_RGB.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 2.1+.

    • GL_EXT_texture_sRGB.

    OpenGL ES Support
    • Core 3.0+.

    • GL_EXT_sRGB.

    WebGL Support
Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_B8G8R8_UNORM
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB8.

  • glFormat: GL_BGR.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 1.2+.

    • GL_EXT_bgra.

    OpenGL ES Support
    • GL_EXT_bgra.

    • GL_NV_bgr.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_B8G8R8_SNORM
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB8_SNORM.

  • glFormat: GL_BGR.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.1+.

    • GL_EXT_texture_snorm.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_B8G8R8_UINT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB8UI.

  • glFormat: GL_BGR_INTEGER.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_B8G8R8_SINT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB8I.

  • glFormat: GL_BGR_INTEGER.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_B8G8R8_SRGB
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_SRGB8.

  • glFormat: GL_BGR.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 2.1+.

    • GL_EXT_texture_sRGB.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R8G8B8A8_UNORM
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA8.

  • glFormat: GL_RGBA.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 1.0+.

    OpenGL ES Support
    • Core 1.0+.

    WebGL Support
    • Core 1.0+.

Direct3D
Metal
VK_FORMAT_R8G8B8A8_SNORM
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA8_SNORM.

  • glFormat: GL_RGBA.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.1+.

    • GL_EXT_texture_snorm.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R8G8B8A8_UINT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA8UI.

  • glFormat: GL_RGBA_INTEGER.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R8G8B8A8_SINT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA8I.

  • glFormat: GL_RGBA_INTEGER.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R8G8B8A8_SRGB
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_SRGB8_ALPHA8.

  • glFormat: GL_RGBA.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 2.1+.

    • GL_EXT_texture_sRGB.

    OpenGL ES Support
    • Core 3.0+.

    • GL_EXT_sRGB.

    WebGL Support
Direct3D
Metal
VK_FORMAT_B8G8R8A8_UNORM
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA8.

  • glFormat: GL_BGRA.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 1.2+.

    • GL_EXT_bgra.

    OpenGL ES Support
    • GL_APPLE_texture_format_BGRA8888.

    • GL_EXT_bgra.

    • GL_EXT_texture_format_BGRA8888.

    • GL_IMG_texture_format_BGRA8888.

    WebGL Support
    • None.

Direct3D
Metal
VK_FORMAT_B8G8R8A8_SNORM
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA8_SNORM.

  • glFormat: GL_BGRA.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.1+.

    • GL_EXT_texture_snorm.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_B8G8R8A8_UINT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA8UI.

  • glFormat: GL_BGRA_INTEGER.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_B8G8R8A8_SINT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA8I.

  • glFormat: GL_BGRA_INTEGER.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_B8G8R8A8_SRGB
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_SRGB8_ALPHA8.

  • glFormat: GL_BGRA.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 2.1+.

    • GL_EXT_texture_sRGB.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
Metal
VK_FORMAT_A8B8G8R8_UNORM_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA8.

  • glFormat: GL_RGBA.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 1.0+.

    OpenGL ES Support
    • Core 1.0+.

    WebGL Support
    • Core 1.0+.

Direct3D
Metal
VK_FORMAT_A8B8G8R8_SNORM_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA8_SNORM.

  • glFormat: GL_RGBA.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.1+.

    • GL_EXT_texture_snorm.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_A8B8G8R8_UINT_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA8UI.

  • glFormat: GL_RGBA_INTEGER.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_A8B8G8R8_SINT_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA8I.

  • glFormat: GL_RGBA_INTEGER.

  • glType: GL_BYTE.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_A8B8G8R8_SRGB_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_SRGB8_ALPHA8.

  • glFormat: GL_RGBA.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 2.1+.

    • GL_EXT_texture_sRGB.

    OpenGL ES Support
    • Core 3.0+.

    • GL_EXT_sRGB.

    WebGL Support
Direct3D
Metal
VK_FORMAT_A2R10G10B10_UNORM_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB10_A2.

  • glFormat: GL_BGRA.

  • glType: GL_UNSIGNED_INT_2_10_10_10_REV.

    OpenGL Support
    • Core 1.2+.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
VK_FORMAT_A2R10G10B10_SNORM_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_A2R10G10B10_UINT_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB10_A2UI.

  • glFormat: GL_BGRA_INTEGER.

  • glType: GL_UNSIGNED_INT_2_10_10_10_REV.

    OpenGL Support
    • Core 3.3+.

    • GL_ARB_texture_rgb10_a2ui.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_A2R10G10B10_SINT_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_A2B10G10R10_UNORM_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB10_A2.

  • glFormat: GL_RGBA.

  • glType: GL_UNSIGNED_INT_2_10_10_10_REV.

    OpenGL Support
    • Core 1.2+.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_A2B10G10R10_SNORM_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_A2B10G10R10_UINT_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB10_A2UI.

  • glFormat: GL_RGBA_INTEGER.

  • glType: GL_UNSIGNED_INT_2_10_10_10_REV.

    OpenGL Support
    • Core 3.3+.

    • GL_ARB_texture_rgb10_a2ui.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_A2B10G10R10_SINT_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R16_UNORM
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_R16.

  • glFormat: GL_RED.

  • glType: GL_UNSIGNED_SHORT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg.

    OpenGL ES Support
    • GL_EXT_texture_norm16.

    WebGL Support
Direct3D
Metal
VK_FORMAT_R16_SNORM
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_R16_SNORM.

  • glFormat: GL_RED.

  • glType: GL_SHORT.

    OpenGL Support
    • Core 3.1+.

    • GL_EXT_texture_snorm.

    OpenGL ES Support
    • GL_EXT_texture_norm16.

    WebGL Support
Direct3D
Metal
VK_FORMAT_R16_UINT
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_R16UI.

  • glFormat: GL_RED_INTEGER.

  • glType: GL_UNSIGNED_SHORT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg + GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R16_SINT
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_R16I.

  • glFormat: GL_RED_INTEGER.

  • glType: GL_SHORT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg + GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R16_SFLOAT
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_R16F.

  • glFormat: GL_RED.

  • glType: GL_HALF_FLOAT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_half_float_pixel + GL_ARB_texture_float + GL_ARB_texture_rg.

    • GL_ARB_texture_float + GL_ARB_texture_rg + GL_NV_half_float.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R16G16_UNORM
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RG16.

  • glFormat: GL_RG.

  • glType: GL_UNSIGNED_SHORT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg.

    OpenGL ES Support
    • GL_EXT_texture_norm16.

    WebGL Support
Direct3D
Metal
VK_FORMAT_R16G16_SNORM
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RG16_SNORM.

  • glFormat: GL_RG.

  • glType: GL_SHORT.

    OpenGL Support
    • Core 3.1+.

    • GL_EXT_texture_snorm.

    OpenGL ES Support
    • GL_EXT_texture_norm16.

    WebGL Support
Direct3D
Metal
VK_FORMAT_R16G16_UINT
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RG16UI.

  • glFormat: GL_RG_INTEGER.

  • glType: GL_UNSIGNED_SHORT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg + GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R16G16_SINT
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RG16I.

  • glFormat: GL_RG_INTEGER.

  • glType: GL_SHORT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg + GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R16G16_SFLOAT
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RG16F.

  • glFormat: GL_RG.

  • glType: GL_HALF_FLOAT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_half_float_pixel + GL_ARB_texture_float + GL_ARB_texture_rg.

    • GL_ARB_texture_float + GL_ARB_texture_rg + GL_NV_half_float.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R16G16B16_UNORM
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB16.

  • glFormat: GL_RGB.

  • glType: GL_UNSIGNED_SHORT.

    OpenGL Support
    • Core 1.0+.

    OpenGL ES Support
    • GL_EXT_texture_norm16.

    WebGL Support
Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R16G16B16_SNORM
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB16_SNORM.

  • glFormat: GL_RGB.

  • glType: GL_SHORT.

    OpenGL Support
    • Core 3.1+.

    • GL_EXT_texture_snorm.

    OpenGL ES Support
    • GL_EXT_texture_norm16.

    WebGL Support
Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R16G16B16_UINT
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB16UI.

  • glFormat: GL_RGB_INTEGER.

  • glType: GL_UNSIGNED_SHORT.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R16G16B16_SINT
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB16I.

  • glFormat: GL_RGB_INTEGER.

  • glType: GL_SHORT.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R16G16B16_SFLOAT
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB16F.

  • glFormat: GL_RGB.

  • glType: GL_HALF_FLOAT.

    OpenGL Support
    • Core 3.0+.

    • GL_APPLE_float_pixels.

    • GL_ARB_half_float_pixel + GL_ARB_texture_float.

    • GL_ARB_half_float_pixel + GL_ATI_texture_float.

    • GL_NV_half_float + GL_ARB_texture_float.

    • GL_NV_half_float + GL_ATI_texture_float.

    OpenGL ES Support
    • Core 3.0+.

    • GL_OES_texture_half_float.

    WebGL Support
Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R16G16B16A16_UNORM
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA16.

  • glFormat: GL_RGBA.

  • glType: GL_UNSIGNED_SHORT.

    OpenGL Support
    • Core 1.0+.

    OpenGL ES Support
    • GL_EXT_texture_norm16.

    WebGL Support
Direct3D
Metal
VK_FORMAT_R16G16B16A16_SNORM
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA16_SNORM.

  • glFormat: GL_RGBA.

  • glType: GL_SHORT.

    OpenGL Support
    • Core 3.1+.

    • GL_EXT_texture_snorm.

    OpenGL ES Support
    • GL_EXT_texture_norm16.

    WebGL Support
Direct3D
Metal
VK_FORMAT_R16G16B16A16_UINT
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA16UI.

  • glFormat: GL_RGBA_INTEGER.

  • glType: GL_UNSIGNED_SHORT.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R16G16B16A16_SINT
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA16I.

  • glFormat: GL_RGBA_INTEGER.

  • glType: GL_SHORT.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R16G16B16A16_SFLOAT
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA16F.

  • glFormat: GL_RGBA.

  • glType: GL_HALF_FLOAT.

    OpenGL Support
    • Core 3.0+.

    • GL_APPLE_float_pixels.

    • GL_ARB_half_float_pixel + GL_ARB_texture_float.

    • GL_ARB_half_float_pixel + GL_ATI_texture_float.

    • GL_NV_half_float + GL_ARB_texture_float.

    • GL_NV_half_float + GL_ATI_texture_float.

    OpenGL ES Support
    • Core 3.0+.

    • GL_OES_texture_half_float.

    WebGL Support
Direct3D
Metal
VK_FORMAT_R32_UINT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_R32UI.

  • glFormat: GL_RED_INTEGER.

  • glType: GL_UNSIGNED_INT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg + GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R32_SINT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_R32I.

  • glFormat: GL_RED_INTEGER.

  • glType: GL_INT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg + GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R32_SFLOAT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_R32F.

  • glFormat: GL_RED.

  • glType: GL_FLOAT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_float + GL_ARB_texture_rg.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R32G32_UINT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RG32UI.

  • glFormat: GL_RG_INTEGER.

  • glType: GL_UNSIGNED_INT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg + GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R32G32_SINT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RG32I.

  • glFormat: GL_RG_INTEGER.

  • glType: GL_INT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_rg + GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R32G32_SFLOAT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RG32F.

  • glFormat: GL_RG.

  • glType: GL_FLOAT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_float + GL_ARB_texture_rg.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R32G32B32_UINT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB32UI.

  • glFormat: GL_RGB_INTEGER.

  • glType: GL_UNSIGNED_INT.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
  • No mapping available.

VK_FORMAT_R32G32B32_SINT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB32I.

  • glFormat: GL_RGB_INTEGER.

  • glType: GL_INT.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
  • No mapping available.

VK_FORMAT_R32G32B32_SFLOAT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB32F.

  • glFormat: GL_RGB.

  • glType: GL_FLOAT.

    OpenGL Support
    • Core 3.0+.

    • GL_APPLE_float_pixels.

    • GL_ARB_texture_float.

    • GL_ATI_texture_float.

    OpenGL ES Support
    • Core 3.0+.

    • GL_OES_texture_float.

    WebGL Support
Direct3D
Metal
  • No mapping available.

VK_FORMAT_R32G32B32A32_UINT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA32UI.

  • glFormat: GL_RGBA_INTEGER.

  • glType: GL_UNSIGNED_INT.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R32G32B32A32_SINT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA32I.

  • glFormat: GL_RGBA_INTEGER.

  • glType: GL_INT.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_integer.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_R32G32B32A32_SFLOAT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA32F.

  • glFormat: GL_RGBA.

  • glType: GL_FLOAT.

    OpenGL Support
    • Core 3.0+.

    • GL_APPLE_float_pixels.

    • GL_ARB_texture_float.

    • GL_ATI_texture_float.

    OpenGL ES Support
    • Core 3.0+.

    • GL_OES_texture_float.

    WebGL Support
Direct3D
Metal
VK_FORMAT_R64_UINT
Layout
  • Type Size: 8.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R64_SINT
Layout
  • Type Size: 8.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R64_SFLOAT
Layout
  • Type Size: 8.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R64G64_UINT
Layout
  • Type Size: 8.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R64G64_SINT
Layout
  • Type Size: 8.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R64G64_SFLOAT
Layout
  • Type Size: 8.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R64G64B64_UINT
Layout
  • Type Size: 8.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R64G64B64_SINT
Layout
  • Type Size: 8.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R64G64B64_SFLOAT
Layout
  • Type Size: 8.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R64G64B64A64_UINT
Layout
  • Type Size: 8.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R64G64B64A64_SINT
Layout
  • Type Size: 8.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_R64G64B64A64_SFLOAT
Layout
  • Type Size: 8.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_B10G11R11_UFLOAT_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_R11F_G11F_B10F.

  • glFormat: GL_RGB.

  • glType: GL_UNSIGNED_INT_10F_11F_11F_REV.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_packed_float.

    OpenGL ES Support
    • Core 3.0+.

    • GL_APPLE_texture_packed_float.

    • GL_NV_packed_float.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB9_E5.

  • glFormat: GL_RGB.

  • glType: GL_UNSIGNED_INT_5_9_9_9_REV.

    OpenGL Support
    • Core 3.0+.

    • GL_EXT_texture_shared_exponent.

    OpenGL ES Support
    • Core 3.0+.

    • GL_APPLE_texture_packed_float.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_D16_UNORM
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_DEPTH_COMPONENT16.

  • glFormat: GL_DEPTH_COMPONENT.

  • glType: GL_UNSIGNED_SHORT.

    OpenGL Support
    • Core 1.4+.

    • GL_ARB_depth_texture.

    • GL_SGIX_depth_texture.

    OpenGL ES Support
    • Core 3.0+.

    • GL_OES_depth_texture.

    WebGL Support
Direct3D
Metal
VK_FORMAT_X8_D24_UNORM_PACK32
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_D32_SFLOAT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_DEPTH_COMPONENT32F.

  • glFormat: GL_DEPTH_COMPONENT.

  • glType: GL_FLOAT.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_depth_buffer_float.

    • GL_NV_depth_buffer_float.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_S8_UINT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_STENCIL_INDEX8.

  • glFormat: GL_STENCIL_INDEX.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 4.4+.

    • GL_ARB_texture_stencil8.

    OpenGL ES Support
    • Core 3.2+.

    • GL_OES_texture_stencil8.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
VK_FORMAT_D16_UNORM_S8_UINT
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • No mapping available.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_D24_UNORM_S8_UINT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_DEPTH24_STENCIL8.

  • glFormat: GL_DEPTH_STENCIL.

  • glType: GL_UNSIGNED_INT_24_8.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_framebuffer_object.

    • GL_EXT_packed_depth_stencil.

    • GL_NV_packed_depth_stencil.

    OpenGL ES Support
    • Core 3.0+.

    • GL_OES_packed_depth_stencil.

    WebGL Support
    • Core 2.0+.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_D32_SFLOAT_S8_UINT
Layout
  • Type Size: 4.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_DEPTH32F_STENCIL8.

  • glFormat: GL_DEPTH_STENCIL.

  • glType: GL_FLOAT_32_UNSIGNED_INT_24_8_REV.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_depth_buffer_float.

    • GL_NV_depth_buffer_float.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
    • Core 2.0+.

Direct3D
Metal
VK_FORMAT_BC1_RGB_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGB_S3TC_DXT1_EXT.

    OpenGL Support
    • GL_EXT_texture_compression_s3tc.

    OpenGL ES Support
    • GL_ANGLE_texture_compression_dxt1.

    • GL_EXT_texture_compression_dxt1.

    • GL_EXT_texture_compression_s3tc.

    • GL_NV_texture_compression_s3tc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_BC1_RGB_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB_S3TC_DXT1_EXT.

    OpenGL Support
    • GL_EXT_texture_compression_s3tc + GL_EXT_texture_sRGB.

    OpenGL ES Support
    • GL_EXT_texture_compression_s3tc_srgb.

    • GL_EXT_texture_compression_s3tc + GL_NV_sRGB_formats.

    • GL_NV_texture_compression_s3tc + GL_NV_sRGB_formats.

    WebGL Support
Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_BC1_RGBA_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_S3TC_DXT1_EXT.

    OpenGL Support
    • GL_EXT_texture_compression_s3tc.

    OpenGL ES Support
    • GL_ANGLE_texture_compression_dxt1.

    • GL_EXT_texture_compression_dxt1.

    • GL_EXT_texture_compression_s3tc.

    • GL_NV_texture_compression_s3tc.

    WebGL Support
Direct3D
Metal
VK_FORMAT_BC1_RGBA_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT.

    OpenGL Support
    • GL_EXT_texture_compression_s3tc + GL_EXT_texture_sRGB.

    OpenGL ES Support
    • GL_EXT_texture_compression_s3tc_srgb.

    • GL_EXT_texture_compression_s3tc + GL_NV_sRGB_formats.

    • GL_NV_texture_compression_s3tc + GL_NV_sRGB_formats.

    WebGL Support
Direct3D
Metal
VK_FORMAT_BC2_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_S3TC_DXT3_EXT.

    OpenGL Support
    • GL_EXT_texture_compression_s3tc.

    OpenGL ES Support
    • GL_ANGLE_texture_compression_dxt3.

    • GL_EXT_texture_compression_s3tc.

    • GL_NV_texture_compression_s3tc.

    WebGL Support
Direct3D
Metal
VK_FORMAT_BC2_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT.

    OpenGL Support
    • GL_EXT_texture_compression_s3tc + GL_EXT_texture_sRGB.

    OpenGL ES Support
    • GL_EXT_texture_compression_s3tc_srgb.

    • GL_EXT_texture_compression_s3tc + GL_NV_sRGB_formats.

    • GL_NV_texture_compression_s3tc + GL_NV_sRGB_formats.

    WebGL Support
Direct3D
Metal
VK_FORMAT_BC3_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_S3TC_DXT5_EXT.

    OpenGL Support
    • GL_EXT_texture_compression_s3tc.

    OpenGL ES Support
    • GL_ANGLE_texture_compression_dxt3.

    • GL_EXT_texture_compression_s3tc.

    • GL_NV_texture_compression_s3tc.

    WebGL Support
Direct3D
Metal
VK_FORMAT_BC3_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT.

    OpenGL Support
    • GL_EXT_texture_compression_s3tc + GL_EXT_texture_sRGB.

    OpenGL ES Support
    • GL_EXT_texture_compression_s3tc_srgb.

    • GL_EXT_texture_compression_s3tc + GL_NV_sRGB_formats.

    • GL_NV_texture_compression_s3tc + GL_NV_sRGB_formats.

    WebGL Support
Direct3D
Metal
VK_FORMAT_BC4_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RED_RGTC1.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_compression_rgtc.

    • GL_EXT_texture_compression_rgtc.

    OpenGL ES Support
    • GL_EXT_texture_compression_rgtc.

    WebGL Support
Direct3D
Metal
VK_FORMAT_BC4_SNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SIGNED_RED_RGTC1.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_compression_rgtc.

    • GL_EXT_texture_compression_rgtc.

    OpenGL ES Support
    • GL_EXT_texture_compression_rgtc.

    WebGL Support
Direct3D
Metal
VK_FORMAT_BC5_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RG_RGTC2.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_compression_rgtc.

    • GL_EXT_texture_compression_rgtc.

    OpenGL ES Support
    • GL_EXT_texture_compression_rgtc.

    WebGL Support
Direct3D
Metal
VK_FORMAT_BC5_SNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SIGNED_RG_RGTC2.

    OpenGL Support
    • Core 3.0+.

    • GL_ARB_texture_compression_rgtc.

    • GL_EXT_texture_compression_rgtc.

    OpenGL ES Support
    • GL_EXT_texture_compression_rgtc.

    WebGL Support
Direct3D
Metal
VK_FORMAT_BC6H_UFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT.

    OpenGL Support
    • Core 4.2+.

    • GL_ARB_texture_compression_bptc.

    OpenGL ES Support
    • GL_EXT_texture_compression_bptc.

    WebGL Support
Direct3D
Metal
VK_FORMAT_BC6H_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT.

    OpenGL Support
    • Core 4.2+.

    • GL_ARB_texture_compression_bptc.

    OpenGL ES Support
    • GL_EXT_texture_compression_bptc.

    WebGL Support
Direct3D
Metal
VK_FORMAT_BC7_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_BPTC_UNORM.

    OpenGL Support
    • Core 4.2+.

    • GL_ARB_texture_compression_bptc.

    OpenGL ES Support
    • GL_EXT_texture_compression_bptc.

    WebGL Support
Direct3D
Metal
VK_FORMAT_BC7_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM.

    OpenGL Support
    • Core 4.2+.

    • GL_ARB_texture_compression_bptc.

    OpenGL ES Support
    • GL_EXT_texture_compression_bptc.

    WebGL Support
Direct3D
Metal
VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGB8_ETC2.

    OpenGL Support
    • Core 4.3+.

    • GL_ARB_ES3_compatibility.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ETC2.

    OpenGL Support
    • Core 4.3+.

    • GL_ARB_ES3_compatibility.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2.

    OpenGL Support
    • Core 4.3+.

    • GL_ARB_ES3_compatibility.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2.

    OpenGL Support
    • Core 4.3+.

    • GL_ARB_ES3_compatibility.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA8_ETC2_EAC.

    OpenGL Support
    • Core 4.3+.

    • GL_ARB_ES3_compatibility.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC.

    OpenGL Support
    • Core 4.3+.

    • GL_ARB_ES3_compatibility.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_EAC_R11_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_R11_EAC.

    OpenGL Support
    • Core 4.3+.

    • GL_ARB_ES3_compatibility.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_EAC_R11_SNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SIGNED_R11_EAC.

    OpenGL Support
    • Core 4.3+.

    • GL_ARB_ES3_compatibility.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_EAC_R11G11_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RG11_EAC.

    OpenGL Support
    • Core 4.3+.

    • GL_ARB_ES3_compatibility.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_EAC_R11G11_SNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SIGNED_RG11_EAC.

    OpenGL Support
    • Core 4.3+.

    • GL_ARB_ES3_compatibility.

    OpenGL ES Support
    • Core 3.0+.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_4x4_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_4x4_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_4x4_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_4x4_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_5x4_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_5x4_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_5x4_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_5x4_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_5x5_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x5x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_5x5_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_5x5_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x5x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x5x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_5x5_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_6x5_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x5x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_6x5_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_6x5_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x5x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x5x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_6x5_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_6x6_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x6x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_6x6_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_6x6_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x6x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x6x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_6x6_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_8x5_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 8x5x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_8x5_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_8x5_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 8x5x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 8x5x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_8x5_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_8x6_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 8x6x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_8x6_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_8x6_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 8x6x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 8x6x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_8x6_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_8x8_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 8x8x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_8x8_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_8x8_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 8x8x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 8x8x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_8x8_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_10x5_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 10x5x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_10x5_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_10x5_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 10x5x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 10x5x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_10x5_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_10x6_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 10x6x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_10x6_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_10x6_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 10x6x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 10x6x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_10x6_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_10x8_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 10x8x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_10x8_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_10x8_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 10x8x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 10x8x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_10x8_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_10x10_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 10x10x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_10x10_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_10x10_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 10x10x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 10x10x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_10x10_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_12x10_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 12x10x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_12x10_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_12x10_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 12x10x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 12x10x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_12x10_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_12x12_UNORM_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 12x12x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_12x12_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_12x12_SRGB_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 12x12x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_ldr.

    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 12x12x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_12x12_KHR.

    OpenGL Support
    • GL_KHR_texture_compression_astc_hdr.

    OpenGL ES Support
    • GL_KHR_texture_compression_astc_hdr.

    • GL_OES_texture_compression_astc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 3x3x3.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_3x3x3_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 3x3x3.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 3x3x3.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_3x3x3_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_4x3x3_UNORM_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x3x3.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_4x3x3_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x3x3.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_4x3x3_SFLOAT_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x3x3.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_4x3x3_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_4x4x3_UNORM_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x3.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_4x4x3_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x3.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_4x4x3_SFLOAT_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x3.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_4x4x3_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_4x4x4_UNORM_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x4.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_4x4x4_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x4.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_4x4x4_SFLOAT_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x4.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_4x4x4_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_5x4x4_UNORM_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x4x4.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_5x4x4_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x4x4.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_5x4x4_SFLOAT_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x4x4.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_5x4x4_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_5x5x4_UNORM_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x5x4.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_5x5x4_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x5x4.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_5x5x4_SFLOAT_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x5x4.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_5x5x4_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_5x5x5_UNORM_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x5x5.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_5x5x5_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x5x5.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_5x5x5_SFLOAT_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 5x5x5.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_5x5x5_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_6x5x5_UNORM_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x5x5.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_6x5x5_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x5x5.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_6x5x5_SFLOAT_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x5x5.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_6x5x5_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_6x6x5_UNORM_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x6x5.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_6x6x5_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x6x5.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_6x6x5_SFLOAT_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x6x5.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_6x6x5_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x6x6.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_6x6x6_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x6x6.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 6x6x6.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_ASTC_6x6x6_OES.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_OES_texture_compression_astc.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 8x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_IMG_texture_compression_pvrtc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_IMG_texture_compression_pvrtc.

    WebGL Support
Direct3D
  • No mapping available.

Metal
VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 8x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_IMG_texture_compression_pvrtc2.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_IMG_texture_compression_pvrtc2.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 8x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_EXT_pvrtc_sRGB.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_EXT_pvrtc_sRGB.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 8x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_EXT_pvrtc_sRGB + GL_IMG_texture_compression_pvrtc2.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 4x4x1.

OpenGL
  • glInternalFormat: GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG.

    OpenGL Support
    • None.

    OpenGL ES Support
    • GL_EXT_pvrtc_sRGB + GL_IMG_texture_compression_pvrtc2.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_A4R4G4B4_UNORM_PACK16
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA4.

  • glFormat: GL_BGRA.

  • glType: GL_UNSIGNED_SHORT_4_4_4_4_REV.

    OpenGL Support
    • Core 1.2+.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
Metal
  • No mapping available.

VK_FORMAT_A4B4G4R4_UNORM_PACK16
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGBA4.

  • glFormat: GL_RGBA.

  • glType: GL_UNSIGNED_SHORT_4_4_4_4_REV.

    OpenGL Support
    • Core 1.2+.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR
Layout
  • Type Size: 2.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_RGB5_A1.

  • glFormat: GL_RGBA.

  • glType: GL_UNSIGNED_SHORT_1_5_5_5_REV.

    OpenGL Support
    • Core 1.2+.

    OpenGL ES Support
    • None.

    WebGL Support
    • None.

Direct3D
  • No mapping available.

Metal
  • No mapping available.

VK_FORMAT_A8_UNORM_KHR
Layout
  • Type Size: 1.

  • Texel Block Dimensions: 1x1x1.

OpenGL
  • glInternalFormat: GL_ALPHA8_EXT.

  • glFormat: GL_ALPHA.

  • glType: GL_UNSIGNED_BYTE.

    OpenGL Support
    • Core 1.2+.

    OpenGL ES Support
    • Core 1.0+.

    WebGL Support
    • Core 1.0+.

Direct3D
Metal

Appendix C: BasisLZ Global Data

BasisLZ combines encoding to a block-compressed format, that can be easily transcoded to various GPU-native block-compressed formats, with lossless supercompression. Supercompression is accomplished by conditioning the block-compressed representation for entropy encoding then Huffman encoding the result. BasisLZ creates a global codebook referenced by each supercompressed image that contains the processed endpoint and selector data from the block-compression and the Huffman tables. The global data block contains this codebook.

It also contains an array of image descriptors with flags for each image and the offset and length within the mip level of the data for that image.

The global data structure is designed to accommodate various transcodable block-compressed formats. The format in use is indicated by the Data Format Descriptor. Currently BasisLZ only supports one, ETC1S (a subset of ETC1, see Section 21.1 of [KDF13]). ETC1S is a common subset of many GPU-native formats.

The bitstreams for endpoints, selectors, Huffman tables and the image data are specific to the transcodable format in use. Those for ETC1S are defined in Appendix D, BasisLZ/ETC1S Bitstream Specification. These bitstreams have to be decoded to reconstruct the base images.

The structure of the global data is shown below.

BasisLZ Global Data Structure
UInt16 endpointCount;
UInt16 selectorCount;
UInt32 endpointsByteLength;
UInt32 selectorsByteLength;
UInt32 tablesByteLength;
UInt32 extendedByteLength;

ImageDesc[imageCount] imageDescs;

Byte[endpointsByteLength] endpointsData
Byte[selectorsByteLength] selectorsData
Byte[tablesByteLength] tablesData
Byte[extendedByteLength] extendedData

ImageDesc is the following structure.

ImageDesc
UInt32 imageFlags
UInt32 rgbSliceByteOffset
UInt32 rgbSliceByteLength
UInt32 alphaSliceByteOffset
UInt32 alphaSliceByteLength

Descriptions in the imageDescs array are in the order layer, face and z_slice as if arranged by the following pseudo code.

for each level in max(levelCount, 1)
    for each layer in max (layerCount, 1)
        for each face in faceCount // 1 or 6
            for each z_slice in max((pixelDepth of level), 1)

imageCount is the total number of images in the Mip Level Array.

imageCount may be calculated as follows:

int imageCount = max(layerCount, 1) * faceCount * layerPixelDepth;

// where layerPixelDepth can be derived as
int layerPixelDepth = max(pixelDepth, 1);
for(int i = 1; i < levelCount; i++)
    layerPixelDepth += max(pixelDepth >> i, 1);

There must be no trailing bytes in the global data section after the extendedData field, i.e., the following condition must always be true:

sgdByteLength == 20 +
                 20 * imageCount +
                 endpointsByteLength +
                 selectorsByteLength +
                 tablesByteLength +
                 extendedByteLength

C.1. endpointCount

The number of endpoints in endpointsData.

C.2. selectorCount

The number of selectors in selectorsData.

C.3. endpointsByteLength

The length of endpointsData.

C.4. selectorsByteLength

The length of selectorsData.

C.5. tablesByteLength

The length of tablesData.

C.6. extendedByteLength

The length of extendedData. Must be 0 if the data format descriptor colorModel is KHR_DF_MODEL_ETC1S (= 163).

C.7. ImageDesc

C.7.1. imageFlags

Flags giving information about an individual image. The following flag is valid:

isPFrame = 0x02

BasisLZ/ETC1S supports inter-frame (video) encoding for 2D slices. If isPFrame is set the image (frame) is a P frame. That is, it refers to the previous image of an animation sequence. All other images are I frames. Only animation sequences can have P frames. See Section 4.4, “Animation Sequence” for details.

C.7.2. rgbSliceByteOffset, rgbSliceByteLength

The offset of the start of the RGB slice within the levelImages of its mip level and its byte length. The offset of levelImages within the file is given in the Level Index.

rgbSliceByteLength must not be zero.

rgbSliceByteOffset + rgbSliceByteLength must not be greater than the byte length of the corresponding mip level.

C.7.3. alphaSliceByteOffset, alphaSliceByteLength

The offset of the start of the alpha slice within the levelImages of its mip level and its byte length.

If there is only one slice these values must be 0. For ETC1S with the Data Format Descriptor color model of KHR_DF_MODEL_ETC1S this corresponds to the DFD having only one sample. (As the format is supercompressed bytesPlane fields can’t be used to determine the number of planes.)

If the second slice is present, alphaSliceByteLength must not be zero.

alphaSliceByteOffset + alphaSliceByteLength must not be greater than the byte length of the corresponding mip level.

C.8. endpointsData

Compressed endpoints data. The bitstream of this for ETC1S is described in Section D.2, “ETC1S Endpoint Codebooks”.

C.9. selectorsData

Compressed selectors data. The bitstream of this for ETC1S is described in Section D.3, “ETC1S Selector Codebooks”.

C.10. tablesData

Huffman tables data. The format of this data for ETC1S is described in Section D.4, “ETC1S Slice Huffman Tables”.

C.11. extendedData

Extended data. This is not used for ETC1S.

Appendix D: BasisLZ/ETC1S Bitstream Specification

BasisLZ is a lossless compression scheme for ETC1S block data, which is based off Vector Quantization. VQ is applied to the ETC1S color endpoint/intensity values and texel selectors, each treated as two separate vectors. The two codebooks are global and shared across all mipmap levels, cubemap faces, animation frames, etc. There are two VQ codebook indices per block, which are compressed using a combination of canonical Huffman coding, Run-Length Encoding, DPCM coding, and an approximate Move to Front transform.

It stores different ETC1S format fields in separately-compressed data streams thus reducing the transmission size.

BasisLZ data comprises:

  • global endpoint array, where each element is a base color and an intensity table index pair;

  • global selectors array, where each element contains 16 values, called ETC1 “pixel index bits” in KDFS;

  • four global Huffman tables used for slice decoding;

  • per-slice block data encoded as references to the endpoint and selectors arrays.

The following sections describe each section’s payload independently. After decoding them and recovering per-block endpoint and selector values, the decoder can build ETC1S blocks. See the KDFS for ETC1S definition and bitstream.

D.1. Compressed Huffman Tables

Many BasisLZ compressed sections use multiple Huffman tables. The process described in this section defines read_huffman_table() routine in the subsequent sections of this specification.

Huffman codes are stored in each output byte in LSB to MSB order.

Huffman coding in BasisLZ is compatible with the canonical Huffman methods used by Deflate encoders/decoders. Section 3.2.2 of Deflate - RFC 1951, which describes how to compute the value of each Huffman code given an array of symbol codelengths.

A BasisLZ Huffman table consists of 1 to 16383 symbols. Each compressed Huffman table is described by an array of symbol code lengths in bits. The table’s symbol code lengths are themselves RLE+Huffman coded, just like Deflate.

Each table begins with a small fixed header followed by the code lengths for the small Huffman table which is used to send the compressed codelengths.

total_used_syms                                 b(14)
num_codelength_codes                            b(5)
for (int i = 0; i < num_codelength_codes; i++)
{
    code_length_code_sizes[codes_order[i]]      b(3)
}

There are a maximum of 21 symbols in a compressed Huffman code length table, so num_codelength_codes must be in [1..21] range.

The code lengths are reordered to potentially reduce the number of used codes:

codes_order = {
    17, 18, 19, 20, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, 16
};

A canonical Huffman decoding table (of up to 21 symbols) is built from these code lengths.

Immediately following this data are the Huffman symbols (sometimes intermixed with raw bits) which describe how to unpack the codelengths of each symbol in the Huffman table. This is a slightly modified version of dynamic Huffman codes described in RFC 1951, Section 3.2.7.

  • Symbols [0..16] indicate a specific symbol code length in bits, so maximum supported Huffman code size is 16 bits.

  • Symbol 17 indicates a short run of symbols with 0 bit code lengths. 3 bits are sent after this symbol, which indicates the run’s size after adding the minimum size of 3, so the run has 3..10 symbols.

  • Symbol 18 indicates a long run of symbols with 0 bit code lengths. 7 bits are sent after this symbol, which indicates the run’s size after adding the minimum size of 11, so the run has 11..138 symbols.

  • Symbol 19 indicates a short run of symbols that repeat the previous symbol’s code length. 2 bits are sent after this symbol, which indicates the number of times to repeat the previous symbol’s code length, after adding the minimum size of 3, so the run has 3..6 symbols. Cannot be the first symbol, and the previous symbol cannot have a code length of 0.

  • Symbol 20 indicates a short run of symbols that repeat the previous symbol’s code length. 7 bits are sent after this symbol, which indicates the number of times to repeat the previous symbol’s code length, after adding the minimum size of 7, so the run has 7..134 symbols. Cannot be the first symbol, and the previous symbol cannot have a code length of 0.

There should be exactly total_used_syms code lengths stored in the compressed Huffman table. If not, the stream is either corrupted or invalid.

After all the symbol codelengths are uncompressed, the symbol codes can be computed and the canonical Huffman decoding tables can be built.

decode_huffman(model) in the sections below denotes reading the Huffman-encoded value from a current bitstream position using the table model.

D.2. ETC1S Endpoint Codebooks

The byte offset and the byte length (endpointsByteLength) of the endpoint codebook section (endpointsData) as well as the number of endpoint entries (called endpointCount) are defined by the BasisLZ Global Data Structure.

D.2.1. Header

At the beginning of the compressed endpoint codebook section are four compressed Huffman tables, stored using the procedure outlined in Section D.1, “Compressed Huffman Tables” and a 1-bit flag signalling whether endpoints have three color channles or one.

colorDeltaModel0     read_huffman_table()
colorDeltaModel1     read_huffman_table()
colorDeltaModel2     read_huffman_table()
intenDeltaModel      read_huffman_table()
isGrayscale          b(1)

D.2.2. Endpoints

Immediately after the header is the compressed color endpoint codebook data (inten[endpointCount], red[endpointCount], green[endpointCount] and blue[endpointCount] arrays). A simple form of DPCM (Delta Pulse Code Modulation) coding is used to send the ETC1S intensity table indices and color values. Here is the procedure to decode the endpoint codebook:

  1. Set initial values:

    1. Let the previous intensity index prevInten be 0.

    2. If isGrayscale is 1, let prevLuma be 16.

    3. Else, let prevRed, prevGreen and prevBlue be 16.

  2. For i from 0 to endpointCount:

    1. Decode table intensity index:

      1. Read an intenDelta value using the intenDeltaModel Huffman table.

      2. Set inten[i] to ((prevInten + intenDelta) & 7).

      3. Set prevInten to inten[i].

    2. Decode endpoint color value:

      1. Depending on the isGrayscale value, read lumaDelta or {redDelta, greenDelta and blueDelta} using the Huffman tables depending on the prevLuma or {prevRed, prevGreen and prevBlue} ranges:

        • colorDeltaModel0 for values in [0..9];

        • colorDeltaModel1 for values in [10..21];

        • colorDeltaModel2 for values in [22..31].

      2. Sum deltas with the previous values as value = (prevValue + valueDelta) & 31.

      3. Set red[i], green[i] and blue[i] from the decoded values. For grayscale endpoints, set all channels to the luma value.

      4. Update prevLuma or {prevRed, prevGreen and prevBlue}.

  3. The rest of the section’s data (if any) can be ignored.

D.3. ETC1S Selector Codebooks

Selector entries contain 16 2-bit values that map to the ETC1 pixel index bits as:

Selector Value Pixel Index MSB Pixel Index LSB Modifier

0

1

1

-b

1

1

0

-a

2

0

0

+a

3

0

1

+b

The byte offset and the byte length (selectorsByteLength) of the selector codebook section (selectorsData) as well as the number of selector entries (called selectorCount) are defined by the BasisLZ Global Data Structure.

D.3.1. Header

The first two bits are reserved and must always be set to 0. The input is invalid otherwise.

The third bit indicates if the selector codebook is stored in raw form (uncompressed). If it’s unset, the deltaSelectorModel Huffman table will immediately follow the third bit.

D.3.2. Selectors

Each selector entry is a 4x4 grid, ordered left-to-right, top-to-bottom. Each row is packed to 8 bits, thus each selector entry could be expressed as four 8-bit bytes. Each packed row corresponds to four 2-bit values. The first (left) value of each row starts at the LSB (least significant bit) of each 8-bit group.

X0 X1 X2 X3

Y0

s0[1:0]

s0[3:2]

s0[5:4]

s0[7:6]

Y1

s1[1:0]

s1[3:2]

s1[5:4]

s1[7:6]

Y2

s2[1:0]

s2[3:2]

s2[5:4]

s2[7:6]

Y3

s3[1:0]

s3[3:2]

s3[5:4]

s3[7:6]

When isUncompressed bit is set, all selectors are stored uncompressed. When that bit is unset, only the first selector entry is stored uncompressed while all subsequent entries are DPCM coded (by using four XOR-deltas for each subsequent selector entry) with Huffman coding.

Sample implementation
zeros                                                  b(2)
isUncompressed                                         b(1)
if (isUncompressed)
{
    for (int i = 0; i < selectorCount; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            selector[i][j]                             b(8)
        }
    }
}
else
{
    deltaSelectorModel                                 read_huffman_table()

    for (int j = 0; j < 4; j++)
    {
        selector[0][j]                                 b(8)
    }

    for (int i = 1; i < selectorCount; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            selector[i][j] =
                decode_huffman(deltaSelectorModel) ^
                selector[i - 1][j]
        }
    }
}

Any bytes in this section following the selector codebook bits can be safely ignored.

D.4. ETC1S Slice Huffman Tables

Each ETC1S slice is compressed with four Huffman tables (tablesData) stored using the procedure outlined in Section D.1, “Compressed Huffman Tables”. Their byte offset and byte length (tablesByteLength) are defined by the BasisLZ Global Data Structure.

Following the last Huffman table are 13-bits indicating the size of the selector history buffer.

endpointPredModel               read_huffman_table()
endpointDeltaModel              read_huffman_table()
selectorModel                   read_huffman_table()
selectorHistoryBufRleModel      read_huffman_table()
selectorHistoryBufSize          b(13)

Any remaining bits may be safely ignored.

D.5. ETC1S Slice Decoding

The data for each mip level is a set of ETC1S slices. The corresponding element of the imageDescs array in the BasisLZ Global Data Structure provides slice locations within the mip level data.

ETC1S slices consist of a compressed 2D array of ETC1S blocks, compressed in the order indicated by Section 5.2, “KTXorientation” metadata (defaults to top-down/left-right raster order). For an animation sequence, the previous slice’s already decoded contents may be referred to when blocks are encoded using Conditional Replenishment (also known as “skip blocks”).

Each ETC1S block is encoded by using references to the color endpoint codebook and the selector codebook. The following sections describe the helper procedures used by the decoder, and how the array of ETC1S blocks is actually decoded.

D.5.1. ETC1S Approximate Move to Front Routines

An approximate Move to Front (MTF) approach is used to efficiently encode the selector codebook references. Here is the C++ example class for approximate MTF decoding:

Example implementation
class approx_move_to_front
{
public:
    approx_move_to_front(uint32_t n)
    {
        init(n);
    }

    void init(uint32_t n)
    {
        m_values.resize(n);
        m_rover = n / 2;
    }

    size_t size() const { return m_values.size(); }

    const int& operator[] (uint32_t index) const { return m_values[index]; }
          int operator[] (uint32_t index)        { return m_values[index]; }

    void add(int new_value)
    {
        m_values[m_rover++] = new_value;
        if (m_rover == m_values.size())
        {
            m_rover = (uint32_t)m_values.size() / 2;
        }
    }

    void use(uint32_t index)
    {
        if (index)
        {
            int x = m_values[index / 2];
            int y = m_values[index];
            m_values[index / 2] = y;
            m_values[index] = x;
        }
    }

private:
    std::vector<int> m_values;
    uint32_t m_rover;
};

D.5.2. ETC1S VLC Decoding Procedure

ETC1S slice decoding utilizes a simple Variable Length Coding (VLC) scheme that sends raw bits using chunks of 5 or 8 bits. The MSB of each chunk signals whether there’s another chunk for the current encoded value.

Here is the VLC decoding procedures, get_bits(n) extracts next n bits from the bitstream:

Example implementation
uint32_t decode_vlc4()
{
    uint32_t v = 0;
    uint32_t ofs = 0;

    for ( ; ; )
    {
        uint32_t s = get_bits(5);
        v |= ((s & 0xF) << ofs);
        ofs += 4;

        if ((s & 0x10) == 0)
        {
            break;
        }

        if (ofs >= 32)
        {
            // Invalid encoding
            break;
        }
    }

    return v;
}

uint32_t decode_vlc7()
{
    uint32_t v = 0;
    uint32_t ofs = 0;

    for ( ; ; )
    {
        uint32_t s = get_bits(8);
        v |= ((s & 0x7F) << ofs);
        ofs += 7;

        if ((s & 0x80) == 0)
        {
            break;
        }

        if (ofs >= 32)
        {
            // Invalid encoding
            break;
        }
    }

    return v;
}

D.5.3. ETC1S Slice Block Decoding

The decoder has no knowledge of the orientation of the image it is decoding. It iterates through all the slice blocks in order of increasing memory. The blocks form a num_blocks_x by num_blocks_y grid. The block at num_blocks_x * y starts row y where 0 <= y < num_blocks_y. To simplify the following description, a top-down, left-right raster order is assumed. Left refers to the previous block in memory and above to the block num_blocks_x * 8 bytes earlier in memory. Each block is represented by an index into the color endpoint codebook and another index into the selector endpoint codebook. The endpoint codebook contains each ETC1S block’s base RGB color and intensity table information, and the selector codebook contains the 4x4 texel selector entry (which are 2-bits each) information. This is all the information needed to fully represent the texels within each block.

The decoding procedure loops over all the blocks in memory order, and decodes the endpoint and selector indices used to represent each block. The decoding procedure is complex enough that commented code is best used to describe it.

The compressed format allows the encoder to reuse the endpoint index used by the block to the left, the block immediately above the current block, or the block to the upper left (if the slice is not a P-frame). Alternately, the encoder can send a Huffman-coded DPCM encoded index relative to the previously used endpoint index.

Which type of prediction was used by the encoder is controlled by the endpoint prediction indices, which are sent with Huffman coding (using the endpointPredModel table) once every 2x2 blocks.

For P-frames (that have isPFrame flag in imageFlags set, matches is_p_frame flag in the code below) used in animation sequences (matches is_video flag in the code below), the endpoint prediction symbol normally used to refer to the upper left block (endpoint prediction index 2) instead indicates that both the endpoint and selector indices from the previous frame’s block should be reused on the current frame’s block. The endpoint prediction indices are RLE coded, so this allows the encoder to efficiently skip over a large number of unchanged blocks in a video sequence.

The first frame of an animation sequence must be an I-frame.

A KTX file that is not an animation sequence cannot contain P-frames.

Reference implementation
// Constants used by the decoder
const uint32_t ENDPOINT_PRED_TOTAL_SYMBOLS = (4 * 4 * 4 * 4) + 1;
const uint32_t ENDPOINT_PRED_REPEAT_LAST_SYMBOL = ENDPOINT_PRED_TOTAL_SYMBOLS - 1;
const uint32_t ENDPOINT_PRED_MIN_REPEAT_COUNT = 3;

const uint32_t NUM_ENDPOINT_PREDS = 3;
const uint32_t CR_ENDPOINT_PRED_INDEX = NUM_ENDPOINT_PREDS - 1;

// Endpoint/selector codebooks - decoded previously.
endpoint endpoints[endpointCount];
selector selectors[selectorCount];

// Array of per-block values used for endpoint index prediction (enough for 2 rows).
uint16_t [2][num_block_x] block_endpoint_preds;

// Odd rows prediction information for two blocks packed into 4-bit values
uint8_t block_pred_bits[(num_blocks_x + 1) >> 1]

// Some constants and state used during block decoding
const uint32_t SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX = selectorCount;
const uint32_t SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX = selectorHistoryBufSize + SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX;
uint32_t cur_selector_rle_count = 0;

uint32_t cur_pred_bits = 0;
uint32_t prev_endpoint_pred_sym = 0;
uint32_t endpoint_pred_repeat_count = 0;
uint32_t prev_endpoint_index = 0;

// These arrays are only used for texture video. They hold the previous frame's endpoint and selector indices.
uint16_t prev_frame_endpoints[num_blocks_x][num_blocks_y];
uint16_t prev_frame_selectors[num_blocks_x][num_blocks_y];

// Selector history buffer - See Approximate Move to Front Routines
approx_move_to_front selector_history_buf(selectorHistoryBufSize);

// Loop over all slice blocks in raster order
for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++)
{
    // The index into the block_endpoint_preds array
    const uint32_t cur_block_endpoint_pred_array = block_y & 1;

    for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++)
    {
        // Check if we're at the start of a 2x2 block group.
        if ((block_x & 1) == 0)
        {
            // Are we on an even or odd row of blocks?
            if ((block_y & 1) == 0)
            {
                // We're on an even row and column of blocks. Decode the combined endpoint index predictor
                // symbols for 2x2 blocks. This symbol tells the decoder how the endpoints are decoded for
                // each block in a 2x2 group of blocks.

                // Are we in an RLE run?
                if (endpoint_pred_repeat_count)
                {
                    // Inside a run of endpoint predictor symbols.
                    endpoint_pred_repeat_count--;
                    cur_pred_bits = prev_endpoint_pred_sym;
                }
                else
                {
                    // Decode the endpoint prediction symbol, using the "endpoint pred" Huffman table.
                    cur_pred_bits = decode_huffman(endpointPredModel);
                    if (cur_pred_bits == ENDPOINT_PRED_REPEAT_LAST_SYMBOL)
                    {
                        // It's a run of symbols, so decode the count using VLC decoding
                        endpoint_pred_repeat_count = decode_vlc4() + ENDPOINT_PRED_MIN_REPEAT_COUNT - 1;

                        cur_pred_bits = prev_endpoint_pred_sym;
                    }
                    else
                    {
                        // It's not a run of symbols
                        prev_endpoint_pred_sym = cur_pred_bits;
                    }
                }

                // The symbol has enough endpoint prediction information for 4 blocks (2 bits per block),
                // so 8 bits total. Remember the prediction information we should use for the next row of
                // 2 blocks beneath the current block.
                block_pred_bits[block_x >> 1] = (uint8_t)(cur_pred_bits >> 4);
            }
            else
            {
                // We're on an odd row of blocks, so use the endpoint prediction information we previously
                // stored on the previous even row.
                cur_pred_bits = block_pred_bits[block_x >> 1];
            }
        }

        // Decode the current block's endpoint and selector indices.
        uint32_t endpoint_index, selector_index = 0;

        // Get the 2-bit endpoint prediction index for this block.
        const uint32_t pred = cur_pred_bits & 3;

        // Get the next block's endpoint prediction bits ready.
        cur_pred_bits >>= 2;

        // Now check to see if we should reuse a previously encoded block's endpoints.
        if (pred == 0)
        {
            // Reuse the left block's endpoint index
            assert(block_x > 0);
            endpoint_index = prev_endpoint_index;
        }
        else if (pred == 1)
        {
            // Reuse the upper block's endpoint index
            assert(block_y > 0)
            endpoint_index = block_endpoint_preds[cur_block_endpoint_pred_array ^ 1][block_x];
        }
        else if (pred == 2)
        {
            if (is_p_frame)
            {
                // If it's a P-frame, reuse the previous frame's endpoint index, at this block.
                assert(pred == CR_ENDPOINT_PRED_INDEX);
                endpoint_index = prev_frame_endpoints[block_x][block_y];
                selector_index = prev_frame_selectors[block_x][block_y];
            }
            else
            {
                // Reuse the upper left block's endpoint index.
                assert((block_x > 0) && (block_y > 0));
                endpoint_index = block_endpoint_preds[cur_block_endpoint_pred_array ^ 1][block_x - 1];
            }
        }
        else
        {
            // We need to decode and apply a DPCM encoded delta to the previously used endpoint index.
            // This uses the delta endpoint Huffman table.
            const uint32_t delta_sym = decode_huffman(endpointDeltaModel);

            endpoint_index = delta_sym + prev_endpoint_index;

            // Wrap around if the index goes beyond the end of the endpoint codebook
            if (endpoint_index >= endpointCount)
                endpoint_index -= endpointCount;
        }

        // Remember the endpoint index we used on this block, so the next row can potentially reuse the index.
        block_endpoint_preds[cur_block_endpoint_pred_array][block_x] = (uint16_t)endpoint_index;

        // Remember the endpoint index used
        prev_endpoint_index = endpoint_index;

        // Now we have fully decoded the ETC1S endpoint codebook index, in endpoint_index.

        // Now decode the selector index.
        const uint32_t MAX_SELECTOR_HISTORY_BUF_SIZE = 64;
        const uint32_t SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH = 3;
        const uint32_t SELECTOR_HISTORY_BUF_RLE_COUNT_BITS = 6;
        const uint32_t SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL = (1 << SELECTOR_HISTORY_BUF_RLE_COUNT_BITS);

        // Decode selector index, unless it's a P-frame and the endpoint predictor indicated that the
        // block's endpoints and selectors were reused from the previous frame.
        if ((!is_p_frame) || (pred != CR_ENDPOINT_PRED_INDEX))
        {
            int selector_sym;

            // Are we in a selector RLE run?
            if (cur_selector_rle_count > 0)
            {
                // Handle selector RLE run.
                cur_selector_rle_count--;

                selector_sym = selectorCount;
            }
            else
            {
                // Decode the selector symbol, using the selector Huffman table.
                selector_sym = decode_huffman(selectorModel);

                // Is it a run?
                if (selector_sym == static_cast<int>(SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX))
                {
                    // Decode the selector run's size, using the selector history buf RLE Huffman table.
                    int run_sym = decode_huffman(selectorHistoryBufRleModel);

                    // Is it a very long run?
                    if (run_sym == (SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL - 1))
                        cur_selector_rle_count = decode_vlc7() + SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;
                    else
                        cur_selector_rle_count = run_sym + SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;

                    selector_sym = selectorCount;

                    cur_selector_rle_count--;
                }
            }

            // Is it a reference into the selector history buffer?
            if (selector_sym >= selectorCount)
            {
                assert(selectorHistoryBufSize > 0);

                // Compute the history buffer index
                int history_buf_index = selector_sym - selectorCount;

                assert(history_buf_index < selector_history_buf.size());

                // Access the history buffer
                selector_index = selector_history_buf[history_buf_index];

                // Update the history buffer
                if (history_buf_index != 0)
                    selector_history_buf.use(history_buf_index);
            }
            else
            {
                // It's an index into the selector codebook
                selector_index = selector_sym;

                // Add it to the selector history buffer
                if (m_selector_history_buf_size)
                    selector_history_buf.add(selector_index);
            }
        }

        // For texture video, remember the endpoint and selector indices used by the block on this frame,
        // for later reuse on the next frame.
        if (is_video)
        {
            prev_frame_endpoints[block_x][block_y] = endpoint_index;
            prev_frame_selectors[block_x][block_y] = selector_index;
        }

        // The block is fully decoded here. The codebook indices are endpoint_index and selector_index.
        // Make sure they are valid
        assert((endpoint_index < endpointCount) && (selector_index < selectorCount));

    } // block_x
} // block_y

At this point, the decoder has decoded each block’s endpoint and selector codebook indices. It can now fetch the actual ETC1S endpoints/selectors from the codebooks and write out ETC1S texture data, or it can immediately transcode the ETC1S data to another GPU texture format.

Appendix E: Registered Vendor Key/Value Pairs

This appendix is non-normative.

There are currently no registered key/value pairs.

Appendix F: Changes compared to KTX version 1

  • vkFormat added.

  • OpenGL format information fields removed.

  • Data format descriptor added.

  • Supercompression added.

  • Transcodable format support added.

  • Files always little endian.

  • Swizzle and writer id metadata added.

  • Row and cube padding removed.

  • Mip level alignment (mipPadding) changed to match GPU requirements.

  • Mip level order changed so smallest level is first.

Revision History

Document Revision Date Remark

pr-draft1

2020-08-01

  • Remove width & height restrictions.

  • Update draft Media Type registration.

pr-draft2

2020-09-04

  • Update status to ratified.

  • Add KTXwriteScParams.

  • Update logo.

  • Make clarifications in size restriction tips.

  • Add a tip about byteLength.

0

2021-04-18

  • Polish abstract.

  • Allow KTXanimData for any kind of array texture.

  • Add VK_EXT_4444_formats to mapping.

  • Remove “required” from key-value data.

  • Bug fixes in ETC1S video spec.

  • Define coordinate system for cubemaps.

1

2022-12-09

  • Disallow 3D block-compressed formats for non 3D textures.

  • Adjust DFD transfer function restrictions.

  • Fix VK_FORMAT_X8_D24_UNORM_PACK32 mapping entry.

  • Clarify valid mipPadding length.

  • Define valid values for ETC1S slice byte lengths and offsets.

  • Clarify descriptions of ETC1S slices.

  • Clarify 422 formats block size.

  • Disallow block-compressed formats for 1D textures.

  • Clarify mip-level data layouts.

  • Define valid size of Supercompression Global Data for BasisLZ.

  • Remove non-normative notice from Appendix A.

  • Clarify format of KTXwriter and KTXwriterScParams metadata values.

  • Remove single-plane formats from the prohibited formats list.

  • Clarify valid usage of format mapping and KTXcubemapIncomplete metadata.

  • Fix block_pred_bits size.

  • Minor formatting and typo fixes.

2

2023-09-07

  • Provide detailed instructions for how to register supercompression schemes and metadata.

  • Adjust D24_UNORM_S8_UINT description.

  • Fix description of block ordering in ETC1S slices and clarify that decoder has no knowledge of image orientation.

  • Clarify level data layout for BasisLz/ETC1S.

  • Fix list of data that comprises a mip level.

  • Fix missing max(1, …​) in num_blocks_x calculation.

  • Clarify that KTXwriterScParams can be used for ASTC and other block-compression scheme encoding parameters.

  • Add VK_KHR_maintenance5 formats to GL formats mapping.

  • Increase document width from 55em to 60em.

3

2024-02-20

  • Fix typeSize for formats with _nPACKxx suffix.

  • Prohibit YCbCr 2-plane 444 formats recently added to Vulkan.

  • Allow A8B8G8R8*PACK32 formats.

Acknowledgements

Thanks to Dominic Agoro-Ombaka for designing the KTX logo and icons.

Thanks to Rich Geldreich for inventing transcodable textures and BasisLZ and providing documentation of them.

Thanks to Alexey Knyazev for polishing Rich’s documentation and for enormous help tightening the specification and removing potential conflicts.

Thanks to David Wilkinson for chairing the initial effort.