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