1Name 2 3 OES_texture_compression_astc 4 5Name Strings 6 7 GL_OES_texture_compression_astc 8 GL_KHR_texture_compression_astc_hdr 9 GL_KHR_texture_compression_astc_ldr 10 11Contact 12 13 Sean Ellis (sean.ellis 'at' arm.com) 14 15Contributors 16 17 Sean Ellis, ARM 18 Jorn Nystad, ARM 19 Tom Olson, ARM 20 Andy Pomianowski, AMD 21 Cass Everitt, NVIDIA 22 Walter Donovan, NVIDIA 23 Robert Simpson, Qualcomm 24 Maurice Ribble, Qualcomm 25 Larry Seiler, Intel 26 Daniel Koch, Transgaming 27 Anthony Wood, Imagination Technologies 28 Andrew Garrard, Samsung 29 30Notice 31 32 Copyright (c) 2013-2016 The Khronos Group Inc. Copyright terms at 33 http://www.khronos.org/registry/speccopyright.html 34 35Specification Update Policy 36 37 Khronos-approved extension specifications are updated in response to 38 issues and bugs prioritized by the Khronos OpenGL ES Working Group. For 39 extensions which have been promoted to a core Specification, fixes will 40 first appear in the latest version of that core Specification, and will 41 eventually be backported to the extension document. This policy is 42 described in more detail at 43 https://www.khronos.org/registry/OpenGL/docs/update_policy.php 44 45IP Status 46 47 No known issues. 48 49Status 50 51 Ratified by the Khronos Board of Promoters, 27 September 2013 52 53Version 54 55 Last Modified Date: December 12, 2022 56 57Number 58 59 OpenGL ES Extension #162 60 61Dependencies 62 63 Written based on the wording of the OpenGL ES 3.0 specification 64 65Overview 66 67 Adaptive Scalable Texture Compression (ASTC) is a new texture 68 compression technology that offers unprecendented flexibility, 69 while producing better or comparable results than existing texture 70 compressions at all bit rates. It includes support for 2D and 3D 71 textures, with low and high dynamic range, at bitrates from below 72 1 bit/pixel up to 8 bits/pixel in fine steps. 73 74 The goal of this extension is to support the full profile of the 75 ASTC texture compression specification. 76 77 ASTC-compressed textures are handled in OpenGL ES and OpenGL by 78 adding new supported formats to the existing mechanisms for handling 79 compressed textures. 80 81Issues 82 83Interactions with Other Extensions 84 85 EXT_texture_storage affects the definition of this extension. 86 87 Extends extension KHR_texture_compression_astc_ldr and 88 KHR_texture_compression_astc_hdr. 89 90Interactions with OpenGL 4.2 91 92 OpenGL 4.2 supports the feature that compressed textures can be 93 compressed online, by passing the compressed texture format enum as 94 the internal format when uploading a texture using TexImage1D, 95 TexImage2D or TexImage3D (see Section 3.9.3, Texture Image 96 Specification, subsection Encoding of Special Internal Formats). 97 98 Due to the complexity of the ASTC compression algorithm, it is not 99 usually suitable for online use, and therefore ASTC support will be 100 limited to pre-compressed textures only. Where on-device compression 101 is required, a domain-specific limited compressor will typically 102 be used, and this is therefore not suitable for implementation in 103 the driver. 104 105 In particular, the ASTC format specifiers will not be added to 106 Table 3.14, and thus will not be accepted by the TexImage*D 107 functions, and will not be returned by the (already deprecated) 108 COMPRESSED_TEXTURE_FORMATS query. 109 110New Procedures and Functions 111 112 None 113 114New Tokens 115 116 Accepted by the <format> parameter of CompressedTexSubImage2D, and 117 by the <internalformat> parameter of CompressedTexImage2D, TexStorage2D, 118 TextureStorage2D, TexStorage3D, and TextureStorage3D: 119 120 COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 121 COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 122 COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 123 COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 124 COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 125 COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 126 COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 127 COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 128 COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 129 COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 130 COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA 131 COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB 132 COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC 133 COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD 134 135 COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 136 COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 137 COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 138 COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 139 COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 140 COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 141 COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 142 COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 143 COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 144 COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 145 COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA 146 COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB 147 COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC 148 COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD 149 150 If extension "EXT_texture_storage" is supported, these tokens are also 151 accepted by TexStorage2DEXT, TextureStorage2DEXT, TexStorage3DEXT and 152 TextureStorage3DEXT. 153 154 Accepted by the <format> parameter of CompressedTexSubImage3D, and 155 by the <internalformat> parameter of CompressedTexImage3D, TexStorage3D, 156 and TextureStorage3D: 157 158 COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0 159 COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1 160 COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2 161 COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3 162 COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4 163 COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5 164 COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6 165 COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7 166 COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8 167 COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9 168 169 COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0 170 COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1 171 COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2 172 COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3 173 COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4 174 COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5 175 COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6 176 COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7 177 COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8 178 COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9 179 180 If extension "EXT_texture_storage" is supported, these tokens are also 181 accepted by TexStorage3DEXT and TextureStorage3DEXT. 182 183Additions to Chapter 2 of the OpenGL ES 3.0 Specification (OpenGL ES 184Operation) 185 186 None 187 188Additions to Chapter 3 of the OpenGL ES 3.0 Specification (Rasterization) 189 190 Added to Section 3.8.6, Compressed Texture Images 191 192 Add the tokens specified above to Table 3.16, Compressed Internal Formats. 193 In all cases, the base internal format will be RGBA. The encoding allows 194 images to be encoded with fewer channels, but this is always presented as 195 RGBA to the sampler. 196 197 After the paragraph discussing ETC2/EAC formats, add: 198 199 "If internalformat is one of the ASTC formats described in table 3.16, 200 the compressed image data is stored using one of the ASTC compressed 201 texture image encodings (see appendix C). The ASTC texture compression 202 algorithm supports both two- and three-dimensional images. If 203 internalformat is a 2D ASTC format, CompressedTexImage3D will accept an 204 array of compressed data consisting of multiple rows of compressed 205 blocks laid out as described in Section 3.8.3. If 206 internalformat is a 3D ASTC format, CompressedTexImage2D will generate 207 an INVALID_OPERATION error. If internalformat is a 3D ASTC format and 208 target is not TEXTURE_3D, CompressedTexImage3D will generate an 209 INVALID_OPERATION error. If internalformat is a 3D ASTC format, 210 and only the ASTC LDR or HDR Profile is supported, then 211 CompressedTexImage3D will also generate an INVALID_OPERATION error." 212 213 At the end of the section, add: 214 215 "If internalformat is one of the ASTC formats described in table 3.16, the 216 texture is stored using one of the ASTC compressed texture image 217 encodings (see appendix C). Since ASTC images are easily edited along 218 block footprint boundaries, the limitations on subimage location and size 219 are as follows for CompressedTexSubImage2D and CompressedTexSubImage3D. 220 These commands will result in an INVALID_OPERATION error if one of the 221 following conditions occurs: 222 * width is not a multiple of the block width, and width + xoffset is not 223 equal to the width of the texture level. 224 * height is not a multiple of block height, and height+yoffset is not 225 equal to the height of the texture level. 226 * depth is not a multiple of block depth, and depth+zoffset is not 227 equal to the depth of the texture level. (If a 3D image is constructed 228 from 2D slices, the block depth is treated as 1.) 229 * xoffset, yoffset or zoffset is not a multiple of the corresponding 230 block dimension. 231 The contents of any block of texels of an ASTC compressed texture 232 image that does not intersect the area being modified are preserved 233 during valid CompressedTexSubImage* calls. 234 235 The block width, height and depth for each ASTC format are determined 236 according to Table 3.17: 237 238 -------------------------------------------------------------- 239 Block 240 Compressed Internal Format Width Height Depth 241 -------------------------------------------------------------- 242 COMPRESSED_RGBA_ASTC_4x4_KHR 4 4 243 COMPRESSED_RGBA_ASTC_5x4_KHR 5 4 244 COMPRESSED_RGBA_ASTC_5x5_KHR 5 5 245 COMPRESSED_RGBA_ASTC_6x5_KHR 6 5 246 COMPRESSED_RGBA_ASTC_6x6_KHR 6 6 247 COMPRESSED_RGBA_ASTC_8x5_KHR 8 5 248 COMPRESSED_RGBA_ASTC_8x6_KHR 8 6 249 COMPRESSED_RGBA_ASTC_8x8_KHR 8 8 250 COMPRESSED_RGBA_ASTC_10x5_KHR 10 5 251 COMPRESSED_RGBA_ASTC_10x6_KHR 10 6 252 COMPRESSED_RGBA_ASTC_10x8_KHR 10 8 253 COMPRESSED_RGBA_ASTC_10x10_KHR 10 10 254 COMPRESSED_RGBA_ASTC_12x10_KHR 12 10 255 COMPRESSED_RGBA_ASTC_12x12_KHR 12 12 256 257 COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 4 4 258 COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 5 4 259 COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 5 5 260 COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 6 5 261 COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 6 6 262 COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 8 5 263 COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 8 6 264 COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 8 8 265 COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 10 5 266 COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 10 6 267 COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 10 8 268 COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 10 10 269 COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 12 10 270 COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 12 12 271 272 COMPRESSED_RGBA_ASTC_3x3x3_OES 3 3 3 273 COMPRESSED_RGBA_ASTC_4x3x3_OES 4 3 3 274 COMPRESSED_RGBA_ASTC_4x4x3_OES 4 4 3 275 COMPRESSED_RGBA_ASTC_4x4x4_OES 4 4 4 276 COMPRESSED_RGBA_ASTC_5x4x4_OES 5 4 4 277 COMPRESSED_RGBA_ASTC_5x5x4_OES 5 5 4 278 COMPRESSED_RGBA_ASTC_5x5x5_OES 5 5 5 279 COMPRESSED_RGBA_ASTC_6x5x5_OES 6 5 5 280 COMPRESSED_RGBA_ASTC_6x6x5_OES 6 6 5 281 COMPRESSED_RGBA_ASTC_6x6x6_OES 6 6 6 282 283 COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 3 3 3 284 COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 4 3 3 285 COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 4 4 3 286 COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 4 4 4 287 COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 5 4 4 288 COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 5 5 4 289 COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 5 5 5 290 COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 6 5 5 291 COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 6 6 5 292 COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 6 6 6 293 -------------------------------------------------------------- 294 295 Table 3.17: Compressed ASTC Format Block Sizes" 296 297 Added to Section 3.8.15: 298 299 The list of converted internal formats at the start of this section must 300 be expanded to include all of the COMPRESSED_SRGB8_ALPHA8_ASTC_*_KHR and 301 COMPRESSED_SRGB8_ALPHA8_ASTC_*_OES formats. 302 303Additions to Chapter 4 of the OpenGL ES 3.0 Specification (Per-Fragment 304 Operations and the Framebuffer) 305 306 None 307 308Additions to Chapter 5 of the OpenGL ES 3.0 Specification (Special Functions) 309 310 None 311 312Additions to Chapter 6 of the OpenGL ES 3.0 Specification (State and 313 State Requests) 314 315 None 316 317Additions to Appendix A of the OpenGL ES 3.0 Specification (Invariance) 318 319 None 320 321Additions to Appendix B of the OpenGL ES 3.0 Specification (Corollaries) 322 323 None 324 325Additions to Appendix C of the OpenGL ES 3.0 Specification (Compressed 326 Texture Image Formats) 327 328 Add a new sub-section on ASTC image formats, as follows: 329 330 C.2 ASTC Compressed Texture Image Formats 331 ========================================= 332 333 C.2.1 What is ASTC? 334 --------------------- 335 336 ASTC stands for Adaptive Scalable Texture Compression. 337 The ASTC formats form a family of related compressed texture image 338 formats. They are all derived from a common set of definitions. 339 340 ASTC textures may be either 2D or 3D. 341 342 ASTC textures may be encoded using either high or low dynamic range. 343 Low dynamic range images may optionally be specified using the sRGB 344 color space for the RGB channels. 345 346 Two sub-profiles ("LDR Profile" and "HDR Profile") may be implemented, 347 which support only 2D images at low or high dynamic range respectively. 348 The LDR profile is indicated by the presence of only the extension 349 string "GL_KHR_texture_compression_astc_ldr". If the HDR profile is 350 implemented, both "GL_KHR_texture_compression_astc_ldr" 351 and "GL_KHR_texture_compression_astc_hdr" must be published. If the full 352 profile (including 3D textures) is implemented, then all three extension 353 strings "GL_KHR_texture_compression_astc_ldr", 354 "GL_KHR_texture_compression_astc_hdr" 355 and "GL_OES_texture_compression_astc" must be published. 356 357 ASTC textures may be encoded as 1, 2, 3 or 4 components, but they are 358 all decoded into RGBA. 359 360 ASTC has a variable block size, and this is specified as part of the 361 name of the token passed to CompressedImage2D and its related functions. 362 363 C.2.2 Design Goals 364 -------------------- 365 366 The design goals for the format are as follows: 367 368 * Random access. This is a must for any texture compression format. 369 * Bit exact decode. This is a must for conformance testing and 370 reproducibility. 371 * Suitable for mobile use. The format should be suitable for both 372 desktop and mobile GPU environments. It should be low bandwidth 373 and low in area. 374 * Flexible choice of bit rate. Current formats only offer a few bit 375 rates, leaving content developers with only coarse control over 376 the size/quality tradeoff. 377 * Scalable and long-lived. The format should support existing R, RG, 378 RGB and RGBA image types, and also have high "headroom", allowing 379 continuing use for several years and the ability to innovate in 380 encoders. Part of this is the choice to include HDR and 3D. 381 * Feature orthogonality. The choices for the various features of the 382 format are all orthogonal to each other. This has three effects: 383 first, it allows a large, flexible configuration space; second, 384 it makes that space easier to understand; and third, it makes 385 verification easier. 386 * Best in class at given bit rate. It should beat or match the current 387 best in class for peak signal-to-noise ratio (PSNR) at all bit rates. 388 * Fast decode. Texel throughput for a cached texture should be one 389 texel decode per clock cycle per decoder. Parallel decoding of several 390 texels from the same block should be possible at incremental cost. 391 * Low bandwidth. The encoding scheme should ensure that memory access 392 is kept to a minimum, cache reuse is high and memory bandwidth for 393 the format is low. 394 * Low area. It must occupy comparable die size to competing formats. 395 396 C.2.3 Basic Concepts 397 ---------------------- 398 399 ASTC is a block-based lossy compression format. The compressed image 400 is divided into a number of blocks of uniform size, which makes it 401 possible to quickly determine which block a given texel resides in. 402 403 Each block has a fixed memory footprint of 128 bits, but these bits 404 can represent varying numbers of texels (the block "footprint"). 405 406 Block footprint sizes are not confined to powers-of-two, and are 407 also not confined to be square. They may be 2D, in which case the 408 block dimensions range from 4 to 12 texels, or 3D, in which case 409 the block dimensions range from 3 to 6 texels. 410 411 Decoding one texel requires only the data from a single block. This 412 simplifies cache design, reduces bandwidth and improves encoder throughput. 413 414 C.2.4 Block Encoding 415 ---------------------- 416 417 To understand how the blocks are stored and decoded, it is useful to start 418 with a simple example, and then introduce additional features. 419 420 The simplest block encoding starts by defining two color "endpoints". The 421 endpoints define two colors, and a number of additional colors are generated 422 by interpolating between them. We can define these colors using 1, 2, 3, 423 or 4 components (usually corresponding to R, RG, RGB and RGBA textures), 424 and using low or high dynamic range. 425 426 We then store a color interpolant weight for each texel in the image, which 427 specifies how to calculate the color to use. From this, a weighted average 428 of the two endpoint colors is used to generate the intermediate color, 429 which is the returned color for this texel. 430 431 There are several different ways of specifying the endpoint colors, and the 432 weights, but once they have been defined, calculation of the texel colors 433 proceeds identically for all of them. Each block is free to choose whichever 434 encoding scheme best represents its color endpoints, within the constraint 435 that all the data fits within the 128 bit block. 436 437 For blocks which have a large number of texels (e.g. a 12x12 block), there is 438 not enough space to explicitly store a weight for every texel. In this case, 439 a sparser grid with fewer weights is stored, and interpolation is used to 440 determine the effective weight to be used for each texel position. This allows 441 very low bit rates to be used with acceptable quality. This can also be used 442 to more efficiently encode blocks with low detail, or with strong vertical 443 or horizontal features. 444 445 For blocks which have a mixture of disparate colors, a single line in the 446 color space is not a good fit to the colors of the pixels in the original 447 image. It is therefore possible to partition the texels into multiple sets, 448 the pixels within each set having similar colors. For each of these 449 "partitions", we specify separate endpoint pairs, and choose which pair of 450 endpoints to use for a particular texel by looking up the partition index 451 from a partitioning pattern table. In ASTC, this partition table is actually 452 implemented as a function. 453 454 The endpoint encoding for each partition is independent. 455 456 For blocks which have uncorrelated channels - for example an image with a 457 transparency mask, or an image used as a normal map - it may be necessary 458 to specify two weights for each texel. Interpolation between the components 459 of the endpoint colors can then proceed independently for each "plane" of 460 the image. The assignment of channels to planes is selectable. 461 462 Since each of the above options is independent, it is possible to specify any 463 combination of channels, endpoint color encoding, weight encoding, 464 interpolation, multiple partitions and single or dual planes. 465 466 Since these values are specified per block, it is important that they are 467 represented with the minimum possible number of bits. As a result, these 468 values are packed together in ways which can be difficult to read, but 469 which are nevertheless highly amenable to hardware decode. 470 471 All of the values used as weights and color endpoint values can be specified 472 with a variable number of bits. The encoding scheme used allows a fine- 473 grained tradeoff between weight bits and color endpoint bits using "integer 474 sequence encoding". This can pack adjacent values together, allowing us to 475 use fractional numbers of bits per value. 476 477 Finally, a block may be just a single color. This is a so-called "void 478 extent block" and has a special coding which also allows it to identify 479 nearby regions of single color. This may be used to short-circuit fetching of 480 what would be identical blocks, and further reduce memory bandwidth. 481 482 C.2.5 LDR and HDR Modes 483 ------------------------- 484 485 The decoding process for LDR content can be simplified if it is known in 486 advance that sRGB output is required. This selection is therefore included 487 as part of the global configuration. 488 489 The two modes differ in various ways. 490 491 ----------------------------------------------------------------------------- 492 Operation LDR Mode HDR Mode 493 ----------------------------------------------------------------------------- 494 Returned value Vector of FP16 values, Vector of FP16 values 495 or Vector of UNORM8 values. 496 497 sRGB compatible Yes No 498 499 LDR endpoint 16 bits, or 16 bits 500 decoding precision 8 bits for sRGB 501 502 HDR endpoint mode Error color As decoded 503 results 504 505 Error results Error color Vector of NaNs (0xFFFF) 506 ----------------------------------------------------------------------------- 507 Table C.2.1 - Differences Between LDR and HDR Modes 508 509 The error color is opaque fully-saturated magenta 510 (R,G,B,A = 0xFF, 0x00, 0xFF, 0xFF). This has been chosen as it is much more 511 noticeable than black or white, and occurs far less often in valid images. 512 513 For linear RGB decode, the error color may be either opaque fully-saturated 514 magenta (R,G,B,A = 1.0, 0.0, 1.0, 1.0) or a vector of four NaNs 515 (R,G,B,A = NaN, NaN, NaN, NaN). In the latter case, the recommended NaN 516 value returned is 0xFFFF. 517 518 The error color is returned as an informative response to invalid 519 conditions, including invalid block encodings or use of reserved endpoint 520 modes. 521 522 Future, forward-compatible extensions to OES_texture_compression_astc 523 may define valid interpretations of these conditions, which will decode to 524 some other color. Therefore, encoders and applications must not rely on 525 invalid encodings as a way of generating the error color. 526 527 C.2.6 Configuration Summary 528 ----------------------------- 529 530 The global configuration data for the format is as follows: 531 532 * Block dimension (2D or 3D) 533 * Block footprint size 534 * sRGB output enabled or not 535 536 The data specified per block is as follows: 537 538 * Texel weight grid size 539 * Texel weight range 540 * Texel weight values 541 * Number of partitions 542 * Partition pattern index 543 * Color endpoint modes (includes LDR or HDR selection) 544 * Color endpoint data 545 * Number of planes 546 * Plane-to-channel assignment 547 548 C.2.7 Decode Procedure 549 ------------------------ 550 551 To decode one texel: 552 (Optimization: If within known void-extent, immediately return single 553 color) 554 555 Find block containing texel 556 Read block mode 557 If void-extent block, store void extent and immediately return single 558 color 559 560 For each plane in image 561 If block mode requires infill 562 Find and decode stored weights adjacent to texel, unquantize and 563 interpolate 564 Else 565 Find and decode weight for texel, and unquantize 566 567 Read number of partitions 568 If number of partitions > 1 569 Read partition table pattern index 570 Look up partition number from pattern 571 572 Read color endpoint mode and endpoint data for selected partition 573 Unquantize color endpoints 574 Interpolate color endpoints using weight (or weights in dual-plane mode) 575 Return interpolated color 576 577 C.2.8 Block Determination and Bit Rates 578 The block footprint is a global setting for any given texture, and is 579 therefore not encoded in the individual blocks. 580 581 For 2D textures, the block footprint's width and height are selectable 582 from a number of predefined sizes, namely 4, 5, 6, 8, 10 and 12 pixels. 583 584 For square and nearly-square blocks, this gives the following bit rates: 585 586 ------------------------------------- 587 Footprint 588 Width Height Bit Rate Increment 589 ------------------------------------- 590 4 4 8.00 125% 591 5 4 6.40 125% 592 5 5 5.12 120% 593 6 5 4.27 120% 594 6 6 3.56 114% 595 8 5 3.20 120% 596 8 6 2.67 105% 597 10 5 2.56 120% 598 10 6 2.13 107% 599 8 8 2.00 125% 600 10 8 1.60 125% 601 10 10 1.28 120% 602 12 10 1.07 120% 603 12 12 0.89 604 ------------------------------------- 605 Table C.2.2 - 2D Footprint and Bit Rates 606 607 The block footprint is shown as width x height in the format enumerator, 608 so for example the enumerator COMPRESSED_RGBA_ASTC_8x6_KHR specifies an 609 image with a block width of 8 texels, and a block height of 6 texels. 610 611 The "Increment" column indicates the ratio of bit rate against the next 612 lower available rate. A consistent value in this column indicates an even 613 spread of bit rates. 614 615 For 3D textures, the block footprint's width, height and depth are 616 selectable from a number of predefined sizes, namely 3, 4, 5, and 6 pixels. 617 618 For cubic and near-cubic blocks, this gives the following bit rates: 619 620 ------------------------------------------- 621 Block Footprint 622 Width Height Depth Bit Rate Increment 623 ------------------------------------------- 624 3 3 3 4.74 133% 625 4 3 3 3.56 133% 626 4 4 3 2.67 133% 627 4 4 4 2.00 125% 628 5 4 4 1.60 125% 629 5 5 4 1.28 125% 630 5 5 5 1.02 120% 631 6 5 5 0.85 120% 632 6 6 5 0.71 120% 633 6 6 6 0.59 634 ------------------------------------------- 635 Table C.2.3 - 3D Footprint and Bit Rates 636 637 The block footprint is shown as width x height x depth in the format 638 enumerator, so for example the enumerator COMPRESSED_RGBA_ASTC_5x4x4_OES 639 specifies an image with a block width of 5 texels, a block height of 4 640 texels and a block depth of 4 texels. 641 642 The full profile supports only those block footprints listed in Tables 643 C.2.2 and C.2.3. Other block sizes are not supported. 644 645 For images which are not an integer multiple of the block size, additional 646 texels are added to the edges with maximum X and Y (and Z for 3D textures). 647 These texels may be any color, as they will not be accessed. 648 649 Although these are not all powers of two, it is possible to calculate block 650 addresses and pixel addresses within the block, for legal image sizes, 651 without undue complexity. 652 653 Given an image which is W x H x D pixels in size, with block size 654 w x h x d, the size of the image in blocks is: 655 656 Bw = ceiling(W/w) 657 Bh = ceiling(H/h) 658 Bd = ceiling(D/d) 659 660 For a 3D image built from 2D slices, each 2D slice is a single texel thick, 661 so that for an image which is W x H x D pixels in size, with block size 662 w x h, the size of the image in blocks is: 663 664 Bw = ceiling(W/w) 665 Bh = ceiling(H/h) 666 Bd = D 667 668 C.2.9 Block Layout 669 -------------------- 670 671 Each block in the image is stored as a single 128-bit block in memory. These 672 blocks are laid out in raster order, starting with the block at (0,0,0), then 673 ordered sequentially by X, Y and finally Z (if present). They are aligned to 674 128-bit boundaries in memory. 675 676 The bits in the block are labeled in little-endian order - the byte at the 677 lowest address contains bits 0..7. Bit 0 is the least significant bit in the 678 byte. 679 680 Each block has the same basic layout: 681 682 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112 683 -------------------------------------------------------------- 684 | Texel Weight Data (variable width) Fill direction -> 685 -------------------------------------------------------------- 686 687 111 110 109 108 107 106 105 104 103 102 101 100 99 98 97 96 688 -------------------------------------------------------------- 689 Texel Weight Data 690 -------------------------------------------------------------- 691 692 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 693 -------------------------------------------------------------- 694 Texel Weight Data 695 -------------------------------------------------------------- 696 697 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 698 -------------------------------------------------------------- 699 Texel Weight Data 700 -------------------------------------------------------------- 701 702 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 703 -------------------------------------------------------------- 704 : More config data : 705 -------------------------------------------------------------- 706 707 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 708 -------------------------------------------------------------- 709 <-Fill direction Color Endpoint Data 710 -------------------------------------------------------------- 711 712 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 713 -------------------------------------------------------------- 714 : Extra configuration data 715 -------------------------------------------------------------- 716 717 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 718 -------------------------------------------------------------- 719 Extra | Part | Block mode | 720 -------------------------------------------------------------- 721 722 Table C.2.4 - Block Layout Overview 723 724 Dotted partition lines indicate that the split position is not fixed. 725 726 The "Block mode" field specifies how the Texel Weight Data is encoded. 727 728 The "Part" field specifies the number of partitions, minus one. If dual 729 plane mode is enabled, the number of partitions must be 3 or fewer. 730 If 4 partitions are specified, the error value is returned for all 731 texels in the block. 732 733 The size and layout of the extra configuration data depends on the 734 number of partitions, and the number of planes in the image, as follows 735 (only the bottom 32 bits are shown): 736 737 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 738 -------------------------------------------------------------- 739 <- Color endpoint data |CEM 740 -------------------------------------------------------------- 741 742 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 743 -------------------------------------------------------------- 744 CEM | 0 0 | Block Mode | 745 -------------------------------------------------------------- 746 747 Table C.2.5 - Single-partition Block Layout 748 749 CEM is the color endpoint mode field, which determines how the Color 750 Endpoint Data is encoded. 751 752 If dual-plane mode is active, the color component selector bits appear 753 directly below the weight bits. 754 755 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 756 -------------------------------------------------------------- 757 | CEM | Partition Index 758 -------------------------------------------------------------- 759 760 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 761 -------------------------------------------------------------- 762 Partition Index | Block Mode | 763 -------------------------------------------------------------- 764 765 Table C.2.6 - Multi-partition Block Layout 766 767 The Partition Index field specifies which partition layout to use. CEM is 768 the first 6 bits of color endpoint mode information for the various 769 partitions. For modes which require more than 6 bits of CEM data, the 770 additional bits appear at a variable position directly beneath the texel 771 weight data. 772 773 If dual-plane mode is active, the color component selector bits then appear 774 directly below the additional CEM bits. 775 776 The final special case is that if bits [8:0] of the block are "111111100", 777 then the block is a void-extent block, which has a separate encoding 778 described in section C.2.22. 779 780 C.2.10 Block Mode 781 ------------------ 782 783 The Block Mode field specifies the width, height and depth of the grid of 784 weights, what range of values they use, and whether dual weight planes are 785 present. Since some these are not represented using powers of two (there 786 are 12 possible weight widths, for example), and not all combinations are 787 allowed, this is not a simple bit packing. However, it can be unpacked 788 quickly in hardware. 789 790 The weight ranges are encoded using a 3 bit value R, which is interpreted 791 together with a precision bit H, as follows: 792 793 Low Precision Range (H=0) High Precision Range (H=1) 794R Weight Range Trits Quints Bits Weight Range Trits Quints Bits 795----------------------------------------------------------------------------- 796000 Invalid Invalid 797001 Invalid Invalid 798010 0..1 1 0..9 1 1 799011 0..2 1 0..11 1 2 800100 0..3 2 0..15 4 801101 0..4 1 0..19 1 2 802110 0..5 1 1 0..23 1 3 803111 0..7 3 0..31 5 804----------------------------------------------------------------------------- 805 Table C.2.7 - Weight Range Encodings 806 807 Each weight value is encoded using the specified number of Trits, Quints 808 and Bits. The details of this encoding can be found in Section C.3.12 - 809 Integer Sequence Encoding. 810 811 For 2D blocks, the Block Mode field is laid out as follows: 812 813 ------------------------------------------------------------------------- 814 10 9 8 7 6 5 4 3 2 1 0 Width Height Notes 815 ------------------------------------------------------------------------- 816 D H B A R0 0 0 R2 R1 B+4 A+2 817 D H B A R0 0 1 R2 R1 B+8 A+2 818 D H B A R0 1 0 R2 R1 A+2 B+8 819 D H 0 B A R0 1 1 R2 R1 A+2 B+6 820 D H 1 B A R0 1 1 R2 R1 B+2 A+2 821 D H 0 0 A R0 R2 R1 0 0 12 A+2 822 D H 0 1 A R0 R2 R1 0 0 A+2 12 823 D H 1 1 0 0 R0 R2 R1 0 0 6 10 824 D H 1 1 0 1 R0 R2 R1 0 0 10 6 825 B 1 0 A R0 R2 R1 0 0 A+6 B+6 D=0, H=0 826 x x 1 1 1 1 1 1 1 0 0 - - Void-extent 827 x x 1 1 1 x x x x 0 0 - - Reserved* 828 x x x x x x x 0 0 0 0 - - Reserved 829 ------------------------------------------------------------------------- 830 Table C.2.8 - 2D Block Mode Layout 831 832 Note that, due to the encoding of the R field, as described in the 833 previous page, bits R2 and R1 cannot both be zero, which disambiguates 834 the first five rows from the rest of the table. 835 836 Bit positions with a value of x are ignored for purposes of determining 837 if a block is a void-extent block or reserved, but may have defined 838 encodings for specific void-extent blocks. 839 840 The penultimate row of the table is reserved only if bits [5:2] are not 841 all 1, in which case it encodes a void-extent block (as shown in the 842 previous row). 843 844 For 3D blocks, the Block Mode field is laid out as follows: 845 846 ------------------------------------------------------------------------- 847 10 9 8 7 6 5 4 3 2 1 0 Width Height Depth Notes 848 ------------------------------------------------------------------------- 849 D H B A R0 C R2 R1 A+2 B+2 C+2 850 B 0 0 A R0 R2 R1 0 0 6 B+2 A+2 D=0, H=0 851 B 0 1 A R0 R2 R1 0 0 A+2 6 B+2 D=0, H=0 852 B 1 0 A R0 R2 R1 0 0 A+2 B+2 6 D=0, H=0 853 D H 1 1 0 0 R0 R2 R1 0 0 6 2 2 854 D H 1 1 0 1 R0 R2 R1 0 0 2 6 2 855 D H 1 1 1 0 R0 R2 R1 0 0 2 2 6 856 x x 1 1 1 1 1 1 1 0 0 - - - Void-extent 857 x x 1 1 1 1 x x x 0 0 - - - Reserved* 858 x x x x x x x 0 0 0 0 - - - Reserved 859 ------------------------------------------------------------------------ 860 Table C.2.9 - 3D Block Mode Layout 861 862 The D bit is set to indicate dual-plane mode. In this mode, the maximum 863 allowed number of partitions is 3. 864 865 The penultimate row of the table is reserved only if bits [4:2] are not 866 all 1, in which case it encodes a void-extent block (as shown in the 867 previous row). 868 869 The size of the grid in each dimension must be less than or equal to 870 the corresponding dimension of the block footprint. If the grid size 871 is greater than the footprint dimension in any axis, then this is an 872 illegal block encoding and all texels will decode to the error color. 873 874 C.2.11 Color Endpoint Mode 875 --------------------------- 876 877 In single-partition mode, the Color Endpoint Mode (CEM) field stores one 878 of 16 possible values. Each of these specifies how many raw data values 879 are encoded, and how to convert these raw values into two RGBA color 880 endpoints. They can be summarized as follows: 881 882 --------------------------------------------- 883 CEM Description Class 884 --------------------------------------------- 885 0 LDR Luminance, direct 0 886 1 LDR Luminance, base+offset 0 887 2 HDR Luminance, large range 0 888 3 HDR Luminance, small range 0 889 4 LDR Luminance+Alpha, direct 1 890 5 LDR Luminance+Alpha, base+offset 1 891 6 LDR RGB, base+scale 1 892 7 HDR RGB, base+scale 1 893 8 LDR RGB, direct 2 894 9 LDR RGB, base+offset 2 895 10 LDR RGB, base+scale plus two A 2 896 11 HDR RGB, direct 2 897 12 LDR RGBA, direct 3 898 13 LDR RGBA, base+offset 3 899 14 HDR RGB, direct + LDR Alpha 3 900 15 HDR RGB, direct + HDR Alpha 3 901 --------------------------------------------- 902 Table C.2.10 - Color Endpoint Modes 903 904 In multi-partition mode, the CEM field is of variable width, from 6 to 14 905 bits. The lowest 2 bits of the CEM field specify how the endpoint mode 906 for each partition is calculated: 907 908 ---------------------------------------------------- 909 Value Meaning 910 ---------------------------------------------------- 911 00 All color endpoint pairs are of the same type. 912 A full 4-bit CEM is stored in block bits [28:25] 913 and is used for all partitions. 914 01 All endpoint pairs are of class 0 or 1. 915 10 All endpoint pairs are of class 1 or 2. 916 11 All endpoint pairs are of class 2 or 3. 917 ---------------------------------------------------- 918 Table C.2.11 - Multi-Partition Color Endpoint Modes 919 920 If the CEM selector value in bits [24:23] is not 00, 921 then data layout is as follows: 922 923 Part n m l k j i h g 924 ------------------------------------------ 925 2 ... Weight : M1 : ... 926 ------------------------------------------ 927 3 ... Weight : M2 : M1 :M0 : ... 928 ------------------------------------------ 929 4 ... Weight : M3 : M2 : M1 : M0 : ... 930 ------------------------------------------ 931 932 Part 28 27 26 25 24 23 933 ---------------------- 934 2 | M0 |C1 |C0 | CEM | 935 ---------------------- 936 3 |M0 |C2 |C1 |C0 | CEM | 937 ---------------------- 938 4 |C3 |C2 |C1 |C0 | CEM | 939 ---------------------- 940 941 Table C.2.12 - Multi-Partition Color Endpoint Modes 942 943 In this view, each partition i has two fields. Ci is the class selector 944 bit, choosing between the two possible CEM classes (0 indicates the 945 lower of the two classes), and Mi is a two-bit field specifying the low 946 bits of the color endpoint mode within that class. The additional bits 947 appear at a variable bit position, immediately below the texel weight 948 data. 949 950 The ranges used for the data values are not explicitly specified. 951 Instead, they are derived from the number of available bits remaining 952 after the configuration data and weight data have been specified. 953 954 Details of the decoding procedure for Color Endpoints can be found in 955 section C.2.13. 956 957 C.2.12 Integer Sequence Encoding 958 --------------------------------- 959 960 Both the weight data and the endpoint color data are variable width, and 961 are specified using a sequence of integer values. The range of each 962 value in a sequence (e.g. a color weight) is constrained. 963 964 Since it is often the case that the most efficient range for these 965 values is not a power of two, each value sequence is encoded using a 966 technique known as "integer sequence encoding". This allows efficient, 967 hardware-friendly packing and unpacking of values with non-power-of-two 968 ranges. 969 970 In a sequence, each value has an identical range. The range is specified 971 in one of the following forms: 972 973 Value range MSB encoding LSB encoding 974 0 .. 2^n-1 - n bit value m (n <= 8) 975 0 .. (3 * 2^n)-1 Base-3 "trit" value t n bit value m (n <= 6) 976 0 .. (5 * 2^n)-1 Base-5 "quint" value q n bit value m (n <= 5) 977 978 Value range Value Block Packed block size 979 0 .. 2^n-1 m 1 n 980 0 .. (3 * 2^n)-1 t * 2^n + m 5 8 + 5*n 981 0 .. (5 * 2^n)-1 q * 2^n + m 3 7 + 3*n 982 983 Table C.2.13 -Encoding for Different Ranges 984 985 Since 3^5 is 243, it is possible to pack five trits into 8 bits(which has 986 256 possible values), so a trit can effectively be encoded as 1.6 bits. 987 Similarly, since 5^3 is 125, it is possible to pack three quints into 988 7 bits (which has 128 possible values), so a quint can be encoded as 989 2.33 bits. 990 991 The encoding scheme packs the trits or quints, and then interleaves the n 992 additional bits in positions that satisfy the requirements of an 993 arbitrary length stream. This makes it possible to correctly specify 994 lists of values whose length is not an integer multiple of 3 or 5 values. 995 It also makes it possible to easily select a value at random within the stream. 996 997 If there are insufficient bits in the stream to fill the final block, then 998 unused (higher order) bits are assumed to be 0 when decoding. 999 1000 To decode the bits for value number i in a sequence of bits b, both 1001 indexed from 0, perform the following: 1002 1003 If the range is encoded as n bits per value, then the value is bits 1004 b[i*n+n-1:i*n] - a simple multiplexing operation. 1005 1006 If the range is encoded using a trit, then each block contains 5 values 1007 (v0 to v4), each of which contains a trit (t0 to t4) and a corresponding 1008 LSB value (m0 to m4). The first bit of the packed block is bit 1009 floor(i/5)*(8+5*n). The bits in the block are packed as follows 1010 (in this example, n is 4): 1011 1012 27 26 25 24 23 22 21 20 19 18 17 16 1013 ----------------------------------------------- 1014 |T7 | m4 |T6 T5 | m3 |T4 | 1015 ----------------------------------------------- 1016 1017 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 1018 -------------------------------------------------------------- 1019 | m2 |T3 T2 | m1 |T1 T0 | m0 | 1020 -------------------------------------------------------------- 1021 1022 Table C.2.14 - Trit-based Packing 1023 1024 The five trits t0 to t4 are obtained by bit manipulations of the 8 bits 1025 T[7:0] as follows: 1026 1027 if T[4:2] = 111 1028 C = { T[7:5], T[1:0] }; t4 = t3 = 2 1029 else 1030 C = T[4:0] 1031 if T[6:5] = 11 1032 t4 = 2; t3 = T[7] 1033 else 1034 t4 = T[7]; t3 = T[6:5] 1035 1036 if C[1:0] = 11 1037 t2 = 2; t1 = C[4]; t0 = { C[3], C[2]&~C[3] } 1038 else if C[3:2] = 11 1039 t2 = 2; t1 = 2; t0 = C[1:0] 1040 else 1041 t2 = C[4]; t1 = C[3:2]; t0 = { C[1], C[0]&~C[1] } 1042 1043 If the range is encoded using a quint, then each block contains 3 values 1044 (v0 to v2), each of which contains a quint (q0 to q2) and a corresponding 1045 LSB value (m0 to m2). The first bit of the packed block is bit 1046 floor(i/3)*(7+3*n). 1047 1048 The bits in the block are packed as follows (in this example, n is 4): 1049 1050 18 17 16 1051 ----------- 1052 |Q6 Q5 | m2 1053 ----------- 1054 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 1055 --------------------------------------------------------------- 1056 m2 |Q4 Q3 | m1 |Q2 Q1 Q0 | m0 | 1057 --------------------------------------------------------------- 1058 1059 Table C.2.15 - Quint-based Packing 1060 1061 The three quints q0 to q2 are obtained by bit manipulations of the 7 bits 1062 Q[6:0] as follows: 1063 1064 if Q[2:1] = 11 and Q[6:5] = 00 1065 q2 = { Q[0], Q[4]&~Q[0], Q[3]&~Q[0] }; q1 = q0 = 4 1066 else 1067 if Q[2:1] = 11 1068 q2 = 4; C = { Q[4:3], ~Q[6:5], Q[0] } 1069 else 1070 q2 = Q[6:5]; C = Q[4:0] 1071 1072 if C[2:0] = 101 1073 q1 = 4; q0 = C[4:3] 1074 else 1075 q1 = C[4:3]; q0 = C[2:0] 1076 1077 Both these procedures ensure a valid decoding for all 128 possible values 1078 (even though a few are duplicates). They can also be implemented 1079 efficiently in software using small tables. 1080 1081 Encoding methods are not specified here, although table-based mechanisms 1082 work well. 1083 1084 C.2.13 Endpoint Unquantization 1085 ------------------------------- 1086 1087 Each color endpoint is specified as a sequence of integers in a given 1088 range. These values are packed using integer sequence encoding, as a 1089 stream of bits stored from just above the configuration data, and 1090 growing upwards. 1091 1092 Once unpacked, the values must be unquantized from their storage range, 1093 returning them to a standard range of 0..255. 1094 1095 For bit-only representations, this is simple bit replication from the 1096 most significant bit of the value. 1097 1098 For trit or quint-based representations, this involves a set of bit 1099 manipulations and adjustments to avoid the expense of full-width 1100 multipliers. This procedure ensures correct scaling, but scrambles 1101 the order of the decoded values relative to the encoded values. 1102 This must be compensated for using a table in the encoder. 1103 1104 The initial inputs to the procedure are denoted A (9 bits), B (9 bits), 1105 C (9 bits) and D (3 bits) and are decoded using the range as follows: 1106 1107 --------------------------------------------------------------- 1108 Range T Q B Bits A B C D 1109 --------------------------------------------------------------- 1110 0..5 1 1 a aaaaaaaaa 000000000 204 Trit value 1111 0..9 1 1 a aaaaaaaaa 000000000 113 Quint value 1112 0..11 1 2 ba aaaaaaaaa b000b0bb0 93 Trit value 1113 0..19 1 2 ba aaaaaaaaa b0000bb00 54 Quint value 1114 0..23 1 3 cba aaaaaaaaa cb000cbcb 44 Trit value 1115 0..39 1 3 cba aaaaaaaaa cb0000cbc 26 Quint value 1116 0..47 1 4 dcba aaaaaaaaa dcb000dcb 22 Trit value 1117 0..79 1 4 dcba aaaaaaaaa dcb0000dc 13 Quint value 1118 0..95 1 5 edcba aaaaaaaaa edcb000ed 11 Trit value 1119 0..159 1 5 edcba aaaaaaaaa edcb0000e 6 Quint value 1120 0..191 1 6 fedcba aaaaaaaaa fedcb000f 5 Trit value 1121 --------------------------------------------------------------- 1122 Table C.2.16 - Color Unquantization Parameters 1123 1124 These are then processed as follows: 1125 1126 T = D * C + B; 1127 T = T ^ A; 1128 T = (A & 0x80) | (T >> 2); 1129 1130 Note that the multiply in the first line is nearly trivial as it only 1131 needs to multiply by 0, 1, 2, 3 or 4. 1132 1133 C.2.14 LDR Endpoint Decoding 1134 ----------------------------- 1135 The decoding method used depends on the Color Endpoint Mode (CEM) field, 1136 which specifies how many values are used to represent the endpoint. 1137 1138 The CEM field also specifies how to take the n unquantized color endpoint 1139 values v0 to v[n-1] and convert them into two RGBA color endpoints e0 1140 and e1. 1141 1142 The HDR Modes are more complex and do not fit neatly into this section. 1143 They are documented in following section. 1144 1145 The methods can be summarized as follows. 1146 1147 ------------------------------------------------- 1148 CEM Range Description n 1149 ------------------------------------------------- 1150 0 LDR Luminance, direct 2 1151 1 LDR Luminance, base+offset 2 1152 2 HDR Luminance, large range 2 1153 3 HDR Luminance, small range 2 1154 4 LDR Luminance+Alpha, direct 4 1155 5 LDR Luminance+Alpha, base+offset 4 1156 6 LDR RGB, base+scale 4 1157 7 HDR RGB, base+scale 4 1158 8 LDR RGB, direct 6 1159 9 LDR RGB, base+offset 6 1160 10 LDR RGB, base+scale plus two A 6 1161 11 HDR RGB 6 1162 12 LDR RGBA, direct 8 1163 13 LDR RGBA, base+offset 8 1164 14 HDR RGB + LDR Alpha 8 1165 15 HDR RGB + HDR Alpha 8 1166 ------------------------------------------------- 1167 Table C.2.17 -Color Endpoint Modes 1168 1169 Mode 14 is special in that the alpha values are interpolated linearly, 1170 but the color components are interpolated logarithmically. This is the 1171 only endpoint format with mixed-mode operation, and will return the 1172 error value if encountered in LDR mode. 1173 1174 Decode the different LDR endpoint modes as follows: 1175 1176 Mode 0 LDR Luminance, direct 1177 1178 e0=(v0,v0,v0,0xFF); e1=(v1,v1,v1,0xFF); 1179 1180 Mode 1 LDR Luminance, base+offset 1181 1182 L0 = (v0>>2)|(v1&0xC0); L1=L0+(v1&0x3F); 1183 if (L1>0xFF) { L1=0xFF; } 1184 e0=(L0,L0,L0,0xFF); e1=(L1,L1,L1,0xFF); 1185 1186 Mode 4 LDR Luminance+Alpha,direct 1187 1188 e0=(v0,v0,v0,v2); 1189 e1=(v1,v1,v1,v3); 1190 1191 Mode 5 LDR Luminance+Alpha, base+offset 1192 1193 bit_transfer_signed(v1,v0); bit_transfer_signed(v3,v2); 1194 e0=(v0,v0,v0,v2); e1=(v0+v1,v0+v1,v0+v1,v2+v3); 1195 clamp_unorm8(e0); clamp_unorm8(e1); 1196 1197 Mode 6 LDR RGB, base+scale 1198 1199 e0=(v0*v3>>8,v1*v3>>8,v2*v3>>8, 0xFF); 1200 e1=(v0,v1,v2,0xFF); 1201 1202 Mode 8 LDR RGB, Direct 1203 1204 s0= v0+v2+v4; s1= v1+v3+v5; 1205 if (s1>=s0){e0=(v0,v2,v4,0xFF); 1206 e1=(v1,v3,v5,0xFF); } 1207 else { e0=blue_contract(v1,v3,v5,0xFF); 1208 e1=blue_contract(v0,v2,v4,0xFF); } 1209 1210 Mode 9 LDR RGB, base+offset 1211 1212 bit_transfer_signed(v1,v0); 1213 bit_transfer_signed(v3,v2); 1214 bit_transfer_signed(v5,v4); 1215 if(v1+v3+v5 >= 0) 1216 { e0=(v0,v2,v4,0xFF); e1=(v0+v1,v2+v3,v4+v5,0xFF); } 1217 else 1218 { e0=blue_contract(v0+v1,v2+v3,v4+v5,0xFF); 1219 e1=blue_contract(v0,v2,v4,0xFF); } 1220 clamp_unorm8(e0); clamp_unorm8(e1); 1221 1222 Mode 10 LDR RGB, base+scale plus two A 1223 1224 e0=(v0*v3>>8,v1*v3>>8,v2*v3>>8, v4); 1225 e1=(v0,v1,v2, v5); 1226 1227 Mode 12 LDR RGBA, direct 1228 1229 s0= v0+v2+v4; s1= v1+v3+v5; 1230 if (s1>=s0){e0=(v0,v2,v4,v6); 1231 e1=(v1,v3,v5,v7); } 1232 else { e0=blue_contract(v1,v3,v5,v7); 1233 e1=blue_contract(v0,v2,v4,v6); } 1234 1235 Mode 13 LDR RGBA, base+offset 1236 1237 bit_transfer_signed(v1,v0); 1238 bit_transfer_signed(v3,v2); 1239 bit_transfer_signed(v5,v4); 1240 bit_transfer_signed(v7,v6); 1241 if(v1+v3+v5>=0) { e0=(v0,v2,v4,v6); 1242 e1=(v0+v1,v2+v3,v4+v5,v6+v7); } 1243 else { e0=blue_contract(v0+v1,v2+v3,v4+v5,v6+v7); 1244 e1=blue_contract(v0,v2,v4,v6); } 1245 clamp_unorm8(e0); clamp_unorm8(e1); 1246 1247 The bit_transfer_signed procedure transfers a bit from one value (a) 1248 to another (b). Initially, both a and b are in the range 0..255. 1249 After calling this procedure, a's range becomes -32..31, and b remains 1250 in the range 0..255. Note that, as is often the case, this is easier to 1251 express in hardware than in C: 1252 1253 bit_transfer_signed(int& a, int& b) 1254 { 1255 b >>= 1; 1256 b |= a & 0x80; 1257 a >>= 1; 1258 a &= 0x3F; 1259 if( (a&0x20)!=0 ) a-=0x40; 1260 } 1261 1262 The blue_contract procedure is used to give additional precision to 1263 RGB colors near grey: 1264 1265 color blue_contract( int r, int g, int b, int a ) 1266 { 1267 color c; 1268 c.r = (r+b) >> 1; 1269 c.g = (g+b) >> 1; 1270 c.b = b; 1271 c.a = a; 1272 return c; 1273 } 1274 1275 The clamp_unorm8 procedure is used to clamp a color into the UNORM8 range: 1276 1277 void clamp_unorm8(color c) 1278 { 1279 if(c.r < 0) {c.r=0;} else if(c.r > 255) {c.r=255;} 1280 if(c.g < 0) {c.g=0;} else if(c.g > 255) {c.g=255;} 1281 if(c.b < 0) {c.b=0;} else if(c.b > 255) {c.b=255;} 1282 if(c.a < 0) {c.a=0;} else if(c.a > 255) {c.a=255;} 1283 } 1284 1285 C.2.15 HDR Endpoint Decoding 1286 ------------------------- 1287 1288 For HDR endpoint modes, color values are represented in a 12-bit 1289 pseudo-logarithmic representation. 1290 1291 HDR Endpoint Mode 2 1292 1293 Mode 2 represents luminance-only data with a large range. It encodes 1294 using two values (v0, v1). The complete decoding procedure is as follows: 1295 1296 if(v1 >= v0) 1297 { 1298 y0 = (v0 << 4); 1299 y1 = (v1 << 4); 1300 } 1301 else 1302 { 1303 y0 = (v1 << 4) + 8; 1304 y1 = (v0 << 4) - 8; 1305 } 1306 // Construct RGBA result (0x780 is 1.0f) 1307 e0 = (y0, y0, y0, 0x780); 1308 e1 = (y1, y1, y1, 0x780); 1309 1310 HDR Endpoint Mode 3 1311 1312 Mode 3 represents luminance-only data with a small range. It packs the 1313 bits for a base luminance value, together with an offset, into two values 1314 (v0, v1): 1315 1316 Value 7 6 5 4 3 2 1 0 1317 ----- ------------------------------ 1318 v0 |M | L[6:0] | 1319 ------------------------------ 1320 v1 | X[3:0] | d[3:0] | 1321 ------------------------------ 1322 1323 Table C.2.18 - HDR Mode 3 Value Layout 1324 1325 The bit field marked as X allocates different bits to L or d depending 1326 on the value of the mode bit M. 1327 1328 The complete decoding procedure is as follows: 1329 1330 // Check mode bit and extract. 1331 if((v0&0x80) !=0) 1332 { 1333 y0 = ((v1 & 0xE0) << 4) | ((v0 & 0x7F) << 2); 1334 d = (v1 & 0x1F) << 2; 1335 } 1336 else 1337 { 1338 y0 = ((v1 & 0xF0) << 4) | ((v0 & 0x7F) << 1); 1339 d = (v1 & 0x0F) << 1; 1340 } 1341 1342 // Add delta and clamp 1343 y1 = y0 + d; 1344 if(y1 > 0xFFF) { y1 = 0xFFF; } 1345 1346 // Construct RGBA result (0x780 is 1.0f) 1347 e0 = (y0, y0, y0, 0x780); 1348 e1 = (y1, y1, y1, 0x780); 1349 1350 HDR Endpoint Mode 7 1351 1352 Mode 7 packs the bits for a base RGB value, a scale factor, and some 1353 mode bits into the four values (v0, v1, v2, v3): 1354 1355 Value 7 6 5 4 3 2 1 0 1356 ----- ------------------------------ 1357 v0 |M[3:2] | R[5:0] | 1358 ----- ------------------------------ 1359 v1 |M1 |X0 |X1 | G[4:0] | 1360 ----- ------------------------------ 1361 v2 |M0 |X2 |X3 | B[4:0] | 1362 ----- ------------------------------ 1363 v3 |X4 |X5 |X6 | S[4:0] | 1364 ----- ------------------------------ 1365 Table C.2.19 - HDR Mode 7 Value Layout 1366 1367 The mode bits M0 to M3 are a packed representation of an endpoint bit 1368 mode, together with the major component index. For modes 0 to 4, the 1369 component (red, green, or blue) with the largest magnitude is identified, 1370 and the values swizzled to ensure that it is decoded from the red channel. 1371 1372 The endpoint bit mode is used to determine the number of bits assigned 1373 to each component of the endpoint, and the destination of each of the 1374 extra bits X0 to X6, as follows: 1375 1376 ------------------------------------------------------ 1377 Number of bits Destination of extra bits 1378 Mode R G B S X0 X1 X2 X3 X4 X5 X6 1379 ------------------------------------------------------ 1380 0 11 5 5 7 R9 R8 R7 R10 R6 S6 S5 1381 1 11 6 6 5 R8 G5 R7 B5 R6 R10 R9 1382 2 10 5 5 8 R9 R8 R7 R6 S7 S6 S5 1383 3 9 6 6 7 R8 G5 R7 B5 R6 S6 S5 1384 4 8 7 7 6 G6 G5 B6 B5 R6 R7 S5 1385 5 7 7 7 7 G6 G5 B6 B5 R6 S6 S5 1386 ------------------------------------------------------ 1387 Table C.2.20 - Endpoint Bit Mode 1388 1389 As noted before, this appears complex when expressed in C, but much 1390 easier to achieve in hardware - bit masking, extraction, shifting 1391 and assignment usually ends up as a single wire or multiplexer. 1392 1393 The complete decoding procedure is as follows: 1394 1395 // Extract mode bits and unpack to major component and mode. 1396 int modeval = ((v0&0xC0)>>6) | ((v1&0x80)>>5) | ((v2&0x80)>>4); 1397 1398 int majcomp; 1399 int mode; 1400 1401 if( (modeval & 0xC ) != 0xC ) 1402 { 1403 majcomp = modeval >> 2; mode = modeval & 3; 1404 } 1405 else if( modeval != 0xF ) 1406 { 1407 majcomp = modeval & 3; mode = 4; 1408 } 1409 else 1410 { 1411 majcomp = 0; mode = 5; 1412 } 1413 1414 // Extract low-order bits of r, g, b, and s. 1415 int red = v0 & 0x3f; 1416 int green = v1 & 0x1f; 1417 int blue = v2 & 0x1f; 1418 int scale = v3 & 0x1f; 1419 1420 // Extract high-order bits, which may be assigned depending on mode 1421 int x0 = (v1 >> 6) & 1; int x1 = (v1 >> 5) & 1; 1422 int x2 = (v2 >> 6) & 1; int x3 = (v2 >> 5) & 1; 1423 int x4 = (v3 >> 7) & 1; int x5 = (v3 >> 6) & 1; 1424 int x6 = (v3 >> 5) & 1; 1425 1426 // Now move the high-order xs into the right place. 1427 int ohm = 1 << mode; 1428 if( ohm & 0x30 ) green |= x0 << 6; 1429 if( ohm & 0x3A ) green |= x1 << 5; 1430 if( ohm & 0x30 ) blue |= x2 << 6; 1431 if( ohm & 0x3A ) blue |= x3 << 5; 1432 if( ohm & 0x3D ) scale |= x6 << 5; 1433 if( ohm & 0x2D ) scale |= x5 << 6; 1434 if( ohm & 0x04 ) scale |= x4 << 7; 1435 if( ohm & 0x3B ) red |= x4 << 6; 1436 if( ohm & 0x04 ) red |= x3 << 6; 1437 if( ohm & 0x10 ) red |= x5 << 7; 1438 if( ohm & 0x0F ) red |= x2 << 7; 1439 if( ohm & 0x05 ) red |= x1 << 8; 1440 if( ohm & 0x0A ) red |= x0 << 8; 1441 if( ohm & 0x05 ) red |= x0 << 9; 1442 if( ohm & 0x02 ) red |= x6 << 9; 1443 if( ohm & 0x01 ) red |= x3 << 10; 1444 if( ohm & 0x02 ) red |= x5 << 10; 1445 1446 // Shift the bits to the top of the 12-bit result. 1447 static const int shamts[6] = { 1,1,2,3,4,5 }; 1448 int shamt = shamts[mode]; 1449 red <<= shamt; green <<= shamt; blue <<= shamt; scale <<= shamt; 1450 1451 // Minor components are stored as differences 1452 if( mode != 5 ) { green = red - green; blue = red - blue; } 1453 1454 // Swizzle major component into place 1455 if( majcomp == 1 ) swap( red, green ); 1456 if( majcomp == 2 ) swap( red, blue ); 1457 1458 // Clamp output values, set alpha to 1.0 1459 e1.r = clamp( red, 0, 0xFFF ); 1460 e1.g = clamp( green, 0, 0xFFF ); 1461 e1.b = clamp( blue, 0, 0xFFF ); 1462 e1.alpha = 0x780; 1463 1464 e0.r = clamp( red - scale, 0, 0xFFF ); 1465 e0.g = clamp( green - scale, 0, 0xFFF ); 1466 e0.b = clamp( blue - scale, 0, 0xFFF ); 1467 e0.alpha = 0x780; 1468 1469 HDR Endpoint Mode 11 1470 1471 Mode 11 specifies two RGB values, which it calculates from a number of 1472 bitfields (a, b0, b1, c, d0 and d1) which are packed together with some 1473 mode bits into the six values (v0, v1, v2, v3, v4, v5): 1474 1475 Value 7 6 5 4 3 2 1 0 1476 ----- ------------------------------ 1477 v0 | a[7:0] | 1478 ----- ------------------------------ 1479 v1 |m0 |a8 | c[5:0] | 1480 ----- ------------------------------ 1481 v2 |m1 |X0 | b0[5:0] | 1482 ----- ------------------------------ 1483 v3 |m2 |X1 | b1[5:0] | 1484 ----- ------------------------------ 1485 v4 |mj0|X2 |X4 | d0[4:0] | 1486 ----- ------------------------------ 1487 v5 |mj1|X3 |X5 | d1[4:0] | 1488 ----- ------------------------------ 1489 Table C.2.21 - HDR Mode 11 Value Layout 1490 1491 If the major component bits mj[1:0 ] are both 1, then the RGB values 1492 are specified directly 1493 1494 Value 7 6 5 4 3 2 1 0 1495 ----- ------------------------------ 1496 v0 | R0[11:4] | 1497 ----- ------------------------------ 1498 v1 | R1[11:4] | 1499 ----- ------------------------------ 1500 v2 | G0[11:4] | 1501 ----- ------------------------------ 1502 v3 | G1[11:4] | 1503 ----- ------------------------------ 1504 v4 | 1 | B0[11:5] | 1505 ----- ------------------------------ 1506 v5 | 1 | B1[11:5] | 1507 ----- ------------------------------ 1508 Table C.2.22 - HDR Mode 11 Value Layout 1509 1510 The mode bits m[2:0] specify the bit allocation for the different 1511 values, and the destinations of the extra bits X0 to X5: 1512 1513 ------------------------------------------------------------------------- 1514 Number of bits Destination of extra bits 1515 Mode a b c d X0 X1 X2 X3 X4 X5 1516 ------------------------------------------------------------------------- 1517 0 9 7 6 7 b0[6] b1[6] d0[6] d1[6] d0[5] d1[5] 1518 1 9 8 6 6 b0[6] b1[6] b0[7] b1[7] d0[5] d1[5] 1519 2 10 6 7 7 a[9] c[6] d0[6] d1[6] d0[5] d1[5] 1520 3 10 7 7 6 b0[6] b1[6] a[9] c[6] d0[5] d1[5] 1521 4 11 8 6 5 b0[6] b1[6] b0[7] b1[7] a[9] a[10] 1522 5 11 6 7 6 a[9] a[10] c[7] c[6] d0[5] d1[5] 1523 6 12 7 7 5 b0[6] b1[6] a[11] c[6] a[9] a[10] 1524 7 12 6 7 6 a[9] a[10] a[11] c[6] d0[5] d1[5] 1525 ------------------------------------------------------------------------- 1526 Table C.2.23 - Endpoint Bit Mode 1527 1528 The complete decoding procedure is as follows: 1529 1530 // Find major component 1531 int majcomp = ((v4 & 0x80) >> 7) | ((v5 & 0x80) >> 6); 1532 1533 // Deal with simple case first 1534 if( majcomp == 3 ) 1535 { 1536 e0 = (v0 << 4, v2 << 4, (v4 & 0x7f) << 5, 0x780); 1537 e1 = (v1 << 4, v3 << 4, (v5 & 0x7f) << 5, 0x780); 1538 return; 1539 } 1540 1541 // Decode mode, parameters. 1542 int mode = ((v1&0x80)>>7) | ((v2&0x80)>>6) | ((v3&0x80)>>5); 1543 int va = v0 | ((v1 & 0x40) << 2); 1544 int vb0 = v2 & 0x3f; 1545 int vb1 = v3 & 0x3f; 1546 int vc = v1 & 0x3f; 1547 int vd0 = v4 & 0x7f; 1548 int vd1 = v5 & 0x7f; 1549 1550 // Assign top bits of vd0, vd1. 1551 static const int dbitstab[8] = {7,6,7,6,5,6,5,6}; 1552 vd0 = signextend( vd0, dbitstab[mode] ); 1553 vd1 = signextend( vd1, dbitstab[mode] ); 1554 1555 // Extract and place extra bits 1556 int x0 = (v2 >> 6) & 1; 1557 int x1 = (v3 >> 6) & 1; 1558 int x2 = (v4 >> 6) & 1; 1559 int x3 = (v5 >> 6) & 1; 1560 int x4 = (v4 >> 5) & 1; 1561 int x5 = (v5 >> 5) & 1; 1562 1563 int ohm = 1 << mode; 1564 if( ohm & 0xA4 ) va |= x0 << 9; 1565 if( ohm & 0x08 ) va |= x2 << 9; 1566 if( ohm & 0x50 ) va |= x4 << 9; 1567 if( ohm & 0x50 ) va |= x5 << 10; 1568 if( ohm & 0xA0 ) va |= x1 << 10; 1569 if( ohm & 0xC0 ) va |= x2 << 11; 1570 if( ohm & 0x04 ) vc |= x1 << 6; 1571 if( ohm & 0xE8 ) vc |= x3 << 6; 1572 if( ohm & 0x20 ) vc |= x2 << 7; 1573 if( ohm & 0x5B ) vb0 |= x0 << 6; 1574 if( ohm & 0x5B ) vb1 |= x1 << 6; 1575 if( ohm & 0x12 ) vb0 |= x2 << 7; 1576 if( ohm & 0x12 ) vb1 |= x3 << 7; 1577 1578 // Now shift up so that major component is at top of 12-bit value 1579 int shamt = (modeval >> 1) ^ 3; 1580 va <<= shamt; vb0 <<= shamt; vb1 <<= shamt; 1581 vc <<= shamt; vd0 <<= shamt; vd1 <<= shamt; 1582 1583 e1.r = clamp( va, 0, 0xFFF ); 1584 e1.g = clamp( va - vb0, 0, 0xFFF ); 1585 e1.b = clamp( va - vb1, 0, 0xFFF ); 1586 e1.alpha = 0x780; 1587 1588 e0.r = clamp( va - vc, 0, 0xFFF ); 1589 e0.g = clamp( va - vb0 - vc - vd0, 0, 0xFFF ); 1590 e0.b = clamp( va - vb1 - vc - vd1, 0, 0xFFF ); 1591 e0.alpha = 0x780; 1592 1593 if( majcomp == 1 ) { swap( e0.r, e0.g ); swap( e1.r, e1.g ); } 1594 else if( majcomp == 2 ) { swap( e0.r, e0.b ); swap( e1.r, e1.b ); } 1595 1596 HDR Endpoint Mode 14 1597 1598 Mode 14 specifies two RGBA values, using the eight values (v0, v1, v2, 1599 v3, v4, v5, v6, v7). First, the RGB values are decoded from (v0..v5) 1600 using the method from Mode 11, then the alpha values are filled in 1601 from v6 and v7: 1602 1603 // Decode RGB as for mode 11 1604 (e0,e1) = decode_mode_11(v0,v1,v2,v3,v4,v5) 1605 1606 // Now fill in the alphas 1607 e0.alpha = v6; 1608 e1.alpha = v7; 1609 1610 Note that in this mode, the alpha values are interpreted (and 1611 interpolated) as 8-bit unsigned normalized values, as in the LDR modes. 1612 This is the only mode that exhibits this behaviour. 1613 1614 HDR Endpoint Mode 15 1615 1616 Mode 15 specifies two RGBA values, using the eight values (v0, v1, v2, 1617 v3, v4, v5, v6, v7). First, the RGB values are decoded from (v0..v5) 1618 using the method from Mode 11. The alpha values are stored in values 1619 v6 and v7 as a mode and two values which are interpreted according 1620 to the mode: 1621 1622 Value 7 6 5 4 3 2 1 0 1623 ----- ------------------------------ 1624 v6 |M0 | A[6:0] | 1625 ----- ------------------------------ 1626 v7 |M1 | B[6:0] | 1627 ----- ------------------------------ 1628 Table C.2.24 - HDR Mode 15 Alpha Value Layout 1629 1630 The alpha values are decoded from v6 and v7 as follows: 1631 1632 // Decode RGB as for mode 11 1633 (e0,e1) = decode_mode_11(v0,v1,v2,v3,v4,v5) 1634 1635 // Extract mode bits 1636 mode = ((v6 >> 7) & 1) | ((v7 >> 6) & 2); 1637 v6 &= 0x7F; 1638 v7 &= 0x7F; 1639 1640 if(mode==3) 1641 { 1642 // Directly specify alphas 1643 e0.alpha = v6 << 5; 1644 e1.alpha = v7 << 5; 1645 } 1646 else 1647 { 1648 // Transfer bits from v7 to v6 and sign extend v7. 1649 v6 |= (v7 << (mode+1))) & 0x780; 1650 v7 &= (0x3F >> mode); 1651 v7 ^= 0x20 >> mode; 1652 v7 -= 0x20 >> mode; 1653 v6 <<= (4-mode); 1654 v7 <<= (4-mode); 1655 1656 // Add delta and clamp 1657 v7 += v6; 1658 v7 = clamp(v7, 0, 0xFFF); 1659 e0.alpha = v6; 1660 e1.alpha = v7; 1661 } 1662 1663 Note that in this mode, the alpha values are interpreted (and 1664 interpolated) as 12-bit HDR values, and are interpolated as 1665 for any other HDR component. 1666 1667 C.2.16 Weight Decoding 1668 ----------------------- 1669 The weight information is stored as a stream of bits, growing downwards 1670 from the most significant bit in the block. Bit n in the stream is thus 1671 bit 127-n in the block. 1672 1673 For each location in the weight grid, a value (in the specified range) 1674 is packed into the stream. These are ordered in a raster pattern 1675 starting from location (0,0,0), with the X dimension increasing fastest, 1676 and the Z dimension increasing slowest. If dual-plane mode is selected, 1677 both weights are emitted together for each location, plane 0 first, 1678 then plane 1. 1679 1680 C.2.17 Weight Unquantization 1681 ----------------------------- 1682 1683 Each weight plane is specified as a sequence of integers in a given 1684 range. These values are packed using integer sequence encoding. 1685 1686 Once unpacked, the values must be unquantized from their storage 1687 range, returning them to a standard range of 0..64. The procedure 1688 for doing so is similar to the color endpoint unquantization. 1689 1690 First, we unquantize the actual stored weight values to the range 0..63. 1691 1692 For bit-only representations, this is simple bit replication from the 1693 most significant bit of the value. 1694 1695 For trit or quint-based representations, this involves a set of bit 1696 manipulations and adjustments to avoid the expense of full-width 1697 multipliers. 1698 1699 For representations with no additional bits, the results are as follows: 1700 1701 Range 0 1 2 3 4 1702 -------------------------- 1703 0..2 0 32 63 - - 1704 0..4 0 16 32 47 63 1705 -------------------------- 1706 Table C.2.25 - Weight Unquantization Values 1707 1708 For other values, we calculate the initial inputs to a bit manipulation 1709 procedure. These are denoted A (7 bits), B (7 bits), C (7 bits), and 1710 D (3 bits) and are decoded using the range as follows: 1711 1712 Range T Q B Bits A B C D 1713 ------------------------------------------------------- 1714 0..5 1 1 a aaaaaaa 0000000 50 Trit value 1715 0..9 1 1 a aaaaaaa 0000000 28 Quint value 1716 0..11 1 2 ba aaaaaaa b000b0b 23 Trit value 1717 0..19 1 2 ba aaaaaaa b0000b0 13 Quint value 1718 0..23 1 3 cba aaaaaaa cb000cb 11 Trit value 1719 ------------------------------------------------------- 1720 Table C.2.26 - Weight Unquantization Parameters 1721 1722 These are then processed as follows: 1723 1724 T = D * C + B; 1725 T = T ^ A; 1726 T = (A & 0x20) | (T >> 2); 1727 1728 Note that the multiply in the first line is nearly trivial as it only 1729 needs to multiply by 0, 1, 2, 3 or 4. 1730 1731 As a final step, for all types of value, the range is expanded from 1732 0..63 up to 0..64 as follows: 1733 1734 if (T > 32) { T += 1; } 1735 1736 This allows the implementation to use 64 as a divisor during inter- 1737 polation, which is much easier than using 63. 1738 1739 C.2.18 Weight Infill 1740 --------------------- 1741 1742 After unquantization, the weights are subject to weight selection and 1743 infill. The infill method is used to calculate the weight for a texel 1744 position, based on the weights in the stored weight grid array (which 1745 may be a different size). 1746 1747 The procedure below must be followed exactly, to ensure bit exact 1748 results. 1749 1750 The block size is specified as three dimensions along the s, t and r 1751 axes (Bs, Bt, Br). Texel coordinates within the block (s,t,r) can 1752 have values from 0 to one less than the block dimension in that axis. 1753 For each block dimension, we compute scale factors (Ds, Dt, Dr) 1754 1755 Ds = floor( (1024 + floor(Bs/2)) / (Bs-1) ); 1756 Dt = floor( (1024 + floor(Bt/2)) / (Bt-1) ); 1757 Dr = floor( (1024 + floor(Br/2)) / (Br-1) ); 1758 1759 Since the block dimensions are constrained, these are easily looked up 1760 in a table. These scale factors are then used to scale the (s,t,r) 1761 coordinates to a homogeneous coordinate (cs, ct, cr): 1762 1763 cs = Ds * s; 1764 ct = Dt * t; 1765 cr = Dr * r; 1766 1767 This homogeneous coordinate (cs, ct, cr) is then scaled again to give 1768 a coordinate (gs, gt, gr) in the weight-grid space . The weight-grid is 1769 of size (N, M, Q), as specified in the block mode field: 1770 1771 gs = (cs*(N-1)+32) >> 6; 1772 gt = (ct*(M-1)+32) >> 6; 1773 gr = (cr*(Q-1)+32) >> 6; 1774 1775 The resulting coordinates may be in the range 0..176. These are inter- 1776 preted as 4:4 unsigned fixed point numbers in the range 0.0 .. 11.0. 1777 1778 If we label the integral parts of these (js, jt, jr) and the fractional 1779 parts (fs, ft, fr), then: 1780 1781 js = gs >> 4; fs = gs & 0x0F; 1782 jt = gt >> 4; ft = gt & 0x0F; 1783 jr = gr >> 4; fr = gr & 0x0F; 1784 1785 These values are then used to interpolate between the stored weights. 1786 This process differs for 2D and 3D. 1787 1788 For 2D, bilinear interpolation is used: 1789 1790 v0 = js + jt*N; 1791 p00 = decode_weight(v0); 1792 p01 = decode_weight(v0 + 1); 1793 p10 = decode_weight(v0 + N); 1794 p11 = decode_weight(v0 + N + 1); 1795 1796 The function decode_weight(n) decodes the nth weight in the stored weight 1797 stream. The values p00 to p11 are the weights at the corner of the square 1798 in which the texel position resides. These are then weighted using the 1799 fractional position to produce the effective weight i as follows: 1800 1801 w11 = (fs*ft+8) >> 4; 1802 w10 = ft - w11; 1803 w01 = fs - w11; 1804 w00 = 16 - fs - ft + w11; 1805 i = (p00*w00 + p01*w01 + p10*w10 + p11*w11 + 8) >> 4; 1806 1807 For 3D, simplex interpolation is used as it is cheaper than a naïve 1808 trilinear interpolation. First, we pick some parameters for the inter- 1809 polation based on comparisons of the fractional parts of the texel 1810 position: 1811 1812 fs>ft ft>fr fs>fr s1 s2 w0 w1 w2 w3 1813 ---------------------------------------------------------- 1814 True True True 1 N 16-fs fs-ft ft-fr fr 1815 False True True N 1 16-ft ft-fs fs-fr fr 1816 True False True 1 N*M 16-fs fs-fr fr-ft ft 1817 True False False N*M 1 16-fr fr-fs fs-ft ft 1818 False True False N N*M 16-ft ft-fr fr-fs fs 1819 False False False N*M N 16-fr fr-ft ft-fs fs 1820 ---------------------------------------------------------- 1821 Table C.2.27 -Simplex Interpolation Parameters 1822 1823 Some test results are implied by the others. The effective 1824 weight i is then calculated as: 1825 1826 v0 = js + jt*N + jr*N*M; 1827 p0 = decode_index(v0); 1828 p1 = decode_index(v0 + s1); 1829 p2 = decode_index(v0 + s1 + s2); 1830 p3 = decode_index(v0 + N*M + N + 1); 1831 i = (p0*w0 + p1*w1 + p2*w2 + p3*w3 + 8) >> 4; 1832 1833 C.2.19 Weight Application 1834 -------------------------- 1835 Once the effective weight i for the texel has been calculated, the color 1836 endpoints are interpolated and expanded. 1837 1838 For LDR endpoint modes, each color component C is calculated from the 1839 corresponding 8-bit endpoint components C0 and C1 as follows: 1840 1841 If sRGB conversion is not enabled, or for the alpha channel in any case, 1842 C0 and C1 are first expanded to 16 bits by bit replication: 1843 1844 C0 = (C0 << 8) | C0; C1 = (C1 << 8) | C1; 1845 1846 If sRGB conversion is enabled, C0 and C1 for the R, G, and B channels 1847 are expanded to 16 bits differently, as follows: 1848 1849 C0 = (C0 << 8) | 0x80; C1 = (C1 << 8) | 0x80; 1850 1851 C0 and C1 are then interpolated to produce a UNORM16 result C: 1852 1853 C = floor( (C0*(64-i) + C1*i + 32)/64 ) 1854 1855 If sRGB conversion is enabled, the top 8 bits of the interpolation 1856 result for the R, G and B channels are passed to the external sRGB 1857 conversion block. Otherwise, if C = 65535, then the final result is 1858 1.0 (0x3C00) otherwise C is divided by 65536 and the infinite-precision 1859 result of the division is converted to FP16 with round-to-zero 1860 semantics. 1861 1862 For HDR endpoint modes, color values are represented in a 12-bit 1863 pseudo-logarithmic representation, and interpolation occurs in a 1864 piecewise-approximate logarithmic manner as follows: 1865 1866 In LDR mode, the error result is returned. 1867 1868 In HDR mode, the color components from each endpoint, C0 and C1, are 1869 initially shifted left 4 bits to become 16-bit integer values and these 1870 are interpolated in the same way as LDR. The 16-bit value C is then 1871 decomposed into the top five bits, E, and the bottom 11 bits M, which 1872 are then processed and recombined with E to form the final value Cf: 1873 1874 C = floor( (C0*(64-i) + C1*i + 32)/64 ) 1875 E = (C&0xF800) >> 11; M = C&0x7FF; 1876 if (M < 512) { Mt = 3*M; } 1877 else if (M >= 1536) { Mt = 5*M - 2048; } 1878 else { Mt = 4*M - 512; } 1879 Cf = (E<<10) + (Mt>>3) 1880 1881 This interpolation is a considerably closer approximation to a 1882 logarithmic space than simple 16-bit interpolation. 1883 1884 This final value Cf is interpreted as an IEEE FP16 value. If the result 1885 is +Inf or NaN, it is converted to the bit pattern 0x7BFF, which is the 1886 largest representable finite value. 1887 1888 C.2.20 Dual-Plane Decoding 1889 --------------------------- 1890 If dual-plane mode is disabled, all of the endpoint components are inter- 1891 polated using the same weight value. 1892 1893 If dual-plane mode is enabled, two weights are stored with each texel. 1894 One component is then selected to use the second weight for interpolation, 1895 instead of the first weight. The first weight is then used for all other 1896 components. 1897 1898 The component to treat specially is indicated using the 2-bit Color 1899 Component Selector (CCS) field as follows: 1900 1901 Value Weight 0 Weight 1 1902 -------------------------- 1903 0 GBA R 1904 1 RBA G 1905 2 RGA B 1906 3 RGB A 1907 -------------------------- 1908 Table C.2.28 -Dual Plane Color Component Selector Values 1909 1910 The CCS bits are stored at a variable position directly below the weight 1911 bits and any additional CEM bits. 1912 1913 C.2.21 Partition Pattern Generation 1914 ------------------------------------ 1915 1916 When multiple partitions are active, each texel position is assigned a 1917 partition index. This partition index is calculated using a seed (the 1918 partition pattern index), the texel's x,y,z position within the block, 1919 and the number of partitions. An additional argument, small_block, is 1920 set to 1 if the number of texels in the block is less than 31, 1921 otherwise it is set to 0. 1922 1923 This function is specified in terms of x, y and z in order to support 1924 3D textures. For 2D textures and texture slices, z will always be 0. 1925 1926 The full partition selection algorithm is as follows: 1927 1928 int select_partition(int seed, int x, int y, int z, 1929 int partitioncount, int small_block) 1930 { 1931 if( small_block ){ x <<= 1; y <<= 1; z <<= 1; } 1932 seed += (partitioncount-1) * 1024; 1933 uint32_t rnum = hash52(seed); 1934 uint8_t seed1 = rnum & 0xF; 1935 uint8_t seed2 = (rnum >> 4) & 0xF; 1936 uint8_t seed3 = (rnum >> 8) & 0xF; 1937 uint8_t seed4 = (rnum >> 12) & 0xF; 1938 uint8_t seed5 = (rnum >> 16) & 0xF; 1939 uint8_t seed6 = (rnum >> 20) & 0xF; 1940 uint8_t seed7 = (rnum >> 24) & 0xF; 1941 uint8_t seed8 = (rnum >> 28) & 0xF; 1942 uint8_t seed9 = (rnum >> 18) & 0xF; 1943 uint8_t seed10 = (rnum >> 22) & 0xF; 1944 uint8_t seed11 = (rnum >> 26) & 0xF; 1945 uint8_t seed12 = ((rnum >> 30) | (rnum << 2)) & 0xF; 1946 1947 seed1 *= seed1; seed2 *= seed2; 1948 seed3 *= seed3; seed4 *= seed4; 1949 seed5 *= seed5; seed6 *= seed6; 1950 seed7 *= seed7; seed8 *= seed8; 1951 seed9 *= seed9; seed10 *= seed10; 1952 seed11 *= seed11; seed12 *= seed12; 1953 1954 int sh1, sh2, sh3; 1955 if( seed & 1 ) 1956 { sh1 = (seed&2 ? 4:5); sh2 = (partitioncount==3 ? 6:5); } 1957 else 1958 { sh1 = (partitioncount==3 ? 6:5); sh2 = (seed&2 ? 4:5); } 1959 sh3 = (seed & 0x10) ? sh1 : sh2; 1960 1961 seed1 >>= sh1; seed2 >>= sh2; seed3 >>= sh1; seed4 >>= sh2; 1962 seed5 >>= sh1; seed6 >>= sh2; seed7 >>= sh1; seed8 >>= sh2; 1963 seed9 >>= sh3; seed10 >>= sh3; seed11 >>= sh3; seed12 >>= sh3; 1964 1965 int a = seed1*x + seed2*y + seed11*z + (rnum >> 14); 1966 int b = seed3*x + seed4*y + seed12*z + (rnum >> 10); 1967 int c = seed5*x + seed6*y + seed9 *z + (rnum >> 6); 1968 int d = seed7*x + seed8*y + seed10*z + (rnum >> 2); 1969 1970 a &= 0x3F; b &= 0x3F; c &= 0x3F; d &= 0x3F; 1971 1972 if( partitioncount < 4 ) d = 0; 1973 if( partitioncount < 3 ) c = 0; 1974 1975 if( a >= b && a >= c && a >= d ) return 0; 1976 else if( b >= c && b >= d ) return 1; 1977 else if( c >= d ) return 2; 1978 else return 3; 1979 } 1980 1981 As has been observed before, the bit selections are much easier to 1982 express in hardware than in C. 1983 1984 The seed is expanded using a hash function hash52, which is defined as 1985 follows: 1986 1987 uint32_t hash52( uint32_t p ) 1988 { 1989 p ^= p >> 15; p -= p << 17; p += p << 7; p += p << 4; 1990 p ^= p >> 5; p += p << 16; p ^= p >> 7; p ^= p >> 3; 1991 p ^= p << 6; p ^= p >> 17; 1992 return p; 1993 } 1994 1995 This assumes that all operations act on 32-bit values 1996 1997 C.2.22 Data Size Determination 1998 ------------------------------- 1999 2000 The size of the data used to represent color endpoints is not 2001 explicitly specified. Instead, it is determined from the block mode and 2002 number of partitions as follows: 2003 2004 config_bits = 17; 2005 if(num_partitions>1) 2006 if(single_CEM) 2007 config_bits = 29; 2008 else 2009 config_bits = 25 + 3*num_partitions; 2010 2011 num_weights = M * N * Q; // size of weight grid 2012 2013 if(dual_plane) 2014 config_bits += 2; 2015 num_weights *= 2; 2016 2017 weight_bits = ceil(num_weights*8*trits_in_weight_range/5) + 2018 ceil(num_weights*7*quints_in_weight_range/3) + 2019 num_weights*bits_in_weight_range; 2020 2021 remaining_bits = 128 - config_bits - weight_bits; 2022 2023 num_CEM_pairs = base_CEM_class+1 + count_bits(extra_CEM_bits); 2024 2025 The CEM value range is then looked up from a table indexed by remaining 2026 bits and num_CEM_pairs. This table is initialized such that the range 2027 is as large as possible, consistent with the constraint that the number 2028 of bits required to encode num_CEM_pairs pairs of values is not more 2029 than the number of remaining bits. 2030 2031 An equivalent iterative algorithm would be: 2032 2033 num_CEM_values = num_CEM_pairs*2; 2034 2035 for(range = each possible CEM range in descending order of size) 2036 { 2037 CEM_bits = ceil(num_CEM_values*8*trits_in_CEM_range/5) + 2038 ceil(num_CEM_values*7*quints_in_CEM_range/3) + 2039 num_CEM_values*bits_in_CEM_range; 2040 2041 if(CEM_bits <= remaining_bits) 2042 break; 2043 } 2044 return range; 2045 2046 In cases where this procedure results in unallocated bits, these bits 2047 are not read by the decoding process and can have any value. 2048 2049 C.2.23 Void-Extent Blocks 2050 -------------------------- 2051 2052 A void-extent block is a block encoded with a single color. It also 2053 specifies some additional information about the extent of the single- 2054 color area beyond this block, which can optionally be used by a 2055 decoder to reduce or prevent redundant block fetches. 2056 2057 The layout of a 2D Void-Extent block is as follows: 2058 2059 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112 2060 --------------------------------------------------------------- 2061 | Block color A component | 2062 --------------------------------------------------------------- 2063 2064 111 110 109 108 107 106 105 104 103 102 101 100 99 98 97 96 2065 --------------------------------------------------------------- 2066 | Block color B component | 2067 --------------------------------------------------------------- 2068 2069 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 2070 --------------------------------------------------------------- 2071 | Block color G component | 2072 --------------------------------------------------------------- 2073 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 2074 --------------------------------------------------------------- 2075 | Block color R component | 2076 --------------------------------------------------------------- 2077 2078 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 2079 --------------------------------------------------------------- 2080 | Void-extent maximum T coordinate | Min T 2081 --------------------------------------------------------------- 2082 2083 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 2084 --------------------------------------------------------------- 2085 Void-extent minimum T coordinate | Void-extent max S 2086 --------------------------------------------------------------- 2087 2088 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 2089 --------------------------------------------------------------- 2090 Void-extent max S coord | Void-extent minimum S coordinate 2091 --------------------------------------------------------------- 2092 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 2093 -------------------------------------------------------------- 2094 Min S coord | 1 | 1 | D | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 2095 -------------------------------------------------------------- 2096 2097 Table C.2.29 - 2D Void-Extent Block Layout Overview 2098 2099 The layout of a 3D Void-Extent block is as follows: 2100 2101 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112 2102 --------------------------------------------------------------- 2103 | Block color A component | 2104 --------------------------------------------------------------- 2105 2106 111 110 109 108 107 106 105 104 103 102 101 100 99 98 97 96 2107 --------------------------------------------------------------- 2108 | Block color B component | 2109 --------------------------------------------------------------- 2110 2111 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 2112 --------------------------------------------------------------- 2113 | Block color G component | 2114 --------------------------------------------------------------- 2115 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 2116 --------------------------------------------------------------- 2117 | Block color R component | 2118 --------------------------------------------------------------- 2119 2120 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 2121 --------------------------------------------------------------- 2122 | Void-extent max R coordinate | Void-extent min R coord 2123 --------------------------------------------------------------- 2124 2125 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 2126 --------------------------------------------------------------- 2127 min R | Void-extent max T coordinate | Void-extent min T 2128 --------------------------------------------------------------- 2129 2130 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 2131 --------------------------------------------------------------- 2132 min T coord | Void-extent minimum S coordinate | Minimum S 2133 --------------------------------------------------------------- 2134 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 2135 -------------------------------------------------------------- 2136 Minimum S coord | D | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 2137 -------------------------------------------------------------- 2138 2139 Table C.2.30 - 3D Void-Extent Block Layout Overview 2140 2141 Bit 9 is the Dynamic Range flag, which indicates the format in which 2142 colors are stored. A 0 value indicates LDR, in which case the color 2143 components are stored as UNORM16 values. A 1 indicates HDR, in which 2144 case the color components are stored as FP16 values. 2145 2146 The reason for the storage of UNORM16 values in the LDR case is due 2147 to the possibility that the value will need to be passed on to sRGB 2148 conversion. By storing the color value in the format which comes out 2149 of the interpolator, before the conversion to FP16, we avoid having 2150 to have separate versions for sRGB and linear modes. 2151 2152 If a void-extent block with HDR values is decoded in LDR mode, then 2153 the result will be the error color, opaque magenta, for all texels 2154 within the block. 2155 2156 In the HDR case, if the color component values are infinity or NaN, this 2157 will result in undefined behavior. As usual, this must not lead to GL 2158 interruption or termination. 2159 2160 Bits 10 and 11 are reserved and must be 1. 2161 2162 The minimum and maximum coordinate values are treated as unsigned 2163 integers and then normalized into the range 0..1 (by dividing by 2^13-1 2164 or 2^9-1, for 2D and 3D respectively). The maximum values for each 2165 dimension must be greater than the corresponding minimum values, 2166 unless they are all all-1s. 2167 2168 If all the coordinates are all-1s, then the void extent is ignored, 2169 and the block is simply a constant-color block. 2170 2171 The existence of single-color blocks with void extents must not produce 2172 results different from those obtained if these single-color blocks are 2173 defined without void-extents. Any situation in which the results would 2174 differ is invalid. Results from invalid void extents are undefined. 2175 2176 If a void-extent appears in a MIPmap level other than the most detailed 2177 one, then the extent will apply to all of the more detailed levels too. 2178 This allows decoders to avoid sampling more detailed MIPmaps. 2179 2180 If the more detailed MIPmap level is not a constant color in this region, 2181 then the block may be marked as constant color, but without a void extent, 2182 as detailed above. 2183 2184 If a void-extent extends to the edge of a texture, then filtered texture 2185 colors may not be the same color as that specified in the block, due to 2186 texture border colors, wrapping, or cube face wrapping. 2187 2188 Care must be taken when updating or extracting partial image data that 2189 void-extents in the image do not become invalid. 2190 2191 C.2.24 Illegal Encodings 2192 ------------------------- 2193 2194 In ASTC, there is a variety of ways to encode an illegal block. Decoders 2195 are required to recognize all illegal blocks and emit the standard error 2196 color value upon encountering an illegal block. 2197 2198 Here is a comprehensive list of situations that represent illegal block 2199 encodings: 2200 2201 * The block mode specified is one of the modes explicitly listed 2202 as Reserved. 2203 * A 2D void-extent block that has any of the reserved bits not 2204 set to 1. 2205 * A block mode has been specified that would require more than 2206 64 weights total. 2207 * A block mode has been specified that would require more than 2208 96 bits for integer sequence encoding of the weight grid. 2209 * A block mode has been specifed that would require fewer than 2210 24 bits for integer sequence encoding of the weight grid. 2211 * The size of the weight grid exceeds the size of the block footprint 2212 in any dimension. 2213 * Color endpoint modes have been specified such that the color 2214 integer sequence encoding would require more than 18 integers. 2215 * The number of bits available for color endpoint encoding after all 2216 the other fields have been counted is less than ceil(13C/5) where C 2217 is the number of color endpoint integers (this would restrict color 2218 integers to a range smaller than 0..5, which is not supported). 2219 * Dual weight mode is enabled for a block with 4 partitions. 2220 * Void-Extent blocks where the low coordinate for some texture axis 2221 is greater than or equal to the high coordinate. 2222 2223 Note also that, in LDR mode, a block which has both HDR and LDR endpoint 2224 modes assigned to different partitions is not an error block. Only those 2225 texels which belong to the HDR partition will result in the error color. 2226 Texels belonging to a LDR partition will be decoded as normal. 2227 2228 C.2.25 LDR PROFILE SUPPORT 2229 --------------------------- 2230 In order to ease verification and accelerate adoption, an LDR-only 2231 subset of the full ASTC specification has been made available. 2232 2233 Implementations of this LDR Profile must satisfy the following requirements: 2234 * All textures with valid encodings for LDR Profile must decode 2235 identically using either a LDR Profile, HDR Profile, or Full Profile 2236 decoder. 2237 * All features included only in the HDR Profile or Full Profile must be 2238 treated as reserved in the LDR Profile, and return the error color on 2239 decoding. 2240 * Any sequence of API calls valid for the LDR Profile must also be valid 2241 for the HDR Profile or Full Profile and return identical results when 2242 given a texture encoded for the LDR Profile. 2243 2244 The feature subset for the LDR profile is: 2245 * 2D textures only. 2246 * Only those block sizes listed in Table C.2.2 are supported. 2247 * LDR operation mode only. 2248 * Only LDR endpoint formats must be supported, namely formats 2249 0, 1, 4, 5, 6, 8, 9, 10, 12, 13. 2250 * Decoding from a HDR endpoint results in the error color. 2251 * Interpolation returns UNORM8 results when used in conjunction 2252 with sRGB. 2253 * LDR void extent blocks must be supported, but void extents 2254 may not be checked. 2255 2256 C.2.26 HDR PROFILE SUPPORT 2257 --------------------------- 2258 In order to ease verification and accelerate adoption, a second subset 2259 of the full ASTC specification has been made available, known as the 2260 HDR profile. 2261 2262 Implementations of the HDR Profile must satisfy the following requirements: 2263 * The HDR profile is a sueprset of the LDR profile and therefore all 2264 valid LDR encodings must decode identically using a HDR profile 2265 decoder. 2266 * All textures with valid encodings for HDR Profile must decode 2267 identically using either a HDR Profile or Full Profile decoder. 2268 * All features included only in the Full Profile must be treated as 2269 reserved in the HDR Profile, and return the error color on decoding. 2270 * Any sequence of API calls valid for the HDR Profile must also be valid 2271 for the Full Profile and return identical results when given a texture 2272 encoded for the HDR Profile. 2273 2274 The feature subset for the HDR profile is: 2275 * 2D textures only. 2276 * Only those block sizes listed in Table C.2.2 are supported. 2277 * All endpoint formats must be supported. 2278 * 2D void extent blocks must be supported, but void extents 2279 may not be checked. 2280 2281 2282Additions to Appendix D of the OpenGL ES 3.0 Specification (Shared 2283 Objects and Multiple Contexts) 2284 2285 None 2286 2287Additions to Appendix E of the OpenGL ES 3.0 Specification (Version 3.0 2288 and before) 2289 2290 None 2291 2292Revision History 2293 2294 December 12 2022 - Clarified that ASTC 3D blocks can only be used with 2295 3D targets, not 2D or cubemap arrays. 2296 2297 Revision 3, July 20, 2016 - Clarified definition of 2D void-extent 2298 blocks. 2299 2300 Revision 2, March 8, 2016 - Clarified that sRGB transform is not 2301 applied to Alpha channel. 2302