| 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 <internalformat> 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: |
| |
| * <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. |
| |
| For any other formats, calling CompressedTexSubImage2D will result |
| in an INVALID_OPERATION error if <xoffset> or <yoffset> is not |
| equal to zero, or if <width> and <height> 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 <width>, <height>, <xoffset>, and <yoffset> |
| 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 <level> bound to <target> 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 |
| <internalformat> 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: |
| |
| * <width> is not a multiple of four, and <width> plus |
| <xoffset> is not equal to the texture width; |
| |
| * <height> is not a multiple of four, and <height> plus |
| <yoffset> is not equal to the texture height; or |
| |
| * <xoffset> or <yoffset> 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 <w>, height of <h>, and block |
| size of <blocksize> (8 or 16 bytes) is decoded, the corresponding |
| image size (in bytes) is: |
| |
| ceil(<w>/4) * ceil(<h>/4) * blocksize. |
| |
| When decoding an LATC 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 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 <format> 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 |