| Name |
| |
| EXT_texture_compression_bptc |
| |
| Name Strings |
| |
| GL_EXT_texture_compression_bptc |
| |
| Contact |
| |
| Daniel Koch, NVIDIA Corporation (dkoch 'at' nvidia.com) |
| |
| Contributors |
| |
| Contributors to ARB_texture_compression_bptc |
| Daniel Koch, NVIDIA |
| Jason Schmidt, NVIDIA |
| Slawomir Grajewski, Intel |
| |
| Notice |
| |
| Copyright (c) 2010-2013 The Khronos Group Inc. Copyright terms at |
| http://www.khronos.org/registry/speccopyright.html |
| |
| Status |
| |
| Complete. |
| |
| Version |
| |
| Last Modified Date: April 7, 2017 |
| Revision: 1 |
| |
| Number |
| |
| OpenGL ES Extension #287 |
| |
| Dependencies |
| |
| OpenGL ES 3.0 is required. |
| |
| This extension is written against the OpenGL ES 3.2 Specification |
| (Nov. 3, 2016). |
| |
| Overview |
| |
| This extension provides additional texture compression functionality |
| specific to the BPTC and BPTC_FLOAT compressed texture formats (called BC7 |
| and BC6H respectively in Microsoft's DirectX API). |
| |
| Traditional block compression methods as typified by s3tc and latc |
| compress a block of pixels into indicies along a gradient. This works well |
| for smooth images, but can have quality issues along sharp edges and |
| strong chrominance transitions. To improve quality in these problematic |
| cases, the BPTC formats can divide each block into multiple partitions, |
| each of which are compressed using an independent gradient. |
| |
| In addition, it is desirable to directly support high dynamic range |
| imagery in compressed formats, which is accomplished by the BPTC_FLOAT |
| formats. |
| |
| IP Status |
| |
| No known IP claims. |
| |
| New Procedures and Functions |
| |
| None. |
| |
| New Tokens |
| |
| Accepted by the <internalformat> parameter of TexImage2D, TexImage3D, |
| TexStorage2D, TexStorage3D, CompressedTexImage2D, and CompressedTexImage3D |
| and the <format> parameter of CompressedTexSubImage2D and |
| CompressedTexSubImage3D: |
| |
| COMPRESSED_RGBA_BPTC_UNORM_EXT 0x8E8C |
| COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT 0x8E8D |
| COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT 0x8E8E |
| COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT 0x8E8F |
| |
| |
| Additions to Chapter 8 of the OpenGL ES 3.2 Specification (Rasterization) |
| |
| Add to Section 8.4, Table 8.2: Valid combinations of format, type, |
| and sized internalFormat |
| |
| External |
| Bytes |
| Format Type Per Pixel Internal Format |
| ------ ------------- --------- -------------------------------------- |
| RGBA UNSIGNED_BYTE 8 COMPRESSED_RGBA_BPTC_UNORM_EXT |
| RGBA UNSIGNED_BYTE 8 COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT |
| RGB FLOAT 8 COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT |
| RGB FLOAT 8 COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT |
| |
| |
| Add to Section 8.7, Table 8.17: Compressed internal formats |
| |
| Compressed Internal Format Base Block Border 3D Cube |
| Internal Width x Type Tex Map |
| Format Height Array |
| Tex |
| --------------------------------- -------- ------- ------ --- ----- |
| COMPRESSED_RGBA_BPTC_UNORM_EXT RGBA 4x4 unorm yes yes |
| COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT RGBA 4x4 unorm yes yes |
| COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT RGB 4x4 float yes yes |
| COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT RGB 4x4 float yes yes |
| |
| |
| Add to Section 8.7, Compressed Texture Images (adding to the end of the |
| Errors section) |
| |
| If <internalformat> is COMPRESSED_RGBA_BPTC_UNORM_EXT, |
| COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, |
| COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, or |
| COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT the compressed texture is stored |
| using the specified BPTC compressed texture image format. The BPTC |
| texture compression algorithm supports only 2D images without borders, |
| though 3D images can be compressed as multiple slices of compressed 2D |
| images. CompressedTexImage2D and CompressedTexImage3D will produce an |
| INVALID_OPERATION error if <border> is non-zero. |
| |
| If the internal format of the texture image being modified is |
| COMPRESSED_RGBA_BPTC_UNORM_EXT, COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, |
| COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, or |
| COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT the texture is stored using the |
| specified BPTC compressed texture image formats. Since BPTC |
| images are easily edited along 4x4 texel boundaries, the limitations on |
| CompressedTexSubImage2D and CompressedTexSubImage3D are relaxed. |
| CompressedTexSubImage2D and CompressedTexSubImage3D will result in an |
| INVALID_OPERATION error only if one of the following conditions occurs: |
| |
| * <width> is not a multiple of four, and <width> plus <xoffset> is not |
| equal to TEXTURE_WIDTH; |
| |
| * <height> is not a multiple of four, and <height> plus <yoffset> is |
| not equal to TEXTURE_HEIGHT; or |
| |
| * <xoffset> or <yoffset> is not a multiple of four. |
| |
| The contents of any 4x4 block of texels of a BPTC compressed texture image |
| that does not intersect the area being modified are preserved during valid |
| TexSubImage2D/3D calls. |
| |
| Additions to Appendix C of the OpenGL ES 3.2 Specification (Compressed Texture |
| Image Formats) |
| |
| Add a new Section C.4 (BPTC Compressed Texture Image Formats) |
| |
| BPTC formats are described in the "BPTC Compressed Texture Image Formats" |
| chapter of the Khronos Data Format Specification. The mapping between |
| OpenGL ES BPTC formats and that specification is shown in table C.4. |
| |
| OpenGL ES format Data Format Specification |
| Description |
| ------------------------------- ------------------------- |
| COMPRESSED_RGBA_BPTC_UNORM_EXT BC7 |
| COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT BC7 sRGB |
| COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT BC6H signed |
| COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT BC6H unsigned |
| |
| Additions to the AGL/GLX/WGL/EGL Specifications |
| |
| None. |
| |
| Errors |
| |
| INVALID_OPERATION is generated by CompressedTexImage2D if |
| <internalformat> is COMPRESSED_RGBA_BPTC_UNORM_EXT, |
| COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, |
| COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, or |
| COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT and <border> is not equal to zero. |
| |
| INVALID_OPERATION is generated by TexSubImage2D if |
| TEXTURE_INTERNAL_FORMAT is COMPRESSED_RGBA_BPTC_UNORM_EXT, |
| COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, |
| COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, or |
| COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT and any of the following apply: |
| |
| * <width> is not a multiple of four, <width> plus <xoffset> is not |
| equal to TEXTURE_WIDTH, and either <xoffset> or <yoffset> is |
| non-zero; |
| |
| * <height> is not a multiple of four, <height> plus <yoffset> is not |
| equal to TEXTURE_HEIGHT, and either <xoffset> or <yoffset> is |
| non-zero; or |
| |
| * <xoffset> or <yoffset> is not a multiple of four. |
| |
| INVALID_OPERATION is generated by CompressedTexSubImage2D if |
| TEXTURE_INTERNAL_FORMAT is COMPRESSED_RGBA_BPTC_UNORM_EXT, |
| COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, |
| COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, or |
| COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT and any of the following apply: |
| |
| * <width> is not a multiple of four, and <width> plus <xoffset> is not |
| equal to TEXTURE_WIDTH; |
| |
| * <height> is not a multiple of four, and <height> plus <yoffset> is |
| not equal to TEXTURE_HEIGHT; or |
| |
| * <xoffset> or <yoffset> is not a multiple of four. |
| |
| INVALID_OPERATION is generated by TexImage2D, TexImage3D, TexStorage2D, and |
| TexStorage3D if a BPTC format is used as the <internalFormat> parameter |
| with a <type> and <format> combination NOT listed: |
| |
| InternalFormat Format Type |
| ---------------------- ---------- -------------- |
| COMPRESSED_RGBA_BPTC_UNORM_EXT RGBA UNSIGNED_BYTE |
| COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT RGBA UNSIGNED_BYTE |
| COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT RGB FLOAT |
| COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT RGB FLOAT |
| |
| New Implementation Dependent State |
| |
| None |
| |
| Appendix |
| |
| BPTC Compressed Texture Image Format |
| |
| Compressed texture images stored using the BPTC compressed image formats |
| are represented as a collection of 4x4 texel blocks, where each block |
| contains 128 bits of texel data. The image is encoded as a normal 2D |
| raster image in which each 4x4 block is treated as a single pixel. If a |
| BPTC image has a width or height that is not a multiple of four, the data |
| corresponding to texels outside the image are irrelevant and undefined. |
| |
| When a BPTC image with a width of <w>, height of <h>, and block size of |
| <blocksize> (16 bytes) is decoded, the corresponding image size (in bytes) |
| is: |
| |
| ceil(<w>/4) * ceil(<h>/4) * blocksize. |
| |
| When decoding a BPTC image, the block containing the texel at offset |
| (<x>, <y>) begins at an offset (in bytes) relative to the base of the |
| image of: |
| |
| blocksize * (ceil(<w>/4) * floor(<y>/4) + floor(<x>/4)). |
| |
| The data corresponding to a specific texel (<x>, <y>) are extracted from a |
| 4x4 texel block using a relative (x,y) value of |
| |
| (<x> modulo 4, <y> modulo 4). |
| |
| There are two distinct BPTC image formats each of which has two |
| variants. COMPRESSED_RGBA_BPTC_UNORM_EXT and |
| COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT compress 8-bit fixed-point |
| data. COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT and |
| COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT compress high dynamic range |
| floating point values. The formats are similar, so the description of the |
| float format will reference significant sections of the UNORM description. |
| |
| COMPRESSED_RGBA_BPTC_UNORM_EXT (and the SRGB_ALPHA equivalent): Each 4x4 |
| block of texels consists of 128 bits of RGBA or SRGB_ALPHA image data. |
| |
| Each block contains enough information to select and decode a pair of |
| colors called endpoints, interpolate between those endpoints in a variety |
| of ways, then remap the result into the final output. |
| |
| Each block can contain data in one of eight modes. The mode is identified |
| by the lowest bits of the lowest byte. It is encoded as zero or more zeros |
| followed by a one. For example, using x to indicate a bit not included in |
| the mode number, mode 0 is encoded as xxxxxxx1 in the low byte in binary, |
| mode 5 is xx100000, and mode 7 is 10000000. Encoding the low byte as zero |
| is reserved and should not be used when encoding a BPTC texture. |
| |
| All further decoding is driven by the values derived from the mode listed |
| in Table.M below. The fields in the block are always in the same order for |
| all modes. Starting at the lowest bit after the mode and going up from LSB |
| to MSB in byte stream order, these fields are: partition number, rotation, |
| index selection, color, alpha, per-endpoint P-bit, shared P-bit, primary |
| indices, and secondary indices. The number of bits to be read in each |
| field is determined directly from the table. |
| |
| Each block can be divided into between 1 and 3 groups of pixels with |
| independent compression parameters called subsets. A texel in a block with |
| one subset is always considered to be in subset zero. Otherwise, a number |
| determined by the number of partition bits is used to look up in the |
| partition tables Table.P2 or Table.P3 for 2 and 3 subsets |
| respectively. This partitioning is indexed by the X and Y within the block |
| to generate the subset index. |
| |
| Each block has two colors for each subset, stored first by endpoint, then |
| by subset, then by color. For example, a format with two subsets and five |
| color bits would have five bits of red for endpoint 0 of the first subset, |
| then five bits of red for endpoint 1, then the two ends of the second |
| subset, then green and blue stored similarly. If a block has non-zero |
| alpha bits, the alpha data follows the color data with the same |
| organization. If not, alpha is overridden to 1.0. These bits are treated |
| as the high bits of a fixed-point value in a byte. If the format has a |
| shared P-bit, there are two bits for endpoints 0 and 1 from low to |
| high. If the format has a per-endpoint P-bits, then there are 2*subsets |
| P-bits stored in the same order as color and alpha. Both kinds of P-bits |
| are added as a bit below the color data stored in the byte. So, for a |
| format with 5 red bits, the P-bit ends up in bit 2. For final scaling, the |
| top bits of the value are replicated into any remaining bits in the |
| byte. For the preceding example, bits 6 and 7 would be written to bits 0 |
| and 1. |
| |
| The endpoint colors are interpolated using index values stored in the |
| block. The index bits are stored in x-major order. Each index has the |
| number of bits indicated by the mode except for one special index per |
| subset called the anchor index. Since the ordering of the endpoints is |
| unimportant, we can save one bit on one index per subset by ordering the |
| endpoints such that the highest bit is guaranteed to be zero. In partition |
| zero, the anchor index is always index zero. In other partitions, the |
| anchor index is specified by tables Table.A2 and Table.A3. If secondary |
| index bits are present, they are read in the same manner. The anchor index |
| information is only used to determine the number of bits each index has |
| when it's read from the block data. |
| |
| The endpoint color and alpha values used for final interpolation are the |
| decoded values corresponding to the applicable subset as selected |
| above. The index value for interpolating color comes from the secondary |
| index for the texel if the format has an index selection bit and its value |
| is one and from the primary index otherwise. The alpha index comes from |
| the secondary index if the block has a secondary index and the block |
| either doesn't have an index selection bit or that bit is zero and the |
| primary index otherwise. |
| |
| Interpolation is always performed using a 6-bit interpolation factor. The |
| effective interpolation factors for 2, 3, and 4 bit indices are given |
| below: |
| |
| 2: 0, 21, 43, 64 |
| 3: 0, 9, 18, 27, 37, 46, 55, 64 |
| 4: 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 |
| |
| The interpolation results in an RGBA color. If rotation bits are present, |
| this color is remapped according to: |
| |
| 0: no change |
| 1: swap(a,r) |
| 2: swap(a,g) |
| 3: swap(a,b) |
| |
| These 8-bit values show up in the shader interpreted as either RGBA8 or |
| SRGB8_ALPHA8 for COMPRESSED_RGBA_BPTC_UNORM_EXT and |
| COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT respectively. |
| |
| |
| Table.M |
| |
| Mode NS PB RB ISB CB AB EPB SPB IB IB2 |
| ---- -- -- -- --- -- -- --- --- -- --- |
| 0 3 4 0 0 4 0 1 0 3 0 |
| 1 2 6 0 0 6 0 0 1 3 0 |
| 2 3 6 0 0 5 0 0 0 2 0 |
| 3 2 6 0 0 7 0 1 0 2 0 |
| 4 1 0 2 1 5 6 0 0 2 3 |
| 5 1 0 2 0 7 8 0 0 2 2 |
| 6 1 0 0 0 7 7 1 0 4 0 |
| 7 2 6 0 0 5 5 1 0 2 0 |
| |
| The columns are as as follows: |
| |
| Mode: As described above |
| |
| NS: Number of subsets in each partition |
| |
| PB: Partition bits |
| |
| RB: Rotation bits |
| |
| ISB: Index selection bits |
| |
| CB: Color bits |
| |
| AB: Alpha bits |
| |
| EPB: Endpoint P-bits |
| |
| SPB: Shared P-bits |
| |
| IB: Index bits per element |
| |
| IB2: Secondary index bits per element |
| |
| |
| Table.P2 |
| |
| (each row is one 4x4 block) |
| |
| |
| 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1 |
| 0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1 |
| 0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1 |
| 0,0,0,1,0,0,1,1,0,0,1,1,0,1,1,1 |
| 0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1 |
| 0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1 |
| 0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1 |
| 0,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1 |
| 0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1 |
| 0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1 |
| 0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1 |
| 0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1 |
| 0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1 |
| 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1 |
| 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1 |
| 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1 |
| 0,0,0,0,1,0,0,0,1,1,1,0,1,1,1,1 |
| 0,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0 |
| 0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,0 |
| 0,1,1,1,0,0,1,1,0,0,0,1,0,0,0,0 |
| 0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0 |
| 0,0,0,0,1,0,0,0,1,1,0,0,1,1,1,0 |
| 0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0 |
| 0,1,1,1,0,0,1,1,0,0,1,1,0,0,0,1 |
| 0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,0 |
| 0,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0 |
| 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0 |
| 0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0 |
| 0,0,0,1,0,1,1,1,1,1,1,0,1,0,0,0 |
| 0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0 |
| 0,1,1,1,0,0,0,1,1,0,0,0,1,1,1,0 |
| 0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0 |
| 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1 |
| 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1 |
| 0,1,0,1,1,0,1,0,0,1,0,1,1,0,1,0 |
| 0,0,1,1,0,0,1,1,1,1,0,0,1,1,0,0 |
| 0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0 |
| 0,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0 |
| 0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1 |
| 0,1,0,1,1,0,1,0,1,0,1,0,0,1,0,1 |
| 0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,0 |
| 0,0,0,1,0,0,1,1,1,1,0,0,1,0,0,0 |
| 0,0,1,1,0,0,1,0,0,1,0,0,1,1,0,0 |
| 0,0,1,1,1,0,1,1,1,1,0,1,1,1,0,0 |
| 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 |
| 0,0,1,1,1,1,0,0,1,1,0,0,0,0,1,1 |
| 0,1,1,0,0,1,1,0,1,0,0,1,1,0,0,1 |
| 0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0 |
| 0,1,0,0,1,1,1,0,0,1,0,0,0,0,0,0 |
| 0,0,1,0,0,1,1,1,0,0,1,0,0,0,0,0 |
| 0,0,0,0,0,0,1,0,0,1,1,1,0,0,1,0 |
| 0,0,0,0,0,1,0,0,1,1,1,0,0,1,0,0 |
| 0,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1 |
| 0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,1 |
| 0,1,1,0,0,0,1,1,1,0,0,1,1,1,0,0 |
| 0,0,1,1,1,0,0,1,1,1,0,0,0,1,1,0 |
| 0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,1 |
| 0,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1 |
| 0,1,1,1,1,1,1,0,1,0,0,0,0,0,0,1 |
| 0,0,0,1,1,0,0,0,1,1,1,0,0,1,1,1 |
| 0,0,0,0,1,1,1,1,0,0,1,1,0,0,1,1 |
| 0,0,1,1,0,0,1,1,1,1,1,1,0,0,0,0 |
| 0,0,1,0,0,0,1,0,1,1,1,0,1,1,1,0 |
| 0,1,0,0,0,1,0,0,0,1,1,1,0,1,1,1 |
| |
| Table.P3 |
| |
| 0,0,1,1,0,0,1,1,0,2,2,1,2,2,2,2 |
| 0,0,0,1,0,0,1,1,2,2,1,1,2,2,2,1 |
| 0,0,0,0,2,0,0,1,2,2,1,1,2,2,1,1 |
| 0,2,2,2,0,0,2,2,0,0,1,1,0,1,1,1 |
| 0,0,0,0,0,0,0,0,1,1,2,2,1,1,2,2 |
| 0,0,1,1,0,0,1,1,0,0,2,2,0,0,2,2 |
| 0,0,2,2,0,0,2,2,1,1,1,1,1,1,1,1 |
| 0,0,1,1,0,0,1,1,2,2,1,1,2,2,1,1 |
| 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2 |
| 0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2 |
| 0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2 |
| 0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2 |
| 0,1,1,2,0,1,1,2,0,1,1,2,0,1,1,2 |
| 0,1,2,2,0,1,2,2,0,1,2,2,0,1,2,2 |
| 0,0,1,1,0,1,1,2,1,1,2,2,1,2,2,2 |
| 0,0,1,1,2,0,0,1,2,2,0,0,2,2,2,0 |
| 0,0,0,1,0,0,1,1,0,1,1,2,1,1,2,2 |
| 0,1,1,1,0,0,1,1,2,0,0,1,2,2,0,0 |
| 0,0,0,0,1,1,2,2,1,1,2,2,1,1,2,2 |
| 0,0,2,2,0,0,2,2,0,0,2,2,1,1,1,1 |
| 0,1,1,1,0,1,1,1,0,2,2,2,0,2,2,2 |
| 0,0,0,1,0,0,0,1,2,2,2,1,2,2,2,1 |
| 0,0,0,0,0,0,1,1,0,1,2,2,0,1,2,2 |
| 0,0,0,0,1,1,0,0,2,2,1,0,2,2,1,0 |
| 0,1,2,2,0,1,2,2,0,0,1,1,0,0,0,0 |
| 0,0,1,2,0,0,1,2,1,1,2,2,2,2,2,2 |
| 0,1,1,0,1,2,2,1,1,2,2,1,0,1,1,0 |
| 0,0,0,0,0,1,1,0,1,2,2,1,1,2,2,1 |
| 0,0,2,2,1,1,0,2,1,1,0,2,0,0,2,2 |
| 0,1,1,0,0,1,1,0,2,0,0,2,2,2,2,2 |
| 0,0,1,1,0,1,2,2,0,1,2,2,0,0,1,1 |
| 0,0,0,0,2,0,0,0,2,2,1,1,2,2,2,1 |
| 0,0,0,0,0,0,0,2,1,1,2,2,1,2,2,2 |
| 0,2,2,2,0,0,2,2,0,0,1,2,0,0,1,1 |
| 0,0,1,1,0,0,1,2,0,0,2,2,0,2,2,2 |
| 0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0 |
| 0,0,0,0,1,1,1,1,2,2,2,2,0,0,0,0 |
| 0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0 |
| 0,1,2,0,2,0,1,2,1,2,0,1,0,1,2,0 |
| 0,0,1,1,2,2,0,0,1,1,2,2,0,0,1,1 |
| 0,0,1,1,1,1,2,2,2,2,0,0,0,0,1,1 |
| 0,1,0,1,0,1,0,1,2,2,2,2,2,2,2,2 |
| 0,0,0,0,0,0,0,0,2,1,2,1,2,1,2,1 |
| 0,0,2,2,1,1,2,2,0,0,2,2,1,1,2,2 |
| 0,0,2,2,0,0,1,1,0,0,2,2,0,0,1,1 |
| 0,2,2,0,1,2,2,1,0,2,2,0,1,2,2,1 |
| 0,1,0,1,2,2,2,2,2,2,2,2,0,1,0,1 |
| 0,0,0,0,2,1,2,1,2,1,2,1,2,1,2,1 |
| 0,1,0,1,0,1,0,1,0,1,0,1,2,2,2,2 |
| 0,2,2,2,0,1,1,1,0,2,2,2,0,1,1,1 |
| 0,0,0,2,1,1,1,2,0,0,0,2,1,1,1,2 |
| 0,0,0,0,2,1,1,2,2,1,1,2,2,1,1,2 |
| 0,2,2,2,0,1,1,1,0,1,1,1,0,2,2,2 |
| 0,0,0,2,1,1,1,2,1,1,1,2,0,0,0,2 |
| 0,1,1,0,0,1,1,0,0,1,1,0,2,2,2,2 |
| 0,0,0,0,0,0,0,0,2,1,1,2,2,1,1,2 |
| 0,1,1,0,0,1,1,0,2,2,2,2,2,2,2,2 |
| 0,0,2,2,0,0,1,1,0,0,1,1,0,0,2,2 |
| 0,0,2,2,1,1,2,2,1,1,2,2,0,0,2,2 |
| 0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,2 |
| 0,0,0,2,0,0,0,1,0,0,0,2,0,0,0,1 |
| 0,2,2,2,1,2,2,2,0,2,2,2,1,2,2,2 |
| 0,1,0,1,2,2,2,2,2,2,2,2,2,2,2,2 |
| 0,1,1,1,2,0,1,1,2,2,0,1,2,2,2,0 |
| |
| Table.A2 (Anchor index values for the second subset of two-subset |
| partitioning) |
| |
| (wrapped for readability - values run right then down) |
| |
| 15,15,15,15,15,15,15,15, |
| 15,15,15,15,15,15,15,15, |
| 15, 2, 8, 2, 2, 8, 8,15, |
| 2, 8, 2, 2, 8, 8, 2, 2, |
| 15,15, 6, 8, 2, 8,15,15, |
| 2, 8, 2, 2, 2,15,15, 6, |
| 6, 2, 6, 8,15,15, 2, 2, |
| 15,15,15,15,15, 2, 2,15, |
| |
| Table.A3a (Anchor index values for the second subset of three-subset |
| partitioning) |
| |
| (wrapped for readability - values run right then down) |
| |
| 3, 3,15,15, 8, 3,15,15, |
| 8, 8, 6, 6, 6, 5, 3, 3, |
| 3, 3, 8,15, 3, 3, 6,10, |
| 5, 8, 8, 6, 8, 5,15,15, |
| 8,15, 3, 5, 6,10, 8,15, |
| 15, 3,15, 5,15,15,15,15, |
| 3,15, 5, 5, 5, 8, 5,10, |
| 5,10, 8,13,15,12, 3, 3, |
| |
| Table.A3b (Anchor index values for the third subset of three-subset |
| partitioning) |
| |
| (wrapped for readability - values run right then down) |
| |
| 15, 8, 8, 3,15,15, 3, 8, |
| 15,15,15,15,15,15,15, 8, |
| 15, 8,15, 3,15, 8,15, 8, |
| 3,15, 6,10,15,15,10, 8, |
| 15, 3,15,10,10, 8, 9,10, |
| 6,15, 8,15, 3, 6, 6, 8, |
| 15, 3,15,15,15,15,15,15, |
| 15,15,15,15, 3,15,15, 8, |
| |
| COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT and |
| COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: Each 4x4 block of texels consists |
| of 128 bits of RGB data. These formats are very similar and will be |
| described together. In the description and pseudocode below, <signed> will |
| be used as a condition which is true for the SIGNED format and false for |
| the UNSIGNED format. Both formats only contain RGB data, so the returned |
| alpha value is 1.0. If a block uses a reserved or invalid encoding, the |
| return value is (0,0,0,1). |
| |
| Each block can contain data in one of 14 modes. The mode number is encoded |
| in either the low two bits or the low five bits. If the low two bits are |
| less than two, that is the mode number, otherwise the low five bits the |
| mode number. Mode numbers not listed in Table.MF are reserved (19, 23, 27, |
| and 31). |
| |
| The data for the compressed blocks is stored in a different format for |
| each mode. The formats are specified in Table.F. The format strings are |
| intended to be read from left to right with the LSB on the left. Each |
| element is of the form v[a:b]. If a>=b, this indicates to extract b-a+1 |
| bits from the block at that location and put it in the corresponding bits |
| of the variable v. If a<b, then the bits are reversed. v[a] is used as a |
| shorthand for the one bit v[a:a]. As an example, m[1:0],g2[4] would move |
| the low two bits from the block into the low two bits of m then the next |
| bit of the block into bit 4 of g2. The variable names given in the table |
| will be referred to in the language below. |
| |
| Subsets and indices work in much the same way as described for the |
| fixed-point formats above. If a float block has no partition bits, then it |
| is a single-subset block. If it has partition bits, then it is a 2 subset |
| block. The partition index references the first half of Table.P2. Indices |
| are read in the same way as the fixed-point formats including obeying the |
| anchor values for index 0 and as needed by Table.A2. |
| |
| In a single-subset blocks, the two endpoints are contained in r0,g0,b0 |
| (hence e0) and r1,g1,b1 (hence e1). In a two-subset block, the endpoints |
| for the second subset are in r2,g2,b2 and r3,g3,b3. The value in e0 is |
| sign-extended if the format of the texture is signed. The values in e1 and |
| e2 and e3 if the block is two-subset are sign-extended if the format of |
| the texture is signed or if the block mode has transformed endpoints. If |
| the mode has transformed endpoints, the values from e0 are used as a base |
| to offset all other endpoints, wrapped at the number of endpoint bits. For |
| example, r1 = (r0+r1) & ((1<<EPB)-1). |
| |
| Next, the endpoints are unquantized to maximize the usage of the bits and |
| to ensure that the negative ranges are oriented properly to interpolate as |
| a two's complement value. The following pseudocode assumes the computation |
| is being done using sufficiently large intermediate values to avoid |
| overflow. For the unsigned float format, we unquantize a value x to unq |
| by: |
| |
| if (EPB >= 15) |
| unq = x; |
| else if (x == 0) |
| unq = 0; |
| else if (x == ((1<<EPB)-1)) |
| unq = 0xFFFF; |
| else |
| unq = ((x << 15) + 0x4000) >> (EPB-1); |
| |
| The signed float unquantization is similar, but needs to worry about |
| orienting the negative range: |
| |
| s = 0; |
| if (EPB >= 16) |
| unq = x; |
| else { |
| if (x < 0) { |
| s = 1; |
| x = -x; |
| } |
| |
| if (x == 0) |
| unq = 0; |
| else if (x >= ((1<<(EPB-1))-1)) |
| unq = 0x7FFF; |
| else |
| unq = ((x << 15) + 0x4000) >> (EPB-1); |
| |
| if (s) |
| unq = -unq; |
| } |
| |
| After the endpoints are unquantized, interpolation proceeds as in the |
| fixed-point formats above including the interpolation weight table. |
| |
| The interpolated values are passed through a final unquantization |
| step. For the unsigned format, this step simply multiplies by 31/64. The |
| signed format negates negative components, multiplies by 31/32, then or's |
| in the sign bit if the original value was negative. |
| |
| The resultant value should be a legal 16-bit half float which is then |
| returned as a float to the shader. |
| |
| Table.MF |
| |
| MN Tr PB EPB Delta Bits |
| -- -- -- --- ---------- |
| 0 1 5 10 {5, 5, 5} |
| 1 1 5 7 {6, 6, 6} |
| 2 1 5 11 {5, 4, 4} |
| 6 1 5 11 {4, 5, 4} |
| 10 1 5 11 {4, 4, 5} |
| 14 1 5 9 {5, 5, 5} |
| 18 1 5 8 {6, 5, 5} |
| 22 1 5 8 {5, 6, 5} |
| 26 1 5 8 {5, 5, 6} |
| 30 0 5 6 {6, 6, 6} |
| 3 0 0 10 {10, 10, 10} |
| 7 1 0 11 {9, 9, 9} |
| 11 1 0 12 {8, 8, 8} |
| 15 1 0 16 {4, 4, 4} |
| |
| MN: Mode number |
| Tr: Transformed endpoints |
| PB: Partition bits |
| EPB: Endpoint bits |
| |
| |
| Table.F |
| |
| MN Format |
| -- ------------------------------------------------------------------------ |
| 0 m[1:0],g2[4],b2[4],b3[4],r0[9:0],g0[9:0],b0[9:0],r1[4:0],g3[4],g2[3:0], |
| g1[4:0],b3[0],g3[3:0],b1[4:0],b3[1],b2[3:0],r2[4:0],b3[2],r3[4:0],b3[3] |
| |
| 1 m[1:0],g2[5],g3[4],g3[5],r0[6:0],b3[0],b3[1],b2[4],g0[6:0],b2[5],b3[2], |
| g2[4],b0[6:0],b3[3],b3[5],b3[4],r1[5:0],g2[3:0],g1[5:0],g3[3:0],b1[5:0], |
| b2[3:0],r2[5:0],r3[5:0] |
| |
| 2 m[4:0],r0[9:0],g0[9:0],b0[9:0],r1[4:0],r0[10],g2[3:0],g1[3:0],g0[10], |
| b3[0],g3[3:0],b1[3:0],b0[10],b3[1],b2[3:0],r2[4:0],b3[2],r3[4:0],b3[3] |
| |
| 6 m[4:0],r0[9:0],g0[9:0],b0[9:0],r1[3:0],r0[10],g3[4],g2[3:0],g1[4:0], |
| g0[10],g3[3:0],b1[3:0],b0[10],b3[1],b2[3:0],r2[3:0],b3[0],b3[2],r3[3:0], |
| g2[4],b3[3] |
| |
| 10 m[4:0],r0[9:0],g0[9:0],b0[9:0],r1[3:0],r0[10],b2[4],g2[3:0],g1[3:0], |
| g0[10],b3[0],g3[3:0],b1[4:0],b0[10],b2[3:0],r2[3:0],b3[1],b3[2],r3[3:0], |
| b3[4],b3[3] |
| |
| 14 m[4:0],r0[8:0],b2[4],g0[8:0],g2[4],b0[8:0],b3[4],r1[4:0],g3[4],g2[3:0], |
| g1[4:0],b3[0],g3[3:0],b1[4:0],b3[1],b2[3:0],r2[4:0],b3[2],r3[4:0],b3[3] |
| |
| 18 m[4:0],r0[7:0],g3[4],b2[4],g0[7:0],b3[2],g2[4],b0[7:0],b3[3],b3[4], |
| r1[5:0],g2[3:0],g1[4:0],b3[0],g3[3:0],b1[4:0],b3[1],b2[3:0],r2[5:0], |
| r3[5:0] |
| |
| 22 m[4:0],r0[7:0],b3[0],b2[4],g0[7:0],g2[5],g2[4],b0[7:0],g3[5],b3[4], |
| r1[4:0],g3[4],g2[3:0],g1[5:0],g3[3:0],b1[4:0],b3[1],b2[3:0],r2[4:0], |
| b3[2],r3[4:0],b3[3] |
| |
| 26 m[4:0],r0[7:0],b3[1],b2[4],g0[7:0],b2[5],g2[4],b0[7:0],b3[5],b3[4], |
| r1[4:0],g3[4],g2[3:0],g1[4:0],b3[0],g3[3:0],b1[5:0],b2[3:0],r2[4:0], |
| b3[2],r3[4:0],b3[3] |
| |
| 30 m[4:0],r0[5:0],g3[4],b3[0],b3[1],b2[4],g0[5:0],g2[5],b2[5],b3[2], |
| g2[4],b0[5:0],g3[5],b3[3],b3[5],b3[4],r1[5:0],g2[3:0],g1[5:0],g3[3:0], |
| b1[5:0],b2[3:0],r2[5:0],r3[5:0] |
| |
| 3 m[4:0],r0[9:0],g0[9:0],b0[9:0],r1[9:0],g1[9:0],b1[9:0] |
| |
| 7 m[4:0],r0[9:0],g0[9:0],b0[9:0],r1[8:0],r0[10],g1[8:0],g0[10],b1[8:0], |
| b0[10] |
| |
| 11 m[4:0],r0[9:0],g0[9:0],b0[9:0],r1[7:0],r0[10:11],g1[7:0],g0[10:11], |
| b1[7:0],b0[10:11] |
| |
| 15 m[4:0],r0[9:0],g0[9:0],b0[9:0],r1[3:0],r0[10:15],g1[3:0],g0[10:15], |
| b1[3:0],b0[10:15] |
| |
| |
| Issues |
| |
| Note: These issues apply specifically to the definition of the |
| EXT_texture_compression_bptc specification, which is based on the OpenGL |
| extension ARB_texture_compression_bptc. For the full set of historical |
| issues, see ARB_texture_compression_bptc which can be found |
| in the OpenGL Registry. |
| |
| (1) What functionality was changed relative to ARB_texture_compression_bptc? |
| |
| BPTC formats are not accepted as <internalFormat> parameters by |
| CopyTexSubImage2D or CopyTexSubImage3D. |
| Queries to GL_NUM_COMPRESSED_TEXTURE_FORMATS and |
| GL_COMPRESSED_TEXTURE_FORMATS should return the BPTC formats. |
| More restrictions are placed on the use of BPTC formats with TexImage* |
| and TexStorage*. |
| |
| |
| Revision History |
| |
| Rev. Date Author Changes |
| ---- -------- ----------- -------------------------------------------- |
| 1 04/10/17 jaschmidt EXT version based on revision 9 of |
| ARB_texture_compression_bptc |
| |