Home | History | Annotate | Line # | Download | only in vulkan
      1 
      2 /*
      3  * Copyright  2016 Red Hat.
      4  * Copyright  2016 Bas Nieuwenhuizen
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the next
     14  * paragraph) shall be included in all copies or substantial portions of the
     15  * Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     23  * DEALINGS IN THE SOFTWARE.
     24  */
     25 
     26 #include "tu_private.h"
     27 
     28 #include "registers/adreno_common.xml.h"
     29 #include "registers/a6xx.xml.h"
     30 
     31 #include "util/format_r11g11b10f.h"
     32 #include "util/format_srgb.h"
     33 #include "util/u_half.h"
     34 #include "vk_format.h"
     35 #include "vk_util.h"
     36 
     37 /**
     38  * Declare a format table.  A format table is an array of tu_native_format.
     39  * It can map a consecutive range of VkFormat to the corresponding
     40  * tu_native_format.
     41  *
     42  * TU_FORMAT_TABLE_FIRST and TU_FORMAT_TABLE_LAST must already be defined and
     43  * have the values of the first and last VkFormat of the array respectively.
     44  */
     45 #define TU_FORMAT_TABLE(var)                                                 \
     46    static const VkFormat var##_first = TU_FORMAT_TABLE_FIRST;                \
     47    static const VkFormat var##_last = TU_FORMAT_TABLE_LAST;                  \
     48    static const struct tu_native_format var[TU_FORMAT_TABLE_LAST - TU_FORMAT_TABLE_FIRST + 1]
     49 #undef TU_FORMAT_TABLE_FIRST
     50 #undef TU_FORMAT_TABLE_LAST
     51 
     52 #define VFMT6_x -1
     53 #define TFMT6_x -1
     54 #define RB6_x -1
     55 
     56 #define TU6_FMT(vkfmt, vtxfmt, texfmt, rbfmt, swapfmt, valid)                \
     57    [VK_FORMAT_##vkfmt - TU_FORMAT_TABLE_FIRST] = {                           \
     58       .vtx = VFMT6_##vtxfmt,                                                 \
     59       .tex = TFMT6_##texfmt,                                                 \
     60       .rb = RB6_##rbfmt,                                                     \
     61       .swap = swapfmt,                                                       \
     62       .present = valid,                                                      \
     63    }
     64 
     65 /**
     66  * fmt/alias/swap are derived from VkFormat mechanically (and might not even
     67  * exist).  It is the macro of choice that decides whether a VkFormat is
     68  * supported and how.
     69  */
     70 #define TU6_VTC(vk, fmt, alias, swap) TU6_FMT(vk, fmt, fmt, alias, swap, true)
     71 #define TU6_xTC(vk, fmt, alias, swap) TU6_FMT(vk, x, fmt, alias, swap, true)
     72 #define TU6_VTx(vk, fmt, alias, swap) TU6_FMT(vk, fmt, fmt, x, swap, true)
     73 #define TU6_Vxx(vk, fmt, alias, swap) TU6_FMT(vk, fmt, x, x, swap, true)
     74 #define TU6_xTx(vk, fmt, alias, swap) TU6_FMT(vk, x, fmt, x, swap, true)
     75 #define TU6_xxx(vk, fmt, alias, swap) TU6_FMT(vk, x, x, x, WZYX, false)
     76 
     77 #define TU_FORMAT_TABLE_FIRST VK_FORMAT_UNDEFINED
     78 #define TU_FORMAT_TABLE_LAST VK_FORMAT_ASTC_12x12_SRGB_BLOCK
     79 TU_FORMAT_TABLE(tu6_format_table0) = {
     80    TU6_xxx(UNDEFINED,                  x,                 x,                  x),    /* 0 */
     81 
     82    /* 8-bit packed */
     83    TU6_xxx(R4G4_UNORM_PACK8,           4_4_UNORM,         R4G4_UNORM,         WZXY), /* 1 */
     84 
     85    /* 16-bit packed */
     86    TU6_xTC(R4G4B4A4_UNORM_PACK16,      4_4_4_4_UNORM,     R4G4B4A4_UNORM,     XYZW), /* 2 */
     87    TU6_xTC(B4G4R4A4_UNORM_PACK16,      4_4_4_4_UNORM,     R4G4B4A4_UNORM,     ZYXW), /* 3 */
     88    TU6_xTC(R5G6B5_UNORM_PACK16,        5_6_5_UNORM,       R5G6B5_UNORM,       WXYZ), /* 4 */
     89    TU6_xTC(B5G6R5_UNORM_PACK16,        5_6_5_UNORM,       R5G6B5_UNORM,       WXYZ), /* 5 */
     90    TU6_xxx(R5G5B5A1_UNORM_PACK16,      1_5_5_5_UNORM,     A1R5G5B5_UNORM,     XYZW), /* 6 */
     91    TU6_xxx(B5G5R5A1_UNORM_PACK16,      1_5_5_5_UNORM,     A1R5G5B5_UNORM,     XYZW), /* 7 */
     92    TU6_xTC(A1R5G5B5_UNORM_PACK16,      5_5_5_1_UNORM,     R5G5B5A1_UNORM,     WXYZ), /* 8 */
     93 
     94    /* 8-bit R */
     95    TU6_VTC(R8_UNORM,                   8_UNORM,           R8_UNORM,           WZYX), /* 9 */
     96    TU6_VTC(R8_SNORM,                   8_SNORM,           R8_SNORM,           WZYX), /* 10 */
     97    TU6_Vxx(R8_USCALED,                 8_UINT,            R8_UINT,            WZYX), /* 11 */
     98    TU6_Vxx(R8_SSCALED,                 8_SINT,            R8_SINT,            WZYX), /* 12 */
     99    TU6_VTC(R8_UINT,                    8_UINT,            R8_UINT,            WZYX), /* 13 */
    100    TU6_VTC(R8_SINT,                    8_SINT,            R8_SINT,            WZYX), /* 14 */
    101    TU6_xTC(R8_SRGB,                    8_UNORM,           R8_UNORM,           WZYX), /* 15 */
    102 
    103    /* 16-bit RG */
    104    TU6_VTC(R8G8_UNORM,                 8_8_UNORM,         R8G8_UNORM,         WZYX), /* 16 */
    105    TU6_VTC(R8G8_SNORM,                 8_8_SNORM,         R8G8_SNORM,         WZYX), /* 17 */
    106    TU6_Vxx(R8G8_USCALED,               8_8_UINT,          R8G8_UINT,          WZYX), /* 18 */
    107    TU6_Vxx(R8G8_SSCALED,               8_8_SINT,          R8G8_SINT,          WZYX), /* 19 */
    108    TU6_VTC(R8G8_UINT,                  8_8_UINT,          R8G8_UINT,          WZYX), /* 20 */
    109    TU6_VTC(R8G8_SINT,                  8_8_SINT,          R8G8_SINT,          WZYX), /* 21 */
    110    TU6_xTC(R8G8_SRGB,                  8_8_UNORM,         R8G8_UNORM,         WZYX), /* 22 */
    111 
    112    /* 24-bit RGB */
    113    TU6_Vxx(R8G8B8_UNORM,               8_8_8_UNORM,       R8G8B8_UNORM,       WZYX), /* 23 */
    114    TU6_Vxx(R8G8B8_SNORM,               8_8_8_SNORM,       R8G8B8_SNORM,       WZYX), /* 24 */
    115    TU6_Vxx(R8G8B8_USCALED,             8_8_8_UINT,        R8G8B8_UINT,        WZYX), /* 25 */
    116    TU6_Vxx(R8G8B8_SSCALED,             8_8_8_SINT,        R8G8B8_SINT,        WZYX), /* 26 */
    117    TU6_Vxx(R8G8B8_UINT,                8_8_8_UINT,        R8G8B8_UINT,        WZYX), /* 27 */
    118    TU6_Vxx(R8G8B8_SINT,                8_8_8_SINT,        R8G8B8_SINT,        WZYX), /* 28 */
    119    TU6_xxx(R8G8B8_SRGB,                8_8_8_UNORM,       R8G8B8_UNORM,       WZYX), /* 29 */
    120 
    121    /* 24-bit BGR */
    122    TU6_Vxx(B8G8R8_UNORM,               8_8_8_UNORM,       R8G8B8_UNORM,       WXYZ), /* 30 */
    123    TU6_Vxx(B8G8R8_SNORM,               8_8_8_SNORM,       R8G8B8_SNORM,       WXYZ), /* 31 */
    124    TU6_Vxx(B8G8R8_USCALED,             8_8_8_UINT,        R8G8B8_UINT,        WXYZ), /* 32 */
    125    TU6_Vxx(B8G8R8_SSCALED,             8_8_8_SINT,        R8G8B8_SINT,        WXYZ), /* 33 */
    126    TU6_Vxx(B8G8R8_UINT,                8_8_8_UINT,        R8G8B8_UINT,        WXYZ), /* 34 */
    127    TU6_Vxx(B8G8R8_SINT,                8_8_8_SINT,        R8G8B8_SINT,        WXYZ), /* 35 */
    128    TU6_xxx(B8G8R8_SRGB,                8_8_8_UNORM,       R8G8B8_UNORM,       WXYZ), /* 36 */
    129 
    130    /* 32-bit RGBA */
    131    TU6_VTC(R8G8B8A8_UNORM,             8_8_8_8_UNORM,     R8G8B8A8_UNORM,     WZYX), /* 37 */
    132    TU6_VTC(R8G8B8A8_SNORM,             8_8_8_8_SNORM,     R8G8B8A8_SNORM,     WZYX), /* 38 */
    133    TU6_Vxx(R8G8B8A8_USCALED,           8_8_8_8_UINT,      R8G8B8A8_UINT,      WZYX), /* 39 */
    134    TU6_Vxx(R8G8B8A8_SSCALED,           8_8_8_8_SINT,      R8G8B8A8_SINT,      WZYX), /* 40 */
    135    TU6_VTC(R8G8B8A8_UINT,              8_8_8_8_UINT,      R8G8B8A8_UINT,      WZYX), /* 41 */
    136    TU6_VTC(R8G8B8A8_SINT,              8_8_8_8_SINT,      R8G8B8A8_SINT,      WZYX), /* 42 */
    137    TU6_xTC(R8G8B8A8_SRGB,              8_8_8_8_UNORM,     R8G8B8A8_UNORM,     WZYX), /* 43 */
    138 
    139    /* 32-bit BGRA */
    140    TU6_VTC(B8G8R8A8_UNORM,             8_8_8_8_UNORM,     R8G8B8A8_UNORM,     WXYZ), /* 44 */
    141    TU6_VTC(B8G8R8A8_SNORM,             8_8_8_8_SNORM,     R8G8B8A8_SNORM,     WXYZ), /* 45 */
    142    TU6_Vxx(B8G8R8A8_USCALED,           8_8_8_8_UINT,      R8G8B8A8_UINT,      WXYZ), /* 46 */
    143    TU6_Vxx(B8G8R8A8_SSCALED,           8_8_8_8_SINT,      R8G8B8A8_SINT,      WXYZ), /* 47 */
    144    TU6_VTC(B8G8R8A8_UINT,              8_8_8_8_UINT,      R8G8B8A8_UINT,      WXYZ), /* 48 */
    145    TU6_VTC(B8G8R8A8_SINT,              8_8_8_8_SINT,      R8G8B8A8_SINT,      WXYZ), /* 49 */
    146    TU6_xTC(B8G8R8A8_SRGB,              8_8_8_8_UNORM,     R8G8B8A8_UNORM,     WXYZ), /* 50 */
    147 
    148    /* 32-bit packed */
    149    TU6_VTC(A8B8G8R8_UNORM_PACK32,      8_8_8_8_UNORM,     R8G8B8A8_UNORM,     WZYX), /* 51 */
    150    TU6_VTC(A8B8G8R8_SNORM_PACK32,      8_8_8_8_SNORM,     R8G8B8A8_SNORM,     WZYX), /* 52 */
    151    TU6_Vxx(A8B8G8R8_USCALED_PACK32,    8_8_8_8_UINT,      R8G8B8A8_UINT,      WZYX), /* 53 */
    152    TU6_Vxx(A8B8G8R8_SSCALED_PACK32,    8_8_8_8_SINT,      R8G8B8A8_SINT,      WZYX), /* 54 */
    153    TU6_VTC(A8B8G8R8_UINT_PACK32,       8_8_8_8_UINT,      R8G8B8A8_UINT,      WZYX), /* 55 */
    154    TU6_VTC(A8B8G8R8_SINT_PACK32,       8_8_8_8_SINT,      R8G8B8A8_SINT,      WZYX), /* 56 */
    155    TU6_xTC(A8B8G8R8_SRGB_PACK32,       8_8_8_8_UNORM,     R8G8B8A8_UNORM,     WZYX), /* 57 */
    156    TU6_VTC(A2R10G10B10_UNORM_PACK32,   10_10_10_2_UNORM,  R10G10B10A2_UNORM,  WXYZ), /* 58 */
    157    TU6_Vxx(A2R10G10B10_SNORM_PACK32,   10_10_10_2_SNORM,  R10G10B10A2_SNORM,  WXYZ), /* 59 */
    158    TU6_Vxx(A2R10G10B10_USCALED_PACK32, 10_10_10_2_UINT,   R10G10B10A2_UINT,   WXYZ), /* 60 */
    159    TU6_Vxx(A2R10G10B10_SSCALED_PACK32, 10_10_10_2_SINT,   R10G10B10A2_SINT,   WXYZ), /* 61 */
    160    TU6_VTC(A2R10G10B10_UINT_PACK32,    10_10_10_2_UINT,   R10G10B10A2_UINT,   WXYZ), /* 62 */
    161    TU6_Vxx(A2R10G10B10_SINT_PACK32,    10_10_10_2_SINT,   R10G10B10A2_SINT,   WXYZ), /* 63 */
    162    TU6_VTC(A2B10G10R10_UNORM_PACK32,   10_10_10_2_UNORM,  R10G10B10A2_UNORM,  WZYX), /* 64 */
    163    TU6_Vxx(A2B10G10R10_SNORM_PACK32,   10_10_10_2_SNORM,  R10G10B10A2_SNORM,  WZYX), /* 65 */
    164    TU6_Vxx(A2B10G10R10_USCALED_PACK32, 10_10_10_2_UINT,   R10G10B10A2_UINT,   WZYX), /* 66 */
    165    TU6_Vxx(A2B10G10R10_SSCALED_PACK32, 10_10_10_2_SINT,   R10G10B10A2_SINT,   WZYX), /* 67 */
    166    TU6_VTC(A2B10G10R10_UINT_PACK32,    10_10_10_2_UINT,   R10G10B10A2_UINT,   WZYX), /* 68 */
    167    TU6_Vxx(A2B10G10R10_SINT_PACK32,    10_10_10_2_SINT,   R10G10B10A2_SINT,   WZYX), /* 69 */
    168 
    169    /* 16-bit R */
    170    TU6_VTC(R16_UNORM,                  16_UNORM,          R16_UNORM,          WZYX), /* 70 */
    171    TU6_VTC(R16_SNORM,                  16_SNORM,          R16_SNORM,          WZYX), /* 71 */
    172    TU6_Vxx(R16_USCALED,                16_UINT,           R16_UINT,           WZYX), /* 72 */
    173    TU6_Vxx(R16_SSCALED,                16_SINT,           R16_SINT,           WZYX), /* 73 */
    174    TU6_VTC(R16_UINT,                   16_UINT,           R16_UINT,           WZYX), /* 74 */
    175    TU6_VTC(R16_SINT,                   16_SINT,           R16_SINT,           WZYX), /* 75 */
    176    TU6_VTC(R16_SFLOAT,                 16_FLOAT,          R16_FLOAT,          WZYX), /* 76 */
    177 
    178    /* 32-bit RG */
    179    TU6_VTC(R16G16_UNORM,               16_16_UNORM,       R16G16_UNORM,       WZYX), /* 77 */
    180    TU6_VTC(R16G16_SNORM,               16_16_SNORM,       R16G16_SNORM,       WZYX), /* 78 */
    181    TU6_VTx(R16G16_USCALED,             16_16_UINT,        R16G16_UINT,        WZYX), /* 79 */
    182    TU6_VTx(R16G16_SSCALED,             16_16_SINT,        R16G16_SINT,        WZYX), /* 80 */
    183    TU6_VTC(R16G16_UINT,                16_16_UINT,        R16G16_UINT,        WZYX), /* 81 */
    184    TU6_VTC(R16G16_SINT,                16_16_SINT,        R16G16_SINT,        WZYX), /* 82 */
    185    TU6_VTC(R16G16_SFLOAT,              16_16_FLOAT,       R16G16_FLOAT,       WZYX), /* 83 */
    186 
    187    /* 48-bit RGB */
    188    TU6_Vxx(R16G16B16_UNORM,            16_16_16_UNORM,    R16G16B16_UNORM,    WZYX), /* 84 */
    189    TU6_Vxx(R16G16B16_SNORM,            16_16_16_SNORM,    R16G16B16_SNORM,    WZYX), /* 85 */
    190    TU6_Vxx(R16G16B16_USCALED,          16_16_16_UINT,     R16G16B16_UINT,     WZYX), /* 86 */
    191    TU6_Vxx(R16G16B16_SSCALED,          16_16_16_SINT,     R16G16B16_SINT,     WZYX), /* 87 */
    192    TU6_Vxx(R16G16B16_UINT,             16_16_16_UINT,     R16G16B16_UINT,     WZYX), /* 88 */
    193    TU6_Vxx(R16G16B16_SINT,             16_16_16_SINT,     R16G16B16_SINT,     WZYX), /* 89 */
    194    TU6_Vxx(R16G16B16_SFLOAT,           16_16_16_FLOAT,    R16G16B16_FLOAT,    WZYX), /* 90 */
    195 
    196    /* 64-bit RGBA */
    197    TU6_VTC(R16G16B16A16_UNORM,         16_16_16_16_UNORM, R16G16B16A16_UNORM, WZYX), /* 91 */
    198    TU6_VTC(R16G16B16A16_SNORM,         16_16_16_16_SNORM, R16G16B16A16_SNORM, WZYX), /* 92 */
    199    TU6_VTx(R16G16B16A16_USCALED,       16_16_16_16_UINT,  R16G16B16A16_UINT,  WZYX), /* 93 */
    200    TU6_VTx(R16G16B16A16_SSCALED,       16_16_16_16_SINT,  R16G16B16A16_SINT,  WZYX), /* 94 */
    201    TU6_VTC(R16G16B16A16_UINT,          16_16_16_16_UINT,  R16G16B16A16_UINT,  WZYX), /* 95 */
    202    TU6_VTC(R16G16B16A16_SINT,          16_16_16_16_SINT,  R16G16B16A16_SINT,  WZYX), /* 96 */
    203    TU6_VTC(R16G16B16A16_SFLOAT,        16_16_16_16_FLOAT, R16G16B16A16_FLOAT, WZYX), /* 97 */
    204 
    205    /* 32-bit R */
    206    TU6_VTC(R32_UINT,                   32_UINT,           R32_UINT,           WZYX), /* 98 */
    207    TU6_VTC(R32_SINT,                   32_SINT,           R32_SINT,           WZYX), /* 99 */
    208    TU6_VTC(R32_SFLOAT,                 32_FLOAT,          R32_FLOAT,          WZYX), /* 100 */
    209 
    210    /* 64-bit RG */
    211    TU6_VTC(R32G32_UINT,                32_32_UINT,        R32G32_UINT,        WZYX), /* 101 */
    212    TU6_VTC(R32G32_SINT,                32_32_SINT,        R32G32_SINT,        WZYX), /* 102 */
    213    TU6_VTC(R32G32_SFLOAT,              32_32_FLOAT,       R32G32_FLOAT,       WZYX), /* 103 */
    214 
    215    /* 96-bit RGB */
    216    TU6_VTx(R32G32B32_UINT,             32_32_32_UINT,     R32G32B32_UINT,     WZYX), /* 104 */
    217    TU6_VTx(R32G32B32_SINT,             32_32_32_SINT,     R32G32B32_SINT,     WZYX), /* 105 */
    218    TU6_VTx(R32G32B32_SFLOAT,           32_32_32_FLOAT,    R32G32B32_FLOAT,    WZYX), /* 106 */
    219 
    220    /* 128-bit RGBA */
    221    TU6_VTC(R32G32B32A32_UINT,          32_32_32_32_UINT,  R32G32B32A32_UINT,  WZYX), /* 107 */
    222    TU6_VTC(R32G32B32A32_SINT,          32_32_32_32_SINT,  R32G32B32A32_SINT,  WZYX), /* 108 */
    223    TU6_VTC(R32G32B32A32_SFLOAT,        32_32_32_32_FLOAT, R32G32B32A32_FLOAT, WZYX), /* 109 */
    224 
    225    /* 64-bit R */
    226    TU6_xxx(R64_UINT,                   64_UINT,           R64_UINT,           WZYX), /* 110 */
    227    TU6_xxx(R64_SINT,                   64_SINT,           R64_SINT,           WZYX), /* 111 */
    228    TU6_xxx(R64_SFLOAT,                 64_FLOAT,          R64_FLOAT,          WZYX), /* 112 */
    229 
    230    /* 128-bit RG */
    231    TU6_xxx(R64G64_UINT,                64_64_UINT,        R64G64_UINT,        WZYX), /* 113 */
    232    TU6_xxx(R64G64_SINT,                64_64_SINT,        R64G64_SINT,        WZYX), /* 114 */
    233    TU6_xxx(R64G64_SFLOAT,              64_64_FLOAT,       R64G64_FLOAT,       WZYX), /* 115 */
    234 
    235    /* 192-bit RGB */
    236    TU6_xxx(R64G64B64_UINT,             64_64_64_UINT,     R64G64B64_UINT,     WZYX), /* 116 */
    237    TU6_xxx(R64G64B64_SINT,             64_64_64_SINT,     R64G64B64_SINT,     WZYX), /* 117 */
    238    TU6_xxx(R64G64B64_SFLOAT,           64_64_64_FLOAT,    R64G64B64_FLOAT,    WZYX), /* 118 */
    239 
    240    /* 256-bit RGBA */
    241    TU6_xxx(R64G64B64A64_UINT,          64_64_64_64_UINT,  R64G64B64A64_UINT,  WZYX), /* 119 */
    242    TU6_xxx(R64G64B64A64_SINT,          64_64_64_64_SINT,  R64G64B64A64_SINT,  WZYX), /* 120 */
    243    TU6_xxx(R64G64B64A64_SFLOAT,        64_64_64_64_FLOAT, R64G64B64A64_FLOAT, WZYX), /* 121 */
    244 
    245    /* 32-bit packed float */
    246    TU6_VTC(B10G11R11_UFLOAT_PACK32,    11_11_10_FLOAT,    R11G11B10_FLOAT,    WZYX), /* 122 */
    247    TU6_xTx(E5B9G9R9_UFLOAT_PACK32,     9_9_9_E5_FLOAT,    R9G9B9E5_FLOAT,     WZYX), /* 123 */
    248 
    249    /* depth/stencil */
    250    TU6_xTC(D16_UNORM,                  16_UNORM,          R16_UNORM,          WZYX), /* 124 */
    251    TU6_xTC(X8_D24_UNORM_PACK32,        X8Z24_UNORM,       X8Z24_UNORM,        WZYX), /* 125 */
    252    TU6_xTC(D32_SFLOAT,                 32_FLOAT,          R32_FLOAT,          WZYX), /* 126 */
    253    TU6_xTC(S8_UINT,                    8_UINT,            R8_UNORM,           WZYX), /* 127 */
    254    TU6_xxx(D16_UNORM_S8_UINT,          X8Z16_UNORM,       X8Z16_UNORM,        WZYX), /* 128 */
    255    TU6_xTC(D24_UNORM_S8_UINT,          X8Z24_UNORM,       X8Z24_UNORM,        WZYX), /* 129 */
    256    TU6_xTC(D32_SFLOAT_S8_UINT,         32_FLOAT,          R32_FLOAT,          WZYX), /* 130 */
    257 
    258    /* compressed */
    259    TU6_xTx(BC1_RGB_UNORM_BLOCK,        DXT1,              DXT1,               WZYX), /* 131 */
    260    TU6_xTx(BC1_RGB_SRGB_BLOCK,         DXT1,              DXT1,               WZYX), /* 132 */
    261    TU6_xTx(BC1_RGBA_UNORM_BLOCK,       DXT1,              DXT1,               WZYX), /* 133 */
    262    TU6_xTx(BC1_RGBA_SRGB_BLOCK,        DXT1,              DXT1,               WZYX), /* 134 */
    263    TU6_xTx(BC2_UNORM_BLOCK,            DXT3,              DXT3,               WZYX), /* 135 */
    264    TU6_xTx(BC2_SRGB_BLOCK,             DXT3,              DXT3,               WZYX), /* 136 */
    265    TU6_xTx(BC3_UNORM_BLOCK,            DXT5,              DXT5,               WZYX), /* 137 */
    266    TU6_xTx(BC3_SRGB_BLOCK,             DXT5,              DXT5,               WZYX), /* 138 */
    267    TU6_xTx(BC4_UNORM_BLOCK,            RGTC1_UNORM,       RGTC1_UNORM,        WZYX), /* 139 */
    268    TU6_xTx(BC4_SNORM_BLOCK,            RGTC1_SNORM,       RGTC1_SNORM,        WZYX), /* 140 */
    269    TU6_xTx(BC5_UNORM_BLOCK,            RGTC2_UNORM,       RGTC2_UNORM,        WZYX), /* 141 */
    270    TU6_xTx(BC5_SNORM_BLOCK,            RGTC2_SNORM,       RGTC2_SNORM,        WZYX), /* 142 */
    271    TU6_xTx(BC6H_UFLOAT_BLOCK,          BPTC_UFLOAT,       BPTC_UFLOAT,        WZYX), /* 143 */
    272    TU6_xTx(BC6H_SFLOAT_BLOCK,          BPTC_FLOAT,        BPTC_FLOAT,         WZYX), /* 144 */
    273    TU6_xTx(BC7_UNORM_BLOCK,            BPTC,              BPTC,               WZYX), /* 145 */
    274    TU6_xTx(BC7_SRGB_BLOCK,             BPTC,              BPTC,               WZYX), /* 146 */
    275    TU6_xTx(ETC2_R8G8B8_UNORM_BLOCK,    ETC2_RGB8,         ETC2_RGB8,          WZYX), /* 147 */
    276    TU6_xTx(ETC2_R8G8B8_SRGB_BLOCK,     ETC2_RGB8,         ETC2_RGB8,          WZYX), /* 148 */
    277    TU6_xTx(ETC2_R8G8B8A1_UNORM_BLOCK,  ETC2_RGB8A1,       ETC2_RGB8A1,        WZYX), /* 149 */
    278    TU6_xTx(ETC2_R8G8B8A1_SRGB_BLOCK,   ETC2_RGB8A1,       ETC2_RGB8A1,        WZYX), /* 150 */
    279    TU6_xTx(ETC2_R8G8B8A8_UNORM_BLOCK,  ETC2_RGBA8,        ETC2_RGBA8,         WZYX), /* 151 */
    280    TU6_xTx(ETC2_R8G8B8A8_SRGB_BLOCK,   ETC2_RGBA8,        ETC2_RGBA8,         WZYX), /* 152 */
    281    TU6_xTx(EAC_R11_UNORM_BLOCK,        ETC2_R11_UNORM,    ETC2_R11_UNORM,     WZYX), /* 153 */
    282    TU6_xTx(EAC_R11_SNORM_BLOCK,        ETC2_R11_SNORM,    ETC2_R11_SNORM,     WZYX), /* 154 */
    283    TU6_xTx(EAC_R11G11_UNORM_BLOCK,     ETC2_RG11_UNORM,   ETC2_RG11_UNORM,    WZYX), /* 155 */
    284    TU6_xTx(EAC_R11G11_SNORM_BLOCK,     ETC2_RG11_SNORM,   ETC2_RG11_SNORM,    WZYX), /* 156 */
    285    TU6_xTx(ASTC_4x4_UNORM_BLOCK,       ASTC_4x4,          ASTC_4x4,           WZYX), /* 157 */
    286    TU6_xTx(ASTC_4x4_SRGB_BLOCK,        ASTC_4x4,          ASTC_4x4,           WZYX), /* 158 */
    287    TU6_xTx(ASTC_5x4_UNORM_BLOCK,       ASTC_5x4,          ASTC_5x4,           WZYX), /* 159 */
    288    TU6_xTx(ASTC_5x4_SRGB_BLOCK,        ASTC_5x4,          ASTC_5x4,           WZYX), /* 160 */
    289    TU6_xTx(ASTC_5x5_UNORM_BLOCK,       ASTC_5x5,          ASTC_5x5,           WZYX), /* 161 */
    290    TU6_xTx(ASTC_5x5_SRGB_BLOCK,        ASTC_5x5,          ASTC_5x5,           WZYX), /* 162 */
    291    TU6_xTx(ASTC_6x5_UNORM_BLOCK,       ASTC_6x5,          ASTC_6x5,           WZYX), /* 163 */
    292    TU6_xTx(ASTC_6x5_SRGB_BLOCK,        ASTC_6x5,          ASTC_6x5,           WZYX), /* 164 */
    293    TU6_xTx(ASTC_6x6_UNORM_BLOCK,       ASTC_6x6,          ASTC_6x6,           WZYX), /* 165 */
    294    TU6_xTx(ASTC_6x6_SRGB_BLOCK,        ASTC_6x6,          ASTC_6x6,           WZYX), /* 166 */
    295    TU6_xTx(ASTC_8x5_UNORM_BLOCK,       ASTC_8x5,          ASTC_8x5,           WZYX), /* 167 */
    296    TU6_xTx(ASTC_8x5_SRGB_BLOCK,        ASTC_8x5,          ASTC_8x5,           WZYX), /* 168 */
    297    TU6_xTx(ASTC_8x6_UNORM_BLOCK,       ASTC_8x6,          ASTC_8x6,           WZYX), /* 169 */
    298    TU6_xTx(ASTC_8x6_SRGB_BLOCK,        ASTC_8x6,          ASTC_8x6,           WZYX), /* 170 */
    299    TU6_xTx(ASTC_8x8_UNORM_BLOCK,       ASTC_8x8,          ASTC_8x8,           WZYX), /* 171 */
    300    TU6_xTx(ASTC_8x8_SRGB_BLOCK,        ASTC_8x8,          ASTC_8x8,           WZYX), /* 172 */
    301    TU6_xTx(ASTC_10x5_UNORM_BLOCK,      ASTC_10x5,         ASTC_10x5,          WZYX), /* 173 */
    302    TU6_xTx(ASTC_10x5_SRGB_BLOCK,       ASTC_10x5,         ASTC_10x5,          WZYX), /* 174 */
    303    TU6_xTx(ASTC_10x6_UNORM_BLOCK,      ASTC_10x6,         ASTC_10x6,          WZYX), /* 175 */
    304    TU6_xTx(ASTC_10x6_SRGB_BLOCK,       ASTC_10x6,         ASTC_10x6,          WZYX), /* 176 */
    305    TU6_xTx(ASTC_10x8_UNORM_BLOCK,      ASTC_10x8,         ASTC_10x8,          WZYX), /* 177 */
    306    TU6_xTx(ASTC_10x8_SRGB_BLOCK,       ASTC_10x8,         ASTC_10x8,          WZYX), /* 178 */
    307    TU6_xTx(ASTC_10x10_UNORM_BLOCK,     ASTC_10x10,        ASTC_10x10,         WZYX), /* 179 */
    308    TU6_xTx(ASTC_10x10_SRGB_BLOCK,      ASTC_10x10,        ASTC_10x10,         WZYX), /* 180 */
    309    TU6_xTx(ASTC_12x10_UNORM_BLOCK,     ASTC_12x10,        ASTC_12x10,         WZYX), /* 181 */
    310    TU6_xTx(ASTC_12x10_SRGB_BLOCK,      ASTC_12x10,        ASTC_12x10,         WZYX), /* 182 */
    311    TU6_xTx(ASTC_12x12_UNORM_BLOCK,     ASTC_12x12,        ASTC_12x12,         WZYX), /* 183 */
    312    TU6_xTx(ASTC_12x12_SRGB_BLOCK,      ASTC_12x12,        ASTC_12x12,         WZYX), /* 184 */
    313 };
    314 #undef TU_FORMAT_TABLE_FIRST
    315 #undef TU_FORMAT_TABLE_LAST
    316 
    317 const struct tu_native_format *
    318 tu6_get_native_format(VkFormat format)
    319 {
    320    const struct tu_native_format *fmt = NULL;
    321 
    322    if (format >= tu6_format_table0_first && format <= tu6_format_table0_last)
    323       fmt = &tu6_format_table0[format - tu6_format_table0_first];
    324 
    325    return (fmt && fmt->present) ? fmt : NULL;
    326 }
    327 
    328 enum a6xx_2d_ifmt
    329 tu6_rb_fmt_to_ifmt(enum a6xx_color_fmt fmt)
    330 {
    331    switch (fmt) {
    332    case RB6_A8_UNORM:
    333    case RB6_R8_UNORM:
    334    case RB6_R8_SNORM:
    335    case RB6_R8G8_UNORM:
    336    case RB6_R8G8_SNORM:
    337    case RB6_R8G8B8A8_UNORM:
    338    case RB6_R8G8B8_UNORM:
    339    case RB6_R8G8B8A8_SNORM:
    340       return R2D_UNORM8;
    341 
    342    case RB6_R32_UINT:
    343    case RB6_R32_SINT:
    344    case RB6_R32G32_UINT:
    345    case RB6_R32G32_SINT:
    346    case RB6_R32G32B32A32_UINT:
    347    case RB6_R32G32B32A32_SINT:
    348       return R2D_INT32;
    349 
    350    case RB6_R16_UINT:
    351    case RB6_R16_SINT:
    352    case RB6_R16G16_UINT:
    353    case RB6_R16G16_SINT:
    354    case RB6_R16G16B16A16_UINT:
    355    case RB6_R16G16B16A16_SINT:
    356       return R2D_INT16;
    357 
    358    case RB6_R8_UINT:
    359    case RB6_R8_SINT:
    360    case RB6_R8G8_UINT:
    361    case RB6_R8G8_SINT:
    362    case RB6_R8G8B8A8_UINT:
    363    case RB6_R8G8B8A8_SINT:
    364       return R2D_INT8;
    365 
    366    case RB6_R16_UNORM:
    367    case RB6_R16_SNORM:
    368    case RB6_R16G16_UNORM:
    369    case RB6_R16G16_SNORM:
    370    case RB6_R16G16B16A16_UNORM:
    371    case RB6_R16G16B16A16_SNORM:
    372    case RB6_R32_FLOAT:
    373    case RB6_R32G32_FLOAT:
    374    case RB6_R32G32B32A32_FLOAT:
    375       return R2D_FLOAT32;
    376 
    377    case RB6_R16_FLOAT:
    378    case RB6_R16G16_FLOAT:
    379    case RB6_R16G16B16A16_FLOAT:
    380       return R2D_FLOAT16;
    381 
    382    case RB6_R4G4B4A4_UNORM:
    383    case RB6_R5G5B5A1_UNORM:
    384    case RB6_R5G6B5_UNORM:
    385    case RB6_R10G10B10A2_UNORM:
    386    case RB6_R10G10B10A2_UINT:
    387    case RB6_R11G11B10_FLOAT:
    388    case RB6_X8Z24_UNORM:
    389       // ???
    390       return 0;
    391    default:
    392       unreachable("bad format");
    393       return 0;
    394    }
    395 }
    396 
    397 static uint32_t
    398 tu_pack_mask(int bits)
    399 {
    400    assert(bits <= 32);
    401    return (1ull << bits) - 1;
    402 }
    403 
    404 static uint32_t
    405 tu_pack_float32_for_unorm(float val, int bits)
    406 {
    407    const uint32_t max = tu_pack_mask(bits);
    408    if (val < 0.0f)
    409       return 0;
    410    else if (val > 1.0f)
    411       return max;
    412    else
    413       return _mesa_lroundevenf(val * (float) max);
    414 }
    415 
    416 static uint32_t
    417 tu_pack_float32_for_snorm(float val, int bits)
    418 {
    419    const int32_t max = tu_pack_mask(bits - 1);
    420    int32_t tmp;
    421    if (val < -1.0f)
    422       tmp = -max;
    423    else if (val > 1.0f)
    424       tmp = max;
    425    else
    426       tmp = _mesa_lroundevenf(val * (float) max);
    427 
    428    return tmp & tu_pack_mask(bits);
    429 }
    430 
    431 static uint32_t
    432 tu_pack_float32_for_uscaled(float val, int bits)
    433 {
    434    const uint32_t max = tu_pack_mask(bits);
    435    if (val < 0.0f)
    436       return 0;
    437    else if (val > (float) max)
    438       return max;
    439    else
    440       return (uint32_t) val;
    441 }
    442 
    443 static uint32_t
    444 tu_pack_float32_for_sscaled(float val, int bits)
    445 {
    446    const int32_t max = tu_pack_mask(bits - 1);
    447    const int32_t min = -max - 1;
    448    int32_t tmp;
    449    if (val < (float) min)
    450       tmp = min;
    451    else if (val > (float) max)
    452       tmp = max;
    453    else
    454       tmp = (int32_t) val;
    455 
    456    return tmp & tu_pack_mask(bits);
    457 }
    458 
    459 static uint32_t
    460 tu_pack_uint32_for_uint(uint32_t val, int bits)
    461 {
    462    return val & tu_pack_mask(bits);
    463 }
    464 
    465 static uint32_t
    466 tu_pack_int32_for_sint(int32_t val, int bits)
    467 {
    468    return val & tu_pack_mask(bits);
    469 }
    470 
    471 static uint32_t
    472 tu_pack_float32_for_sfloat(float val, int bits)
    473 {
    474    assert(bits == 16 || bits == 32);
    475    return bits == 16 ? util_float_to_half(val) : fui(val);
    476 }
    477 
    478 union tu_clear_component_value {
    479    float float32;
    480    int32_t int32;
    481    uint32_t uint32;
    482 };
    483 
    484 static uint32_t
    485 tu_pack_clear_component_value(union tu_clear_component_value val,
    486                               const struct vk_format_channel_description *ch)
    487 {
    488    uint32_t packed;
    489 
    490    switch (ch->type) {
    491    case VK_FORMAT_TYPE_UNSIGNED:
    492       /* normalized, scaled, or pure integer */
    493       assert(ch->normalized + ch->scaled + ch->pure_integer == 1);
    494       if (ch->normalized)
    495          packed = tu_pack_float32_for_unorm(val.float32, ch->size);
    496       else if (ch->scaled)
    497          packed = tu_pack_float32_for_uscaled(val.float32, ch->size);
    498       else
    499          packed = tu_pack_uint32_for_uint(val.uint32, ch->size);
    500       break;
    501    case VK_FORMAT_TYPE_SIGNED:
    502       /* normalized, scaled, or pure integer */
    503       assert(ch->normalized + ch->scaled + ch->pure_integer == 1);
    504       if (ch->normalized)
    505          packed = tu_pack_float32_for_snorm(val.float32, ch->size);
    506       else if (ch->scaled)
    507          packed = tu_pack_float32_for_sscaled(val.float32, ch->size);
    508       else
    509          packed = tu_pack_int32_for_sint(val.int32, ch->size);
    510       break;
    511    case VK_FORMAT_TYPE_FLOAT:
    512       packed = tu_pack_float32_for_sfloat(val.float32, ch->size);
    513       break;
    514    default:
    515       unreachable("unexpected channel type");
    516       packed = 0;
    517       break;
    518    }
    519 
    520    assert((packed & tu_pack_mask(ch->size)) == packed);
    521    return packed;
    522 }
    523 
    524 static const struct vk_format_channel_description *
    525 tu_get_format_channel_description(const struct vk_format_description *desc,
    526                                   int comp)
    527 {
    528    switch (desc->swizzle[comp]) {
    529    case VK_SWIZZLE_X:
    530       return &desc->channel[0];
    531    case VK_SWIZZLE_Y:
    532       return &desc->channel[1];
    533    case VK_SWIZZLE_Z:
    534       return &desc->channel[2];
    535    case VK_SWIZZLE_W:
    536       return &desc->channel[3];
    537    default:
    538       return NULL;
    539    }
    540 }
    541 
    542 static union tu_clear_component_value
    543 tu_get_clear_component_value(const VkClearValue *val, int comp, bool color)
    544 {
    545    union tu_clear_component_value tmp;
    546    if (color) {
    547       assert(comp < 4);
    548       tmp.uint32 = val->color.uint32[comp];
    549    } else {
    550       assert(comp < 2);
    551       if (comp == 0)
    552          tmp.float32 = val->depthStencil.depth;
    553       else
    554          tmp.uint32 = val->depthStencil.stencil;
    555    }
    556 
    557    return tmp;
    558 }
    559 
    560 /**
    561  * Pack a VkClearValue into a 128-bit buffer.  \a format is respected except
    562  * for the component order.  The components are always packed in WZYX order
    563  * (i.e., msb is white and lsb is red).
    564  *
    565  * Return the number of uint32_t's used.
    566  */
    567 int
    568 tu_pack_clear_value(const VkClearValue *val, VkFormat format, uint32_t buf[4])
    569 {
    570    const struct vk_format_description *desc = vk_format_description(format);
    571    assert(desc && desc->layout == VK_FORMAT_LAYOUT_PLAIN);
    572 
    573    /* S8_UINT is special and has no depth */
    574    const int max_components =
    575       format == VK_FORMAT_S8_UINT ? 2 : desc->nr_channels;
    576 
    577    int buf_offset = 0;
    578    int bit_shift = 0;
    579    for (int comp = 0; comp < max_components; comp++) {
    580       const struct vk_format_channel_description *ch =
    581          tu_get_format_channel_description(desc, comp);
    582       if (!ch) {
    583          assert(format == VK_FORMAT_S8_UINT && comp == 0);
    584          continue;
    585       }
    586 
    587       union tu_clear_component_value v = tu_get_clear_component_value(
    588          val, comp, desc->colorspace != VK_FORMAT_COLORSPACE_ZS);
    589 
    590       /* move to the next uint32_t when there is not enough space */
    591       assert(ch->size <= 32);
    592       if (bit_shift + ch->size > 32) {
    593          buf_offset++;
    594          bit_shift = 0;
    595       }
    596 
    597       if (bit_shift == 0)
    598          buf[buf_offset] = 0;
    599 
    600       buf[buf_offset] |= tu_pack_clear_component_value(v, ch) << bit_shift;
    601       bit_shift += ch->size;
    602    }
    603 
    604    return buf_offset + 1;
    605 }
    606 
    607 static void
    608 tu_physical_device_get_format_properties(
    609    struct tu_physical_device *physical_device,
    610    VkFormat format,
    611    VkFormatProperties *out_properties)
    612 {
    613    VkFormatFeatureFlags linear = 0, tiled = 0, buffer = 0;
    614    const struct vk_format_description *desc = vk_format_description(format);
    615    const struct tu_native_format *native_fmt = tu6_get_native_format(format);
    616    if (!desc || !native_fmt) {
    617       out_properties->linearTilingFeatures = linear;
    618       out_properties->optimalTilingFeatures = tiled;
    619       out_properties->bufferFeatures = buffer;
    620       return;
    621    }
    622 
    623    linear |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
    624    tiled |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
    625    buffer |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
    626 
    627    if (native_fmt->tex >= 0) {
    628       linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
    629       tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
    630       buffer |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
    631    }
    632 
    633    if (native_fmt->rb >= 0) {
    634       linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
    635       tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
    636    }
    637 
    638    if (native_fmt->vtx >= 0) {
    639       buffer |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
    640    }
    641 
    642    out_properties->linearTilingFeatures = linear;
    643    out_properties->optimalTilingFeatures = tiled;
    644    out_properties->bufferFeatures = buffer;
    645 }
    646 
    647 void
    648 tu_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
    649                                      VkFormat format,
    650                                      VkFormatProperties *pFormatProperties)
    651 {
    652    TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
    653 
    654    tu_physical_device_get_format_properties(physical_device, format,
    655                                             pFormatProperties);
    656 }
    657 
    658 void
    659 tu_GetPhysicalDeviceFormatProperties2(
    660    VkPhysicalDevice physicalDevice,
    661    VkFormat format,
    662    VkFormatProperties2 *pFormatProperties)
    663 {
    664    TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
    665 
    666    tu_physical_device_get_format_properties(
    667       physical_device, format, &pFormatProperties->formatProperties);
    668 }
    669 
    670 static VkResult
    671 tu_get_image_format_properties(
    672    struct tu_physical_device *physical_device,
    673    const VkPhysicalDeviceImageFormatInfo2 *info,
    674    VkImageFormatProperties *pImageFormatProperties)
    675 
    676 {
    677    VkFormatProperties format_props;
    678    VkFormatFeatureFlags format_feature_flags;
    679    VkExtent3D maxExtent;
    680    uint32_t maxMipLevels;
    681    uint32_t maxArraySize;
    682    VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
    683 
    684    tu_physical_device_get_format_properties(physical_device, info->format,
    685                                             &format_props);
    686    if (info->tiling == VK_IMAGE_TILING_LINEAR) {
    687       format_feature_flags = format_props.linearTilingFeatures;
    688    } else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {
    689       format_feature_flags = format_props.optimalTilingFeatures;
    690    } else {
    691       unreachable("bad VkImageTiling");
    692    }
    693 
    694    if (format_feature_flags == 0)
    695       goto unsupported;
    696 
    697    if (info->type != VK_IMAGE_TYPE_2D &&
    698        vk_format_is_depth_or_stencil(info->format))
    699       goto unsupported;
    700 
    701    switch (info->type) {
    702    default:
    703       unreachable("bad vkimage type\n");
    704    case VK_IMAGE_TYPE_1D:
    705       maxExtent.width = 16384;
    706       maxExtent.height = 1;
    707       maxExtent.depth = 1;
    708       maxMipLevels = 15; /* log2(maxWidth) + 1 */
    709       maxArraySize = 2048;
    710       break;
    711    case VK_IMAGE_TYPE_2D:
    712       maxExtent.width = 16384;
    713       maxExtent.height = 16384;
    714       maxExtent.depth = 1;
    715       maxMipLevels = 15; /* log2(maxWidth) + 1 */
    716       maxArraySize = 2048;
    717       break;
    718    case VK_IMAGE_TYPE_3D:
    719       maxExtent.width = 2048;
    720       maxExtent.height = 2048;
    721       maxExtent.depth = 2048;
    722       maxMipLevels = 12; /* log2(maxWidth) + 1 */
    723       maxArraySize = 1;
    724       break;
    725    }
    726 
    727    if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
    728        info->type == VK_IMAGE_TYPE_2D &&
    729        (format_feature_flags &
    730         (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
    731          VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
    732        !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
    733        !(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
    734       sampleCounts |= VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT |
    735                       VK_SAMPLE_COUNT_8_BIT;
    736    }
    737 
    738    if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
    739       if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
    740          goto unsupported;
    741       }
    742    }
    743 
    744    if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
    745       if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
    746          goto unsupported;
    747       }
    748    }
    749 
    750    if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
    751       if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
    752          goto unsupported;
    753       }
    754    }
    755 
    756    if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
    757       if (!(format_feature_flags &
    758             VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
    759          goto unsupported;
    760       }
    761    }
    762 
    763    *pImageFormatProperties = (VkImageFormatProperties) {
    764       .maxExtent = maxExtent,
    765       .maxMipLevels = maxMipLevels,
    766       .maxArrayLayers = maxArraySize,
    767       .sampleCounts = sampleCounts,
    768 
    769       /* FINISHME: Accurately calculate
    770        * VkImageFormatProperties::maxResourceSize.
    771        */
    772       .maxResourceSize = UINT32_MAX,
    773    };
    774 
    775    return VK_SUCCESS;
    776 unsupported:
    777    *pImageFormatProperties = (VkImageFormatProperties) {
    778       .maxExtent = { 0, 0, 0 },
    779       .maxMipLevels = 0,
    780       .maxArrayLayers = 0,
    781       .sampleCounts = 0,
    782       .maxResourceSize = 0,
    783    };
    784 
    785    return VK_ERROR_FORMAT_NOT_SUPPORTED;
    786 }
    787 
    788 VkResult
    789 tu_GetPhysicalDeviceImageFormatProperties(
    790    VkPhysicalDevice physicalDevice,
    791    VkFormat format,
    792    VkImageType type,
    793    VkImageTiling tiling,
    794    VkImageUsageFlags usage,
    795    VkImageCreateFlags createFlags,
    796    VkImageFormatProperties *pImageFormatProperties)
    797 {
    798    TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
    799 
    800    const VkPhysicalDeviceImageFormatInfo2 info = {
    801       .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
    802       .pNext = NULL,
    803       .format = format,
    804       .type = type,
    805       .tiling = tiling,
    806       .usage = usage,
    807       .flags = createFlags,
    808    };
    809 
    810    return tu_get_image_format_properties(physical_device, &info,
    811                                          pImageFormatProperties);
    812 }
    813 
    814 static VkResult
    815 tu_get_external_image_format_properties(
    816    const struct tu_physical_device *physical_device,
    817    const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
    818    VkExternalMemoryHandleTypeFlagBits handleType,
    819    VkExternalMemoryProperties *external_properties)
    820 {
    821    VkExternalMemoryFeatureFlagBits flags = 0;
    822    VkExternalMemoryHandleTypeFlags export_flags = 0;
    823    VkExternalMemoryHandleTypeFlags compat_flags = 0;
    824 
    825    /* From the Vulkan 1.1.98 spec:
    826     *
    827     *    If handleType is not compatible with the format, type, tiling,
    828     *    usage, and flags specified in VkPhysicalDeviceImageFormatInfo2,
    829     *    then vkGetPhysicalDeviceImageFormatProperties2 returns
    830     *    VK_ERROR_FORMAT_NOT_SUPPORTED.
    831     */
    832 
    833    switch (handleType) {
    834    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
    835    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
    836       switch (pImageFormatInfo->type) {
    837       case VK_IMAGE_TYPE_2D:
    838          flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT |
    839                  VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
    840                  VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
    841          compat_flags = export_flags =
    842             VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
    843             VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
    844          break;
    845       default:
    846          return vk_errorf(physical_device->instance, VK_ERROR_FORMAT_NOT_SUPPORTED,
    847                           "VkExternalMemoryTypeFlagBits(0x%x) unsupported for VkImageType(%d)",
    848                           handleType, pImageFormatInfo->type);
    849       }
    850       break;
    851    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
    852       flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
    853       compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
    854       break;
    855    default:
    856       return vk_errorf(physical_device->instance, VK_ERROR_FORMAT_NOT_SUPPORTED,
    857                        "VkExternalMemoryTypeFlagBits(0x%x) unsupported",
    858                        handleType);
    859    }
    860 
    861    *external_properties = (VkExternalMemoryProperties) {
    862       .externalMemoryFeatures = flags,
    863       .exportFromImportedHandleTypes = export_flags,
    864       .compatibleHandleTypes = compat_flags,
    865    };
    866 
    867    return VK_SUCCESS;
    868 }
    869 
    870 VkResult
    871 tu_GetPhysicalDeviceImageFormatProperties2(
    872    VkPhysicalDevice physicalDevice,
    873    const VkPhysicalDeviceImageFormatInfo2 *base_info,
    874    VkImageFormatProperties2 *base_props)
    875 {
    876    TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
    877    const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
    878    VkExternalImageFormatProperties *external_props = NULL;
    879    VkResult result;
    880 
    881    result = tu_get_image_format_properties(
    882       physical_device, base_info, &base_props->imageFormatProperties);
    883    if (result != VK_SUCCESS)
    884       return result;
    885 
    886    /* Extract input structs */
    887    vk_foreach_struct_const(s, base_info->pNext)
    888    {
    889       switch (s->sType) {
    890       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
    891          external_info = (const void *) s;
    892          break;
    893       default:
    894          break;
    895       }
    896    }
    897 
    898    /* Extract output structs */
    899    vk_foreach_struct(s, base_props->pNext)
    900    {
    901       switch (s->sType) {
    902       case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
    903          external_props = (void *) s;
    904          break;
    905       default:
    906          break;
    907       }
    908    }
    909 
    910    /* From the Vulkan 1.0.42 spec:
    911     *
    912     *    If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will
    913     *    behave as if VkPhysicalDeviceExternalImageFormatInfo was not
    914     *    present and VkExternalImageFormatProperties will be ignored.
    915     */
    916    if (external_info && external_info->handleType != 0) {
    917       result = tu_get_external_image_format_properties(
    918          physical_device, base_info, external_info->handleType,
    919          &external_props->externalMemoryProperties);
    920       if (result != VK_SUCCESS)
    921          goto fail;
    922    }
    923 
    924    return VK_SUCCESS;
    925 
    926 fail:
    927    if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
    928       /* From the Vulkan 1.0.42 spec:
    929        *
    930        *    If the combination of parameters to
    931        *    vkGetPhysicalDeviceImageFormatProperties2 is not supported by
    932        *    the implementation for use in vkCreateImage, then all members of
    933        *    imageFormatProperties will be filled with zero.
    934        */
    935       base_props->imageFormatProperties = (VkImageFormatProperties) { 0 };
    936    }
    937 
    938    return result;
    939 }
    940 
    941 void
    942 tu_GetPhysicalDeviceSparseImageFormatProperties(
    943    VkPhysicalDevice physicalDevice,
    944    VkFormat format,
    945    VkImageType type,
    946    uint32_t samples,
    947    VkImageUsageFlags usage,
    948    VkImageTiling tiling,
    949    uint32_t *pNumProperties,
    950    VkSparseImageFormatProperties *pProperties)
    951 {
    952    /* Sparse images are not yet supported. */
    953    *pNumProperties = 0;
    954 }
    955 
    956 void
    957 tu_GetPhysicalDeviceSparseImageFormatProperties2(
    958    VkPhysicalDevice physicalDevice,
    959    const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
    960    uint32_t *pPropertyCount,
    961    VkSparseImageFormatProperties2 *pProperties)
    962 {
    963    /* Sparse images are not yet supported. */
    964    *pPropertyCount = 0;
    965 }
    966 
    967 void
    968 tu_GetPhysicalDeviceExternalBufferProperties(
    969    VkPhysicalDevice physicalDevice,
    970    const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
    971    VkExternalBufferProperties *pExternalBufferProperties)
    972 {
    973    VkExternalMemoryFeatureFlagBits flags = 0;
    974    VkExternalMemoryHandleTypeFlags export_flags = 0;
    975    VkExternalMemoryHandleTypeFlags compat_flags = 0;
    976    switch (pExternalBufferInfo->handleType) {
    977    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
    978    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
    979       flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
    980               VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
    981       compat_flags = export_flags =
    982          VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
    983          VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
    984       break;
    985    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
    986       flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
    987       compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
    988       break;
    989    default:
    990       break;
    991    }
    992    pExternalBufferProperties->externalMemoryProperties =
    993       (VkExternalMemoryProperties) {
    994          .externalMemoryFeatures = flags,
    995          .exportFromImportedHandleTypes = export_flags,
    996          .compatibleHandleTypes = compat_flags,
    997       };
    998 }
    999