NV_texture_compression_latc

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