blob: 3da77d386f455865353529129902afca520773f5 [file] [log] [blame]
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