blob: 8aab36370f2909c92421cdd6a93a69bed1801414 [file] [log] [blame]
Name
ARB_texture_compression_bptc
Name Strings
GL_ARB_texture_compression_bptc
Contact
Eric Werness, NVIDIA Corporation (ewerness 'at' nvidia.com)
Piers Daniell, NVIDIA Corporation (pdaniell 'at' nvidia.com)
Contributors
Barthold Lichtenbelt, NVIDIA
Bill Licea-Kane, AMD
Graham Sellers, AMD
Greg Roth, NVIDIA
Jeannot Breton, NVIDIA
Jeff Bolz, NVIDIA
Nick Haemel, AMD
Pat Brown, NVIDIA
Pierre Boudier, AMD
Piers Daniell, NVIDIA
Notice
Copyright (c) 2010-2013 The Khronos Group Inc. Copyright terms at
http://www.khronos.org/registry/speccopyright.html
Specification Update Policy
Khronos-approved extension specifications are updated in response to
issues and bugs prioritized by the Khronos OpenGL Working Group. For
extensions which have been promoted to a core Specification, fixes will
first appear in the latest version of that core Specification, and will
eventually be backported to the extension document. This policy is
described in more detail at
https://www.khronos.org/registry/OpenGL/docs/update_policy.php
Status
Complete. Approved by the ARB at the 2010/01/22 F2F meeting.
Approved by the Khronos Board of Promoters on March 10, 2010.
Version
Last Modified Date: October 30, 2019
Revision: 9
Number
ARB Extension #77
Dependencies
OpenGL 1.3 or ARB_texture_compression is required.
This extension is written against the OpenGL 3.2 Specification
(Compatibility Profile).
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), subject to all the
requirements and limitations described by the extension
GL_ARB_texture_compression.
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,
CopyTexImage2D, CopyTexImage3D, CompressedTexImage2DARB, and
CompressedTexImage3DARB and the <format> parameter of
CompressedTexSubImage2DARB and CompressedTexSubImage3DARB:
COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
Additions to Chapter 2 of the OpenGL 3.2 Specification (OpenGL Operation)
None.
Additions to Chapter 3 of the OpenGL 3.2 Specification (Rasterization)
Add to Table 3.20: Generic and specific compressed internal formats
Compressed Internal Format Base Internal Format Type
========================== ==================== ========
COMPRESSED_RGBA_BPTC_UNORM_ARB RGBA Specific
COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB RGBA Specific
COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB RGB Specific
COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB RGB Specific
Modify Section 3.9.2, Alternate Texture Image Specification Commands
(add to end of TexSubImage discussion, p.231 -- after edit from the
ARB_texture_compression spec)
If the internal format of the texture image being modified is
COMPRESSED_RGBA_BPTC_UNORM_ARB, COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB,
COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, or
COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB the texture is stored using the
specified BPTC compressed texture image format. Such images are easily
edited along 4x4 texel boundaries, so the limitations on TexSubImage2D,
TexSubImage3D, CopyTexSubImage2D, and CopyTexSubImage3D parameters are
relaxed. TexSubImage2D, TexSubImage3D, CopyTexSubImage2D, and
CopyTexSubImage3D will result in an INVALID_OPERATION error only if one of
the following conditions occurs:
* <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.
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, TexSubImage3D, CopyTexSubImage2D, and CopyTexSubImage3D
calls.
Add to Section 3.9.3, Compressed Texture Images (adding to the end of the
CompressedTexImage section introduced by the ARB_texture_compression spec)
If <internalformat> is COMPRESSED_RGBA_BPTC_UNORM_ARB,
COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB,
COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, or
COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 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. CompressedTexImage1DARB produces an INVALID_ENUM error if
<internalformat> is a BPTC format. CompressedTexImage2DARB and
CompressedTexImage3DARB will produce an INVALID_OPERATION error if
<border> is non-zero.
Add to Section 3.9.3, Compressed Texture Images (adding to the end of the
CompressedTexSubImage section introduced by the ARB_texture_compression
spec)
If the internal format of the texture image being modified is
COMPRESSED_RGBA_BPTC_UNORM_ARB, COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB,
COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, or
COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB the texture is stored using the
specified BPTC compressed texture image formats. Since the BPTC texture
compression algorithm supports only 2D images, CompressedTexSubImage1DARB
produces an INVALID_ENUM error if <format> is a BPTC format. 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 and CopyTexSubImage2D/3D calls.
Additions to Chapter 4 of the OpenGL 3.2 Specification (Per-Fragment
Operations and the Frame Buffer)
None.
Additions to Chapter 5 of the OpenGL 3.2 Specification (Special Functions)
None.
Additions to Chapter 6 of the OpenGL 3.2 Specification (State and
State Requests)
None.
Additions to Appendix A of the OpenGL 3.2 Specification (Invariance)
None.
Additions to the AGL/GLX/WGL Specifications
None.
GLX Protocol
None.
Errors
INVALID_ENUM is generated by CompressedTexImage1DARB if <internalformat>
is COMPRESSED_RGBA_BPTC_UNORM_ARB, COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB,
COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, or
COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB.
INVALID_OPERATION is generated by CompressedTexImage2DARB if
<internalformat> is COMPRESSED_RGBA_BPTC_UNORM_ARB,
COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB,
COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, or
COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB and <border> is not equal to zero.
INVALID_ENUM is generated by CompressedTexSubImage1DARB if <format> is
COMPRESSED_RGBA_BPTC_UNORM_ARB, COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB,
COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, or
COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB.
INVALID_OPERATION is generated by TexSubImage2D or CopyTexSubImage2D if
TEXTURE_INTERNAL_FORMAT is COMPRESSED_RGBA_BPTC_UNORM_ARB,
COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB,
COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, or
COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 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_ARB,
COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB,
COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, or
COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 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.
The following restrictions from the ARB_texture_compression specification
do not apply to BPTC texture formats, since subimage modification is
straightforward as long as the subimage is properly aligned.
DELETE: INVALID_OPERATION is generated by TexSubImage1D, TexSubImage2D,
DELETE: TexSubImage3D, CopyTexSubImage1D, CopyTexSubImage2D, or
DELETE: CopyTexSubImage3D if the internal format of the texture image is
DELETE: compressed and <xoffset>, <yoffset>, or <zoffset> does not equal
DELETE: -b, where b is value of TEXTURE_BORDER.
DELETE: INVALID_VALUE is generated by CompressedTexSubImage1DARB,
DELETE: CompressedTexSubImage2DARB, or CompressedTexSubImage3DARB if the
DELETE: entire texture image is not being edited: if <xoffset>,
DELETE: <yoffset>, or <zoffset> is greater than -b, <xoffset> + <width> is
DELETE: less than w+b, <yoffset> + <height> is less than h+b, or <zoffset>
DELETE: + <depth> is less than d+b, where b is the value of
DELETE: TEXTURE_BORDER, w is the value of TEXTURE_WIDTH, h is the value of
DELETE: TEXTURE_HEIGHT, and d is the value of TEXTURE_DEPTH.
See also errors in the GL_ARB_texture_compression specification.
New State
In the "Textures" state table, increment the TEXTURE_INTERNAL_FORMAT
subscript for Z by 4 in the "Type" row.
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_ARB and
COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB compress 8-bit fixed-point
data. COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB and
COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 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_ARB (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
shared P-bits, there are two endpoint bits, the lower of which applies to
both endpoints of subset 0 and the upper of which applies to both
endpoints of subset 1. 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_ARB and
COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 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_ARB and
COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: 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
(1) Are both RGB and RGBA versions interesting?
RESOLVED. Not for the unorm formats. Every BPTC mode has a defined
alpha, so an RGB mode isn't needed. Also, since modes are per-block, a
given texture can have both RGB1 and RGBA portions.
The float formats don't compress alpha at all, so they only have RGB
variants, not RGBA.
(2) Put both BC7 and BC6H in the same spec?
RESOLVED. Yes. They share enough that it's worthwhile to amortize the
"overhead".
(3) Why are there two versions of the float BPTC formats for signed and
unsigned? Do they pass through the GL differently?
RESOLVED. The unsigned formats are decoded distinctly from signed
formats, so it is necessary to distinguish between them.
The values still pass through the shader and the pixel path as signed
floats, but the interpretation of the compressed block changes as
described.
(4) Should the result of the compressed float formats be half floats or
single floats?
RESOLVED. The expansion from packed to half to float will be specified
as part of the decompression process.
(5) What should be expected for a driver compressor for these formats?
RESOLVED: The current best known compression algorithms have to
exhaustively test all partitionings across all modes. The compressor in
the GL will have to make a tradeoff between performance and
quality. Compressing offline is highly recommended.
(6) How should floating point specials (Inf and NaN) be handled in the
float formats?
RESOLVED: Decompressor will never generate them. Compressor should
flush to max half float.
(7) Does this spec require bit-exact decompression?
RESOLVED: Yes.
(8) Does the data format depend on the endianness of the system?
RESOLVED: No. The data is interpeted as an endian-independent
byte stream.
(9) What should be the internal format of the floating-point BPTC format?
RESOLVED: The format has three components, with the alpha component
mapped to 1.0, just like RGB textures. So we should call it RGB.
In the originally ratified version of this extension (and all versions
prior to January 20, 2011), such textures were treated as having a base
internal format of RGBA, where the alpha component was not present in
the texture and instead is just set to the constant 1.0. Some
implementations of this extension may also use a base internal format
of RGBA.
There are very few places where there is a difference between an RGB
texture and an RGBA texture where alpha is always 1.0. Two known
differences:
* A compressed "RGB" texture could be used for the generic
COMPRESSED_RGB format, but an "RGBA" texture should not be.
However, it seems unlikely that implementations would choose the
floating-point BPTC format as its generic COMPRESSED_RGB format.
* Using fixed-function fragment shading in the compatibility profile,
a texture environment mode of REPLACE would leave alpha unmodified
for RGB base formats but would replace the fragment alpha with the
texture alpha (constant 1.0 here) for RGBA base formats.
Revision History
Rev. Date Author Changes
---- -------- ----------- --------------------------------------------
9 30/10/19 pdaniell Fix shared p-bits specification to match
DX and the Khronos Data Format spec.
8 06/06/16 Nanley Chery Reduce the requirements to the minimal set.
7 01/20/11 pbrown Change the base internal format of the floating-
point BPTC formats from "RGBA" to "RGB" (bug
7231).
6 01/19/11 Jon Leech Fix state table modification for
TEXTURE_INTERNAL_FORMAT (Bug 7239).
5 05/20/10 ewerness Finalize some UNRESOLVED issues
4 04/09/10 pdaniell Modify for inclusion into OpenGL 4.1.
3 12/07/09 pdaniell ARBify.
2 10/13/09 ewerness Fix errors in the anchor index tables caused
by incorrect conversion scripts and a couple
typos in the input.
1 ewerness Internal revisions.