blob: e1a0397fe5a80e609bf2c62754d3a8bb52592952 [file] [log] [blame]
Name Strings
Jan-Harald Fredriksen (jan-harald.fredriksen 'at'
Edvard Fielding
Jan-Harald Fredriksen
Jakob Fries
Tom Olson
Jorn Nystad
IP Status
No known issues.
Version 4, January 23, 2017
OpenGL ES Extension #276
OpenGL ES 3.0 is required.
GL_KHR_texture_compression_astc_hdr, GL_KHR_texture_compression_astc_ldr,
or GL_OES_texture_compression_astc is required.
This extension is written based on the wording of the OpenGL ES 3.2
specification and the GL_KHR_texture_compression_astc_hdr extension.
This extension interacts with GL_KHR_texture_compression_astc_hdr.
Adaptive Scalable Texture Compression (ASTC) is a texture compression
technology that is exposed by existing extensions and specifications.
The existing specifications require that low dynamic range (LDR)
textures are decompressed to FP16 values per component. In many cases,
decompressing LDR textures to a lower precision intermediate result gives
acceptable image quality. Source material for LDR textures is typically
authored as 8-bit UNORM values, so decoding to FP16 values adds little
value. On the other hand, reducing precision of the decoded result
reduces the size of the decompressed data, potentially improving texture
cache performance and saving power.
The goal of this extension is to enable this efficiency gain on existing
ASTC texture data. This is achieved by giving the application the ability
to select the decoding precision.
Two decoding options are provided by
- Decode to FP16: This is the default, and matches the required behavior
in existing APIs.
- Decode to UNORM8: This is provided as an option in LDR mode.
If GL_EXT_texture_compression_astc_decode_mode_rgb9e5 is supported, then
a third decoding option is provided:
- Decode to RGB9_E5: This is provided as an option in both LDR and HDR
mode. In this mode, negative values cannot be represented and are
clamped to zero. The alpha component is ignored, and the results
are as if alpha was 1.0.
New Procedures and Functions
New Tokens
Accepted by the <pname> parameter of TexParameter* and GetTexParameter*:
Changes to 8.10 Texture Parameters
Add to Table 8.19: Texture parameters and their values:
Name Type Legal Values
GL_RGB9_E5 (*)
(*) Note: GL_RGB9_E5 is legal if and only if the
GL_EXT_texture_compression_astc_decode_mode_rgb9e5 extension is supported.
Changes to C.2.5 LDR and HDR Modes
In Table C.2.1 (Differences Between LDR and HDR Modes) in KHR_texture_compression_astc_hdr:
Modify the first row of the table to read:
Operation LDR Mode HDR Mode
Returned value Determined by the Determined by the
decoding mode decoding mode
<the rest of the table remains unchanged>
Table C.2.1 - Differences Between LDR and HDR Modes
Add the following paragraph immediately after Table C.2.1:
The type of the values returned by the decoding process is determined by API
state as follows:
Decode mode LDR Mode HDR Mode
GL_RGBA16F Vector of FP16 values Vector of FP16 values
GL_RGBA8 Vector of UNORM8 values <invalid>
GL_RGB9_E5 Vector using a shared Vector using a shared
exponent format exponent format
Table C.2.1.a - Decoding mode
[[ HDR profile only ]]
Using the GL_RGBA8 decoding mode in HDR mode gives undefined results.
For sRGB output, the decoding mode is ignored, and the decoding always returns
a vector of UNORM8 values.
If the texture does not have an ASTC format, the decoding mode is ignored.
[[ If GL_EXT_texture_compression_astc_decode_mode_rgb9e5 and HDR profile
is supported, then add the following paragraph after the second paragraph
following Table C.2.1 ]]
When using the GL_RGB9_E5 decoding mode in HDR mode, error results
will return the error color because NaN cannot be represented.
Changes to C.2.19 (Weight Application)
Replace the paragraph immediately after the expression for the value C in
LDR mode with the following:
If sRGB conversion is not enabled and the decoding mode is GL_RGBA16F,
then if C = 65535, then the final result is 1.0 (0x3C00) otherwise C is divided by
65536 and the infinite-precision result of the division is converted to FP16 with
round-to-zero semantics.
If sRGB conversion is not enabled and the decoding mode is GL_RGBA8,
then top 8 bits of the interpolation result for the R, G, B, and A channels
are used as the final result.
[[ The following two paragraph applies to
GL_EXT_texture_compression_astc_decode_mode_rgb9e5 only. ]]
If sRGB conversion is not enabled and the decoding mode is GL_RGB9_E5,
then the final result is a combination of the (UNORM16) values of C for the three
color components (Cr, Cg, and Cb) computed as follows:
int lz = clz17( Cr | Cg | Cb | 1);
if (Cr == 65535 ) { Cr = 65536; lz = 0; }
if (Cg == 65535 ) { Cg = 65536; lz = 0; }
if (Cb == 65535 ) { Cb = 65536; lz = 0; }
Cr <<= lz;
Cg <<= lz;
Cb <<= lz;
Cr = (Cr >> 8) & 0x1FF;
Cg = (Cg >> 8) & 0x1FF;
Cb = (Cb >> 8) & 0x1FF;
uint32_t exponent = 16 - lz;
uint32_t texel = (exponent << 27) | (Cb << 18) | (Cg << 9) | Cr;
The clz17() function counts leading zeros in a 17-bit value.
If sRGB conversion is enabled, then the decoding mode is ignored,
and the top 8 bits of the interpolation result for the R, G and B
channels are passed to the external sRGB conversion block and used
as the final result.
[[ If GL_EXT_texture_compression_astc_decode_mode_rgb9e5 and HDR profile
is supported, then add the following at the end of the section. ]]
If the decoding mode is GL_RGB9_E5, then the final result
is a combination of the (IEEE FP16) values of Cf for the three color
components (Cr, Cg, and Cb) computed as follows:
if( Cr > 0x7c00 ) Cr = 0; else if( Cr == 0x7c00 ) Cr = 0x7bff;
if( Cg > 0x7c00 ) Cg = 0; else if( Cg == 0x7c00 ) Cg = 0x7bff;
if( Cb > 0x7c00 ) Cb = 0; else if( Cb == 0x7c00 ) Cb = 0x7bff;
int Re = (Cr >> 10) & 0x1F;
int Ge = (Cg >> 10) & 0x1F;
int Be = (Cb >> 10) & 0x1F;
int Rex = Re == 0 ? 1 : Re;
int Gex = Ge == 0 ? 1 : Ge;
int Bex = Be == 0 ? 1 : Be;
int Xm = ((Cr | Cg | Cb) & 0x200) >> 9;
int Xe = Re | Ge | Be;
uint32_t rshift, gshift, bshift, expo;
if (Xe == 0)
expo = rshift = gshift = bshift = Xm;
else if (Re >= Ge && Re >= Be)
expo = Rex + 1;
rshift = 2;
gshift = Rex - Gex + 2;
bshift = Rex - Bex + 2;
else if (Ge >= Be)
expo = Gex + 1;
rshift = Gex - Rex + 2;
gshift = 2;
bshift = Gex - Bex + 2;
expo = Bex + 1;
rshift = Bex - Rex + 2;
gshift = Bex - Gex + 2;
bshift = 2;
int Rm = (Cr & 0x3FF) | (Re == 0 ? 0 : 0x400);
int Gm = (Cg & 0x3FF) | (Ge == 0 ? 0 : 0x400);
int Bm = (Cb & 0x3FF) | (Be == 0 ? 0 : 0x400);
Rm = (Rm >> rshift) & 0x1FF;
Gm = (Gm >> gshift) & 0x1FF;
Bm = (Bm >> bshift) & 0x1FF;
uint32_t texel = (expo << 27) | (Bm << 18) | (Gm << 9) | (Rm << 0);
Changes to C.2.23 (Void-Extent Blocks)
[[ If GL_EXT_texture_compression_astc_decode_mode_rgb9e5 and HDR profile
is supported, then add the following paragraph. ]]
In the HDR case, if the decoding mode is GL_RGB9_E5, then
any negative color component values are set to 0 before conversion to
the shared exponent format (as described in C.2.19).
New State
In Table 21.10: Textures (state per texture object), add:
Get value Type Get Command Initial value Description Section
---- ---- ------------- ------------- ----------- -------
TEXTURE_ASTC_DECODE_- E GetTexParameter GL_RGBA16F Decode mode C.2.5
Interactions with GL_KHR_texture_compression_astc_hdr
If GL_KHR_texture_compression_astc_hdr is not supported, then the
HDR profile is not supported, all references to HDR are removed.
(1) Should we include the GL_RGB9_E5 mode?
Proposed: Yes.
(2) Are implementations allowed to decode at a higher precision than
what is requested?
Proposed: No.
If we allow this, then this extension could be exposed on all
implementations that support ASTC. But developers would have no
way of knowing what precision was actually used, and thus whether
image quality is sufficient at reduced precision.
(3) What happens to values in void-extent blocks that are infinity or
NaN when using GL_RGB9_E5?
Resolved: Undefined behavior.
KHR_texture_compression_astc_hdr already makes this undefined:
"In the HDR case, if the color component values are infinity or NaN,
this will result in undefined behavior. As usual, this must not lead
to GL interruption or termination."
(4) Should there be an error or a texture completeness rule when using
the GL_RGBA8 decoding mode for HDR mode blocks?
Resolved: No. There is no way for implementations to check this
condition short of iterating through all the blocks of the texture.
(5) Should the decode mode be texture image state and/or sampler state?
Resolved: Texture image state only. Some implementations effectively
treat the the different decode modes as different texture formats.
Revision History
Revision 4, January 23, 2017 - Split functionality in two name strings.
Clarified interaction with
Added issue 5.
Revision 3, January 18, 2017 - Tidy up.
Revision 2, December 6, 2016 - Fixed type errors in rounding operation.
Clarified behavior of negative values in
void-extent blocks when decoding to shared
exponent format.
Revision 1, November 11, 2016 - Initial draft.