Name NV_texture_compression_latc Name Strings GL_NV_texture_compression_latc Contributors Contributors to the OpenGL EXT_texture_compression_latc extension Greg Roth, NVIDIA Contact Ian Stewart, NVIDIA Corporation (istewart 'at' nvidia.com) Status Complete. Version Last Modifed Date: Oct 26, 2012 NVIDIA Revision: 1 Number OpenGL ES Extension #130 Dependencies This extension is written against the OpenGL ES 2.0.25 Specification. This extension interacts with NV_texture_array Overview This extension introduces four new block-based texture compression formats suited for unsigned and signed luminance and luminance-alpha textures (hence the name "latc" for Luminance-Alpha Texture Compression). These formats are designed to reduce the storage requirements and memory bandwidth required for luminance and luminance-alpha textures by a factor of 2-to-1 over conventional uncompressed luminance and luminance-alpha textures with 8-bit components. The compressed signed luminance-alpha format is reasonably suited for storing compressed normal maps. New Tokens Accepted by the parameter of CompressedTexImage2D and CompressedTexSubImage2D: COMPRESSED_LUMINANCE_LATC1_NV 0x8C70 COMPRESSED_SIGNED_LUMINANCE_LATC1_NV 0x8C71 COMPRESSED_LUMINANCE_ALPHA_LATC2_NV 0x8C72 COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_NV 0x8C73 Additions to Chapter 3 of the OpenGL ES 2.0.25 Specification Modify Section 3.7.3, "Compressed Texture Images" (Replace first two sentences with) Texture images may also be specified or modified using image data already stored in a known compressed image format. The GL defines some specific compressed formats, and others may be defined by GL extensions. (Insert after section describing CompressedTexImage2D) The specific compressed texture formats supported by CompressedTexImage2D, and the corresponding base internal format for each specific format, are defined in table 3.X. Table 3.X: "Specific compressed texture formats" Compressed Internal Formats Base Internal Format =========================== ==================== COMPRESSED_LUMINANCE_LATC1_NV LUMINANCE COMPRESSED_SIGNED_LUMINANCE_LATC1_NV LUMINANCE COMPRESSED_LUMINANCE_ALPHA_LATC2_NV LUMINANCE_ALPHA COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_NV LUMINANCE_ALPHA (Replace last paragraph with) If the internal format is one of COMPRESSED_LUMINANCE_LATC1_NV, COMPRESSED_SIGNED_LUMINANCE_LATC1_NV, COMPRESSED_LUMINANCE_ALPHA_LATC2_NV, or COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_NV, the compressed texture is stored using one of the two LATC compressed texture image encodings and is easily edited along 4x4 texel boundaries. In this case, CompressedTexImage2D will result in an INVALID_OPERATION error if one of the following conditions occurs: * is not a multiple of four, and plus is not equal to TEXTURE_WIDTH; * is not a multiple of four, and plus is not equal to TEXTURE_HEIGHT; or * or is not a multiple of four. For any other formats, calling CompressedTexSubImage2D will result in an INVALID_OPERATION error if or is not equal to zero, or if and do not match the width and height of the texture, respectively. The contents of any texel outside the region modified by the call are undefined. These restrictions may be relaxed for other specific compressed internal formats whose images are easily modified. Interactions with NV_texture_array If NV_texture_array is supported, the LATC compressed formats may also be used as the internal formats given to CompressedTexImage3DNV and CompressedTexSubImage3DNV. The restrictions for the , , , and parameters of the CompressedTexSubImage2D function when used with LATC compressed texture formats, described in this extension, also apply to the identically named parameters of CompressedTexSubImage3DNV. Errors INVALID_OPERATION is generated by CopyTexSubImage2D if the texture image bound to has internal format COMPRESSED_LUMINANCE_LATC1_NV, COMPRESSED_SIGNED_LUMINANCE_LATC1_NV, COMPRESSED_LUMINANCE_ALPHA_LATC2_NV, or COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_NV. INVALID_OPERATION is generated by CompressedTexSubImage2D if is COMPRESSED_LUMINANCE_LATC1_NV, COMPRESSED_SIGNED_LUMINANCE_LATC1_NV, COMPRESSED_LUMINANCE_ALPHA_LATC2_NV, or COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_NV and any of the following apply: * is not a multiple of four, and plus is not equal to the texture width; * is not a multiple of four, and plus is not equal to the texture height; or * or is not a multiple of four. New State The queries for NUM_COMPRESSED_TEXTURE_FORMATS and COMPRESSED_TEXTURE_FORMATS include COMPRESSED_LUMINANCE_LATC1_NV, COMPRESSED_SIGNED_LUMINANCE_LATC1_NV, COMPRESSED_LUMINANCE_ALPHA_LATC2_NV, and COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_NV. Appendix LATC Compressed Texture Image Formats Compressed texture images stored using the LATC compressed image encodings are represented as a collection of 4x4 texel blocks, where each block contains 64 or 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 an LATC 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 an LATC image with a width of , height of , and block size of (8 or 16 bytes) is decoded, the corresponding image size (in bytes) is: ceil(/4) * ceil(/4) * blocksize. When decoding an LATC image, the block containing the texel at offset (, ) begins at an offset (in bytes) relative to the base of the image of: blocksize * (ceil(/4) * floor(/4) + floor(/4)). The data corresponding to a specific texel (, ) are extracted from a 4x4 texel block using a relative (x,y) value of ( modulo 4, modulo 4). There are four distinct LATC image formats: COMPRESSED_LUMINANCE_LATC1_NV: Each 4x4 block of texels consists of 64 bits of unsigned luminance image data. Each luminance image data block is encoded as a sequence of 8 bytes, called (in order of increasing address): lum0, lum1, bits_0, bits_1, bits_2, bits_3, bits_4, bits_5 The 6 "bits_*" bytes of the block are decoded into a 48-bit bit vector: bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 + 256 * (bits_4 + 256 * bits_5)))) lum0 and lum1 are 8-bit unsigned integers that are unpacked to luminance values LUM0 and LUM1 as though they were pixels with a of LUMINANCE and a type of UNSIGNED_BTYE. bits is a 48-bit unsigned integer, from which a three-bit control code is extracted for a texel at location (x,y) in the block using: code(x,y) = bits[3*(4*y+x)+2..3*(4*y+x)+0] where bit 47 is the most significant and bit 0 is the least significant bit. The luminance value L for a texel at location (x,y) in the block is given by: LUM0, if lum0 > lum1 and code(x,y) == 0 LUM1, if lum0 > lum1 and code(x,y) == 1 (6*LUM0+ LUM1)/7, if lum0 > lum1 and code(x,y) == 2 (5*LUM0+2*LUM1)/7, if lum0 > lum1 and code(x,y) == 3 (4*LUM0+3*LUM1)/7, if lum0 > lum1 and code(x,y) == 4 (3*LUM0+4*LUM1)/7, if lum0 > lum1 and code(x,y) == 5 (2*LUM0+5*LUM1)/7, if lum0 > lum1 and code(x,y) == 6 ( LUM0+6*LUM1)/7, if lum0 > lum1 and code(x,y) == 7 LUM0, if lum0 <= lum1 and code(x,y) == 0 LUM1, if lum0 <= lum1 and code(x,y) == 1 (4*LUM0+ LUM1)/5, if lum0 <= lum1 and code(x,y) == 2 (3*LUM0+2*LUM1)/5, if lum0 <= lum1 and code(x,y) == 3 (2*LUM0+3*LUM1)/5, if lum0 <= lum1 and code(x,y) == 4 ( LUM0+4*LUM1)/5, if lum0 <= lum1 and code(x,y) == 5 MINLUM, if lum0 <= lum1 and code(x,y) == 6 MAXLUM, if lum0 <= lum1 and code(x,y) == 7 MINLUM and MAXLUM are 0.0 and 1.0 respectively. Since the decoded texel has a luminance format, the resulting RGBA value for the texel is (L,L,L,1). COMPRESSED_SIGNED_LUMINANCE_LATC1_NV: Each 4x4 block of texels consists of 64 bits of signed luminance image data. The luminance values of a texel are extracted in the same way as COMPRESSED_LUMINANCE_LATC1_NV except lum0, lum1, LUM0, LUM1, MINLUM, and MAXLUM are signed values defined as follows: lum0 and lum1 are 8-bit signed (two's complement) integers. { lum0 / 127.0, lum0 > -128 LUM0 = { { -1.0, lum0 == -128 { lum1 / 127.0, lum1 > -128 LUM1 = { { -1.0, lum1 == -128 MINLUM = -1.0 MAXLUM = 1.0 CAVEAT for signed lum0 and lum1 values: the expressions "lum0 > lum1" and "lum0 <= lum1" above are considered undefined (read: may vary by implementation) when lum0 equals -127 and lum1 equals -128, This is because if lum0 were remapped to -127 prior to the comparison to reduce the latency of a hardware decompressor, the expressions would reverse their logic. Encoders for the signed LA formats should avoid encoding blocks where lum0 equals -127 and lum1 equals -128. COMPRESSED_LUMINANCE_ALPHA_LATC2_NV: Each 4x4 block of texels consists of 64 bits of compressed unsigned luminance image data followed by 64 bits of compressed unsigned alpha image data. The first 64 bits of compressed luminance are decoded exactly like COMPRESSED_LUMINANCE_LATC1_NV above. The second 64 bits of compressed alpha are decoded exactly like COMPRESSED_LUMINANCE_LATC1_NV above except the decoded value L for this second block is considered the resulting alpha value A. Since the decoded texel has a luminance-alpha format, the resulting RGBA value for the texel is (L,L,L,A). COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_NV: Each 4x4 block of texels consists of 64 bits of compressed signed luminance image data followed by 64 bits of compressed signed alpha image data. The first 64 bits of compressed luminance are decoded exactly like COMPRESSED_SIGNED_LUMINANCE_LATC1_NV above. The second 64 bits of compressed alpha are decoded exactly like COMPRESSED_SIGNED_LUMINANCE_LATC1_NV above except the decoded value L for this second block is considered the resulting alpha value A. Since this image has a luminance-alpha format, the resulting RGBA value is (L,L,L,A). Issues 1) How are signed integer values mapped to floating-point values? RESOLVED: A signed 8-bit two's complement value X is computed to a floating-point value Xf with the formula: { X / 127.0, X > -128 Xf = { { -1.0, X == -128 This conversion means -1, 0, and +1 are all exactly representable, however -128 and -127 both map to -1.0. Mapping -128 to -1.0 avoids the numerical awkwardness of having a representable value slightly more negative than -1.0. 2) Should the NUM_COMPRESSED_TEXTURE_FORMATS and COMPRESSED_TEXTURE_FORMATS queries return the LATC formats? RESOLVED: No. The OpenGL ES 2.0.25 specification says "The only values returned by this query [GL_COMPRESSED_TEXTURE_FORMATS] are those corresponding to 'internalformat' parameters accepted by CompressedTexImage2D and suitable for general-purpose usage. The renderer will not enumerate formats with restrictions that need to be specifically understood prior to use." Historically, OpenGL implementations have advertised the RGB and RGBA versions of the S3TC extensions compressed format tokens through this mechanism. The specification is not sufficiently clear about what "suitable for general-purpose usage" means. Historically that seems to mean unsigned RGB or unsigned RGBA. The DXT1 format supporting alpha (GL_COMPRESSED_RGBA_S3TC_DXT1_NV) is not exposed in the list (at least for NVIDIA drivers) because the alpha is always 1.0 except when it is 0.0 when RGB is required to be black. NVIDIA's implementation even limits itself to true linear RGB or RGBA formats, specifically not including NV_sRGB_formats's sRGB S3TC compressed formats. Adding luminance and luminance-alpha texture formats (and certainly signed versions of luminance and luminance-alpha formats) invites potential comptaibility problems with old applications using this mechanism since old applications are unlikely to expect non-RGB or non-RGBA formats to be advertised through this mechanism. However no specific misinteractions with old applications is known. Applications that seek to use the LATC formats should do so by looking for this extension's name in the string returned by glGetString(GL_EXTENSIONS) rather than what GL_NUM_COMPRESSED_TEXTURE_FORMATS and GL_COMPRESSED_TEXTURE_FORMATS return. 3) The EXT_texture_compression_latc extension already lists GL_NV_texture_compression_latc as a name string. Do these extensions conflict? RESOLVED: No. The EXT_texture_compression_latc extension, written against the OpenGL 1.3 specification, was originally an NVIDIA-proprietary extension and published as NV_texture_compression_latc. It was later promoted to be an EXT extension, in part with S3, and was renamed. However, NVIDIA OpenGL implementations continue to expose the GL_NV_texture_compression_latc string for legacy reasons. This extension, written against the OpenGL ES 2.0.25 specification, provides a subset of the functionality of EXT_texture_compression_latc limited only by the differences between the OpenGL 1.3 and OpenGL ES 2.0 specifications. For example, format conversion from uncompressed data to compressed LATC formats via TexImage2D is not supported by this extension. If the driver exporting the GL_NV_texture_compression_latc string is an OpenGL ES 2.0 driver (or an OpenGL driver using an ES 2.0 profile), this extension describes the available functionality. Otherwise, see EXT_texture_compression_latc. Revision History Rev. Date Author Changes ---- -------- --------- ------------------------------------- 1 10/26/2012 istewart First revision, based of the EXT_texture_compression_latc specification. # vim:ai:ts=4:sts=4:expandtab:textwidth=70