15bd8deadSopenharmony_ciName 25bd8deadSopenharmony_ci 35bd8deadSopenharmony_ci KHR_texture_compression_astc_hdr 45bd8deadSopenharmony_ci 55bd8deadSopenharmony_ciName Strings 65bd8deadSopenharmony_ci 75bd8deadSopenharmony_ci GL_KHR_texture_compression_astc_hdr 85bd8deadSopenharmony_ci GL_KHR_texture_compression_astc_ldr 95bd8deadSopenharmony_ci 105bd8deadSopenharmony_ciContact 115bd8deadSopenharmony_ci 125bd8deadSopenharmony_ci Sean Ellis (sean.ellis 'at' arm.com) 135bd8deadSopenharmony_ci Jon Leech (oddhack 'at' sonic.net) 145bd8deadSopenharmony_ci 155bd8deadSopenharmony_ciContributors 165bd8deadSopenharmony_ci 175bd8deadSopenharmony_ci Sean Ellis, ARM 185bd8deadSopenharmony_ci Jorn Nystad, ARM 195bd8deadSopenharmony_ci Tom Olson, ARM 205bd8deadSopenharmony_ci Andy Pomianowski, AMD 215bd8deadSopenharmony_ci Cass Everitt, NVIDIA 225bd8deadSopenharmony_ci Walter Donovan, NVIDIA 235bd8deadSopenharmony_ci Robert Simpson, Qualcomm 245bd8deadSopenharmony_ci Maurice Ribble, Qualcomm 255bd8deadSopenharmony_ci Larry Seiler, Intel 265bd8deadSopenharmony_ci Daniel Koch, NVIDIA 275bd8deadSopenharmony_ci Anthony Wood, Imagination Technologies 285bd8deadSopenharmony_ci Jon Leech 295bd8deadSopenharmony_ci Andrew Garrard, Samsung 305bd8deadSopenharmony_ci 315bd8deadSopenharmony_ciIP Status 325bd8deadSopenharmony_ci 335bd8deadSopenharmony_ci No known issues. 345bd8deadSopenharmony_ci 355bd8deadSopenharmony_ciNotice 365bd8deadSopenharmony_ci 375bd8deadSopenharmony_ci Copyright (c) 2012-2016 The Khronos Group Inc. Copyright terms at 385bd8deadSopenharmony_ci http://www.khronos.org/registry/speccopyright.html 395bd8deadSopenharmony_ci 405bd8deadSopenharmony_ciSpecification Update Policy 415bd8deadSopenharmony_ci 425bd8deadSopenharmony_ci Khronos-approved extension specifications are updated in response to 435bd8deadSopenharmony_ci issues and bugs prioritized by the Khronos OpenGL and OpenGL ES Working Groups. For 445bd8deadSopenharmony_ci extensions which have been promoted to a core Specification, fixes will 455bd8deadSopenharmony_ci first appear in the latest version of that core Specification, and will 465bd8deadSopenharmony_ci eventually be backported to the extension document. This policy is 475bd8deadSopenharmony_ci described in more detail at 485bd8deadSopenharmony_ci https://www.khronos.org/registry/OpenGL/docs/update_policy.php 495bd8deadSopenharmony_ci 505bd8deadSopenharmony_ciStatus 515bd8deadSopenharmony_ci 525bd8deadSopenharmony_ci Complete. 535bd8deadSopenharmony_ci Approved by the ARB on 2012/06/18. 545bd8deadSopenharmony_ci Approved by the OpenGL ES WG on 2012/06/15. 555bd8deadSopenharmony_ci Ratified by the Khronos Board of Promoters on 2012/07/27 (LDR profile). 565bd8deadSopenharmony_ci Ratified by the Khronos Board of Promoters on 2013/09/27 (HDR profile). 575bd8deadSopenharmony_ci 585bd8deadSopenharmony_ciVersion 595bd8deadSopenharmony_ci 605bd8deadSopenharmony_ci Version 8, June 8, 2017 615bd8deadSopenharmony_ci 625bd8deadSopenharmony_ciNumber 635bd8deadSopenharmony_ci 645bd8deadSopenharmony_ci ARB Extension #118 655bd8deadSopenharmony_ci OpenGL ES Extension #117 665bd8deadSopenharmony_ci 675bd8deadSopenharmony_ciDependencies 685bd8deadSopenharmony_ci 695bd8deadSopenharmony_ci Written based on the wording of the OpenGL ES 3.1 (April 29, 2015) 705bd8deadSopenharmony_ci Specification 715bd8deadSopenharmony_ci 725bd8deadSopenharmony_ci May be implemented against any version of OpenGL or OpenGL ES supporting 735bd8deadSopenharmony_ci compressed textures. 745bd8deadSopenharmony_ci 755bd8deadSopenharmony_ci Some of the functionality of these extensions is not supported if the 765bd8deadSopenharmony_ci underlying implementation does not support cube map array textures. 775bd8deadSopenharmony_ci 785bd8deadSopenharmony_ci 795bd8deadSopenharmony_ciOverview 805bd8deadSopenharmony_ci 815bd8deadSopenharmony_ci Adaptive Scalable Texture Compression (ASTC) is a new texture 825bd8deadSopenharmony_ci compression technology that offers unprecendented flexibility, while 835bd8deadSopenharmony_ci producing better or comparable results than existing texture 845bd8deadSopenharmony_ci compressions at all bit rates. It includes support for 2D and 855bd8deadSopenharmony_ci slice-based 3D textures, with low and high dynamic range, at bitrates 865bd8deadSopenharmony_ci from below 1 bit/pixel up to 8 bits/pixel in fine steps. 875bd8deadSopenharmony_ci 885bd8deadSopenharmony_ci The goal of these extensions is to support the full 2D profile of the 895bd8deadSopenharmony_ci ASTC texture compression specification, and allow construction of 3D 905bd8deadSopenharmony_ci textures from multiple compressed 2D slices. 915bd8deadSopenharmony_ci 925bd8deadSopenharmony_ci ASTC-compressed textures are handled in OpenGL ES and OpenGL by adding 935bd8deadSopenharmony_ci new supported formats to the existing commands for defining and updating 945bd8deadSopenharmony_ci compressed textures, and defining the interaction of the ASTC formats 955bd8deadSopenharmony_ci with each texture target. 965bd8deadSopenharmony_ci 975bd8deadSopenharmony_ciNew Procedures and Functions 985bd8deadSopenharmony_ci 995bd8deadSopenharmony_ci None 1005bd8deadSopenharmony_ci 1015bd8deadSopenharmony_ciNew Tokens 1025bd8deadSopenharmony_ci 1035bd8deadSopenharmony_ci Accepted by the <format> parameter of CompressedTexSubImage2D and 1045bd8deadSopenharmony_ci CompressedTexSubImage3D, and by the <internalformat> parameter of 1055bd8deadSopenharmony_ci CompressedTexImage2D, CompressedTexImage3D, TexStorage2D, 1065bd8deadSopenharmony_ci TextureStorage2D, TexStorage3D, and TextureStorage3D: 1075bd8deadSopenharmony_ci 1085bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 1095bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 1105bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 1115bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 1125bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 1135bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 1145bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 1155bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 1165bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 1175bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 1185bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA 1195bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB 1205bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC 1215bd8deadSopenharmony_ci COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD 1225bd8deadSopenharmony_ci 1235bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 1245bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 1255bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 1265bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 1275bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 1285bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 1295bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 1305bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 1315bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 1325bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 1335bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA 1345bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB 1355bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC 1365bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD 1375bd8deadSopenharmony_ci 1385bd8deadSopenharmony_ci If extension "EXT_texture_storage" is supported, these tokens are also 1395bd8deadSopenharmony_ci accepted by TexStorage2DEXT, TextureStorage2DEXT, TexStorage3DEXT and 1405bd8deadSopenharmony_ci TextureStorage3DEXT. 1415bd8deadSopenharmony_ci 1425bd8deadSopenharmony_ciAdditions to Chapter 8 of the OpenGL ES 3.1 Specification (Textures and Samplers) 1435bd8deadSopenharmony_ci 1445bd8deadSopenharmony_ci Add to Section 8.7 Compressed Texture Images: 1455bd8deadSopenharmony_ci 1465bd8deadSopenharmony_ci Modify table 8.19 (Compressed internal formats) to add all the ASTC 1475bd8deadSopenharmony_ci format tokens in the New Tokens section. The "Base Internal Format" 1485bd8deadSopenharmony_ci column is RGBA for all ASTC formats. 1495bd8deadSopenharmony_ci 1505bd8deadSopenharmony_ci Add a new column "Block Width x Height", which is 4x4 for all non-ASTC 1515bd8deadSopenharmony_ci formats in the table, and matches the size in the token name for ASTC 1525bd8deadSopenharmony_ci formats (e.g. COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR has a block size of 1535bd8deadSopenharmony_ci 10 x 8). 1545bd8deadSopenharmony_ci 1555bd8deadSopenharmony_ci Add a second new column "3D Tex." which is empty for all non-ASTC 1565bd8deadSopenharmony_ci formats. If only the LDR profile is supported by the implementation, 1575bd8deadSopenharmony_ci this column is also empty for all ASTC formats. If both the LDR and HDR 1585bd8deadSopenharmony_ci profiles are supported, this column is checked for all ASTC formats. 1595bd8deadSopenharmony_ci 1605bd8deadSopenharmony_ci Add a third new column "Cube Map Array Tex." which is empty for all 1615bd8deadSopenharmony_ci non-ASTC formats, and checked for all ASTC formats. 1625bd8deadSopenharmony_ci 1635bd8deadSopenharmony_ci Append to the table caption: 1645bd8deadSopenharmony_ci 1655bd8deadSopenharmony_ci "The "Block Size" column specifies the compressed block size of the 1665bd8deadSopenharmony_ci format. Modifying compressed images along aligned block boundaries is 1675bd8deadSopenharmony_ci possible, as described in this section. The "3D Tex." and "Cube Map 1685bd8deadSopenharmony_ci Array Tex." columns determine if 3D images composed of compressed 2D 1695bd8deadSopenharmony_ci slices, and cube map array textures respectively can be specified using 1705bd8deadSopenharmony_ci CompressedTexImage3D." 1715bd8deadSopenharmony_ci 1725bd8deadSopenharmony_ci Append to the paragraph at the bottom of p. 168: 1735bd8deadSopenharmony_ci 1745bd8deadSopenharmony_ci "If <internalformat> is one of the specific ... supports only 1755bd8deadSopenharmony_ci two-dimensional images. However, if the "3D Tex." column of table 8.19 1765bd8deadSopenharmony_ci is checked, CompressedTexImage3D will accept a three-dimensional image 1775bd8deadSopenharmony_ci specified as an array of compressed data consisting of multiple rows of 1785bd8deadSopenharmony_ci compressed blocks laid out as described in section 8.5." 1795bd8deadSopenharmony_ci 1805bd8deadSopenharmony_ci Modify the second and third errors in the Errors section for 1815bd8deadSopenharmony_ci CompressedTexImage[2d]D on p. 169, and add a new error: 1825bd8deadSopenharmony_ci 1835bd8deadSopenharmony_ci "An INVALID_VALUE error is generated by 1845bd8deadSopenharmony_ci 1855bd8deadSopenharmony_ci * CompressedTexImage2D if <target> is 1865bd8deadSopenharmony_ci one of the cube map face targets from table 8.21, and 1875bd8deadSopenharmony_ci * CompressedTexImage3D if <target> is TEXTURE_CUBE_MAP_ARRAY, 1885bd8deadSopenharmony_ci 1895bd8deadSopenharmony_ci and <width> and <height> are not equal. 1905bd8deadSopenharmony_ci 1915bd8deadSopenharmony_ci An INVALID_OPERATION error is generated by CompressedTexImage3D if 1925bd8deadSopenharmony_ci <internalformat> is one of the the formats in table 8.19 and <target> is 1935bd8deadSopenharmony_ci not TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, or TEXTURE_3D. 1945bd8deadSopenharmony_ci 1955bd8deadSopenharmony_ci An INVALID_OPERATION error is generated by CompressedTexImage3D if 1965bd8deadSopenharmony_ci <target> is TEXTURE_CUBE_MAP_ARRAY and the "Cube Map Array" 1975bd8deadSopenharmony_ci column of table 8.19 is *not* checked, or if <target> is 1985bd8deadSopenharmony_ci TEXTURE_3D and the "3D Tex." column of table 8.19 is *not* checked" 1995bd8deadSopenharmony_ci 2005bd8deadSopenharmony_ci Modify the fifth and sixth paragraphs on p. 170: 2015bd8deadSopenharmony_ci 2025bd8deadSopenharmony_ci "Since these specific compressed formats are easily edited along texel 2035bd8deadSopenharmony_ci block boundaries, the limitations on subimage location and size are 2045bd8deadSopenharmony_ci relaxed for CompressedTexSubImage2D and CompressedTexSubImage3D. 2055bd8deadSopenharmony_ci 2065bd8deadSopenharmony_ci The block width and height varies for different formats, as described in 2075bd8deadSopenharmony_ci table 8.19. The contents of any block of texels of a compressed texture 2085bd8deadSopenharmony_ci image in these specific compressed formats that does not intersect the 2095bd8deadSopenharmony_ci area being modified are preserved during CompressedTexSubImage* calls." 2105bd8deadSopenharmony_ci 2115bd8deadSopenharmony_ci Modify the second error in the Errors section for 2125bd8deadSopenharmony_ci CompressedTexSubImage[23]D on p. 170, and add a new error: 2135bd8deadSopenharmony_ci 2145bd8deadSopenharmony_ci "An INVALID_OPERATION error is generated by CompressedTexSubImage3D if 2155bd8deadSopenharmony_ci <format> is one of the formats in table 8.19 and <target> is not 2165bd8deadSopenharmony_ci TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, or TEXTURE_3D. 2175bd8deadSopenharmony_ci 2185bd8deadSopenharmony_ci An INVALID_OPERATION error is generated by CompressedTexSubImage3D if 2195bd8deadSopenharmony_ci <target> is TEXTURE_CUBE_MAP_ARRAY and the "Cube Map Array" column of 2205bd8deadSopenharmony_ci table 8.19 is *not* checked, or if <target> is TEXTURE_3D and the "3D 2215bd8deadSopenharmony_ci Tex." column of table 8.19 is *not* checked" 2225bd8deadSopenharmony_ci 2235bd8deadSopenharmony_ci Modify the final error in the same section, on p. 171: 2245bd8deadSopenharmony_ci 2255bd8deadSopenharmony_ci "An INVALID_OPERATION error is generated if format is one of the formats 2265bd8deadSopenharmony_ci in table 8.19 and any of the following conditions occurs. The block 2275bd8deadSopenharmony_ci width and height refer to the values in the corresponding column of the 2285bd8deadSopenharmony_ci table. 2295bd8deadSopenharmony_ci 2305bd8deadSopenharmony_ci * <width> is not a multiple of the format's block width, and <width> + 2315bd8deadSopenharmony_ci <xoffset> is not equal to the value of TEXTURE_WIDTH. 2325bd8deadSopenharmony_ci * height is not a multiple of the format's block height, and <height> 2335bd8deadSopenharmony_ci + <yoffset> is not equal to the value of TEXTURE_HEIGHT. 2345bd8deadSopenharmony_ci * <xoffset> or <yoffset> is not a multiple of the block width or 2355bd8deadSopenharmony_ci height, respectively." 2365bd8deadSopenharmony_ci 2375bd8deadSopenharmony_ci Modify table 8.24 (sRGB texture internal formats) to add all of the 2385bd8deadSopenharmony_ci COMPRESSED_SRGB8_ALPHA8_ASTC_*_KHR formats defined above. 2395bd8deadSopenharmony_ci 2405bd8deadSopenharmony_ciAdditions to Appendix C of the OpenGL ES 3.1 Specification (Compressed 2415bd8deadSopenharmony_ciTexture Image Formats) 2425bd8deadSopenharmony_ci 2435bd8deadSopenharmony_ci Add a new sub-section on ASTC image formats, as follows: 2445bd8deadSopenharmony_ci 2455bd8deadSopenharmony_ci "C.2 ASTC Compressed Texture Image Formats 2465bd8deadSopenharmony_ci ========================================= 2475bd8deadSopenharmony_ci 2485bd8deadSopenharmony_ci C.2.1 What is ASTC? 2495bd8deadSopenharmony_ci --------------------- 2505bd8deadSopenharmony_ci 2515bd8deadSopenharmony_ci ASTC stands for Adaptive Scalable Texture Compression. 2525bd8deadSopenharmony_ci The ASTC formats form a family of related compressed texture image 2535bd8deadSopenharmony_ci formats. They are all derived from a common set of definitions. 2545bd8deadSopenharmony_ci 2555bd8deadSopenharmony_ci ASTC textures may be encoded using either high or low dynamic range, 2565bd8deadSopenharmony_ci corresponding to the "HDR profile" and "LDR profile". Support for the 2575bd8deadSopenharmony_ci HDR profile is indicated by the "GL_KHR_texture_compression_astc_hdr" 2585bd8deadSopenharmony_ci extension string, and support for the LDR profile is indicated by the 2595bd8deadSopenharmony_ci "GL_KHR_texture_compression_astc_ldr" extension string. 2605bd8deadSopenharmony_ci 2615bd8deadSopenharmony_ci The LDR profile supports two-dimensional images for texture targets 2625bd8deadSopenharmony_ci TEXTURE_2D. TEXTURE_2D_ARRAY, the six texture cube map face targets, and 2635bd8deadSopenharmony_ci TEXTURE_CUBE_MAP_ARRAY. These images may optionally be specified using 2645bd8deadSopenharmony_ci the sRGB color space for the RGB channels. 2655bd8deadSopenharmony_ci 2665bd8deadSopenharmony_ci The HDR profile is a superset of the LDR profile, and also supports 2675bd8deadSopenharmony_ci texture target TEXTURE_3D for images made up of multiple two-dimensional 2685bd8deadSopenharmony_ci slices of compressed data. HDR images may be a mix of low and high 2695bd8deadSopenharmony_ci dynamic range data. If the HDR profile is supported, the LDR profile and 2705bd8deadSopenharmony_ci its extension string must also be supported. 2715bd8deadSopenharmony_ci 2725bd8deadSopenharmony_ci ASTC textures may be encoded as 1, 2, 3 or 4 components, but they are 2735bd8deadSopenharmony_ci all decoded into RGBA. 2745bd8deadSopenharmony_ci 2755bd8deadSopenharmony_ci Different ASTC formats have different block sizes, specified as part of 2765bd8deadSopenharmony_ci the name of the format token passed to CompressedImage2D and its related 2775bd8deadSopenharmony_ci functions, and in table 8.19. 2785bd8deadSopenharmony_ci 2795bd8deadSopenharmony_ci Additional ASTC formats (the "Full profile") exist which support 3D data 2805bd8deadSopenharmony_ci specified as compressed 3D blocks. However, such formats are not defined 2815bd8deadSopenharmony_ci by either the LDR or HDR profiles, and are not described in this 2825bd8deadSopenharmony_ci specification. 2835bd8deadSopenharmony_ci 2845bd8deadSopenharmony_ci C.2.2 Design Goals 2855bd8deadSopenharmony_ci -------------------- 2865bd8deadSopenharmony_ci 2875bd8deadSopenharmony_ci The design goals for the format are as follows: 2885bd8deadSopenharmony_ci 2895bd8deadSopenharmony_ci * Random access. This is a must for any texture compression format. 2905bd8deadSopenharmony_ci * Bit exact decode. This is a must for conformance testing and 2915bd8deadSopenharmony_ci reproducibility. 2925bd8deadSopenharmony_ci * Suitable for mobile use. The format should be suitable for both 2935bd8deadSopenharmony_ci desktop and mobile GPU environments. It should be low bandwidth 2945bd8deadSopenharmony_ci and low in area. 2955bd8deadSopenharmony_ci * Flexible choice of bit rate. Current formats only offer a few bit 2965bd8deadSopenharmony_ci rates, leaving content developers with only coarse control over 2975bd8deadSopenharmony_ci the size/quality tradeoff. 2985bd8deadSopenharmony_ci * Scalable and long-lived. The format should support existing R, RG, 2995bd8deadSopenharmony_ci RGB and RGBA image types, and also have high "headroom", allowing 3005bd8deadSopenharmony_ci continuing use for several years and the ability to innovate in 3015bd8deadSopenharmony_ci encoders. Part of this is the choice to include HDR and 3D. 3025bd8deadSopenharmony_ci * Feature orthogonality. The choices for the various features of the 3035bd8deadSopenharmony_ci format are all orthogonal to each other. This has three effects: 3045bd8deadSopenharmony_ci first, it allows a large, flexible configuration space; second, 3055bd8deadSopenharmony_ci it makes that space easier to understand; and third, it makes 3065bd8deadSopenharmony_ci verification easier. 3075bd8deadSopenharmony_ci * Best in class at given bit rate. It should beat or match the current 3085bd8deadSopenharmony_ci best in class for peak signal-to-noise ratio (PSNR) at all bit rates. 3095bd8deadSopenharmony_ci * Fast decode. Texel throughput for a cached texture should be one 3105bd8deadSopenharmony_ci texel decode per clock cycle per decoder. Parallel decoding of several 3115bd8deadSopenharmony_ci texels from the same block should be possible at incremental cost. 3125bd8deadSopenharmony_ci * Low bandwidth. The encoding scheme should ensure that memory access 3135bd8deadSopenharmony_ci is kept to a minimum, cache reuse is high and memory bandwidth for 3145bd8deadSopenharmony_ci the format is low. 3155bd8deadSopenharmony_ci * Low area. It must occupy comparable die size to competing formats. 3165bd8deadSopenharmony_ci 3175bd8deadSopenharmony_ci C.2.3 Basic Concepts 3185bd8deadSopenharmony_ci ---------------------- 3195bd8deadSopenharmony_ci 3205bd8deadSopenharmony_ci ASTC is a block-based lossy compression format. The compressed image 3215bd8deadSopenharmony_ci is divided into a number of blocks of uniform size, which makes it 3225bd8deadSopenharmony_ci possible to quickly determine which block a given texel resides in. 3235bd8deadSopenharmony_ci 3245bd8deadSopenharmony_ci Each block has a fixed memory footprint of 128 bits, but these bits 3255bd8deadSopenharmony_ci can represent varying numbers of texels (the block "footprint"). 3265bd8deadSopenharmony_ci 3275bd8deadSopenharmony_ci Block footprint sizes are not confined to powers-of-two, and are 3285bd8deadSopenharmony_ci also not confined to be square. They may be 2D, in which case the 3295bd8deadSopenharmony_ci block dimensions range from 4 to 12 texels, or 3D, in which case 3305bd8deadSopenharmony_ci the block dimensions range from 3 to 6 texels. 3315bd8deadSopenharmony_ci 3325bd8deadSopenharmony_ci Decoding one texel requires only the data from a single block. This 3335bd8deadSopenharmony_ci simplifies cache design, reduces bandwidth and improves encoder throughput. 3345bd8deadSopenharmony_ci 3355bd8deadSopenharmony_ci C.2.4 Block Encoding 3365bd8deadSopenharmony_ci ---------------------- 3375bd8deadSopenharmony_ci 3385bd8deadSopenharmony_ci To understand how the blocks are stored and decoded, it is useful to start 3395bd8deadSopenharmony_ci with a simple example, and then introduce additional features. 3405bd8deadSopenharmony_ci 3415bd8deadSopenharmony_ci The simplest block encoding starts by defining two color "endpoints". The 3425bd8deadSopenharmony_ci endpoints define two colors, and a number of additional colors are generated 3435bd8deadSopenharmony_ci by interpolating between them. We can define these colors using 1, 2, 3, 3445bd8deadSopenharmony_ci or 4 components (usually corresponding to R, RG, RGB and RGBA textures), 3455bd8deadSopenharmony_ci and using low or high dynamic range. 3465bd8deadSopenharmony_ci 3475bd8deadSopenharmony_ci We then store a color interpolant weight for each texel in the image, which 3485bd8deadSopenharmony_ci specifies how to calculate the color to use. From this, a weighted average 3495bd8deadSopenharmony_ci of the two endpoint colors is used to generate the intermediate color, 3505bd8deadSopenharmony_ci which is the returned color for this texel. 3515bd8deadSopenharmony_ci 3525bd8deadSopenharmony_ci There are several different ways of specifying the endpoint colors, and the 3535bd8deadSopenharmony_ci weights, but once they have been defined, calculation of the texel colors 3545bd8deadSopenharmony_ci proceeds identically for all of them. Each block is free to choose whichever 3555bd8deadSopenharmony_ci encoding scheme best represents its color endpoints, within the constraint 3565bd8deadSopenharmony_ci that all the data fits within the 128 bit block. 3575bd8deadSopenharmony_ci 3585bd8deadSopenharmony_ci For blocks which have a large number of texels (e.g. a 12x12 block), there is 3595bd8deadSopenharmony_ci not enough space to explicitly store a weight for every texel. In this case, 3605bd8deadSopenharmony_ci a sparser grid with fewer weights is stored, and interpolation is used to 3615bd8deadSopenharmony_ci determine the effective weight to be used for each texel position. This allows 3625bd8deadSopenharmony_ci very low bit rates to be used with acceptable quality. This can also be used 3635bd8deadSopenharmony_ci to more efficiently encode blocks with low detail, or with strong vertical 3645bd8deadSopenharmony_ci or horizontal features. 3655bd8deadSopenharmony_ci 3665bd8deadSopenharmony_ci For blocks which have a mixture of disparate colors, a single line in the 3675bd8deadSopenharmony_ci color space is not a good fit to the colors of the pixels in the original 3685bd8deadSopenharmony_ci image. It is therefore possible to partition the texels into multiple sets, 3695bd8deadSopenharmony_ci the pixels within each set having similar colors. For each of these 3705bd8deadSopenharmony_ci "partitions", we specify separate endpoint pairs, and choose which pair of 3715bd8deadSopenharmony_ci endpoints to use for a particular texel by looking up the partition index 3725bd8deadSopenharmony_ci from a partitioning pattern table. In ASTC, this partition table is actually 3735bd8deadSopenharmony_ci implemented as a function. 3745bd8deadSopenharmony_ci 3755bd8deadSopenharmony_ci The endpoint encoding for each partition is independent. 3765bd8deadSopenharmony_ci 3775bd8deadSopenharmony_ci For blocks which have uncorrelated channels - for example an image with a 3785bd8deadSopenharmony_ci transparency mask, or an image used as a normal map - it may be necessary 3795bd8deadSopenharmony_ci to specify two weights for each texel. Interpolation between the components 3805bd8deadSopenharmony_ci of the endpoint colors can then proceed independently for each "plane" of 3815bd8deadSopenharmony_ci the image. The assignment of channels to planes is selectable. 3825bd8deadSopenharmony_ci 3835bd8deadSopenharmony_ci Since each of the above options is independent, it is possible to specify any 3845bd8deadSopenharmony_ci combination of channels, endpoint color encoding, weight encoding, 3855bd8deadSopenharmony_ci interpolation, multiple partitions and single or dual planes. 3865bd8deadSopenharmony_ci 3875bd8deadSopenharmony_ci Since these values are specified per block, it is important that they are 3885bd8deadSopenharmony_ci represented with the minimum possible number of bits. As a result, these 3895bd8deadSopenharmony_ci values are packed together in ways which can be difficult to read, but 3905bd8deadSopenharmony_ci which are nevertheless highly amenable to hardware decode. 3915bd8deadSopenharmony_ci 3925bd8deadSopenharmony_ci All of the values used as weights and color endpoint values can be specified 3935bd8deadSopenharmony_ci with a variable number of bits. The encoding scheme used allows a fine- 3945bd8deadSopenharmony_ci grained tradeoff between weight bits and color endpoint bits using "integer 3955bd8deadSopenharmony_ci sequence encoding". This can pack adjacent values together, allowing us to 3965bd8deadSopenharmony_ci use fractional numbers of bits per value. 3975bd8deadSopenharmony_ci 3985bd8deadSopenharmony_ci Finally, a block may be just a single color. This is a so-called "void 3995bd8deadSopenharmony_ci extent block" and has a special coding which also allows it to identify 4005bd8deadSopenharmony_ci nearby regions of single color. This may be used to short-circuit fetching of 4015bd8deadSopenharmony_ci what would be identical blocks, and further reduce memory bandwidth. 4025bd8deadSopenharmony_ci 4035bd8deadSopenharmony_ci C.2.5 LDR and HDR Modes 4045bd8deadSopenharmony_ci ------------------------- 4055bd8deadSopenharmony_ci 4065bd8deadSopenharmony_ci The decoding process for LDR content can be simplified if it is known in 4075bd8deadSopenharmony_ci advance that sRGB output is required. This selection is therefore included 4085bd8deadSopenharmony_ci as part of the global configuration. 4095bd8deadSopenharmony_ci 4105bd8deadSopenharmony_ci The two modes differ in various ways. 4115bd8deadSopenharmony_ci 4125bd8deadSopenharmony_ci ----------------------------------------------------------------------------- 4135bd8deadSopenharmony_ci Operation LDR Mode HDR Mode 4145bd8deadSopenharmony_ci ----------------------------------------------------------------------------- 4155bd8deadSopenharmony_ci Returned value Vector of FP16 values, Vector of FP16 values 4165bd8deadSopenharmony_ci or Vector of UNORM8 values. 4175bd8deadSopenharmony_ci 4185bd8deadSopenharmony_ci sRGB compatible Yes No 4195bd8deadSopenharmony_ci 4205bd8deadSopenharmony_ci LDR endpoint 16 bits, or 16 bits 4215bd8deadSopenharmony_ci decoding precision 8 bits for sRGB 4225bd8deadSopenharmony_ci 4235bd8deadSopenharmony_ci HDR endpoint mode Error color As decoded 4245bd8deadSopenharmony_ci results 4255bd8deadSopenharmony_ci 4265bd8deadSopenharmony_ci Error results Error color Vector of NaNs (0xFFFF) 4275bd8deadSopenharmony_ci ----------------------------------------------------------------------------- 4285bd8deadSopenharmony_ci Table C.2.1 - Differences Between LDR and HDR Modes 4295bd8deadSopenharmony_ci 4305bd8deadSopenharmony_ci The error color is opaque fully-saturated magenta 4315bd8deadSopenharmony_ci (R,G,B,A = 0xFF, 0x00, 0xFF, 0xFF). This has been chosen as it is much more 4325bd8deadSopenharmony_ci noticeable than black or white, and occurs far less often in valid images. 4335bd8deadSopenharmony_ci 4345bd8deadSopenharmony_ci For linear RGB decode, the error color may be either opaque fully-saturated 4355bd8deadSopenharmony_ci magenta (R,G,B,A = 1.0, 0.0, 1.0, 1.0) or a vector of four NaNs 4365bd8deadSopenharmony_ci (R,G,B,A = NaN, NaN, NaN, NaN). In the latter case, the recommended NaN 4375bd8deadSopenharmony_ci value returned is 0xFFFF. 4385bd8deadSopenharmony_ci 4395bd8deadSopenharmony_ci The error color is returned as an informative response to invalid 4405bd8deadSopenharmony_ci conditions, including invalid block encodings or use of reserved endpoint 4415bd8deadSopenharmony_ci modes. 4425bd8deadSopenharmony_ci 4435bd8deadSopenharmony_ci Future, forward-compatible extensions to KHR_texture_compression_astc 4445bd8deadSopenharmony_ci may define valid interpretations of these conditions, which will decode to 4455bd8deadSopenharmony_ci some other color. Therefore, encoders and applications must not rely on 4465bd8deadSopenharmony_ci invalid encodings as a way of generating the error color. 4475bd8deadSopenharmony_ci 4485bd8deadSopenharmony_ci C.2.6 Configuration Summary 4495bd8deadSopenharmony_ci ----------------------------- 4505bd8deadSopenharmony_ci 4515bd8deadSopenharmony_ci The global configuration data for the format is as follows: 4525bd8deadSopenharmony_ci 4535bd8deadSopenharmony_ci * Block dimension (always 2D for both LDR and HDR profiles) 4545bd8deadSopenharmony_ci * Block footprint size 4555bd8deadSopenharmony_ci * sRGB output enabled or not 4565bd8deadSopenharmony_ci 4575bd8deadSopenharmony_ci The data specified per block is as follows: 4585bd8deadSopenharmony_ci 4595bd8deadSopenharmony_ci * Texel weight grid size 4605bd8deadSopenharmony_ci * Texel weight range 4615bd8deadSopenharmony_ci * Texel weight values 4625bd8deadSopenharmony_ci * Number of partitions 4635bd8deadSopenharmony_ci * Partition pattern index 4645bd8deadSopenharmony_ci * Color endpoint modes (includes LDR or HDR selection) 4655bd8deadSopenharmony_ci * Color endpoint data 4665bd8deadSopenharmony_ci * Number of planes 4675bd8deadSopenharmony_ci * Plane-to-channel assignment 4685bd8deadSopenharmony_ci 4695bd8deadSopenharmony_ci C.2.7 Decode Procedure 4705bd8deadSopenharmony_ci ------------------------ 4715bd8deadSopenharmony_ci 4725bd8deadSopenharmony_ci To decode one texel: 4735bd8deadSopenharmony_ci 4745bd8deadSopenharmony_ci Find block containing texel 4755bd8deadSopenharmony_ci Read block mode 4765bd8deadSopenharmony_ci If void-extent block, store void extent and immediately return single 4775bd8deadSopenharmony_ci color (optimization) 4785bd8deadSopenharmony_ci 4795bd8deadSopenharmony_ci For each plane in image 4805bd8deadSopenharmony_ci If block mode requires infill 4815bd8deadSopenharmony_ci Find and decode stored weights adjacent to texel, unquantize and 4825bd8deadSopenharmony_ci interpolate 4835bd8deadSopenharmony_ci Else 4845bd8deadSopenharmony_ci Find and decode weight for texel, and unquantize 4855bd8deadSopenharmony_ci 4865bd8deadSopenharmony_ci Read number of partitions 4875bd8deadSopenharmony_ci If number of partitions > 1 4885bd8deadSopenharmony_ci Read partition table pattern index 4895bd8deadSopenharmony_ci Look up partition number from pattern 4905bd8deadSopenharmony_ci 4915bd8deadSopenharmony_ci Read color endpoint mode and endpoint data for selected partition 4925bd8deadSopenharmony_ci Unquantize color endpoints 4935bd8deadSopenharmony_ci Interpolate color endpoints using weight (or weights in dual-plane mode) 4945bd8deadSopenharmony_ci Return interpolated color 4955bd8deadSopenharmony_ci 4965bd8deadSopenharmony_ci C.2.8 Block Determination and Bit Rates 4975bd8deadSopenharmony_ci The block footprint is a global setting for any given texture, and is 4985bd8deadSopenharmony_ci therefore not encoded in the individual blocks. 4995bd8deadSopenharmony_ci 5005bd8deadSopenharmony_ci For 2D textures, the block footprint's width and height are selectable 5015bd8deadSopenharmony_ci from a number of predefined sizes, namely 4, 5, 6, 8, 10 and 12 pixels. 5025bd8deadSopenharmony_ci 5035bd8deadSopenharmony_ci For square and nearly-square blocks, this gives the following bit rates: 5045bd8deadSopenharmony_ci 5055bd8deadSopenharmony_ci ------------------------------------- 5065bd8deadSopenharmony_ci Footprint 5075bd8deadSopenharmony_ci Width Height Bit Rate Increment 5085bd8deadSopenharmony_ci ------------------------------------- 5095bd8deadSopenharmony_ci 4 4 8.00 125% 5105bd8deadSopenharmony_ci 5 4 6.40 125% 5115bd8deadSopenharmony_ci 5 5 5.12 120% 5125bd8deadSopenharmony_ci 6 5 4.27 120% 5135bd8deadSopenharmony_ci 6 6 3.56 114% 5145bd8deadSopenharmony_ci 8 5 3.20 120% 5155bd8deadSopenharmony_ci 8 6 2.67 105% 5165bd8deadSopenharmony_ci 10 5 2.56 120% 5175bd8deadSopenharmony_ci 10 6 2.13 107% 5185bd8deadSopenharmony_ci 8 8 2.00 125% 5195bd8deadSopenharmony_ci 10 8 1.60 125% 5205bd8deadSopenharmony_ci 10 10 1.28 120% 5215bd8deadSopenharmony_ci 12 10 1.07 120% 5225bd8deadSopenharmony_ci 12 12 0.89 5235bd8deadSopenharmony_ci ------------------------------------- 5245bd8deadSopenharmony_ci Table C.2.2 - 2D Footprint and Bit Rates 5255bd8deadSopenharmony_ci 5265bd8deadSopenharmony_ci The block footprint is shown as <width>x<height> in the format name. For 5275bd8deadSopenharmony_ci example, the format COMPRESSED_RGBA_ASTC_8x6_KHR specifies an image with 5285bd8deadSopenharmony_ci a block width of 8 texels, and a block height of 6 texels. 5295bd8deadSopenharmony_ci 5305bd8deadSopenharmony_ci The "Increment" column indicates the ratio of bit rate against the next 5315bd8deadSopenharmony_ci lower available rate. A consistent value in this column indicates an even 5325bd8deadSopenharmony_ci spread of bit rates. 5335bd8deadSopenharmony_ci 5345bd8deadSopenharmony_ci The HDR profile supports only those block footprints listed in Table 5355bd8deadSopenharmony_ci C.2.2. Other block sizes are not supported. 5365bd8deadSopenharmony_ci 5375bd8deadSopenharmony_ci For images which are not an integer multiple of the block size, additional 5385bd8deadSopenharmony_ci texels are added to the edges with maximum X and Y. These texels may be 5395bd8deadSopenharmony_ci any color, as they will not be accessed. 5405bd8deadSopenharmony_ci 5415bd8deadSopenharmony_ci Although these are not all powers of two, it is possible to calculate block 5425bd8deadSopenharmony_ci addresses and pixel addresses within the block, for legal image sizes, 5435bd8deadSopenharmony_ci without undue complexity. 5445bd8deadSopenharmony_ci 5455bd8deadSopenharmony_ci Given a 2D image which is W x H pixels in size, with block size 5465bd8deadSopenharmony_ci w x h, the size of the image in blocks is: 5475bd8deadSopenharmony_ci 5485bd8deadSopenharmony_ci Bw = ceiling(W/w) 5495bd8deadSopenharmony_ci Bh = ceiling(H/h) 5505bd8deadSopenharmony_ci 5515bd8deadSopenharmony_ci For a 3D image, each 2D slice is a single texel thick, so that for an 5525bd8deadSopenharmony_ci image which is W x H x D pixels in size, with block size w x h, the size 5535bd8deadSopenharmony_ci of the image in blocks is: 5545bd8deadSopenharmony_ci 5555bd8deadSopenharmony_ci Bw = ceiling(W/w) 5565bd8deadSopenharmony_ci Bh = ceiling(H/h) 5575bd8deadSopenharmony_ci Bd = D 5585bd8deadSopenharmony_ci 5595bd8deadSopenharmony_ci C.2.9 Block Layout 5605bd8deadSopenharmony_ci -------------------- 5615bd8deadSopenharmony_ci 5625bd8deadSopenharmony_ci Each block in the image is stored as a single 128-bit block in memory. These 5635bd8deadSopenharmony_ci blocks are laid out in raster order, starting with the block at (0,0,0), then 5645bd8deadSopenharmony_ci ordered sequentially by X, Y and finally Z (if present). They are aligned to 5655bd8deadSopenharmony_ci 128-bit boundaries in memory. 5665bd8deadSopenharmony_ci 5675bd8deadSopenharmony_ci The bits in the block are labeled in little-endian order - the byte at the 5685bd8deadSopenharmony_ci lowest address contains bits 0..7. Bit 0 is the least significant bit in the 5695bd8deadSopenharmony_ci byte. 5705bd8deadSopenharmony_ci 5715bd8deadSopenharmony_ci Each block has the same basic layout, as shown in figure C.1. 5725bd8deadSopenharmony_ci 5735bd8deadSopenharmony_ci 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112 5745bd8deadSopenharmony_ci -------------------------------------------------------------- 5755bd8deadSopenharmony_ci | Texel Weight Data (variable width) Fill direction -> 5765bd8deadSopenharmony_ci -------------------------------------------------------------- 5775bd8deadSopenharmony_ci 5785bd8deadSopenharmony_ci 111 110 109 108 107 106 105 104 103 102 101 100 99 98 97 96 5795bd8deadSopenharmony_ci -------------------------------------------------------------- 5805bd8deadSopenharmony_ci Texel Weight Data 5815bd8deadSopenharmony_ci -------------------------------------------------------------- 5825bd8deadSopenharmony_ci 5835bd8deadSopenharmony_ci 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 5845bd8deadSopenharmony_ci -------------------------------------------------------------- 5855bd8deadSopenharmony_ci Texel Weight Data 5865bd8deadSopenharmony_ci -------------------------------------------------------------- 5875bd8deadSopenharmony_ci 5885bd8deadSopenharmony_ci 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 5895bd8deadSopenharmony_ci -------------------------------------------------------------- 5905bd8deadSopenharmony_ci Texel Weight Data 5915bd8deadSopenharmony_ci -------------------------------------------------------------- 5925bd8deadSopenharmony_ci 5935bd8deadSopenharmony_ci 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 5945bd8deadSopenharmony_ci -------------------------------------------------------------- 5955bd8deadSopenharmony_ci : More config data : 5965bd8deadSopenharmony_ci -------------------------------------------------------------- 5975bd8deadSopenharmony_ci 5985bd8deadSopenharmony_ci 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 5995bd8deadSopenharmony_ci -------------------------------------------------------------- 6005bd8deadSopenharmony_ci <-Fill direction Color Endpoint Data 6015bd8deadSopenharmony_ci -------------------------------------------------------------- 6025bd8deadSopenharmony_ci 6035bd8deadSopenharmony_ci 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 6045bd8deadSopenharmony_ci -------------------------------------------------------------- 6055bd8deadSopenharmony_ci : Extra configuration data 6065bd8deadSopenharmony_ci -------------------------------------------------------------- 6075bd8deadSopenharmony_ci 6085bd8deadSopenharmony_ci 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 6095bd8deadSopenharmony_ci -------------------------------------------------------------- 6105bd8deadSopenharmony_ci Extra | Part | Block mode | 6115bd8deadSopenharmony_ci -------------------------------------------------------------- 6125bd8deadSopenharmony_ci 6135bd8deadSopenharmony_ci Figure C.1 - Block Layout Overview 6145bd8deadSopenharmony_ci 6155bd8deadSopenharmony_ci Dotted partition lines indicate that the split position is not fixed. 6165bd8deadSopenharmony_ci 6175bd8deadSopenharmony_ci The "Block mode" field specifies how the Texel Weight Data is encoded. 6185bd8deadSopenharmony_ci 6195bd8deadSopenharmony_ci The "Part" field specifies the number of partitions, minus one. If dual 6205bd8deadSopenharmony_ci plane mode is enabled, the number of partitions must be 3 or fewer. 6215bd8deadSopenharmony_ci If 4 partitions are specified, the error value is returned for all 6225bd8deadSopenharmony_ci texels in the block. 6235bd8deadSopenharmony_ci 6245bd8deadSopenharmony_ci The size and layout of the extra configuration data depends on the 6255bd8deadSopenharmony_ci number of partitions, and the number of planes in the image, as shown in 6265bd8deadSopenharmony_ci figures C.2 and C.3 (only the bottom 32 bits are shown): 6275bd8deadSopenharmony_ci 6285bd8deadSopenharmony_ci 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 6295bd8deadSopenharmony_ci -------------------------------------------------------------- 6305bd8deadSopenharmony_ci <- Color endpoint data |CEM 6315bd8deadSopenharmony_ci -------------------------------------------------------------- 6325bd8deadSopenharmony_ci 6335bd8deadSopenharmony_ci 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 6345bd8deadSopenharmony_ci -------------------------------------------------------------- 6355bd8deadSopenharmony_ci CEM | 0 0 | Block Mode | 6365bd8deadSopenharmony_ci -------------------------------------------------------------- 6375bd8deadSopenharmony_ci 6385bd8deadSopenharmony_ci Figure C.2 - Single-partition Block Layout 6395bd8deadSopenharmony_ci 6405bd8deadSopenharmony_ci CEM is the color endpoint mode field, which determines how the Color 6415bd8deadSopenharmony_ci Endpoint Data is encoded. 6425bd8deadSopenharmony_ci 6435bd8deadSopenharmony_ci If dual-plane mode is active, the color component selector bits appear 6445bd8deadSopenharmony_ci directly below the weight bits. 6455bd8deadSopenharmony_ci 6465bd8deadSopenharmony_ci 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 6475bd8deadSopenharmony_ci -------------------------------------------------------------- 6485bd8deadSopenharmony_ci | CEM | Partition Index 6495bd8deadSopenharmony_ci -------------------------------------------------------------- 6505bd8deadSopenharmony_ci 6515bd8deadSopenharmony_ci 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 6525bd8deadSopenharmony_ci -------------------------------------------------------------- 6535bd8deadSopenharmony_ci Partition Index | Block Mode | 6545bd8deadSopenharmony_ci -------------------------------------------------------------- 6555bd8deadSopenharmony_ci 6565bd8deadSopenharmony_ci Figure C.3 - Multi-partition Block Layout 6575bd8deadSopenharmony_ci 6585bd8deadSopenharmony_ci The Partition Index field specifies which partition layout to use. CEM is 6595bd8deadSopenharmony_ci the first 6 bits of color endpoint mode information for the various 6605bd8deadSopenharmony_ci partitions. For modes which require more than 6 bits of CEM data, the 6615bd8deadSopenharmony_ci additional bits appear at a variable position directly beneath the texel 6625bd8deadSopenharmony_ci weight data. 6635bd8deadSopenharmony_ci 6645bd8deadSopenharmony_ci If dual-plane mode is active, the color component selector bits then appear 6655bd8deadSopenharmony_ci directly below the additional CEM bits. 6665bd8deadSopenharmony_ci 6675bd8deadSopenharmony_ci The final special case is that if bits [8:0] of the block are "111111100", 6685bd8deadSopenharmony_ci then the block is a void-extent block, which has a separate encoding 6695bd8deadSopenharmony_ci described in section C.2.23. 6705bd8deadSopenharmony_ci 6715bd8deadSopenharmony_ci C.2.10 Block Mode 6725bd8deadSopenharmony_ci ------------------ 6735bd8deadSopenharmony_ci 6745bd8deadSopenharmony_ci The Block Mode field specifies the width, height and depth of the grid of 6755bd8deadSopenharmony_ci weights, what range of values they use, and whether dual weight planes are 6765bd8deadSopenharmony_ci present. Since some these are not represented using powers of two (there 6775bd8deadSopenharmony_ci are 12 possible weight widths, for example), and not all combinations are 6785bd8deadSopenharmony_ci allowed, this is not a simple bit packing. However, it can be unpacked 6795bd8deadSopenharmony_ci quickly in hardware. 6805bd8deadSopenharmony_ci 6815bd8deadSopenharmony_ci The weight ranges are encoded using a 3 bit value R, which is interpreted 6825bd8deadSopenharmony_ci together with a precision bit H, as follows: 6835bd8deadSopenharmony_ci 6845bd8deadSopenharmony_ci Low Precision Range (H=0) High Precision Range (H=1) 6855bd8deadSopenharmony_ci R Weight Range Trits Quints Bits Weight Range Trits Quints Bits 6865bd8deadSopenharmony_ci ------------------------------------------------------------------------- 6875bd8deadSopenharmony_ci 000 Invalid Invalid 6885bd8deadSopenharmony_ci 001 Invalid Invalid 6895bd8deadSopenharmony_ci 010 0..1 1 0..9 1 1 6905bd8deadSopenharmony_ci 011 0..2 1 0..11 1 2 6915bd8deadSopenharmony_ci 100 0..3 2 0..15 4 6925bd8deadSopenharmony_ci 101 0..4 1 0..19 1 2 6935bd8deadSopenharmony_ci 110 0..5 1 1 0..23 1 3 6945bd8deadSopenharmony_ci 111 0..7 3 0..31 5 6955bd8deadSopenharmony_ci ------------------------------------------------------------------------- 6965bd8deadSopenharmony_ci Table C.2.7 - Weight Range Encodings 6975bd8deadSopenharmony_ci 6985bd8deadSopenharmony_ci Each weight value is encoded using the specified number of Trits, Quints 6995bd8deadSopenharmony_ci and Bits. The details of this encoding can be found in Section C.2.12 - 7005bd8deadSopenharmony_ci Integer Sequence Encoding. 7015bd8deadSopenharmony_ci 7025bd8deadSopenharmony_ci For 2D blocks, the Block Mode field is laid out as follows: 7035bd8deadSopenharmony_ci 7045bd8deadSopenharmony_ci ------------------------------------------------------------------------- 7055bd8deadSopenharmony_ci 10 9 8 7 6 5 4 3 2 1 0 Width Height Notes 7065bd8deadSopenharmony_ci ------------------------------------------------------------------------- 7075bd8deadSopenharmony_ci D H B A R0 0 0 R2 R1 B+4 A+2 7085bd8deadSopenharmony_ci D H B A R0 0 1 R2 R1 B+8 A+2 7095bd8deadSopenharmony_ci D H B A R0 1 0 R2 R1 A+2 B+8 7105bd8deadSopenharmony_ci D H 0 B A R0 1 1 R2 R1 A+2 B+6 7115bd8deadSopenharmony_ci D H 1 B A R0 1 1 R2 R1 B+2 A+2 7125bd8deadSopenharmony_ci D H 0 0 A R0 R2 R1 0 0 12 A+2 7135bd8deadSopenharmony_ci D H 0 1 A R0 R2 R1 0 0 A+2 12 7145bd8deadSopenharmony_ci D H 1 1 0 0 R0 R2 R1 0 0 6 10 7155bd8deadSopenharmony_ci D H 1 1 0 1 R0 R2 R1 0 0 10 6 7165bd8deadSopenharmony_ci B 1 0 A R0 R2 R1 0 0 A+6 B+6 D=0, H=0 7175bd8deadSopenharmony_ci x x 1 1 1 1 1 1 1 0 0 - - Void-extent 7185bd8deadSopenharmony_ci x x 1 1 1 x x x x 0 0 - - Reserved* 7195bd8deadSopenharmony_ci x x x x x x x 0 0 0 0 - - Reserved 7205bd8deadSopenharmony_ci ------------------------------------------------------------------------- 7215bd8deadSopenharmony_ci Table C.2.8 - 2D Block Mode Layout 7225bd8deadSopenharmony_ci 7235bd8deadSopenharmony_ci Note that, due to the encoding of the R field, as described in the 7245bd8deadSopenharmony_ci previous page, bits R2 and R1 cannot both be zero, which disambiguates 7255bd8deadSopenharmony_ci the first five rows from the rest of the table. 7265bd8deadSopenharmony_ci 7275bd8deadSopenharmony_ci Bit positions with a value of x are ignored for purposes of determining 7285bd8deadSopenharmony_ci if a block is a void-extent block or reserved, but may have defined 7295bd8deadSopenharmony_ci encodings for specific void-extent blocks. 7305bd8deadSopenharmony_ci 7315bd8deadSopenharmony_ci The penultimate row of the table is reserved only if bits [5:2] are not 7325bd8deadSopenharmony_ci all 1, in which case it encodes a void-extent block (as shown in the 7335bd8deadSopenharmony_ci previous row). 7345bd8deadSopenharmony_ci 7355bd8deadSopenharmony_ci The D bit is set to indicate dual-plane mode. In this mode, the maximum 7365bd8deadSopenharmony_ci allowed number of partitions is 3. 7375bd8deadSopenharmony_ci 7385bd8deadSopenharmony_ci The penultimate row of the table is reserved only if bits [4:2] are not 7395bd8deadSopenharmony_ci all 1, in which case it encodes a void-extent block (as shown in the 7405bd8deadSopenharmony_ci previous row). 7415bd8deadSopenharmony_ci 7425bd8deadSopenharmony_ci The size of the grid in each dimension must be less than or equal to 7435bd8deadSopenharmony_ci the corresponding dimension of the block footprint. If the grid size 7445bd8deadSopenharmony_ci is greater than the footprint dimension in any axis, then this is an 7455bd8deadSopenharmony_ci illegal block encoding and all texels will decode to the error color. 7465bd8deadSopenharmony_ci 7475bd8deadSopenharmony_ci C.2.11 Color Endpoint Mode 7485bd8deadSopenharmony_ci --------------------------- 7495bd8deadSopenharmony_ci 7505bd8deadSopenharmony_ci In single-partition mode, the Color Endpoint Mode (CEM) field stores one 7515bd8deadSopenharmony_ci of 16 possible values. Each of these specifies how many raw data values 7525bd8deadSopenharmony_ci are encoded, and how to convert these raw values into two RGBA color 7535bd8deadSopenharmony_ci endpoints. They can be summarized as follows: 7545bd8deadSopenharmony_ci 7555bd8deadSopenharmony_ci --------------------------------------------- 7565bd8deadSopenharmony_ci CEM Description Class 7575bd8deadSopenharmony_ci --------------------------------------------- 7585bd8deadSopenharmony_ci 0 LDR Luminance, direct 0 7595bd8deadSopenharmony_ci 1 LDR Luminance, base+offset 0 7605bd8deadSopenharmony_ci 2 HDR Luminance, large range 0 7615bd8deadSopenharmony_ci 3 HDR Luminance, small range 0 7625bd8deadSopenharmony_ci 4 LDR Luminance+Alpha, direct 1 7635bd8deadSopenharmony_ci 5 LDR Luminance+Alpha, base+offset 1 7645bd8deadSopenharmony_ci 6 LDR RGB, base+scale 1 7655bd8deadSopenharmony_ci 7 HDR RGB, base+scale 1 7665bd8deadSopenharmony_ci 8 LDR RGB, direct 2 7675bd8deadSopenharmony_ci 9 LDR RGB, base+offset 2 7685bd8deadSopenharmony_ci 10 LDR RGB, base+scale plus two A 2 7695bd8deadSopenharmony_ci 11 HDR RGB, direct 2 7705bd8deadSopenharmony_ci 12 LDR RGBA, direct 3 7715bd8deadSopenharmony_ci 13 LDR RGBA, base+offset 3 7725bd8deadSopenharmony_ci 14 HDR RGB, direct + LDR Alpha 3 7735bd8deadSopenharmony_ci 15 HDR RGB, direct + HDR Alpha 3 7745bd8deadSopenharmony_ci --------------------------------------------- 7755bd8deadSopenharmony_ci Table C.2.10 - Color Endpoint Modes. 7765bd8deadSopenharmony_ci [[ If the HDR profile is not implemented, remove from table C.2.10 7775bd8deadSopenharmony_ci all rows whose description starts with "HDR", and add to the 7785bd8deadSopenharmony_ci caption: ]] 7795bd8deadSopenharmony_ci Modes not described in the CEM column are reserved for HDR modes, and 7805bd8deadSopenharmony_ci will generate errors in an unextended OpenGL ES implementation. 7815bd8deadSopenharmony_ci 7825bd8deadSopenharmony_ci In multi-partition mode, the CEM field is of variable width, from 6 to 14 7835bd8deadSopenharmony_ci bits. The lowest 2 bits of the CEM field specify how the endpoint mode 7845bd8deadSopenharmony_ci for each partition is calculated: 7855bd8deadSopenharmony_ci 7865bd8deadSopenharmony_ci ---------------------------------------------------- 7875bd8deadSopenharmony_ci Value Meaning 7885bd8deadSopenharmony_ci ---------------------------------------------------- 7895bd8deadSopenharmony_ci 00 All color endpoint pairs are of the same type. 7905bd8deadSopenharmony_ci A full 4-bit CEM is stored in block bits [28:25] 7915bd8deadSopenharmony_ci and is used for all partitions. 7925bd8deadSopenharmony_ci 01 All endpoint pairs are of class 0 or 1. 7935bd8deadSopenharmony_ci 10 All endpoint pairs are of class 1 or 2. 7945bd8deadSopenharmony_ci 11 All endpoint pairs are of class 2 or 3. 7955bd8deadSopenharmony_ci ---------------------------------------------------- 7965bd8deadSopenharmony_ci Table C.2.11 - Multi-Partition Color Endpoint Modes 7975bd8deadSopenharmony_ci 7985bd8deadSopenharmony_ci If the CEM selector value in bits [24:23] is not 00, 7995bd8deadSopenharmony_ci then data layout is as follows: 8005bd8deadSopenharmony_ci 8015bd8deadSopenharmony_ci --------------------------------------------------- 8025bd8deadSopenharmony_ci Part n m l k j i h g 8035bd8deadSopenharmony_ci ------------------------------------------ 8045bd8deadSopenharmony_ci 2 ... Weight : M1 : ... 8055bd8deadSopenharmony_ci ------------------------------------------ 8065bd8deadSopenharmony_ci 3 ... Weight : M2 : M1 :M0 : ... 8075bd8deadSopenharmony_ci ------------------------------------------ 8085bd8deadSopenharmony_ci 4 ... Weight : M3 : M2 : M1 : M0 : ... 8095bd8deadSopenharmony_ci ------------------------------------------ 8105bd8deadSopenharmony_ci 8115bd8deadSopenharmony_ci Part 28 27 26 25 24 23 8125bd8deadSopenharmony_ci ---------------------- 8135bd8deadSopenharmony_ci 2 | M0 |C1 |C0 | CEM | 8145bd8deadSopenharmony_ci ---------------------- 8155bd8deadSopenharmony_ci 3 |M0 |C2 |C1 |C0 | CEM | 8165bd8deadSopenharmony_ci ---------------------- 8175bd8deadSopenharmony_ci 4 |C3 |C2 |C1 |C0 | CEM | 8185bd8deadSopenharmony_ci ---------------------- 8195bd8deadSopenharmony_ci --------------------------------------------------- 8205bd8deadSopenharmony_ci Figure C.4 - Multi-Partition Color Endpoint Modes 8215bd8deadSopenharmony_ci 8225bd8deadSopenharmony_ci In this view, each partition i has two fields. C<i> is the class 8235bd8deadSopenharmony_ci selector bit, choosing between the two possible CEM classes (0 indicates 8245bd8deadSopenharmony_ci the lower of the two classes), and M<i> is a two-bit field specifying 8255bd8deadSopenharmony_ci the low bits of the color endpoint mode within that class. The 8265bd8deadSopenharmony_ci additional bits appear at a variable bit position, immediately below the 8275bd8deadSopenharmony_ci texel weight data. 8285bd8deadSopenharmony_ci 8295bd8deadSopenharmony_ci The ranges used for the data values are not explicitly specified. 8305bd8deadSopenharmony_ci Instead, they are derived from the number of available bits remaining 8315bd8deadSopenharmony_ci after the configuration data and weight data have been specified. 8325bd8deadSopenharmony_ci 8335bd8deadSopenharmony_ci Details of the decoding procedure for Color Endpoints can be found in 8345bd8deadSopenharmony_ci section C.2.13. 8355bd8deadSopenharmony_ci 8365bd8deadSopenharmony_ci C.2.12 Integer Sequence Encoding 8375bd8deadSopenharmony_ci --------------------------------- 8385bd8deadSopenharmony_ci 8395bd8deadSopenharmony_ci Both the weight data and the endpoint color data are variable width, and 8405bd8deadSopenharmony_ci are specified using a sequence of integer values. The range of each 8415bd8deadSopenharmony_ci value in a sequence (e.g. a color weight) is constrained. 8425bd8deadSopenharmony_ci 8435bd8deadSopenharmony_ci Since it is often the case that the most efficient range for these 8445bd8deadSopenharmony_ci values is not a power of two, each value sequence is encoded using a 8455bd8deadSopenharmony_ci technique known as "integer sequence encoding". This allows efficient, 8465bd8deadSopenharmony_ci hardware-friendly packing and unpacking of values with non-power-of-two 8475bd8deadSopenharmony_ci ranges. 8485bd8deadSopenharmony_ci 8495bd8deadSopenharmony_ci In a sequence, each value has an identical range. The range is specified 8505bd8deadSopenharmony_ci in one of the following forms: 8515bd8deadSopenharmony_ci 8525bd8deadSopenharmony_ci Value range MSB encoding LSB encoding Value Block Packed 8535bd8deadSopenharmony_ci block size 8545bd8deadSopenharmony_ci ----------- ------------ ------------ ----------- ----- ---------- 8555bd8deadSopenharmony_ci 0 .. 2^n-1 - n bit value m 1 n 8565bd8deadSopenharmony_ci m (n <= 8) 8575bd8deadSopenharmony_ci 0 .. (3 * 2^n)-1 Base-3 "trit" n bit value t * 2^n + m 5 8 + 5*n 8585bd8deadSopenharmony_ci value t m (n <= 6) 8595bd8deadSopenharmony_ci 0 .. (5 * 2^n)-1 Base-5 "quint" n bit value q * 2^n + m 3 7 + 3*n 8605bd8deadSopenharmony_ci value q m (n <= 5) 8615bd8deadSopenharmony_ci ------------------------------------------- 8625bd8deadSopenharmony_ci Table C.2.13 -Encoding for Different Ranges 8635bd8deadSopenharmony_ci 8645bd8deadSopenharmony_ci Since 3^5 is 243, it is possible to pack five trits into 8 bits(which has 8655bd8deadSopenharmony_ci 256 possible values), so a trit can effectively be encoded as 1.6 bits. 8665bd8deadSopenharmony_ci Similarly, since 5^3 is 125, it is possible to pack three quints into 8675bd8deadSopenharmony_ci 7 bits (which has 128 possible values), so a quint can be encoded as 8685bd8deadSopenharmony_ci 2.33 bits. 8695bd8deadSopenharmony_ci 8705bd8deadSopenharmony_ci The encoding scheme packs the trits or quints, and then interleaves the n 8715bd8deadSopenharmony_ci additional bits in positions that satisfy the requirements of an 8725bd8deadSopenharmony_ci arbitrary length stream. This makes it possible to correctly specify 8735bd8deadSopenharmony_ci lists of values whose length is not an integer multiple of 3 or 5 values. 8745bd8deadSopenharmony_ci It also makes it possible to easily select a value at random within the stream. 8755bd8deadSopenharmony_ci 8765bd8deadSopenharmony_ci If there are insufficient bits in the stream to fill the final block, then 8775bd8deadSopenharmony_ci unused (higher order) bits are assumed to be 0 when decoding. 8785bd8deadSopenharmony_ci 8795bd8deadSopenharmony_ci To decode the bits for value number i in a sequence of bits b, both 8805bd8deadSopenharmony_ci indexed from 0, perform the following: 8815bd8deadSopenharmony_ci 8825bd8deadSopenharmony_ci If the range is encoded as n bits per value, then the value is bits 8835bd8deadSopenharmony_ci b[i*n+n-1:i*n] - a simple multiplexing operation. 8845bd8deadSopenharmony_ci 8855bd8deadSopenharmony_ci If the range is encoded using a trit, then each block contains 5 values 8865bd8deadSopenharmony_ci (v0 to v4), each of which contains a trit (t0 to t4) and a corresponding 8875bd8deadSopenharmony_ci LSB value (m0 to m4). The first bit of the packed block is bit 8885bd8deadSopenharmony_ci floor(i/5)*(8+5*n). The bits in the block are packed as follows 8895bd8deadSopenharmony_ci (in this example, n is 4): 8905bd8deadSopenharmony_ci 8915bd8deadSopenharmony_ci 27 26 25 24 23 22 21 20 19 18 17 16 8925bd8deadSopenharmony_ci ----------------------------------------------- 8935bd8deadSopenharmony_ci |T7 | m4 |T6 T5 | m3 |T4 | 8945bd8deadSopenharmony_ci ----------------------------------------------- 8955bd8deadSopenharmony_ci 8965bd8deadSopenharmony_ci 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 8975bd8deadSopenharmony_ci -------------------------------------------------------------- 8985bd8deadSopenharmony_ci | m2 |T3 T2 | m1 |T1 T0 | m0 | 8995bd8deadSopenharmony_ci -------------------------------------------------------------- 9005bd8deadSopenharmony_ci 9015bd8deadSopenharmony_ci Figure C.5 - Trit-based Packing 9025bd8deadSopenharmony_ci 9035bd8deadSopenharmony_ci The five trits t0 to t4 are obtained by bit manipulations of the 8 bits 9045bd8deadSopenharmony_ci T[7:0] as follows: 9055bd8deadSopenharmony_ci 9065bd8deadSopenharmony_ci if T[4:2] = 111 9075bd8deadSopenharmony_ci C = { T[7:5], T[1:0] }; t4 = t3 = 2 9085bd8deadSopenharmony_ci else 9095bd8deadSopenharmony_ci C = T[4:0] 9105bd8deadSopenharmony_ci if T[6:5] = 11 9115bd8deadSopenharmony_ci t4 = 2; t3 = T[7] 9125bd8deadSopenharmony_ci else 9135bd8deadSopenharmony_ci t4 = T[7]; t3 = T[6:5] 9145bd8deadSopenharmony_ci 9155bd8deadSopenharmony_ci if C[1:0] = 11 9165bd8deadSopenharmony_ci t2 = 2; t1 = C[4]; t0 = { C[3], C[2]&~C[3] } 9175bd8deadSopenharmony_ci else if C[3:2] = 11 9185bd8deadSopenharmony_ci t2 = 2; t1 = 2; t0 = C[1:0] 9195bd8deadSopenharmony_ci else 9205bd8deadSopenharmony_ci t2 = C[4]; t1 = C[3:2]; t0 = { C[1], C[0]&~C[1] } 9215bd8deadSopenharmony_ci 9225bd8deadSopenharmony_ci If the range is encoded using a quint, then each block contains 3 values 9235bd8deadSopenharmony_ci (v0 to v2), each of which contains a quint (q0 to q2) and a corresponding 9245bd8deadSopenharmony_ci LSB value (m0 to m2). The first bit of the packed block is bit 9255bd8deadSopenharmony_ci floor(i/3)*(7+3*n). 9265bd8deadSopenharmony_ci 9275bd8deadSopenharmony_ci The bits in the block are packed as follows (in this example, n is 4): 9285bd8deadSopenharmony_ci 9295bd8deadSopenharmony_ci 18 17 16 9305bd8deadSopenharmony_ci ----------- 9315bd8deadSopenharmony_ci |Q6 Q5 | m2 9325bd8deadSopenharmony_ci ----------- 9335bd8deadSopenharmony_ci 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 9345bd8deadSopenharmony_ci --------------------------------------------------------------- 9355bd8deadSopenharmony_ci m2 |Q4 Q3 | m1 |Q2 Q1 Q0 | m0 | 9365bd8deadSopenharmony_ci --------------------------------------------------------------- 9375bd8deadSopenharmony_ci 9385bd8deadSopenharmony_ci Figure C.6 - Quint-based Packing 9395bd8deadSopenharmony_ci 9405bd8deadSopenharmony_ci The three quints q0 to q2 are obtained by bit manipulations of the 7 bits 9415bd8deadSopenharmony_ci Q[6:0] as follows: 9425bd8deadSopenharmony_ci 9435bd8deadSopenharmony_ci if Q[2:1] = 11 and Q[6:5] = 00 9445bd8deadSopenharmony_ci q2 = { Q[0], Q[4]&~Q[0], Q[3]&~Q[0] }; q1 = q0 = 4 9455bd8deadSopenharmony_ci else 9465bd8deadSopenharmony_ci if Q[2:1] = 11 9475bd8deadSopenharmony_ci q2 = 4; C = { Q[4:3], ~Q[6:5], Q[0] } 9485bd8deadSopenharmony_ci else 9495bd8deadSopenharmony_ci q2 = Q[6:5]; C = Q[4:0] 9505bd8deadSopenharmony_ci 9515bd8deadSopenharmony_ci if C[2:0] = 101 9525bd8deadSopenharmony_ci q1 = 4; q0 = C[4:3] 9535bd8deadSopenharmony_ci else 9545bd8deadSopenharmony_ci q1 = C[4:3]; q0 = C[2:0] 9555bd8deadSopenharmony_ci 9565bd8deadSopenharmony_ci Both these procedures ensure a valid decoding for all 128 possible values 9575bd8deadSopenharmony_ci (even though a few are duplicates). They can also be implemented 9585bd8deadSopenharmony_ci efficiently in software using small tables. 9595bd8deadSopenharmony_ci 9605bd8deadSopenharmony_ci Encoding methods are not specified here, although table-based mechanisms 9615bd8deadSopenharmony_ci work well. 9625bd8deadSopenharmony_ci 9635bd8deadSopenharmony_ci C.2.13 Endpoint Unquantization 9645bd8deadSopenharmony_ci ------------------------------- 9655bd8deadSopenharmony_ci 9665bd8deadSopenharmony_ci Each color endpoint is specified as a sequence of integers in a given 9675bd8deadSopenharmony_ci range. These values are packed using integer sequence encoding, as a 9685bd8deadSopenharmony_ci stream of bits stored from just above the configuration data, and 9695bd8deadSopenharmony_ci growing upwards. 9705bd8deadSopenharmony_ci 9715bd8deadSopenharmony_ci Once unpacked, the values must be unquantized from their storage range, 9725bd8deadSopenharmony_ci returning them to a standard range of 0..255. 9735bd8deadSopenharmony_ci 9745bd8deadSopenharmony_ci For bit-only representations, this is simple bit replication from the 9755bd8deadSopenharmony_ci most significant bit of the value. 9765bd8deadSopenharmony_ci 9775bd8deadSopenharmony_ci For trit or quint-based representations, this involves a set of bit 9785bd8deadSopenharmony_ci manipulations and adjustments to avoid the expense of full-width 9795bd8deadSopenharmony_ci multipliers. This procedure ensures correct scaling, but scrambles 9805bd8deadSopenharmony_ci the order of the decoded values relative to the encoded values. 9815bd8deadSopenharmony_ci This must be compensated for using a table in the encoder. 9825bd8deadSopenharmony_ci 9835bd8deadSopenharmony_ci The initial inputs to the procedure are denoted A (9 bits), B (9 bits), 9845bd8deadSopenharmony_ci C (9 bits) and D (3 bits) and are decoded using the range as follows: 9855bd8deadSopenharmony_ci 9865bd8deadSopenharmony_ci --------------------------------------------------------------- 9875bd8deadSopenharmony_ci Range T Q B Bits A B C D 9885bd8deadSopenharmony_ci --------------------------------------------------------------- 9895bd8deadSopenharmony_ci 0..5 1 1 a aaaaaaaaa 000000000 204 Trit value 9905bd8deadSopenharmony_ci 0..9 1 1 a aaaaaaaaa 000000000 113 Quint value 9915bd8deadSopenharmony_ci 0..11 1 2 ba aaaaaaaaa b000b0bb0 93 Trit value 9925bd8deadSopenharmony_ci 0..19 1 2 ba aaaaaaaaa b0000bb00 54 Quint value 9935bd8deadSopenharmony_ci 0..23 1 3 cba aaaaaaaaa cb000cbcb 44 Trit value 9945bd8deadSopenharmony_ci 0..39 1 3 cba aaaaaaaaa cb0000cbc 26 Quint value 9955bd8deadSopenharmony_ci 0..47 1 4 dcba aaaaaaaaa dcb000dcb 22 Trit value 9965bd8deadSopenharmony_ci 0..79 1 4 dcba aaaaaaaaa dcb0000dc 13 Quint value 9975bd8deadSopenharmony_ci 0..95 1 5 edcba aaaaaaaaa edcb000ed 11 Trit value 9985bd8deadSopenharmony_ci 0..159 1 5 edcba aaaaaaaaa edcb0000e 6 Quint value 9995bd8deadSopenharmony_ci 0..191 1 6 fedcba aaaaaaaaa fedcb000f 5 Trit value 10005bd8deadSopenharmony_ci --------------------------------------------------------------- 10015bd8deadSopenharmony_ci Table C.2.16 - Color Unquantization Parameters 10025bd8deadSopenharmony_ci 10035bd8deadSopenharmony_ci These are then processed as follows: 10045bd8deadSopenharmony_ci 10055bd8deadSopenharmony_ci T = D * C + B; 10065bd8deadSopenharmony_ci T = T ^ A; 10075bd8deadSopenharmony_ci T = (A & 0x80) | (T >> 2); 10085bd8deadSopenharmony_ci 10095bd8deadSopenharmony_ci Note that the multiply in the first line is nearly trivial as it only 10105bd8deadSopenharmony_ci needs to multiply by 0, 1, 2, 3 or 4. 10115bd8deadSopenharmony_ci 10125bd8deadSopenharmony_ci C.2.14 LDR Endpoint Decoding 10135bd8deadSopenharmony_ci ----------------------------- 10145bd8deadSopenharmony_ci The decoding method used depends on the Color Endpoint Mode (CEM) field, 10155bd8deadSopenharmony_ci which specifies how many values are used to represent the endpoint. 10165bd8deadSopenharmony_ci 10175bd8deadSopenharmony_ci The CEM field also specifies how to take the n unquantized color endpoint 10185bd8deadSopenharmony_ci values v0 to v[n-1] and convert them into two RGBA color endpoints e0 10195bd8deadSopenharmony_ci and e1. 10205bd8deadSopenharmony_ci 10215bd8deadSopenharmony_ci The HDR Modes are more complex and do not fit neatly into this section. 10225bd8deadSopenharmony_ci They are documented in following section. 10235bd8deadSopenharmony_ci 10245bd8deadSopenharmony_ci The methods can be summarized as follows. 10255bd8deadSopenharmony_ci 10265bd8deadSopenharmony_ci ------------------------------------------------- 10275bd8deadSopenharmony_ci CEM Range Description n 10285bd8deadSopenharmony_ci ------------------------------------------------- 10295bd8deadSopenharmony_ci 0 LDR Luminance, direct 2 10305bd8deadSopenharmony_ci 1 LDR Luminance, base+offset 2 10315bd8deadSopenharmony_ci 2 HDR Luminance, large range 2 10325bd8deadSopenharmony_ci 3 HDR Luminance, small range 2 10335bd8deadSopenharmony_ci 4 LDR Luminance+Alpha, direct 4 10345bd8deadSopenharmony_ci 5 LDR Luminance+Alpha, base+offset 4 10355bd8deadSopenharmony_ci 6 LDR RGB, base+scale 4 10365bd8deadSopenharmony_ci 7 HDR RGB, base+scale 4 10375bd8deadSopenharmony_ci 8 LDR RGB, direct 6 10385bd8deadSopenharmony_ci 9 LDR RGB, base+offset 6 10395bd8deadSopenharmony_ci 10 LDR RGB, base+scale plus two A 6 10405bd8deadSopenharmony_ci 11 HDR RGB 6 10415bd8deadSopenharmony_ci 12 LDR RGBA, direct 8 10425bd8deadSopenharmony_ci 13 LDR RGBA, base+offset 8 10435bd8deadSopenharmony_ci 14 HDR RGB + LDR Alpha 8 10445bd8deadSopenharmony_ci 15 HDR RGB + HDR Alpha 8 10455bd8deadSopenharmony_ci ------------------------------------------------- 10465bd8deadSopenharmony_ci Table C.2.17 -Color Endpoint Modes 10475bd8deadSopenharmony_ci [[ If the HDR profile is not implemented, remove from table C.2.17 10485bd8deadSopenharmony_ci all rows whose description starts with "HDR", and add to the 10495bd8deadSopenharmony_ci caption: ]] 10505bd8deadSopenharmony_ci Modes not described are reserved, as described in table C.2.10. 10515bd8deadSopenharmony_ci 10525bd8deadSopenharmony_ci [[ HDR profile only ]] 10535bd8deadSopenharmony_ci Mode 14 is special in that the alpha values are interpolated linearly, 10545bd8deadSopenharmony_ci but the color components are interpolated logarithmically. This is the 10555bd8deadSopenharmony_ci only endpoint format with mixed-mode operation, and will return the 10565bd8deadSopenharmony_ci error value if encountered in LDR mode. 10575bd8deadSopenharmony_ci 10585bd8deadSopenharmony_ci Decode the different LDR endpoint modes as follows: 10595bd8deadSopenharmony_ci 10605bd8deadSopenharmony_ci Mode 0 LDR Luminance, direct 10615bd8deadSopenharmony_ci 10625bd8deadSopenharmony_ci e0=(v0,v0,v0,0xFF); e1=(v1,v1,v1,0xFF); 10635bd8deadSopenharmony_ci 10645bd8deadSopenharmony_ci Mode 1 LDR Luminance, base+offset 10655bd8deadSopenharmony_ci 10665bd8deadSopenharmony_ci L0 = (v0>>2)|(v1&0xC0); L1=L0+(v1&0x3F); 10675bd8deadSopenharmony_ci if (L1>0xFF) { L1=0xFF; } 10685bd8deadSopenharmony_ci e0=(L0,L0,L0,0xFF); e1=(L1,L1,L1,0xFF); 10695bd8deadSopenharmony_ci 10705bd8deadSopenharmony_ci Mode 4 LDR Luminance+Alpha,direct 10715bd8deadSopenharmony_ci 10725bd8deadSopenharmony_ci e0=(v0,v0,v0,v2); 10735bd8deadSopenharmony_ci e1=(v1,v1,v1,v3); 10745bd8deadSopenharmony_ci 10755bd8deadSopenharmony_ci Mode 5 LDR Luminance+Alpha, base+offset 10765bd8deadSopenharmony_ci 10775bd8deadSopenharmony_ci bit_transfer_signed(v1,v0); bit_transfer_signed(v3,v2); 10785bd8deadSopenharmony_ci e0=(v0,v0,v0,v2); e1=(v0+v1,v0+v1,v0+v1,v2+v3); 10795bd8deadSopenharmony_ci clamp_unorm8(e0); clamp_unorm8(e1); 10805bd8deadSopenharmony_ci 10815bd8deadSopenharmony_ci Mode 6 LDR RGB, base+scale 10825bd8deadSopenharmony_ci 10835bd8deadSopenharmony_ci e0=(v0*v3>>8,v1*v3>>8,v2*v3>>8, 0xFF); 10845bd8deadSopenharmony_ci e1=(v0,v1,v2,0xFF); 10855bd8deadSopenharmony_ci 10865bd8deadSopenharmony_ci Mode 8 LDR RGB, Direct 10875bd8deadSopenharmony_ci 10885bd8deadSopenharmony_ci s0= v0+v2+v4; s1= v1+v3+v5; 10895bd8deadSopenharmony_ci if (s1>=s0){e0=(v0,v2,v4,0xFF); 10905bd8deadSopenharmony_ci e1=(v1,v3,v5,0xFF); } 10915bd8deadSopenharmony_ci else { e0=blue_contract(v1,v3,v5,0xFF); 10925bd8deadSopenharmony_ci e1=blue_contract(v0,v2,v4,0xFF); } 10935bd8deadSopenharmony_ci 10945bd8deadSopenharmony_ci Mode 9 LDR RGB, base+offset 10955bd8deadSopenharmony_ci 10965bd8deadSopenharmony_ci bit_transfer_signed(v1,v0); 10975bd8deadSopenharmony_ci bit_transfer_signed(v3,v2); 10985bd8deadSopenharmony_ci bit_transfer_signed(v5,v4); 10995bd8deadSopenharmony_ci if(v1+v3+v5 >= 0) 11005bd8deadSopenharmony_ci { e0=(v0,v2,v4,0xFF); e1=(v0+v1,v2+v3,v4+v5,0xFF); } 11015bd8deadSopenharmony_ci else 11025bd8deadSopenharmony_ci { e0=blue_contract(v0+v1,v2+v3,v4+v5,0xFF); 11035bd8deadSopenharmony_ci e1=blue_contract(v0,v2,v4,0xFF); } 11045bd8deadSopenharmony_ci clamp_unorm8(e0); clamp_unorm8(e1); 11055bd8deadSopenharmony_ci 11065bd8deadSopenharmony_ci Mode 10 LDR RGB, base+scale plus two A 11075bd8deadSopenharmony_ci 11085bd8deadSopenharmony_ci e0=(v0*v3>>8,v1*v3>>8,v2*v3>>8, v4); 11095bd8deadSopenharmony_ci e1=(v0,v1,v2, v5); 11105bd8deadSopenharmony_ci 11115bd8deadSopenharmony_ci Mode 12 LDR RGBA, direct 11125bd8deadSopenharmony_ci 11135bd8deadSopenharmony_ci s0= v0+v2+v4; s1= v1+v3+v5; 11145bd8deadSopenharmony_ci if (s1>=s0){e0=(v0,v2,v4,v6); 11155bd8deadSopenharmony_ci e1=(v1,v3,v5,v7); } 11165bd8deadSopenharmony_ci else { e0=blue_contract(v1,v3,v5,v7); 11175bd8deadSopenharmony_ci e1=blue_contract(v0,v2,v4,v6); } 11185bd8deadSopenharmony_ci 11195bd8deadSopenharmony_ci Mode 13 LDR RGBA, base+offset 11205bd8deadSopenharmony_ci 11215bd8deadSopenharmony_ci bit_transfer_signed(v1,v0); 11225bd8deadSopenharmony_ci bit_transfer_signed(v3,v2); 11235bd8deadSopenharmony_ci bit_transfer_signed(v5,v4); 11245bd8deadSopenharmony_ci bit_transfer_signed(v7,v6); 11255bd8deadSopenharmony_ci if(v1+v3+v5>=0) { e0=(v0,v2,v4,v6); 11265bd8deadSopenharmony_ci e1=(v0+v1,v2+v3,v4+v5,v6+v7); } 11275bd8deadSopenharmony_ci else { e0=blue_contract(v0+v1,v2+v3,v4+v5,v6+v7); 11285bd8deadSopenharmony_ci e1=blue_contract(v0,v2,v4,v6); } 11295bd8deadSopenharmony_ci clamp_unorm8(e0); clamp_unorm8(e1); 11305bd8deadSopenharmony_ci 11315bd8deadSopenharmony_ci The bit_transfer_signed procedure transfers a bit from one value (a) 11325bd8deadSopenharmony_ci to another (b). Initially, both a and b are in the range 0..255. 11335bd8deadSopenharmony_ci After calling this procedure, a's range becomes -32..31, and b remains 11345bd8deadSopenharmony_ci in the range 0..255. Note that, as is often the case, this is easier to 11355bd8deadSopenharmony_ci express in hardware than in C: 11365bd8deadSopenharmony_ci 11375bd8deadSopenharmony_ci bit_transfer_signed(int& a, int& b) 11385bd8deadSopenharmony_ci { 11395bd8deadSopenharmony_ci b >>= 1; 11405bd8deadSopenharmony_ci b |= a & 0x80; 11415bd8deadSopenharmony_ci a >>= 1; 11425bd8deadSopenharmony_ci a &= 0x3F; 11435bd8deadSopenharmony_ci if( (a&0x20)!=0 ) a-=0x40; 11445bd8deadSopenharmony_ci } 11455bd8deadSopenharmony_ci 11465bd8deadSopenharmony_ci The blue_contract procedure is used to give additional precision to 11475bd8deadSopenharmony_ci RGB colors near grey: 11485bd8deadSopenharmony_ci 11495bd8deadSopenharmony_ci color blue_contract( int r, int g, int b, int a ) 11505bd8deadSopenharmony_ci { 11515bd8deadSopenharmony_ci color c; 11525bd8deadSopenharmony_ci c.r = (r+b) >> 1; 11535bd8deadSopenharmony_ci c.g = (g+b) >> 1; 11545bd8deadSopenharmony_ci c.b = b; 11555bd8deadSopenharmony_ci c.a = a; 11565bd8deadSopenharmony_ci return c; 11575bd8deadSopenharmony_ci } 11585bd8deadSopenharmony_ci 11595bd8deadSopenharmony_ci The clamp_unorm8 procedure is used to clamp a color into the UNORM8 range: 11605bd8deadSopenharmony_ci 11615bd8deadSopenharmony_ci void clamp_unorm8(color c) 11625bd8deadSopenharmony_ci { 11635bd8deadSopenharmony_ci if(c.r < 0) {c.r=0;} else if(c.r > 255) {c.r=255;} 11645bd8deadSopenharmony_ci if(c.g < 0) {c.g=0;} else if(c.g > 255) {c.g=255;} 11655bd8deadSopenharmony_ci if(c.b < 0) {c.b=0;} else if(c.b > 255) {c.b=255;} 11665bd8deadSopenharmony_ci if(c.a < 0) {c.a=0;} else if(c.a > 255) {c.a=255;} 11675bd8deadSopenharmony_ci } 11685bd8deadSopenharmony_ci 11695bd8deadSopenharmony_ci [[ If the HDR profile is not implemented, do not include section 11705bd8deadSopenharmony_ci C.2.15 ]] 11715bd8deadSopenharmony_ci 11725bd8deadSopenharmony_ci C.2.15 HDR Endpoint Decoding 11735bd8deadSopenharmony_ci ------------------------- 11745bd8deadSopenharmony_ci 11755bd8deadSopenharmony_ci For HDR endpoint modes, color values are represented in a 12-bit 11765bd8deadSopenharmony_ci pseudo-logarithmic representation. 11775bd8deadSopenharmony_ci 11785bd8deadSopenharmony_ci HDR Endpoint Mode 2 11795bd8deadSopenharmony_ci 11805bd8deadSopenharmony_ci Mode 2 represents luminance-only data with a large range. It encodes 11815bd8deadSopenharmony_ci using two values (v0, v1). The complete decoding procedure is as follows: 11825bd8deadSopenharmony_ci 11835bd8deadSopenharmony_ci if(v1 >= v0) 11845bd8deadSopenharmony_ci { 11855bd8deadSopenharmony_ci y0 = (v0 << 4); 11865bd8deadSopenharmony_ci y1 = (v1 << 4); 11875bd8deadSopenharmony_ci } 11885bd8deadSopenharmony_ci else 11895bd8deadSopenharmony_ci { 11905bd8deadSopenharmony_ci y0 = (v1 << 4) + 8; 11915bd8deadSopenharmony_ci y1 = (v0 << 4) - 8; 11925bd8deadSopenharmony_ci } 11935bd8deadSopenharmony_ci // Construct RGBA result (0x780 is 1.0f) 11945bd8deadSopenharmony_ci e0 = (y0, y0, y0, 0x780); 11955bd8deadSopenharmony_ci e1 = (y1, y1, y1, 0x780); 11965bd8deadSopenharmony_ci 11975bd8deadSopenharmony_ci HDR Endpoint Mode 3 11985bd8deadSopenharmony_ci 11995bd8deadSopenharmony_ci Mode 3 represents luminance-only data with a small range. It packs the 12005bd8deadSopenharmony_ci bits for a base luminance value, together with an offset, into two values 12015bd8deadSopenharmony_ci (v0, v1): 12025bd8deadSopenharmony_ci 12035bd8deadSopenharmony_ci Value 7 6 5 4 3 2 1 0 12045bd8deadSopenharmony_ci ----- ------------------------------ 12055bd8deadSopenharmony_ci v0 |M | L[6:0] | 12065bd8deadSopenharmony_ci ------------------------------ 12075bd8deadSopenharmony_ci v1 | X[3:0] | d[3:0] | 12085bd8deadSopenharmony_ci ------------------------------ 12095bd8deadSopenharmony_ci 12105bd8deadSopenharmony_ci Table C.2.18 - HDR Mode 3 Value Layout 12115bd8deadSopenharmony_ci 12125bd8deadSopenharmony_ci The bit field marked as X allocates different bits to L or d depending 12135bd8deadSopenharmony_ci on the value of the mode bit M. 12145bd8deadSopenharmony_ci 12155bd8deadSopenharmony_ci The complete decoding procedure is as follows: 12165bd8deadSopenharmony_ci 12175bd8deadSopenharmony_ci // Check mode bit and extract. 12185bd8deadSopenharmony_ci if((v0&0x80) !=0) 12195bd8deadSopenharmony_ci { 12205bd8deadSopenharmony_ci y0 = ((v1 & 0xE0) << 4) | ((v0 & 0x7F) << 2); 12215bd8deadSopenharmony_ci d = (v1 & 0x1F) << 2; 12225bd8deadSopenharmony_ci } 12235bd8deadSopenharmony_ci else 12245bd8deadSopenharmony_ci { 12255bd8deadSopenharmony_ci y0 = ((v1 & 0xF0) << 4) | ((v0 & 0x7F) << 1); 12265bd8deadSopenharmony_ci d = (v1 & 0x0F) << 1; 12275bd8deadSopenharmony_ci } 12285bd8deadSopenharmony_ci 12295bd8deadSopenharmony_ci // Add delta and clamp 12305bd8deadSopenharmony_ci y1 = y0 + d; 12315bd8deadSopenharmony_ci if(y1 > 0xFFF) { y1 = 0xFFF; } 12325bd8deadSopenharmony_ci 12335bd8deadSopenharmony_ci // Construct RGBA result (0x780 is 1.0f) 12345bd8deadSopenharmony_ci e0 = (y0, y0, y0, 0x780); 12355bd8deadSopenharmony_ci e1 = (y1, y1, y1, 0x780); 12365bd8deadSopenharmony_ci 12375bd8deadSopenharmony_ci HDR Endpoint Mode 7 12385bd8deadSopenharmony_ci 12395bd8deadSopenharmony_ci Mode 7 packs the bits for a base RGB value, a scale factor, and some 12405bd8deadSopenharmony_ci mode bits into the four values (v0, v1, v2, v3): 12415bd8deadSopenharmony_ci 12425bd8deadSopenharmony_ci Value 7 6 5 4 3 2 1 0 12435bd8deadSopenharmony_ci ----- ------------------------------ 12445bd8deadSopenharmony_ci v0 |M[3:2] | R[5:0] | 12455bd8deadSopenharmony_ci ----- ------------------------------ 12465bd8deadSopenharmony_ci v1 |M1 |X0 |X1 | G[4:0] | 12475bd8deadSopenharmony_ci ----- ------------------------------ 12485bd8deadSopenharmony_ci v2 |M0 |X2 |X3 | B[4:0] | 12495bd8deadSopenharmony_ci ----- ------------------------------ 12505bd8deadSopenharmony_ci v3 |X4 |X5 |X6 | S[4:0] | 12515bd8deadSopenharmony_ci ----- ------------------------------ 12525bd8deadSopenharmony_ci Table C.2.19 - HDR Mode 7 Value Layout 12535bd8deadSopenharmony_ci 12545bd8deadSopenharmony_ci The mode bits M0 to M3 are a packed representation of an endpoint bit 12555bd8deadSopenharmony_ci mode, together with the major component index. For modes 0 to 4, the 12565bd8deadSopenharmony_ci component (red, green, or blue) with the largest magnitude is identified, 12575bd8deadSopenharmony_ci and the values swizzled to ensure that it is decoded from the red channel. 12585bd8deadSopenharmony_ci 12595bd8deadSopenharmony_ci The endpoint bit mode is used to determine the number of bits assigned 12605bd8deadSopenharmony_ci to each component of the endpoint, and the destination of each of the 12615bd8deadSopenharmony_ci extra bits X0 to X6, as follows: 12625bd8deadSopenharmony_ci 12635bd8deadSopenharmony_ci ------------------------------------------------------ 12645bd8deadSopenharmony_ci Number of bits Destination of extra bits 12655bd8deadSopenharmony_ci Mode R G B S X0 X1 X2 X3 X4 X5 X6 12665bd8deadSopenharmony_ci ------------------------------------------------------ 12675bd8deadSopenharmony_ci 0 11 5 5 7 R9 R8 R7 R10 R6 S6 S5 12685bd8deadSopenharmony_ci 1 11 6 6 5 R8 G5 R7 B5 R6 R10 R9 12695bd8deadSopenharmony_ci 2 10 5 5 8 R9 R8 R7 R6 S7 S6 S5 12705bd8deadSopenharmony_ci 3 9 6 6 7 R8 G5 R7 B5 R6 S6 S5 12715bd8deadSopenharmony_ci 4 8 7 7 6 G6 G5 B6 B5 R6 R7 S5 12725bd8deadSopenharmony_ci 5 7 7 7 7 G6 G5 B6 B5 R6 S6 S5 12735bd8deadSopenharmony_ci ------------------------------------------------------ 12745bd8deadSopenharmony_ci Table C.2.20 - Endpoint Bit Mode 12755bd8deadSopenharmony_ci 12765bd8deadSopenharmony_ci As noted before, this appears complex when expressed in C, but much 12775bd8deadSopenharmony_ci easier to achieve in hardware - bit masking, extraction, shifting 12785bd8deadSopenharmony_ci and assignment usually ends up as a single wire or multiplexer. 12795bd8deadSopenharmony_ci 12805bd8deadSopenharmony_ci The complete decoding procedure is as follows: 12815bd8deadSopenharmony_ci 12825bd8deadSopenharmony_ci // Extract mode bits and unpack to major component and mode. 12835bd8deadSopenharmony_ci int modeval = ((v0&0xC0)>>6) | ((v1&0x80)>>5) | ((v2&0x80)>>4); 12845bd8deadSopenharmony_ci 12855bd8deadSopenharmony_ci int majcomp; 12865bd8deadSopenharmony_ci int mode; 12875bd8deadSopenharmony_ci 12885bd8deadSopenharmony_ci if( (modeval & 0xC ) != 0xC ) 12895bd8deadSopenharmony_ci { 12905bd8deadSopenharmony_ci majcomp = modeval >> 2; mode = modeval & 3; 12915bd8deadSopenharmony_ci } 12925bd8deadSopenharmony_ci else if( modeval != 0xF ) 12935bd8deadSopenharmony_ci { 12945bd8deadSopenharmony_ci majcomp = modeval & 3; mode = 4; 12955bd8deadSopenharmony_ci } 12965bd8deadSopenharmony_ci else 12975bd8deadSopenharmony_ci { 12985bd8deadSopenharmony_ci majcomp = 0; mode = 5; 12995bd8deadSopenharmony_ci } 13005bd8deadSopenharmony_ci 13015bd8deadSopenharmony_ci // Extract low-order bits of r, g, b, and s. 13025bd8deadSopenharmony_ci int red = v0 & 0x3f; 13035bd8deadSopenharmony_ci int green = v1 & 0x1f; 13045bd8deadSopenharmony_ci int blue = v2 & 0x1f; 13055bd8deadSopenharmony_ci int scale = v3 & 0x1f; 13065bd8deadSopenharmony_ci 13075bd8deadSopenharmony_ci // Extract high-order bits, which may be assigned depending on mode 13085bd8deadSopenharmony_ci int x0 = (v1 >> 6) & 1; int x1 = (v1 >> 5) & 1; 13095bd8deadSopenharmony_ci int x2 = (v2 >> 6) & 1; int x3 = (v2 >> 5) & 1; 13105bd8deadSopenharmony_ci int x4 = (v3 >> 7) & 1; int x5 = (v3 >> 6) & 1; 13115bd8deadSopenharmony_ci int x6 = (v3 >> 5) & 1; 13125bd8deadSopenharmony_ci 13135bd8deadSopenharmony_ci // Now move the high-order xs into the right place. 13145bd8deadSopenharmony_ci int ohm = 1 << mode; 13155bd8deadSopenharmony_ci if( ohm & 0x30 ) green |= x0 << 6; 13165bd8deadSopenharmony_ci if( ohm & 0x3A ) green |= x1 << 5; 13175bd8deadSopenharmony_ci if( ohm & 0x30 ) blue |= x2 << 6; 13185bd8deadSopenharmony_ci if( ohm & 0x3A ) blue |= x3 << 5; 13195bd8deadSopenharmony_ci if( ohm & 0x3D ) scale |= x6 << 5; 13205bd8deadSopenharmony_ci if( ohm & 0x2D ) scale |= x5 << 6; 13215bd8deadSopenharmony_ci if( ohm & 0x04 ) scale |= x4 << 7; 13225bd8deadSopenharmony_ci if( ohm & 0x3B ) red |= x4 << 6; 13235bd8deadSopenharmony_ci if( ohm & 0x04 ) red |= x3 << 6; 13245bd8deadSopenharmony_ci if( ohm & 0x10 ) red |= x5 << 7; 13255bd8deadSopenharmony_ci if( ohm & 0x0F ) red |= x2 << 7; 13265bd8deadSopenharmony_ci if( ohm & 0x05 ) red |= x1 << 8; 13275bd8deadSopenharmony_ci if( ohm & 0x0A ) red |= x0 << 8; 13285bd8deadSopenharmony_ci if( ohm & 0x05 ) red |= x0 << 9; 13295bd8deadSopenharmony_ci if( ohm & 0x02 ) red |= x6 << 9; 13305bd8deadSopenharmony_ci if( ohm & 0x01 ) red |= x3 << 10; 13315bd8deadSopenharmony_ci if( ohm & 0x02 ) red |= x5 << 10; 13325bd8deadSopenharmony_ci 13335bd8deadSopenharmony_ci // Shift the bits to the top of the 12-bit result. 13345bd8deadSopenharmony_ci static const int shamts[6] = { 1,1,2,3,4,5 }; 13355bd8deadSopenharmony_ci int shamt = shamts[mode]; 13365bd8deadSopenharmony_ci red <<= shamt; green <<= shamt; blue <<= shamt; scale <<= shamt; 13375bd8deadSopenharmony_ci 13385bd8deadSopenharmony_ci // Minor components are stored as differences 13395bd8deadSopenharmony_ci if( mode != 5 ) { green = red - green; blue = red - blue; } 13405bd8deadSopenharmony_ci 13415bd8deadSopenharmony_ci // Swizzle major component into place 13425bd8deadSopenharmony_ci if( majcomp == 1 ) swap( red, green ); 13435bd8deadSopenharmony_ci if( majcomp == 2 ) swap( red, blue ); 13445bd8deadSopenharmony_ci 13455bd8deadSopenharmony_ci // Clamp output values, set alpha to 1.0 13465bd8deadSopenharmony_ci e1.r = clamp( red, 0, 0xFFF ); 13475bd8deadSopenharmony_ci e1.g = clamp( green, 0, 0xFFF ); 13485bd8deadSopenharmony_ci e1.b = clamp( blue, 0, 0xFFF ); 13495bd8deadSopenharmony_ci e1.alpha = 0x780; 13505bd8deadSopenharmony_ci 13515bd8deadSopenharmony_ci e0.r = clamp( red - scale, 0, 0xFFF ); 13525bd8deadSopenharmony_ci e0.g = clamp( green - scale, 0, 0xFFF ); 13535bd8deadSopenharmony_ci e0.b = clamp( blue - scale, 0, 0xFFF ); 13545bd8deadSopenharmony_ci e0.alpha = 0x780; 13555bd8deadSopenharmony_ci 13565bd8deadSopenharmony_ci HDR Endpoint Mode 11 13575bd8deadSopenharmony_ci 13585bd8deadSopenharmony_ci Mode 11 specifies two RGB values, which it calculates from a number of 13595bd8deadSopenharmony_ci bitfields (a, b0, b1, c, d0 and d1) which are packed together with some 13605bd8deadSopenharmony_ci mode bits into the six values (v0, v1, v2, v3, v4, v5): 13615bd8deadSopenharmony_ci 13625bd8deadSopenharmony_ci Value 7 6 5 4 3 2 1 0 13635bd8deadSopenharmony_ci ----- ------------------------------ 13645bd8deadSopenharmony_ci v0 | a[7:0] | 13655bd8deadSopenharmony_ci ----- ------------------------------ 13665bd8deadSopenharmony_ci v1 |m0 |a8 | c[5:0] | 13675bd8deadSopenharmony_ci ----- ------------------------------ 13685bd8deadSopenharmony_ci v2 |m1 |X0 | b0[5:0] | 13695bd8deadSopenharmony_ci ----- ------------------------------ 13705bd8deadSopenharmony_ci v3 |m2 |X1 | b1[5:0] | 13715bd8deadSopenharmony_ci ----- ------------------------------ 13725bd8deadSopenharmony_ci v4 |mj0|X2 |X4 | d0[4:0] | 13735bd8deadSopenharmony_ci ----- ------------------------------ 13745bd8deadSopenharmony_ci v5 |mj1|X3 |X5 | d1[4:0] | 13755bd8deadSopenharmony_ci ----- ------------------------------ 13765bd8deadSopenharmony_ci Table C.2.21 - HDR Mode 11 Value Layout 13775bd8deadSopenharmony_ci 13785bd8deadSopenharmony_ci If the major component bits mj[1:0 ] are both 1, then the RGB values 13795bd8deadSopenharmony_ci are specified directly 13805bd8deadSopenharmony_ci 13815bd8deadSopenharmony_ci Value 7 6 5 4 3 2 1 0 13825bd8deadSopenharmony_ci ----- ------------------------------ 13835bd8deadSopenharmony_ci v0 | R0[11:4] | 13845bd8deadSopenharmony_ci ----- ------------------------------ 13855bd8deadSopenharmony_ci v1 | R1[11:4] | 13865bd8deadSopenharmony_ci ----- ------------------------------ 13875bd8deadSopenharmony_ci v2 | G0[11:4] | 13885bd8deadSopenharmony_ci ----- ------------------------------ 13895bd8deadSopenharmony_ci v3 | G1[11:4] | 13905bd8deadSopenharmony_ci ----- ------------------------------ 13915bd8deadSopenharmony_ci v4 | 1 | B0[11:5] | 13925bd8deadSopenharmony_ci ----- ------------------------------ 13935bd8deadSopenharmony_ci v5 | 1 | B1[11:5] | 13945bd8deadSopenharmony_ci ----- ------------------------------ 13955bd8deadSopenharmony_ci Table C.2.22 - HDR Mode 11 Value Layout 13965bd8deadSopenharmony_ci 13975bd8deadSopenharmony_ci The mode bits m[2:0] specify the bit allocation for the different 13985bd8deadSopenharmony_ci values, and the destinations of the extra bits X0 to X5: 13995bd8deadSopenharmony_ci 14005bd8deadSopenharmony_ci ------------------------------------------------------------------------- 14015bd8deadSopenharmony_ci Number of bits Destination of extra bits 14025bd8deadSopenharmony_ci Mode a b c d X0 X1 X2 X3 X4 X5 14035bd8deadSopenharmony_ci ------------------------------------------------------------------------- 14045bd8deadSopenharmony_ci 0 9 7 6 7 b0[6] b1[6] d0[6] d1[6] d0[5] d1[5] 14055bd8deadSopenharmony_ci 1 9 8 6 6 b0[6] b1[6] b0[7] b1[7] d0[5] d1[5] 14065bd8deadSopenharmony_ci 2 10 6 7 7 a[9] c[6] d0[6] d1[6] d0[5] d1[5] 14075bd8deadSopenharmony_ci 3 10 7 7 6 b0[6] b1[6] a[9] c[6] d0[5] d1[5] 14085bd8deadSopenharmony_ci 4 11 8 6 5 b0[6] b1[6] b0[7] b1[7] a[9] a[10] 14095bd8deadSopenharmony_ci 5 11 6 7 6 a[9] a[10] c[7] c[6] d0[5] d1[5] 14105bd8deadSopenharmony_ci 6 12 7 7 5 b0[6] b1[6] a[11] c[6] a[9] a[10] 14115bd8deadSopenharmony_ci 7 12 6 7 6 a[9] a[10] a[11] c[6] d0[5] d1[5] 14125bd8deadSopenharmony_ci ------------------------------------------------------------------------- 14135bd8deadSopenharmony_ci Table C.2.23 - Endpoint Bit Mode 14145bd8deadSopenharmony_ci 14155bd8deadSopenharmony_ci The complete decoding procedure is as follows: 14165bd8deadSopenharmony_ci 14175bd8deadSopenharmony_ci // Find major component 14185bd8deadSopenharmony_ci int majcomp = ((v4 & 0x80) >> 7) | ((v5 & 0x80) >> 6); 14195bd8deadSopenharmony_ci 14205bd8deadSopenharmony_ci // Deal with simple case first 14215bd8deadSopenharmony_ci if( majcomp == 3 ) 14225bd8deadSopenharmony_ci { 14235bd8deadSopenharmony_ci e0 = (v0 << 4, v2 << 4, (v4 & 0x7f) << 5, 0x780); 14245bd8deadSopenharmony_ci e1 = (v1 << 4, v3 << 4, (v5 & 0x7f) << 5, 0x780); 14255bd8deadSopenharmony_ci return; 14265bd8deadSopenharmony_ci } 14275bd8deadSopenharmony_ci 14285bd8deadSopenharmony_ci // Decode mode, parameters. 14295bd8deadSopenharmony_ci int mode = ((v1&0x80)>>7) | ((v2&0x80)>>6) | ((v3&0x80)>>5); 14305bd8deadSopenharmony_ci int va = v0 | ((v1 & 0x40) << 2); 14315bd8deadSopenharmony_ci int vb0 = v2 & 0x3f; 14325bd8deadSopenharmony_ci int vb1 = v3 & 0x3f; 14335bd8deadSopenharmony_ci int vc = v1 & 0x3f; 14345bd8deadSopenharmony_ci int vd0 = v4 & 0x7f; 14355bd8deadSopenharmony_ci int vd1 = v5 & 0x7f; 14365bd8deadSopenharmony_ci 14375bd8deadSopenharmony_ci // Assign top bits of vd0, vd1. 14385bd8deadSopenharmony_ci static const int dbitstab[8] = {7,6,7,6,5,6,5,6}; 14395bd8deadSopenharmony_ci vd0 = signextend( vd0, dbitstab[mode] ); 14405bd8deadSopenharmony_ci vd1 = signextend( vd1, dbitstab[mode] ); 14415bd8deadSopenharmony_ci 14425bd8deadSopenharmony_ci // Extract and place extra bits 14435bd8deadSopenharmony_ci int x0 = (v2 >> 6) & 1; 14445bd8deadSopenharmony_ci int x1 = (v3 >> 6) & 1; 14455bd8deadSopenharmony_ci int x2 = (v4 >> 6) & 1; 14465bd8deadSopenharmony_ci int x3 = (v5 >> 6) & 1; 14475bd8deadSopenharmony_ci int x4 = (v4 >> 5) & 1; 14485bd8deadSopenharmony_ci int x5 = (v5 >> 5) & 1; 14495bd8deadSopenharmony_ci 14505bd8deadSopenharmony_ci int ohm = 1 << mode; 14515bd8deadSopenharmony_ci if( ohm & 0xA4 ) va |= x0 << 9; 14525bd8deadSopenharmony_ci if( ohm & 0x08 ) va |= x2 << 9; 14535bd8deadSopenharmony_ci if( ohm & 0x50 ) va |= x4 << 9; 14545bd8deadSopenharmony_ci if( ohm & 0x50 ) va |= x5 << 10; 14555bd8deadSopenharmony_ci if( ohm & 0xA0 ) va |= x1 << 10; 14565bd8deadSopenharmony_ci if( ohm & 0xC0 ) va |= x2 << 11; 14575bd8deadSopenharmony_ci if( ohm & 0x04 ) vc |= x1 << 6; 14585bd8deadSopenharmony_ci if( ohm & 0xE8 ) vc |= x3 << 6; 14595bd8deadSopenharmony_ci if( ohm & 0x20 ) vc |= x2 << 7; 14605bd8deadSopenharmony_ci if( ohm & 0x5B ) vb0 |= x0 << 6; 14615bd8deadSopenharmony_ci if( ohm & 0x5B ) vb1 |= x1 << 6; 14625bd8deadSopenharmony_ci if( ohm & 0x12 ) vb0 |= x2 << 7; 14635bd8deadSopenharmony_ci if( ohm & 0x12 ) vb1 |= x3 << 7; 14645bd8deadSopenharmony_ci 14655bd8deadSopenharmony_ci // Now shift up so that major component is at top of 12-bit value 14665bd8deadSopenharmony_ci int shamt = (modeval >> 1) ^ 3; 14675bd8deadSopenharmony_ci va <<= shamt; vb0 <<= shamt; vb1 <<= shamt; 14685bd8deadSopenharmony_ci vc <<= shamt; vd0 <<= shamt; vd1 <<= shamt; 14695bd8deadSopenharmony_ci 14705bd8deadSopenharmony_ci e1.r = clamp( va, 0, 0xFFF ); 14715bd8deadSopenharmony_ci e1.g = clamp( va - vb0, 0, 0xFFF ); 14725bd8deadSopenharmony_ci e1.b = clamp( va - vb1, 0, 0xFFF ); 14735bd8deadSopenharmony_ci e1.alpha = 0x780; 14745bd8deadSopenharmony_ci 14755bd8deadSopenharmony_ci e0.r = clamp( va - vc, 0, 0xFFF ); 14765bd8deadSopenharmony_ci e0.g = clamp( va - vb0 - vc - vd0, 0, 0xFFF ); 14775bd8deadSopenharmony_ci e0.b = clamp( va - vb1 - vc - vd1, 0, 0xFFF ); 14785bd8deadSopenharmony_ci e0.alpha = 0x780; 14795bd8deadSopenharmony_ci 14805bd8deadSopenharmony_ci if( majcomp == 1 ) { swap( e0.r, e0.g ); swap( e1.r, e1.g ); } 14815bd8deadSopenharmony_ci else if( majcomp == 2 ) { swap( e0.r, e0.b ); swap( e1.r, e1.b ); } 14825bd8deadSopenharmony_ci 14835bd8deadSopenharmony_ci HDR Endpoint Mode 14 14845bd8deadSopenharmony_ci 14855bd8deadSopenharmony_ci Mode 14 specifies two RGBA values, using the eight values (v0, v1, v2, 14865bd8deadSopenharmony_ci v3, v4, v5, v6, v7). First, the RGB values are decoded from (v0..v5) 14875bd8deadSopenharmony_ci using the method from Mode 11, then the alpha values are filled in 14885bd8deadSopenharmony_ci from v6 and v7: 14895bd8deadSopenharmony_ci 14905bd8deadSopenharmony_ci // Decode RGB as for mode 11 14915bd8deadSopenharmony_ci (e0,e1) = decode_mode_11(v0,v1,v2,v3,v4,v5) 14925bd8deadSopenharmony_ci 14935bd8deadSopenharmony_ci // Now fill in the alphas 14945bd8deadSopenharmony_ci e0.alpha = v6; 14955bd8deadSopenharmony_ci e1.alpha = v7; 14965bd8deadSopenharmony_ci 14975bd8deadSopenharmony_ci Note that in this mode, the alpha values are interpreted (and 14985bd8deadSopenharmony_ci interpolated) as 8-bit unsigned normalized values, as in the LDR modes. 14995bd8deadSopenharmony_ci This is the only mode that exhibits this behaviour. 15005bd8deadSopenharmony_ci 15015bd8deadSopenharmony_ci HDR Endpoint Mode 15 15025bd8deadSopenharmony_ci 15035bd8deadSopenharmony_ci Mode 15 specifies two RGBA values, using the eight values (v0, v1, v2, 15045bd8deadSopenharmony_ci v3, v4, v5, v6, v7). First, the RGB values are decoded from (v0..v5) 15055bd8deadSopenharmony_ci using the method from Mode 11. The alpha values are stored in values 15065bd8deadSopenharmony_ci v6 and v7 as a mode and two values which are interpreted according 15075bd8deadSopenharmony_ci to the mode: 15085bd8deadSopenharmony_ci 15095bd8deadSopenharmony_ci Value 7 6 5 4 3 2 1 0 15105bd8deadSopenharmony_ci ----- ------------------------------ 15115bd8deadSopenharmony_ci v6 |M0 | A[6:0] | 15125bd8deadSopenharmony_ci ----- ------------------------------ 15135bd8deadSopenharmony_ci v7 |M1 | B[6:0] | 15145bd8deadSopenharmony_ci ----- ------------------------------ 15155bd8deadSopenharmony_ci Table C.2.24 - HDR Mode 15 Alpha Value Layout 15165bd8deadSopenharmony_ci 15175bd8deadSopenharmony_ci The alpha values are decoded from v6 and v7 as follows: 15185bd8deadSopenharmony_ci 15195bd8deadSopenharmony_ci // Decode RGB as for mode 11 15205bd8deadSopenharmony_ci (e0,e1) = decode_mode_11(v0,v1,v2,v3,v4,v5) 15215bd8deadSopenharmony_ci 15225bd8deadSopenharmony_ci // Extract mode bits 15235bd8deadSopenharmony_ci mode = ((v6 >> 7) & 1) | ((v7 >> 6) & 2); 15245bd8deadSopenharmony_ci v6 &= 0x7F; 15255bd8deadSopenharmony_ci v7 &= 0x7F; 15265bd8deadSopenharmony_ci 15275bd8deadSopenharmony_ci if(mode==3) 15285bd8deadSopenharmony_ci { 15295bd8deadSopenharmony_ci // Directly specify alphas 15305bd8deadSopenharmony_ci e0.alpha = v6 << 5; 15315bd8deadSopenharmony_ci e1.alpha = v7 << 5; 15325bd8deadSopenharmony_ci } 15335bd8deadSopenharmony_ci else 15345bd8deadSopenharmony_ci { 15355bd8deadSopenharmony_ci // Transfer bits from v7 to v6 and sign extend v7. 15365bd8deadSopenharmony_ci v6 |= (v7 << (mode+1))) & 0x780; 15375bd8deadSopenharmony_ci v7 &= (0x3F >> mode); 15385bd8deadSopenharmony_ci v7 ^= 0x20 >> mode; 15395bd8deadSopenharmony_ci v7 -= 0x20 >> mode; 15405bd8deadSopenharmony_ci v6 <<= (4-mode); 15415bd8deadSopenharmony_ci v7 <<= (4-mode); 15425bd8deadSopenharmony_ci 15435bd8deadSopenharmony_ci // Add delta and clamp 15445bd8deadSopenharmony_ci v7 += v6; 15455bd8deadSopenharmony_ci v7 = clamp(v7, 0, 0xFFF); 15465bd8deadSopenharmony_ci e0.alpha = v6; 15475bd8deadSopenharmony_ci e1.alpha = v7; 15485bd8deadSopenharmony_ci } 15495bd8deadSopenharmony_ci 15505bd8deadSopenharmony_ci Note that in this mode, the alpha values are interpreted (and 15515bd8deadSopenharmony_ci interpolated) as 12-bit HDR values, and are interpolated as 15525bd8deadSopenharmony_ci for any other HDR component. 15535bd8deadSopenharmony_ci 15545bd8deadSopenharmony_ci C.2.16 Weight Decoding 15555bd8deadSopenharmony_ci ----------------------- 15565bd8deadSopenharmony_ci The weight information is stored as a stream of bits, growing downwards 15575bd8deadSopenharmony_ci from the most significant bit in the block. Bit n in the stream is thus 15585bd8deadSopenharmony_ci bit 127-n in the block. 15595bd8deadSopenharmony_ci 15605bd8deadSopenharmony_ci For each location in the weight grid, a value (in the specified range) 15615bd8deadSopenharmony_ci is packed into the stream. These are ordered in a raster pattern 15625bd8deadSopenharmony_ci starting from location (0,0,0), with the X dimension increasing fastest, 15635bd8deadSopenharmony_ci and the Z dimension increasing slowest. If dual-plane mode is selected, 15645bd8deadSopenharmony_ci both weights are emitted together for each location, plane 0 first, 15655bd8deadSopenharmony_ci then plane 1. 15665bd8deadSopenharmony_ci 15675bd8deadSopenharmony_ci C.2.17 Weight Unquantization 15685bd8deadSopenharmony_ci ----------------------------- 15695bd8deadSopenharmony_ci 15705bd8deadSopenharmony_ci Each weight plane is specified as a sequence of integers in a given 15715bd8deadSopenharmony_ci range. These values are packed using integer sequence encoding. 15725bd8deadSopenharmony_ci 15735bd8deadSopenharmony_ci Once unpacked, the values must be unquantized from their storage 15745bd8deadSopenharmony_ci range, returning them to a standard range of 0..64. The procedure 15755bd8deadSopenharmony_ci for doing so is similar to the color endpoint unquantization. 15765bd8deadSopenharmony_ci 15775bd8deadSopenharmony_ci First, we unquantize the actual stored weight values to the range 0..63. 15785bd8deadSopenharmony_ci 15795bd8deadSopenharmony_ci For bit-only representations, this is simple bit replication from the 15805bd8deadSopenharmony_ci most significant bit of the value. 15815bd8deadSopenharmony_ci 15825bd8deadSopenharmony_ci For trit or quint-based representations, this involves a set of bit 15835bd8deadSopenharmony_ci manipulations and adjustments to avoid the expense of full-width 15845bd8deadSopenharmony_ci multipliers. 15855bd8deadSopenharmony_ci 15865bd8deadSopenharmony_ci For representations with no additional bits, the results are as follows: 15875bd8deadSopenharmony_ci 15885bd8deadSopenharmony_ci Range 0 1 2 3 4 15895bd8deadSopenharmony_ci -------------------------- 15905bd8deadSopenharmony_ci 0..2 0 32 63 - - 15915bd8deadSopenharmony_ci 0..4 0 16 32 47 63 15925bd8deadSopenharmony_ci -------------------------- 15935bd8deadSopenharmony_ci Table C.2.25 - Weight Unquantization Values 15945bd8deadSopenharmony_ci 15955bd8deadSopenharmony_ci For other values, we calculate the initial inputs to a bit manipulation 15965bd8deadSopenharmony_ci procedure. These are denoted A (7 bits), B (7 bits), C (7 bits), and 15975bd8deadSopenharmony_ci D (3 bits) and are decoded using the range as follows: 15985bd8deadSopenharmony_ci 15995bd8deadSopenharmony_ci Range T Q B Bits A B C D 16005bd8deadSopenharmony_ci ------------------------------------------------------- 16015bd8deadSopenharmony_ci 0..5 1 1 a aaaaaaa 0000000 50 Trit value 16025bd8deadSopenharmony_ci 0..9 1 1 a aaaaaaa 0000000 28 Quint value 16035bd8deadSopenharmony_ci 0..11 1 2 ba aaaaaaa b000b0b 23 Trit value 16045bd8deadSopenharmony_ci 0..19 1 2 ba aaaaaaa b0000b0 13 Quint value 16055bd8deadSopenharmony_ci 0..23 1 3 cba aaaaaaa cb000cb 11 Trit value 16065bd8deadSopenharmony_ci ------------------------------------------------------- 16075bd8deadSopenharmony_ci Table C.2.26 - Weight Unquantization Parameters 16085bd8deadSopenharmony_ci 16095bd8deadSopenharmony_ci These are then processed as follows: 16105bd8deadSopenharmony_ci 16115bd8deadSopenharmony_ci T = D * C + B; 16125bd8deadSopenharmony_ci T = T ^ A; 16135bd8deadSopenharmony_ci T = (A & 0x20) | (T >> 2); 16145bd8deadSopenharmony_ci 16155bd8deadSopenharmony_ci Note that the multiply in the first line is nearly trivial as it only 16165bd8deadSopenharmony_ci needs to multiply by 0, 1, 2, 3 or 4. 16175bd8deadSopenharmony_ci 16185bd8deadSopenharmony_ci As a final step, for all types of value, the range is expanded from 16195bd8deadSopenharmony_ci 0..63 up to 0..64 as follows: 16205bd8deadSopenharmony_ci 16215bd8deadSopenharmony_ci if (T > 32) { T += 1; } 16225bd8deadSopenharmony_ci 16235bd8deadSopenharmony_ci This allows the implementation to use 64 as a divisor during inter- 16245bd8deadSopenharmony_ci polation, which is much easier than using 63. 16255bd8deadSopenharmony_ci 16265bd8deadSopenharmony_ci C.2.18 Weight Infill 16275bd8deadSopenharmony_ci --------------------- 16285bd8deadSopenharmony_ci 16295bd8deadSopenharmony_ci After unquantization, the weights are subject to weight selection and 16305bd8deadSopenharmony_ci infill. The infill method is used to calculate the weight for a texel 16315bd8deadSopenharmony_ci position, based on the weights in the stored weight grid array (which 16325bd8deadSopenharmony_ci may be a different size). 16335bd8deadSopenharmony_ci 16345bd8deadSopenharmony_ci The procedure below must be followed exactly, to ensure bit exact 16355bd8deadSopenharmony_ci results. 16365bd8deadSopenharmony_ci 16375bd8deadSopenharmony_ci The block size is specified as two dimensions along the s and t 16385bd8deadSopenharmony_ci axes (Bs, Bt). Texel coordinates within the block (s,t) can have values 16395bd8deadSopenharmony_ci from 0 to one less than the block dimension in that axis. 16405bd8deadSopenharmony_ci 16415bd8deadSopenharmony_ci For each block dimension, we compute scale factors (Ds, Dt) 16425bd8deadSopenharmony_ci 16435bd8deadSopenharmony_ci Ds = floor( (1024 + floor(Bs/2)) / (Bs-1) ); 16445bd8deadSopenharmony_ci Dt = floor( (1024 + floor(Bt/2)) / (Bt-1) ); 16455bd8deadSopenharmony_ci 16465bd8deadSopenharmony_ci Since the block dimensions are constrained, these are easily looked up 16475bd8deadSopenharmony_ci in a table. These scale factors are then used to scale the (s,t) 16485bd8deadSopenharmony_ci coordinates to a homogeneous coordinate (cs, ct): 16495bd8deadSopenharmony_ci 16505bd8deadSopenharmony_ci cs = Ds * s; 16515bd8deadSopenharmony_ci ct = Dt * t; 16525bd8deadSopenharmony_ci 16535bd8deadSopenharmony_ci This homogeneous coordinate (cs, ct) is then scaled again to give 16545bd8deadSopenharmony_ci a coordinate (gs, gt) in the weight-grid space . The weight-grid is 16555bd8deadSopenharmony_ci of size (N, M), as specified in the block mode field: 16565bd8deadSopenharmony_ci 16575bd8deadSopenharmony_ci gs = (cs*(N-1)+32) >> 6; 16585bd8deadSopenharmony_ci gt = (ct*(M-1)+32) >> 6; 16595bd8deadSopenharmony_ci 16605bd8deadSopenharmony_ci The resulting coordinates may be in the range 0..176. These are inter- 16615bd8deadSopenharmony_ci preted as 4:4 unsigned fixed point numbers in the range 0.0 .. 11.0. 16625bd8deadSopenharmony_ci 16635bd8deadSopenharmony_ci If we label the integral parts of these (js, jt) and the fractional 16645bd8deadSopenharmony_ci parts (fs, ft), then: 16655bd8deadSopenharmony_ci 16665bd8deadSopenharmony_ci js = gs >> 4; fs = gs & 0x0F; 16675bd8deadSopenharmony_ci jt = gt >> 4; ft = gt & 0x0F; 16685bd8deadSopenharmony_ci 16695bd8deadSopenharmony_ci These values are then used to bilinearly interpolate between the stored 16705bd8deadSopenharmony_ci weights. 16715bd8deadSopenharmony_ci 16725bd8deadSopenharmony_ci v0 = js + jt*N; 16735bd8deadSopenharmony_ci p00 = decode_weight(v0); 16745bd8deadSopenharmony_ci p01 = decode_weight(v0 + 1); 16755bd8deadSopenharmony_ci p10 = decode_weight(v0 + N); 16765bd8deadSopenharmony_ci p11 = decode_weight(v0 + N + 1); 16775bd8deadSopenharmony_ci 16785bd8deadSopenharmony_ci The function decode_weight(n) decodes the nth weight in the stored weight 16795bd8deadSopenharmony_ci stream. The values p00 to p11 are the weights at the corner of the square 16805bd8deadSopenharmony_ci in which the texel position resides. These are then weighted using the 16815bd8deadSopenharmony_ci fractional position to produce the effective weight i as follows: 16825bd8deadSopenharmony_ci 16835bd8deadSopenharmony_ci w11 = (fs*ft+8) >> 4; 16845bd8deadSopenharmony_ci w10 = ft - w11; 16855bd8deadSopenharmony_ci w01 = fs - w11; 16865bd8deadSopenharmony_ci w00 = 16 - fs - ft + w11; 16875bd8deadSopenharmony_ci i = (p00*w00 + p01*w01 + p10*w10 + p11*w11 + 8) >> 4; 16885bd8deadSopenharmony_ci 16895bd8deadSopenharmony_ci C.2.19 Weight Application 16905bd8deadSopenharmony_ci -------------------------- 16915bd8deadSopenharmony_ci Once the effective weight i for the texel has been calculated, the color 16925bd8deadSopenharmony_ci endpoints are interpolated and expanded. 16935bd8deadSopenharmony_ci 16945bd8deadSopenharmony_ci For LDR endpoint modes, each color component C is calculated from the 16955bd8deadSopenharmony_ci corresponding 8-bit endpoint components C0 and C1 as follows: 16965bd8deadSopenharmony_ci 16975bd8deadSopenharmony_ci If sRGB conversion is not enabled, or for the alpha channel in any case, 16985bd8deadSopenharmony_ci C0 and C1 are first expanded to 16 bits by bit replication: 16995bd8deadSopenharmony_ci 17005bd8deadSopenharmony_ci C0 = (C0 << 8) | C0; C1 = (C1 << 8) | C1; 17015bd8deadSopenharmony_ci 17025bd8deadSopenharmony_ci If sRGB conversion is enabled, C0 and C1 for the R, G, and B channels 17035bd8deadSopenharmony_ci are expanded to 16 bits differently, as follows: 17045bd8deadSopenharmony_ci 17055bd8deadSopenharmony_ci C0 = (C0 << 8) | 0x80; C1 = (C1 << 8) | 0x80; 17065bd8deadSopenharmony_ci 17075bd8deadSopenharmony_ci C0 and C1 are then interpolated to produce a UNORM16 result C: 17085bd8deadSopenharmony_ci 17095bd8deadSopenharmony_ci C = floor( (C0*(64-i) + C1*i + 32)/64 ) 17105bd8deadSopenharmony_ci 17115bd8deadSopenharmony_ci If sRGB conversion is enabled, the top 8 bits of the interpolation 17125bd8deadSopenharmony_ci result for the R, G and B channels are passed to the external sRGB 17135bd8deadSopenharmony_ci conversion block. Otherwise, if C = 65535, then the final result is 17145bd8deadSopenharmony_ci 1.0 (0x3C00) otherwise C is divided by 65536 and the infinite-precision 17155bd8deadSopenharmony_ci result of the division is converted to FP16 with round-to-zero 17165bd8deadSopenharmony_ci semantics. 17175bd8deadSopenharmony_ci 17185bd8deadSopenharmony_ci For HDR endpoint modes, color values are represented in a 12-bit 17195bd8deadSopenharmony_ci pseudo-logarithmic representation, and interpolation occurs in a 17205bd8deadSopenharmony_ci piecewise-approximate logarithmic manner as follows: 17215bd8deadSopenharmony_ci 17225bd8deadSopenharmony_ci In LDR mode, the error result is returned. 17235bd8deadSopenharmony_ci 17245bd8deadSopenharmony_ci In HDR mode, the color components from each endpoint, C0 and C1, are 17255bd8deadSopenharmony_ci initially shifted left 4 bits to become 16-bit integer values and these 17265bd8deadSopenharmony_ci are interpolated in the same way as LDR. The 16-bit value C is then 17275bd8deadSopenharmony_ci decomposed into the top five bits, E, and the bottom 11 bits M, which 17285bd8deadSopenharmony_ci are then processed and recombined with E to form the final value Cf: 17295bd8deadSopenharmony_ci 17305bd8deadSopenharmony_ci C = floor( (C0*(64-i) + C1*i + 32)/64 ) 17315bd8deadSopenharmony_ci E = (C&0xF800) >> 11; M = C&0x7FF; 17325bd8deadSopenharmony_ci if (M < 512) { Mt = 3*M; } 17335bd8deadSopenharmony_ci else if (M >= 1536) { Mt = 5*M - 2048; } 17345bd8deadSopenharmony_ci else { Mt = 4*M - 512; } 17355bd8deadSopenharmony_ci Cf = (E<<10) + (Mt>>3) 17365bd8deadSopenharmony_ci 17375bd8deadSopenharmony_ci This interpolation is a considerably closer approximation to a 17385bd8deadSopenharmony_ci logarithmic space than simple 16-bit interpolation. 17395bd8deadSopenharmony_ci 17405bd8deadSopenharmony_ci This final value Cf is interpreted as an IEEE FP16 value. If the result 17415bd8deadSopenharmony_ci is +Inf or NaN, it is converted to the bit pattern 0x7BFF, which is the 17425bd8deadSopenharmony_ci largest representable finite value. 17435bd8deadSopenharmony_ci 17445bd8deadSopenharmony_ci C.2.20 Dual-Plane Decoding 17455bd8deadSopenharmony_ci --------------------------- 17465bd8deadSopenharmony_ci If dual-plane mode is disabled, all of the endpoint components are inter- 17475bd8deadSopenharmony_ci polated using the same weight value. 17485bd8deadSopenharmony_ci 17495bd8deadSopenharmony_ci If dual-plane mode is enabled, two weights are stored with each texel. 17505bd8deadSopenharmony_ci One component is then selected to use the second weight for interpolation, 17515bd8deadSopenharmony_ci instead of the first weight. The first weight is then used for all other 17525bd8deadSopenharmony_ci components. 17535bd8deadSopenharmony_ci 17545bd8deadSopenharmony_ci The component to treat specially is indicated using the 2-bit Color 17555bd8deadSopenharmony_ci Component Selector (CCS) field as follows: 17565bd8deadSopenharmony_ci 17575bd8deadSopenharmony_ci Value Weight 0 Weight 1 17585bd8deadSopenharmony_ci -------------------------- 17595bd8deadSopenharmony_ci 0 GBA R 17605bd8deadSopenharmony_ci 1 RBA G 17615bd8deadSopenharmony_ci 2 RGA B 17625bd8deadSopenharmony_ci 3 RGB A 17635bd8deadSopenharmony_ci -------------------------- 17645bd8deadSopenharmony_ci Table C.2.28 - Dual Plane Color Component Selector Values 17655bd8deadSopenharmony_ci 17665bd8deadSopenharmony_ci The CCS bits are stored at a variable position directly below the weight 17675bd8deadSopenharmony_ci bits and any additional CEM bits. 17685bd8deadSopenharmony_ci 17695bd8deadSopenharmony_ci C.2.21 Partition Pattern Generation 17705bd8deadSopenharmony_ci ------------------------------------ 17715bd8deadSopenharmony_ci 17725bd8deadSopenharmony_ci When multiple partitions are active, each texel position is assigned a 17735bd8deadSopenharmony_ci partition index. This partition index is calculated using a seed (the 17745bd8deadSopenharmony_ci partition pattern index), the texel's x,y,z position within the block, 17755bd8deadSopenharmony_ci and the number of partitions. An additional argument, small_block, is 17765bd8deadSopenharmony_ci set to 1 if the number of texels in the block is less than 31, 17775bd8deadSopenharmony_ci otherwise it is set to 0. 17785bd8deadSopenharmony_ci 17795bd8deadSopenharmony_ci This function is specified in terms of x, y and z in order to support 17805bd8deadSopenharmony_ci 3D textures. For 2D textures and texture slices, z will always be 0. 17815bd8deadSopenharmony_ci 17825bd8deadSopenharmony_ci The full partition selection algorithm is as follows: 17835bd8deadSopenharmony_ci 17845bd8deadSopenharmony_ci int select_partition(int seed, int x, int y, int z, 17855bd8deadSopenharmony_ci int partitioncount, int small_block) 17865bd8deadSopenharmony_ci { 17875bd8deadSopenharmony_ci if( small_block ){ x <<= 1; y <<= 1; z <<= 1; } 17885bd8deadSopenharmony_ci seed += (partitioncount-1) * 1024; 17895bd8deadSopenharmony_ci uint32_t rnum = hash52(seed); 17905bd8deadSopenharmony_ci uint8_t seed1 = rnum & 0xF; 17915bd8deadSopenharmony_ci uint8_t seed2 = (rnum >> 4) & 0xF; 17925bd8deadSopenharmony_ci uint8_t seed3 = (rnum >> 8) & 0xF; 17935bd8deadSopenharmony_ci uint8_t seed4 = (rnum >> 12) & 0xF; 17945bd8deadSopenharmony_ci uint8_t seed5 = (rnum >> 16) & 0xF; 17955bd8deadSopenharmony_ci uint8_t seed6 = (rnum >> 20) & 0xF; 17965bd8deadSopenharmony_ci uint8_t seed7 = (rnum >> 24) & 0xF; 17975bd8deadSopenharmony_ci uint8_t seed8 = (rnum >> 28) & 0xF; 17985bd8deadSopenharmony_ci uint8_t seed9 = (rnum >> 18) & 0xF; 17995bd8deadSopenharmony_ci uint8_t seed10 = (rnum >> 22) & 0xF; 18005bd8deadSopenharmony_ci uint8_t seed11 = (rnum >> 26) & 0xF; 18015bd8deadSopenharmony_ci uint8_t seed12 = ((rnum >> 30) | (rnum << 2)) & 0xF; 18025bd8deadSopenharmony_ci 18035bd8deadSopenharmony_ci seed1 *= seed1; seed2 *= seed2; 18045bd8deadSopenharmony_ci seed3 *= seed3; seed4 *= seed4; 18055bd8deadSopenharmony_ci seed5 *= seed5; seed6 *= seed6; 18065bd8deadSopenharmony_ci seed7 *= seed7; seed8 *= seed8; 18075bd8deadSopenharmony_ci seed9 *= seed9; seed10 *= seed10; 18085bd8deadSopenharmony_ci seed11 *= seed11; seed12 *= seed12; 18095bd8deadSopenharmony_ci 18105bd8deadSopenharmony_ci int sh1, sh2, sh3; 18115bd8deadSopenharmony_ci if( seed & 1 ) 18125bd8deadSopenharmony_ci { sh1 = (seed&2 ? 4:5); sh2 = (partitioncount==3 ? 6:5); } 18135bd8deadSopenharmony_ci else 18145bd8deadSopenharmony_ci { sh1 = (partitioncount==3 ? 6:5); sh2 = (seed&2 ? 4:5); } 18155bd8deadSopenharmony_ci sh3 = (seed & 0x10) ? sh1 : sh2; 18165bd8deadSopenharmony_ci 18175bd8deadSopenharmony_ci seed1 >>= sh1; seed2 >>= sh2; seed3 >>= sh1; seed4 >>= sh2; 18185bd8deadSopenharmony_ci seed5 >>= sh1; seed6 >>= sh2; seed7 >>= sh1; seed8 >>= sh2; 18195bd8deadSopenharmony_ci seed9 >>= sh3; seed10 >>= sh3; seed11 >>= sh3; seed12 >>= sh3; 18205bd8deadSopenharmony_ci 18215bd8deadSopenharmony_ci int a = seed1*x + seed2*y + seed11*z + (rnum >> 14); 18225bd8deadSopenharmony_ci int b = seed3*x + seed4*y + seed12*z + (rnum >> 10); 18235bd8deadSopenharmony_ci int c = seed5*x + seed6*y + seed9 *z + (rnum >> 6); 18245bd8deadSopenharmony_ci int d = seed7*x + seed8*y + seed10*z + (rnum >> 2); 18255bd8deadSopenharmony_ci 18265bd8deadSopenharmony_ci a &= 0x3F; b &= 0x3F; c &= 0x3F; d &= 0x3F; 18275bd8deadSopenharmony_ci 18285bd8deadSopenharmony_ci if( partitioncount < 4 ) d = 0; 18295bd8deadSopenharmony_ci if( partitioncount < 3 ) c = 0; 18305bd8deadSopenharmony_ci 18315bd8deadSopenharmony_ci if( a >= b && a >= c && a >= d ) return 0; 18325bd8deadSopenharmony_ci else if( b >= c && b >= d ) return 1; 18335bd8deadSopenharmony_ci else if( c >= d ) return 2; 18345bd8deadSopenharmony_ci else return 3; 18355bd8deadSopenharmony_ci } 18365bd8deadSopenharmony_ci 18375bd8deadSopenharmony_ci As has been observed before, the bit selections are much easier to 18385bd8deadSopenharmony_ci express in hardware than in C. 18395bd8deadSopenharmony_ci 18405bd8deadSopenharmony_ci The seed is expanded using a hash function hash52, which is defined as 18415bd8deadSopenharmony_ci follows: 18425bd8deadSopenharmony_ci 18435bd8deadSopenharmony_ci uint32_t hash52( uint32_t p ) 18445bd8deadSopenharmony_ci { 18455bd8deadSopenharmony_ci p ^= p >> 15; p -= p << 17; p += p << 7; p += p << 4; 18465bd8deadSopenharmony_ci p ^= p >> 5; p += p << 16; p ^= p >> 7; p ^= p >> 3; 18475bd8deadSopenharmony_ci p ^= p << 6; p ^= p >> 17; 18485bd8deadSopenharmony_ci return p; 18495bd8deadSopenharmony_ci } 18505bd8deadSopenharmony_ci 18515bd8deadSopenharmony_ci This assumes that all operations act on 32-bit values 18525bd8deadSopenharmony_ci 18535bd8deadSopenharmony_ci C.2.22 Data Size Determination 18545bd8deadSopenharmony_ci ------------------------------- 18555bd8deadSopenharmony_ci 18565bd8deadSopenharmony_ci The size of the data used to represent color endpoints is not 18575bd8deadSopenharmony_ci explicitly specified. Instead, it is determined from the block mode and 18585bd8deadSopenharmony_ci number of partitions as follows: 18595bd8deadSopenharmony_ci 18605bd8deadSopenharmony_ci config_bits = 17; 18615bd8deadSopenharmony_ci if(num_partitions>1) 18625bd8deadSopenharmony_ci if(single_CEM) 18635bd8deadSopenharmony_ci config_bits = 29; 18645bd8deadSopenharmony_ci else 18655bd8deadSopenharmony_ci config_bits = 25 + 3*num_partitions; 18665bd8deadSopenharmony_ci 18675bd8deadSopenharmony_ci num_weights = M * N * Q; // size of weight grid 18685bd8deadSopenharmony_ci 18695bd8deadSopenharmony_ci if(dual_plane) 18705bd8deadSopenharmony_ci config_bits += 2; 18715bd8deadSopenharmony_ci num_weights *= 2; 18725bd8deadSopenharmony_ci 18735bd8deadSopenharmony_ci weight_bits = ceil(num_weights*8*trits_in_weight_range/5) + 18745bd8deadSopenharmony_ci ceil(num_weights*7*quints_in_weight_range/3) + 18755bd8deadSopenharmony_ci num_weights*bits_in_weight_range; 18765bd8deadSopenharmony_ci 18775bd8deadSopenharmony_ci remaining_bits = 128 - config_bits - weight_bits; 18785bd8deadSopenharmony_ci 18795bd8deadSopenharmony_ci num_CEM_pairs = base_CEM_class+1 + count_bits(extra_CEM_bits); 18805bd8deadSopenharmony_ci 18815bd8deadSopenharmony_ci The CEM value range is then looked up from a table indexed by remaining 18825bd8deadSopenharmony_ci bits and num_CEM_pairs. This table is initialized such that the range 18835bd8deadSopenharmony_ci is as large as possible, consistent with the constraint that the number 18845bd8deadSopenharmony_ci of bits required to encode num_CEM_pairs pairs of values is not more 18855bd8deadSopenharmony_ci than the number of remaining bits. 18865bd8deadSopenharmony_ci 18875bd8deadSopenharmony_ci An equivalent iterative algorithm would be: 18885bd8deadSopenharmony_ci 18895bd8deadSopenharmony_ci num_CEM_values = num_CEM_pairs*2; 18905bd8deadSopenharmony_ci 18915bd8deadSopenharmony_ci for(range = each possible CEM range in descending order of size) 18925bd8deadSopenharmony_ci { 18935bd8deadSopenharmony_ci CEM_bits = ceil(num_CEM_values*8*trits_in_CEM_range/5) + 18945bd8deadSopenharmony_ci ceil(num_CEM_values*7*quints_in_CEM_range/3) + 18955bd8deadSopenharmony_ci num_CEM_values*bits_in_CEM_range; 18965bd8deadSopenharmony_ci 18975bd8deadSopenharmony_ci if(CEM_bits <= remaining_bits) 18985bd8deadSopenharmony_ci break; 18995bd8deadSopenharmony_ci } 19005bd8deadSopenharmony_ci return range; 19015bd8deadSopenharmony_ci 19025bd8deadSopenharmony_ci In cases where this procedure results in unallocated bits, these bits 19035bd8deadSopenharmony_ci are not read by the decoding process and can have any value. 19045bd8deadSopenharmony_ci 19055bd8deadSopenharmony_ci C.2.23 Void-Extent Blocks 19065bd8deadSopenharmony_ci -------------------------- 19075bd8deadSopenharmony_ci 19085bd8deadSopenharmony_ci A void-extent block is a block encoded with a single color. It also 19095bd8deadSopenharmony_ci specifies some additional information about the extent of the single- 19105bd8deadSopenharmony_ci color area beyond this block, which can optionally be used by a 19115bd8deadSopenharmony_ci decoder to reduce or prevent redundant block fetches. 19125bd8deadSopenharmony_ci 19135bd8deadSopenharmony_ci The layout of a 2D Void-Extent block is as follows: 19145bd8deadSopenharmony_ci 19155bd8deadSopenharmony_ci 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112 19165bd8deadSopenharmony_ci --------------------------------------------------------------- 19175bd8deadSopenharmony_ci | Block color A component | 19185bd8deadSopenharmony_ci --------------------------------------------------------------- 19195bd8deadSopenharmony_ci 19205bd8deadSopenharmony_ci 111 110 109 108 107 106 105 104 103 102 101 100 99 98 97 96 19215bd8deadSopenharmony_ci ---------------------------------------------------------------- 19225bd8deadSopenharmony_ci | Block color B component | 19235bd8deadSopenharmony_ci ---------------------------------------------------------------- 19245bd8deadSopenharmony_ci 19255bd8deadSopenharmony_ci 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 19265bd8deadSopenharmony_ci ---------------------------------------------------------------- 19275bd8deadSopenharmony_ci | Block color G component | 19285bd8deadSopenharmony_ci ---------------------------------------------------------------- 19295bd8deadSopenharmony_ci 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 19305bd8deadSopenharmony_ci ---------------------------------------------------------------- 19315bd8deadSopenharmony_ci | Block color R component | 19325bd8deadSopenharmony_ci ---------------------------------------------------------------- 19335bd8deadSopenharmony_ci 19345bd8deadSopenharmony_ci 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 19355bd8deadSopenharmony_ci ---------------------------------------------------------------- 19365bd8deadSopenharmony_ci | Void-extent maximum T coordinate | Min T | 19375bd8deadSopenharmony_ci ---------------------------------------------------------------- 19385bd8deadSopenharmony_ci 19395bd8deadSopenharmony_ci 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 19405bd8deadSopenharmony_ci ---------------------------------------------------------------- 19415bd8deadSopenharmony_ci Void-extent minimum T coordinate | Void-extent max S | 19425bd8deadSopenharmony_ci ---------------------------------------------------------------- 19435bd8deadSopenharmony_ci 19445bd8deadSopenharmony_ci 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 19455bd8deadSopenharmony_ci ---------------------------------------------------------------- 19465bd8deadSopenharmony_ci Void-extent max S coord | Void-extent minimum S coordinate | 19475bd8deadSopenharmony_ci ---------------------------------------------------------------- 19485bd8deadSopenharmony_ci 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 19495bd8deadSopenharmony_ci ---------------------------------------------------------------- 19505bd8deadSopenharmony_ci Min S coord | 1 | 1 | D | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 19515bd8deadSopenharmony_ci ---------------------------------------------------------------- 19525bd8deadSopenharmony_ci ------------------------------------------------- 19535bd8deadSopenharmony_ci Figure C.7 - 2D Void-Extent Block Layout Overview 19545bd8deadSopenharmony_ci 19555bd8deadSopenharmony_ci Bit 9 is the Dynamic Range flag, which indicates the format in which 19565bd8deadSopenharmony_ci colors are stored. A 0 value indicates LDR, in which case the color 19575bd8deadSopenharmony_ci components are stored as UNORM16 values. A 1 indicates HDR, in which 19585bd8deadSopenharmony_ci case the color components are stored as FP16 values. 19595bd8deadSopenharmony_ci 19605bd8deadSopenharmony_ci The reason for the storage of UNORM16 values in the LDR case is due 19615bd8deadSopenharmony_ci to the possibility that the value will need to be passed on to sRGB 19625bd8deadSopenharmony_ci conversion. By storing the color value in the format which comes out 19635bd8deadSopenharmony_ci of the interpolator, before the conversion to FP16, we avoid having 19645bd8deadSopenharmony_ci to have separate versions for sRGB and linear modes. 19655bd8deadSopenharmony_ci 19665bd8deadSopenharmony_ci If a void-extent block with HDR values is decoded in LDR mode, then 19675bd8deadSopenharmony_ci the result will be the error color, opaque magenta, for all texels 19685bd8deadSopenharmony_ci within the block. 19695bd8deadSopenharmony_ci 19705bd8deadSopenharmony_ci In the HDR case, if the color component values are infinity or NaN, this 19715bd8deadSopenharmony_ci will result in undefined behavior. As usual, this must not lead to GL 19725bd8deadSopenharmony_ci interruption or termination. 19735bd8deadSopenharmony_ci 19745bd8deadSopenharmony_ci Bits 10 and 11 are reserved and must be 1. 19755bd8deadSopenharmony_ci 19765bd8deadSopenharmony_ci The minimum and maximum coordinate values are treated as unsigned 19775bd8deadSopenharmony_ci integers and then normalized into the range 0..1 (by dividing by 2^13-1 19785bd8deadSopenharmony_ci or 2^9-1, for 2D and 3D respectively). The maximum values for each 19795bd8deadSopenharmony_ci dimension must be greater than the corresponding minimum values, 19805bd8deadSopenharmony_ci unless they are all all-1s. 19815bd8deadSopenharmony_ci 19825bd8deadSopenharmony_ci If all the coordinates are all-1s, then the void extent is ignored, 19835bd8deadSopenharmony_ci and the block is simply a constant-color block. 19845bd8deadSopenharmony_ci 19855bd8deadSopenharmony_ci The existence of single-color blocks with void extents must not produce 19865bd8deadSopenharmony_ci results different from those obtained if these single-color blocks are 19875bd8deadSopenharmony_ci defined without void-extents. Any situation in which the results would 19885bd8deadSopenharmony_ci differ is invalid. Results from invalid void extents are undefined. 19895bd8deadSopenharmony_ci 19905bd8deadSopenharmony_ci If a void-extent appears in a MIPmap level other than the most detailed 19915bd8deadSopenharmony_ci one, then the extent will apply to all of the more detailed levels too. 19925bd8deadSopenharmony_ci This allows decoders to avoid sampling more detailed MIPmaps. 19935bd8deadSopenharmony_ci 19945bd8deadSopenharmony_ci If the more detailed MIPmap level is not a constant color in this region, 19955bd8deadSopenharmony_ci then the block may be marked as constant color, but without a void extent, 19965bd8deadSopenharmony_ci as detailed above. 19975bd8deadSopenharmony_ci 19985bd8deadSopenharmony_ci If a void-extent extends to the edge of a texture, then filtered texture 19995bd8deadSopenharmony_ci colors may not be the same color as that specified in the block, due to 20005bd8deadSopenharmony_ci texture border colors, wrapping, or cube face wrapping. 20015bd8deadSopenharmony_ci 20025bd8deadSopenharmony_ci Care must be taken when updating or extracting partial image data that 20035bd8deadSopenharmony_ci void-extents in the image do not become invalid. 20045bd8deadSopenharmony_ci 20055bd8deadSopenharmony_ci C.2.24 Illegal Encodings 20065bd8deadSopenharmony_ci ------------------------- 20075bd8deadSopenharmony_ci 20085bd8deadSopenharmony_ci In ASTC, there is a variety of ways to encode an illegal block. Decoders 20095bd8deadSopenharmony_ci are required to recognize all illegal blocks and emit the standard error 20105bd8deadSopenharmony_ci color value upon encountering an illegal block. 20115bd8deadSopenharmony_ci 20125bd8deadSopenharmony_ci Here is a comprehensive list of situations that represent illegal block 20135bd8deadSopenharmony_ci encodings: 20145bd8deadSopenharmony_ci 20155bd8deadSopenharmony_ci * The block mode specified is one of the modes explicitly listed 20165bd8deadSopenharmony_ci as Reserved. 20175bd8deadSopenharmony_ci * A 2D void-extent block that has any of the reserved bits not 20185bd8deadSopenharmony_ci set to 1. 20195bd8deadSopenharmony_ci * A block mode has been specified that would require more than 20205bd8deadSopenharmony_ci 64 weights total. 20215bd8deadSopenharmony_ci * A block mode has been specified that would require more than 20225bd8deadSopenharmony_ci 96 bits for integer sequence encoding of the weight grid. 20235bd8deadSopenharmony_ci * A block mode has been specifed that would require fewer than 20245bd8deadSopenharmony_ci 24 bits for integer sequence encoding of the weight grid. 20255bd8deadSopenharmony_ci * The size of the weight grid exceeds the size of the block footprint 20265bd8deadSopenharmony_ci in any dimension. 20275bd8deadSopenharmony_ci * Color endpoint modes have been specified such that the color 20285bd8deadSopenharmony_ci integer sequence encoding would require more than 18 integers. 20295bd8deadSopenharmony_ci * The number of bits available for color endpoint encoding after all 20305bd8deadSopenharmony_ci the other fields have been counted is less than ceil(13C/5) where C 20315bd8deadSopenharmony_ci is the number of color endpoint integers (this would restrict color 20325bd8deadSopenharmony_ci integers to a range smaller than 0..5, which is not supported). 20335bd8deadSopenharmony_ci * Dual weight mode is enabled for a block with 4 partitions. 20345bd8deadSopenharmony_ci * Void-Extent blocks where the low coordinate for some texture axis 20355bd8deadSopenharmony_ci is greater than or equal to the high coordinate. 20365bd8deadSopenharmony_ci 20375bd8deadSopenharmony_ci Note also that, in LDR mode, a block which has both HDR and LDR endpoint 20385bd8deadSopenharmony_ci modes assigned to different partitions is not an error block. Only those 20395bd8deadSopenharmony_ci texels which belong to the HDR partition will result in the error color. 20405bd8deadSopenharmony_ci Texels belonging to a LDR partition will be decoded as normal. 20415bd8deadSopenharmony_ci 20425bd8deadSopenharmony_ci C.2.25 LDR PROFILE SUPPORT 20435bd8deadSopenharmony_ci --------------------------- 20445bd8deadSopenharmony_ci 20455bd8deadSopenharmony_ci Implementations of the LDR Profile must satisfy the following requirements: 20465bd8deadSopenharmony_ci 20475bd8deadSopenharmony_ci * All textures with valid encodings for LDR Profile must decode 20485bd8deadSopenharmony_ci identically using either a LDR Profile, HDR Profile, or Full Profile 20495bd8deadSopenharmony_ci decoder. 20505bd8deadSopenharmony_ci * All features included only in the HDR Profile or Full Profile must be 20515bd8deadSopenharmony_ci treated as reserved in the LDR Profile, and return the error color on 20525bd8deadSopenharmony_ci decoding. 20535bd8deadSopenharmony_ci * Any sequence of API calls valid for the LDR Profile must also be valid 20545bd8deadSopenharmony_ci for the HDR Profile or Full Profile and return identical results when 20555bd8deadSopenharmony_ci given a texture encoded for the LDR Profile. 20565bd8deadSopenharmony_ci 20575bd8deadSopenharmony_ci The feature subset for the LDR profile is: 20585bd8deadSopenharmony_ci 20595bd8deadSopenharmony_ci * 2D textures only, including 2D, 2D array, cube map face, 20605bd8deadSopenharmony_ci and cube map array texture targets. 20615bd8deadSopenharmony_ci * Only those block sizes listed in Table C.2.2 are supported. 20625bd8deadSopenharmony_ci * LDR operation mode only. 20635bd8deadSopenharmony_ci * Only LDR endpoint formats must be supported, namely formats 20645bd8deadSopenharmony_ci 0, 1, 4, 5, 6, 8, 9, 10, 12, 13. 20655bd8deadSopenharmony_ci * Decoding from a HDR endpoint results in the error color. 20665bd8deadSopenharmony_ci * Interpolation returns UNORM8 results when used in conjunction 20675bd8deadSopenharmony_ci with sRGB. 20685bd8deadSopenharmony_ci * LDR void extent blocks must be supported, but void extents 20695bd8deadSopenharmony_ci may not be checked." 20705bd8deadSopenharmony_ci 20715bd8deadSopenharmony_ci If only the LDR profile is supported, read this extension by striking 20725bd8deadSopenharmony_ci all descriptions of HDR modes and decoding algorithms. The extension 20735bd8deadSopenharmony_ci documents how to modify the document for some particularly tricky cases, 20745bd8deadSopenharmony_ci but the general rule is as described in this paragraph. 20755bd8deadSopenharmony_ci 20765bd8deadSopenharmony_ciInteractions with immutable-format texture images 20775bd8deadSopenharmony_ci 20785bd8deadSopenharmony_ci ASTC texture formats are supported by immutable-format textures only if 20795bd8deadSopenharmony_ci such textures are supported by the underlying implementation (e.g. 20805bd8deadSopenharmony_ci OpenGL 4.1 or later, OpenGL ES 3.0 or later, or earlier versions 20815bd8deadSopenharmony_ci supporting the GL_EXT_texture_storage extension). Otherwise, remove all 20825bd8deadSopenharmony_ci references to the Tex*Storage* commands from this specification. 20835bd8deadSopenharmony_ci 20845bd8deadSopenharmony_ciInteractions with texture cube map arrays 20855bd8deadSopenharmony_ci 20865bd8deadSopenharmony_ci ASTC textures are supported for the TEXTURE_CUBE_MAP_ARRAY target only 20875bd8deadSopenharmony_ci when cube map arrays are supported by the underlying implementation 20885bd8deadSopenharmony_ci (e.g. OpenGL 4.0 or later, or an OpenGL or OpenGL ES version supporting 20895bd8deadSopenharmony_ci an extension defining cube map arrays). Otherwise, remove all references 20905bd8deadSopenharmony_ci to texture cube map arrays from this specification. 20915bd8deadSopenharmony_ci 20925bd8deadSopenharmony_ciInteractions with OpenGL (all versions) 20935bd8deadSopenharmony_ci 20945bd8deadSopenharmony_ci ASTC is not supported for 1D textures and texture rectangles, and does 20955bd8deadSopenharmony_ci not support non-zero borders. 20965bd8deadSopenharmony_ci 20975bd8deadSopenharmony_ci Add the following error conditions to CompressedTexImage*D: 20985bd8deadSopenharmony_ci 20995bd8deadSopenharmony_ci "An INVALID_ENUM error is generated by CompressedTexImage1D if 21005bd8deadSopenharmony_ci <internalformat> is one of the ASTC formats. 21015bd8deadSopenharmony_ci 21025bd8deadSopenharmony_ci An INVALID_OPERATION error is generated by CompressedTexImage2D 21035bd8deadSopenharmony_ci and CompressedTexImage3D if <internalformat> is one of the ASTC 21045bd8deadSopenharmony_ci formats and <border> is non-zero." 21055bd8deadSopenharmony_ci 21065bd8deadSopenharmony_ci Add the following error conditions to CompressedTexSubImage*D: 21075bd8deadSopenharmony_ci 21085bd8deadSopenharmony_ci "An INVALID_ENUM error is generated by CompressedTex*SubImage1D 21095bd8deadSopenharmony_ci if the internal format of the texture is one of the ASTC formats. 21105bd8deadSopenharmony_ci 21115bd8deadSopenharmony_ci An INVALID_OPERATION error is generated by CompressedTex*SubImage2D 21125bd8deadSopenharmony_ci if the internal format of the texture is one of the ASTC formats 21135bd8deadSopenharmony_ci and <border> is non-zero." 21145bd8deadSopenharmony_ci 21155bd8deadSopenharmony_ci Add the following error conditions to TexStorage1D and TextureStorage1D: 21165bd8deadSopenharmony_ci 21175bd8deadSopenharmony_ci "An INVALID_ENUM error is generated by TexStorage1D and TextureStorage1D 21185bd8deadSopenharmony_ci if <format> is one of the ASTC formats." 21195bd8deadSopenharmony_ci 21205bd8deadSopenharmony_ci Add the following error conditions to TexStorage2D and TextureStorage2D 21215bd8deadSopenharmony_ci for versions of OpenGL that support texture rectangles: 21225bd8deadSopenharmony_ci 21235bd8deadSopenharmony_ci "An INVALID_OPERATON error is generated by TexStorage2D and 21245bd8deadSopenharmony_ci TextureStorage2D if <format> is one of the ASTC formats and <target> 21255bd8deadSopenharmony_ci is TEXTURE_RECTANGLE. 21265bd8deadSopenharmony_ci 21275bd8deadSopenharmony_ciInteractions with OpenGL 4.2 21285bd8deadSopenharmony_ci 21295bd8deadSopenharmony_ci OpenGL 4.2 supports the feature that compressed textures can be 21305bd8deadSopenharmony_ci compressed online, by passing the compressed texture format enum as 21315bd8deadSopenharmony_ci the internal format when uploading a texture using TexImage1D, 21325bd8deadSopenharmony_ci TexImage2D or TexImage3D (see Section 3.9.3, Texture Image 21335bd8deadSopenharmony_ci Specification, subsection Encoding of Special Internal Formats). 21345bd8deadSopenharmony_ci 21355bd8deadSopenharmony_ci Due to the complexity of the ASTC compression algorithm, it is not 21365bd8deadSopenharmony_ci usually suitable for online use, and therefore ASTC support will be 21375bd8deadSopenharmony_ci limited to pre-compressed textures only. Where on-device compression 21385bd8deadSopenharmony_ci is required, a domain-specific limited compressor will typically 21395bd8deadSopenharmony_ci be used, and this is therefore not suitable for implementation in 21405bd8deadSopenharmony_ci the driver. 21415bd8deadSopenharmony_ci 21425bd8deadSopenharmony_ci In particular, the ASTC format specifiers will not be added to 21435bd8deadSopenharmony_ci Table 3.14, and thus will not be accepted by the TexImage*D 21445bd8deadSopenharmony_ci functions, and will not be returned by the (already deprecated) 21455bd8deadSopenharmony_ci COMPRESSED_TEXTURE_FORMATS query. 21465bd8deadSopenharmony_ci 21475bd8deadSopenharmony_ciIssues 21485bd8deadSopenharmony_ci 21495bd8deadSopenharmony_ci 1) Three-dimensional block ASTC formats (e.g. formats whose block depth 21505bd8deadSopenharmony_ci is greater than one) are not supported by these extensions. 21515bd8deadSopenharmony_ci 21525bd8deadSopenharmony_ci 2) The first release of the extension was not clear about the 21535bd8deadSopenharmony_ci restrictions of the LDR profile and did not document interactions 21545bd8deadSopenharmony_ci with cube map array textures. 21555bd8deadSopenharmony_ci 21565bd8deadSopenharmony_ci RESOLVED. This extension has been rewritten to be based on OpenGL ES 21575bd8deadSopenharmony_ci 3.1, to clearly document LDR restrictions, and to add cube map array 21585bd8deadSopenharmony_ci texture interactions. 21595bd8deadSopenharmony_ci 21605bd8deadSopenharmony_ciRevision History 21615bd8deadSopenharmony_ci 21625bd8deadSopenharmony_ci Revision 8, June 8, 2017 - Added missing interactions with OpenGL. 21635bd8deadSopenharmony_ci 21645bd8deadSopenharmony_ci Revision 7, July 14, 2016 - Clarified definition of 2D void-extent 21655bd8deadSopenharmony_ci blocks. 21665bd8deadSopenharmony_ci 21675bd8deadSopenharmony_ci Revision 6, March 8, 2016 - Clarified that sRGB transform is not 21685bd8deadSopenharmony_ci applied to Alpha channel. 21695bd8deadSopenharmony_ci 21705bd8deadSopenharmony_ci Revision 5, September 15, 2015 - fix typo in third paragraph of section 21715bd8deadSopenharmony_ci 8.7. 21725bd8deadSopenharmony_ci 21735bd8deadSopenharmony_ci Revision 4, June 24, 2015 - minor cleanup from feedback. Move Issues and 21745bd8deadSopenharmony_ci Interactions sections to the end of the document. Merge some language 21755bd8deadSopenharmony_ci from OpenGL ES specification edits and rename some tables to figures, 21765bd8deadSopenharmony_ci due to how they're generated in the core specifications. Include a 21775bd8deadSopenharmony_ci description of the "Cube Map Array Texture" column added to table 3.19 21785bd8deadSopenharmony_ci and expand the description of how to read this document when supporting 21795bd8deadSopenharmony_ci only the LDR profile (Bug 13921). 21805bd8deadSopenharmony_ci 21815bd8deadSopenharmony_ci Revision 3, May 28, 2015 - rebase extension on OpenGL ES 3.1. Clarify 21825bd8deadSopenharmony_ci texture formats and targets supported by LDR and HDR profiles. Add cube 21835bd8deadSopenharmony_ci map array targets and an Interactions section defining when they are 21845bd8deadSopenharmony_ci supported. Add an Interactions section for immutable-format textures 21855bd8deadSopenharmony_ci (Bug 13921). 21865bd8deadSopenharmony_ci 21875bd8deadSopenharmony_ci Revision 2, April 28, 2015 - added CompressedTex{Sub,}Image3D to 21885bd8deadSopenharmony_ci commands accepting ASTC format tokens in the New Tokens section (Bug 21895bd8deadSopenharmony_ci 10183). 2190