Name ARB_compressed_texture_pixel_storage Name Strings GL_ARB_compressed_texture_pixel_storage Contact Piers Daniell, NVIDIA Corporation (pdaniell 'at' nvidia.com) Contributors Bruce Merry, ARM Daniel Koch, TransGaming Jeff Bolz, NVIDIA Pat Brown, NVIDIA Patrick Doane, Blizzard Notice Copyright (c) 2011-2013 The Khronos Group Inc. Copyright terms at http://www.khronos.org/registry/speccopyright.html Specification Update Policy Khronos-approved extension specifications are updated in response to issues and bugs prioritized by the Khronos OpenGL Working Group. For extensions which have been promoted to a core Specification, fixes will first appear in the latest version of that core Specification, and will eventually be backported to the extension document. This policy is described in more detail at https://www.khronos.org/registry/OpenGL/docs/update_policy.php Status Complete. Approved by the ARB on 2011/06/20. Approved by the Khronos Promoters on 2011/07/29. Version Last Modified Date: April 26, 2011 Revision: 8 Number ARB Extension #110 Dependencies OpenGL 1.2 is required. This extension is written against The OpenGL 4.1 (Compatibility Profile) specification. Overview This extension expands the functionality of the PixelStore modes to allow UNPACK_ROW_LENGTH, UNPACK_SKIP_ROWS, UNPACK_SKIP_PIXELS, UNPACK_IMAGE_HEIGHT and UNPACK_SKIP_IMAGES to affect the operation of CompressedTexImage*D and CompressedTexSubImage*D. Similarly, it also allows PACK_ROW_LENGTH, PACK_SKIP_ROWS, PACK_SKIP_PIXELS, PACK_IMAGE_HEIGHT and PACK_SKIP_IMAGES to affect the operation of GetCompressedTexImage*D. This allows data to be transferred to or from a specified sub-rectangle of a larger compressed image. This extension is designed primarily to support compressed image formats with fixed-size blocks. To use this new mechanism, an application should program new parameters UNPACK_COMPRESSED_BLOCK_ {WIDTH,HEIGHT,DEPTH,SIZE} to indicate the number of texels in each dimension of the fixed-size block as well as the number of bytes consumed by each block. These parameters, in addition to the existing PixelStore parameters, are used to identify a collection of bytes in client memory or a buffer object's data store to use as compressed texture data. This operation is unlikely to have the desired results if the client programs a block size inconsistent with the underlying compressed image format, or if the compressed image format has variable-sized blocks. New Procedures and Functions None New Tokens Accepted by the parameter of PixelStore[fi], GetBooleanv, GetIntegerv, GetInteger64v, GetFloatv, and GetDoublev: UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 UNPACK_COMPRESSED_BLOCK_SIZE 0x912A PACK_COMPRESSED_BLOCK_WIDTH 0x912B PACK_COMPRESSED_BLOCK_HEIGHT 0x912C PACK_COMPRESSED_BLOCK_DEPTH 0x912D PACK_COMPRESSED_BLOCK_SIZE 0x912E Changes to Section 3.7.4 (Pixel Storage Modes and Pixel Buffer Objects), page 229 Replace the section in the first paragraph, page 229 that states: "Pixel storage modes affect the operation of TexImage*D, TexSubImage*D, DrawPixels, and ReadPixels (as well as other commands; see sections 3.6.2 and 3.8) when one of these commands is issued." With the following: "Pixel storage modes affect the operation of TexImage*D, TexSubImage*D, CompressedTexImage*D, CompressedTexSubImage*d, DrawPixels, and ReadPixels (as well as other commands; see sections 3.6.2 and 3.8) when one of these commands is issued." Modify Table 3.1 description to: "Table 3.1: PixelStore parameters pertaining to one or more of DrawPixels, ColorTable, ColorSubTable, ConvolutionFilter1D, ConvolutionFilter2D, SeparableFilter2D, PolygonStipple, TexImage1D, TexImage2D, TexImage3D, TexSubImage1D, TexSubImage2D, TexSubImage3D, CompressedTexImage1D, CompressedTexImage2D, CompressedTexImage3D, CompressedTexSubImage1D, CompressedTexSubImage2D and CompressedTexSubImage3D." Add to Table 3.1 contents with the following new entries: Parameter Name Type Initial Value Valid Range ------------------------------------------------------------------------- UNPACK_COMPRESSED_BLOCK_WIDTH integer 0 [0,inf) UNPACK_COMPRESSED_BLOCK_HEIGHT integer 0 [0,inf) UNPACK_COMPRESSED_BLOCK_DEPTH integer 0 [0,inf) UNPACK_COMPRESSED_BLOCK_SIZE integer 0 [0,inf) Changes to Section 3.9.5 (Compressed Texture Images), page 297 In the paragraph that starts "For all other compressed internal formats..." remove the following sentence: "All pixel storage and pixel transfer modes are ignored when decoding a compressed texture image." Add a new paragraph which states: "If the compressed data are arranged into fixed-size blocks of texels the pixel storage modes can be used to select a sub-rectangle from a larger containing rectangle. These pixel storage modes operate in the same way as they do for TexImage*D and as described in section 3.7.4. By default the pixel storage modes UNPACK_ROW_LENGTH, UNPACK_SKIP_ROWS, UNPACK_SKIP_PIXELS, UNPACK_IMAGE_HEIGHT and UNPACK_SKIP_IMAGES are ignored for compressed images. To enable UNPACK_SKIP_PIXELS and UNPACK_ROW_LENGTH both UNPACK_COMPRESSED_BLOCK_SIZE and UNPACK_COMPRESSED_BLOCK_WIDTH must be non-zero. To also enable UNPACK_SKIP_ROWS and UNPACK_IMAGE_HEIGHT, UNPACK_COMPRESSED_BLOCK_HEIGHT must be non-zero. And to also enable UNPACK_SKIP_IMAGES, UNPACK_COMPRESSED_BLOCK_DEPTH must be non-zero. Use UNPACK_COMPRESSED_BLOCK_WIDTH to specify the block width in pixels, UNPACK_COMPRESSED_BLOCK_HEIGHT to specify the block height in pixels, UNPACK_COMPRESSED_BLOCK_DEPTH to specify the block depth in pixels and UNPACK_COMPRESSED_BLOCK_SIZE to specify the block size in bytes. All parameters need to be consistent with the compressed format to produce the desired results. When selecting a sub-rectangle from a compressed image: * the UNPACK_SKIP_PIXELS parameter must be a multiple of the UNPACK_COMPRESSED_BLOCK_WIDTH parameter; * the UNPACK_SKIP_ROWS parameter must be a multiple of the UNPACK_COMPRESSED_BLOCK_HEIGHT parameter for CompressedTexImage2D and CompressedTexImage3D; * the UNPACK_SKIP_IMAGES parameter must be a multiple of the UNPACK_COMPRESSED_BLOCK_DEPTH parameter for CompressedTexImage3D. The error INVALID_OPERATION will be generated if any of the previous conditions are violated. For CompressedTexImage1D the parameter must be equal to: UNPACK_COMPRESSED_BLOCK_SIZE * ceil( / UNPACK_COMPRESSED_BLOCK_WIDTH) For CompressedTexImage2D the parameter must be equal to: UNPACK_COMPRESSED_BLOCK_SIZE * ceil( / UNPACK_COMPRESSED_BLOCK_WIDTH) * ceil( / UNPACK_COMPRESSED_BLOCK_HEIGHT) For CompressedTexImage3D the parameter must be equal to: UNPACK_COMPRESSED_BLOCK_SIZE * ceil( / UNPACK_COMPRESSED_BLOCK_WIDTH) * ceil( / UNPACK_COMPRESSED_BLOCK_HEIGHT) * ceil( / UNPACK_COMPRESSED_BLOCK_DEPTH) The error INVALID_VALUE will be generated if does not match this requirement when pixel storage modes are active. Based on the definition of Unpacking from Section 3.7.4 for uncompressed images, unpacking compressed images can be defined where: * "n", the number of elements in a group, is 1 * "s", the size of an element, is UNPACK_COMPRESSED_BLOCK_SIZE * "l", the number of groups in a row, is ceil(UNPACK_ROW_LENGTH / UNPACK_COMPRESSED_BLOCK_WIDTH), where UNPACK_ROW_LENGTH is positive otherwise it's ceil( / UNPACK_COMPRESSED_BLOCK_WIDTH) * "a", the value of UNPACK_ALIGNMENT is ignored and * "k=nl" as is defined for uncompressed images. Before obtaining the first compressed image block from memory, the pointer is advanced by (UNPACK_SKIP_PIXELS / UNPACK_COMPRESSED_BLOCK_WIDTH) * "n" + (UNPACK_SKIP_ROWS / UNPACK_COMPRESSED_BLOCK_HEIGHT) * "k" elements. Then ceil( / UNPACK_COMPRESSED_BLOCK_WIDTH) blocks are obtained from contiguous blocks in memory (without advancing the pointer), after which the pointer is advanced by "k" elements. ceil( / UNPACK_COMPRESSED_BLOCK_HEIGHT) sets of ceil( / UNPACK_COMPRESSED_BLOCK_WIDTH) blocks are obtained this way. For three-dimensional compressed images the pointer is advanced by (UNPACK_SKIP_IMAGES / UNPACK_COMPRESSED_BLOCK_DEPTH) times the number of elements in one two-dimensional image before obtaining the first group from memory. Then after rows are obtained the pointer skips over the remaining ceil(UNPACK_IMAGE_HEIGHT / UNPACK_COMPRESSED_BLOCK_HEIGHT) rows, if UNPACK_IMAGE_HEIGHT is positive before starting the next two- dimensional image." Changes to Section 4.3.2 (Reading Pixels), page 380 Modify Table 4.7, page 382, description to: "Table 4.7: PixelStore parameters pertaining to ReadPixels, GetColorTable, GetConvolutionFilter, GetSeparableFilter, GetHistogram, GetMinmax, GetPolygonStipple, GetTexImage, and GetCompressedTexImage." Add to Table 4.7 contents with the following new entries: Parameter Name Type Initial Value Valid Range ------------------------------------------------------------------------- PACK_COMPRESSED_BLOCK_WIDTH integer 0 [0,inf) PACK_COMPRESSED_BLOCK_HEIGHT integer 0 [0,inf) PACK_COMPRESSED_BLOCK_DEPTH integer 0 [0,inf) PACK_COMPRESSED_BLOCK_SIZE integer 0 [0,inf) Changes to Section 6.1.4 (Texture Queries), page 446 In the paragraph that talks about GetCompressedTexImage remove the following sentence: "All pixel storage and pixel transfer modes are ignored when returning a compressed texture image." Add a new paragraph at this point with the following contents: "By default the pixel storage modes PACK_ROW_LENGTH, PACK_SKIP_ROWS, PACK_SKIP_PIXELS, PACK_IMAGE_HEIGHT and PACK_SKIP_IMAGES are ignored for compressed images. To enable PACK_SKIP_PIXELS and PACK_ROW_LENGTH both PACK_COMPRESSED_BLOCK_SIZE and PACK_COMPRESSED_BLOCK_WIDTH must be non- zero. To also enable PACK_SKIP_ROWS and PACK_IMAGE_HEIGHT, PACK_COMPRESSED_BLOCK_HEIGHT must be non-zero. And to also enable PACK_SKIP_IMAGES, PACK_COMPRESSED_BLOCK_DEPTH must be non-zero. All parameters need to be consistent with the compressed format to produce the desired results. When the pixel storage modes are active, the correspondence of texels to memory locations is as defined for CompressedTexImage3D in section 3.9.5." Additions to the AGL/GLX/WGL Specifications None Errors None New State (Table 6.37, Pixels) add the following: Get Value Type Get Command Initial Value Description Section ------------- ---- ----------- ------------- ----------- ------- UNPACK_COMPRESSED_BLOCK_WIDTH Z+ GetIntegerv 0 Value of UNPACK_COMPRESSED_BLOCK_WIDTH 3.7.4 UNPACK_COMPRESSED_BLOCK_HEIGHT Z+ GetIntegerv 0 Value of UNPACK_COMPRESSED_BLOCK_HEIGHT 3.7.4 UNPACK_COMPRESSED_BLOCK_DEPTH Z+ GetIntegerv 0 Value of UNPACK_COMPRESSED_BLOCK_DEPTH 3.7.4 UNPACK_COMPRESSED_BLOCK_SIZE Z+ GetIntegerv 0 Value of UNPACK_COMPRESSED_BLOCK_SIZE 3.7.4 PACK_COMPRESSED_BLOCK_WIDTH Z+ GetIntegerv 0 Value of PACK_COMPRESSED_BLOCK_WIDTH 4.3.2 PACK_COMPRESSED_BLOCK_HEIGHT Z+ GetIntegerv 0 Value of PACK_COMPRESSED_BLOCK_HEIGHT 4.3.2 PACK_COMPRESSED_BLOCK_DEPTH Z+ GetIntegerv 0 Value of PACK_COMPRESSED_BLOCK_DEPTH 4.3.2 PACK_COMPRESSED_BLOCK_SIZE Z+ GetIntegerv 0 Value of PACK_COMPRESSED_BLOCK_SIZE 4.3.2 New Implementation Dependent State None Issues 1) How do indirect rendering implementations deal with this? They don't know what compressed format is used. RESOLVED: By specifying the BLOCK sizes in the PixelStore parameters the client side implementation has enough information to transfer the minimal amount of data to satisfy the API request without needing detailed knowledge of the compression format. So from the client to server data transfer point of view, it's still just a memcpy of the client data without interpretation based on the compression format. 2) Do we enforce that the block size parameters match those of the format being manipulated? RESOLVED: No. They are only used for this memcpy operation. The issue is that PixelStore is client state, while the actual format of the texture is server state that may not even be knowable by the client. If the user indicates that he is dealing in 8x2 64-bit blocks, the client may not be able to figure out that it doesn't accurately describe the actual format (e.g., DXT1 using 4x4 64-bit blocks). However, we don't really care. These parameters are used (along with the API call parameters) to indicate a collection of bytes to read. The client extracts those bytes and transfers them to the server for further processing. If the byte count isn't consistent with the width/height/internalformat parameters, the server complains. If the byte count is consistent, the server just accepts the data extracted by the client as-is. For example, let's say we specified a 16x16 DXT1 image. That would have the server looking for a 4x4 array of blocks (128B total). If the user said the blocks were 8x2 and 64-bit, the client would transmit a 2x8 array of blocks (still 128B). We'd get no error. However, if the image were 12x12, the server would want a 3x3 array of blocks, while the client would want to transmit a 2x6 array of blocks because the rightmost "8x2" blocks are partial and would be padded out as though the image were 16x12. In that case, the byte counts wouldn't be consistent. 3) Do we need to specify what happens with a hypothetical variable-size block format? RESOLVED: These new "block size" parameters are used to collect scattered bytes from user memory into a single block of "sub image" memory, and they don't care what the format is. 4) Do these new parameters affect TexImage* calls with compressed internal formats? RESOLVED: No, they only affect CompressedTexImage*, CompressedTexSubImage* and GetCompressedTexImage* APIs, where the texels specified or queried are specified or returned in compressed form. In desktop OpenGL, it is possible to specify or query texels for textures with compressed internal formats using APIs like TexImage*, using non-compressed and arguments. In these cases, previously existing PixelStore parameters already applied to the specified image. 5) Should {UN}PACK_ROW_LENGTH and {UN}PACK_IMAGE_HEIGHT be required to be in multiples of the block size? RESOLVED: It's not necessary since the rounding in the specified compressed image unpacking will round up to the next block size and produce a valid result. Revision History Rev. Date Author Changes ---- -------- -------- ----------------------------------------------- 8 04/26/11 pdaniell Fix language which specifies what parameters need to be non-zero for {UN}PACK_IMAGE_HEIGHT to be used. 7 04/21/11 pdaniell Add final enum values. 6 12/15/10 pdaniell Resolve issues 2 and 5. 5 11/29/10 pdaniell Fix typo. 4 11/10/10 pdaniell Fixes based on feedback from Bruce and Pat in bug 7016. 3 11/05/10 pdaniell Resolve issue (2). 2 11/04/10 pdaniell Fixed typos and feedback from bug 6998. Moved edits from Core to Compatibility profile. Further clarifications from internal review. 1 10/19/10 pdaniell Initial version.