| Name |
| |
| EXT_texture_compression_astc_decode_mode |
| |
| Name Strings |
| |
| GL_EXT_texture_compression_astc_decode_mode |
| GL_EXT_texture_compression_astc_decode_mode_rgb9e5 |
| |
| Contact |
| |
| Jan-Harald Fredriksen (jan-harald.fredriksen 'at' arm.com) |
| |
| Contributors |
| |
| Edvard Fielding |
| Jan-Harald Fredriksen |
| Jakob Fries |
| Tom Olson |
| Jorn Nystad |
| |
| IP Status |
| |
| No known issues. |
| |
| Status |
| |
| DRAFT |
| |
| Version |
| |
| Version 4, January 23, 2017 |
| |
| Number |
| |
| OpenGL ES Extension #276 |
| |
| Dependencies |
| |
| 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. |
| |
| Overview |
| |
| 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 |
| GL_EXT_texture_compression_astc_decode_mode |
| - 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 |
| |
| None |
| |
| New Tokens |
| |
| Accepted by the <pname> parameter of TexParameter* and GetTexParameter*: |
| |
| TEXTURE_ASTC_DECODE_PRECISION_EXT 0x8F69 |
| |
| Changes to 8.10 Texture Parameters |
| |
| Add to Table 8.19: Texture parameters and their values: |
| |
| ----------------------------------------------------------------------------- |
| Name Type Legal Values |
| ----------------------------------------------------------------------------- |
| TEXTURE_ASTC_DECODE_PRECISION_EXT enum GL_RGBA16F |
| GL_RGBA8 |
| 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; |
| } |
| else |
| { |
| 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 |
| PRECISION_EXT |
| |
| |
| 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. |
| |
| Issues |
| |
| (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 |
| KHR_texture_compression_astc_hdr |
| 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. |
| |