Home | History | Annotate | Line # | Download | only in wsi
      1 /*
      2  * Copyright  2015 Intel Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21  * IN THE SOFTWARE.
     22  */
     23 
     24 #include <wayland-client.h>
     25 
     26 #include <assert.h>
     27 #include <stdlib.h>
     28 #include <stdio.h>
     29 #include <unistd.h>
     30 #include <errno.h>
     31 #include <string.h>
     32 #include <pthread.h>
     33 #include <poll.h>
     34 #include <sys/mman.h>
     35 
     36 #include "drm-uapi/drm_fourcc.h"
     37 
     38 #include "vk_instance.h"
     39 #include "vk_physical_device.h"
     40 #include "vk_util.h"
     41 #include "wsi_common_entrypoints.h"
     42 #include "wsi_common_private.h"
     43 #include "linux-dmabuf-unstable-v1-client-protocol.h"
     44 
     45 #include <util/compiler.h>
     46 #include <util/hash_table.h>
     47 #include <util/timespec.h>
     48 #include <util/u_vector.h>
     49 #include <util/anon_file.h>
     50 
     51 struct wsi_wayland;
     52 
     53 struct wsi_wl_format {
     54    VkFormat vk_format;
     55    uint32_t has_alpha_format;
     56    uint32_t has_opaque_format;
     57    struct u_vector modifiers;
     58 };
     59 
     60 struct wsi_wl_display {
     61    /* The real wl_display */
     62    struct wl_display *                          wl_display;
     63    /* Actually a proxy wrapper around the event queue */
     64    struct wl_display *                          wl_display_wrapper;
     65    struct wl_event_queue *                      queue;
     66 
     67    struct wl_shm *                              wl_shm;
     68    struct zwp_linux_dmabuf_v1 *                 wl_dmabuf;
     69 
     70    struct wsi_wayland *wsi_wl;
     71 
     72    /* Formats populated by zwp_linux_dmabuf_v1 or wl_shm interfaces */
     73    struct u_vector                              formats;
     74 
     75    /* Only used for displays created by wsi_wl_display_create */
     76    uint32_t                                     refcount;
     77 
     78    bool sw;
     79 };
     80 
     81 struct wsi_wayland {
     82    struct wsi_interface                     base;
     83 
     84    struct wsi_device *wsi;
     85 
     86    const VkAllocationCallbacks *alloc;
     87    VkPhysicalDevice physical_device;
     88 };
     89 
     90 static struct wsi_wl_format *
     91 find_format(struct u_vector *formats, VkFormat format)
     92 {
     93    struct wsi_wl_format *f;
     94 
     95    u_vector_foreach(f, formats)
     96       if (f->vk_format == format)
     97          return f;
     98 
     99    return NULL;
    100 }
    101 
    102 static struct wsi_wl_format *
    103 wsi_wl_display_add_vk_format(struct wsi_wl_display *display,
    104                              struct u_vector *formats,
    105                              VkFormat format,
    106                              bool has_alpha_format,
    107                              bool has_opaque_format)
    108 {
    109    /* Don't add a format that's already in the list */
    110    struct wsi_wl_format *f = find_format(formats, format);
    111    if (f) {
    112       if (has_alpha_format)
    113          f->has_alpha_format = true;
    114       if (has_opaque_format)
    115          f->has_opaque_format = true;
    116       return f;
    117    }
    118 
    119    /* Don't add formats that aren't renderable. */
    120    VkFormatProperties props;
    121 
    122    display->wsi_wl->wsi->GetPhysicalDeviceFormatProperties(display->wsi_wl->physical_device,
    123                                                            format, &props);
    124    if (!(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
    125       return NULL;
    126 
    127    struct u_vector modifiers;
    128    if (!u_vector_init_pow2(&modifiers, 4, sizeof(uint64_t)))
    129       return NULL;
    130 
    131    f = u_vector_add(formats);
    132    if (!f) {
    133       u_vector_finish(&modifiers);
    134       return NULL;
    135    }
    136 
    137    f->vk_format = format;
    138    f->has_alpha_format = has_alpha_format;
    139    f->has_opaque_format = has_opaque_format;
    140    f->modifiers = modifiers;
    141 
    142    return f;
    143 }
    144 
    145 static void
    146 wsi_wl_format_add_modifier(struct wsi_wl_format *format, uint64_t modifier)
    147 {
    148    uint64_t *mod;
    149 
    150    if (modifier == DRM_FORMAT_MOD_INVALID)
    151       return;
    152 
    153    u_vector_foreach(mod, &format->modifiers)
    154       if (*mod == modifier)
    155          return;
    156 
    157    mod = u_vector_add(&format->modifiers);
    158    if (mod)
    159       *mod = modifier;
    160 }
    161 
    162 static void
    163 wsi_wl_display_add_drm_format_modifier(struct wsi_wl_display *display,
    164                                        struct u_vector *formats,
    165                                        uint32_t drm_format, uint64_t modifier)
    166 {
    167    struct wsi_wl_format *format = NULL, *srgb_format = NULL;
    168 
    169    switch (drm_format) {
    170 #if 0
    171    /* TODO: These are only available when VK_EXT_4444_formats is enabled, so
    172     * we probably need to make their use conditional on this extension. */
    173    case DRM_FORMAT_ARGB4444:
    174       format = wsi_wl_display_add_vk_format(display, formats,
    175                                             VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
    176                                             true, false);
    177       break;
    178    case DRM_FORMAT_XRGB4444:
    179       format = wsi_wl_display_add_vk_format(display, formats,
    180                                             VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
    181                                             false, true);
    182       break;
    183    case DRM_FORMAT_ABGR4444:
    184       format = wsi_wl_display_add_vk_format(display, formats,
    185                                             VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
    186                                             true, false);
    187       break;
    188    case DRM_FORMAT_XBGR4444:
    189       format = wsi_wl_display_add_vk_format(display, formats,
    190                                             VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
    191                                             false, true);
    192       break;
    193 #endif
    194 
    195    /* Vulkan _PACKN formats have the same component order as DRM formats
    196     * on little endian systems, on big endian there exists no analog. */
    197 #if MESA_LITTLE_ENDIAN
    198    case DRM_FORMAT_RGBA4444:
    199       format = wsi_wl_display_add_vk_format(display, formats,
    200                                             VK_FORMAT_R4G4B4A4_UNORM_PACK16,
    201                                             true, false);
    202       break;
    203    case DRM_FORMAT_RGBX4444:
    204       format = wsi_wl_display_add_vk_format(display, formats,
    205                                             VK_FORMAT_R4G4B4A4_UNORM_PACK16,
    206                                             false, true);
    207       break;
    208    case DRM_FORMAT_BGRA4444:
    209       format = wsi_wl_display_add_vk_format(display, formats,
    210                                             VK_FORMAT_B4G4R4A4_UNORM_PACK16,
    211                                             true, false);
    212       break;
    213    case DRM_FORMAT_BGRX4444:
    214       format = wsi_wl_display_add_vk_format(display, formats,
    215                                             VK_FORMAT_B4G4R4A4_UNORM_PACK16,
    216                                             false, true);
    217       break;
    218    case DRM_FORMAT_RGB565:
    219       format = wsi_wl_display_add_vk_format(display, formats,
    220                                             VK_FORMAT_R5G6B5_UNORM_PACK16,
    221                                             true, true);
    222       break;
    223    case DRM_FORMAT_BGR565:
    224       format = wsi_wl_display_add_vk_format(display, formats,
    225                                             VK_FORMAT_B5G6R5_UNORM_PACK16,
    226                                             true, true);
    227       break;
    228    case DRM_FORMAT_ARGB1555:
    229       format = wsi_wl_display_add_vk_format(display, formats,
    230                                             VK_FORMAT_A1R5G5B5_UNORM_PACK16,
    231                                             true, false);
    232       break;
    233    case DRM_FORMAT_XRGB1555:
    234       format = wsi_wl_display_add_vk_format(display, formats,
    235                                             VK_FORMAT_A1R5G5B5_UNORM_PACK16,
    236                                             false, true);
    237       break;
    238    case DRM_FORMAT_RGBA5551:
    239       format = wsi_wl_display_add_vk_format(display, formats,
    240                                             VK_FORMAT_R5G5B5A1_UNORM_PACK16,
    241                                             true, false);
    242       break;
    243    case DRM_FORMAT_RGBX5551:
    244       format = wsi_wl_display_add_vk_format(display, formats,
    245                                             VK_FORMAT_R5G5B5A1_UNORM_PACK16,
    246                                             false, true);
    247       break;
    248    case DRM_FORMAT_BGRA5551:
    249       format = wsi_wl_display_add_vk_format(display, formats,
    250                                             VK_FORMAT_B5G5R5A1_UNORM_PACK16,
    251                                             true, false);
    252       break;
    253    case DRM_FORMAT_BGRX5551:
    254       format = wsi_wl_display_add_vk_format(display, formats,
    255                                             VK_FORMAT_B5G5R5A1_UNORM_PACK16,
    256                                             false, true);
    257       break;
    258    case DRM_FORMAT_ARGB2101010:
    259       format = wsi_wl_display_add_vk_format(display, formats,
    260                                             VK_FORMAT_A2R10G10B10_UNORM_PACK32,
    261                                             true, false);
    262       break;
    263    case DRM_FORMAT_XRGB2101010:
    264       format = wsi_wl_display_add_vk_format(display, formats,
    265                                             VK_FORMAT_A2R10G10B10_UNORM_PACK32,
    266                                             false, true);
    267       break;
    268    case DRM_FORMAT_ABGR2101010:
    269       format = wsi_wl_display_add_vk_format(display, formats,
    270                                             VK_FORMAT_A2B10G10R10_UNORM_PACK32,
    271                                             true, false);
    272       break;
    273    case DRM_FORMAT_XBGR2101010:
    274       format = wsi_wl_display_add_vk_format(display, formats,
    275                                             VK_FORMAT_A2B10G10R10_UNORM_PACK32,
    276                                             false, true);
    277       break;
    278 #endif
    279 
    280    /* Non-packed 8-bit formats have an inverted channel order compared to the
    281     * little endian DRM formats, because the DRM channel ordering is high->low
    282     * but the vulkan channel ordering is in memory byte order
    283     *
    284     * For all UNORM formats which have a SRGB variant, we must support both if
    285     * we can. SRGB in this context means that rendering to it will result in a
    286     * linear -> nonlinear SRGB colorspace conversion before the data is stored.
    287     * The inverse function is applied when sampling from SRGB images.
    288     * From Wayland's perspective nothing changes, the difference is just how
    289     * Vulkan interprets the pixel data. */
    290    case DRM_FORMAT_XBGR8888:
    291       srgb_format = wsi_wl_display_add_vk_format(display, formats,
    292                                                  VK_FORMAT_R8G8B8_SRGB,
    293                                                  true, true);
    294       format = wsi_wl_display_add_vk_format(display, formats,
    295                                             VK_FORMAT_R8G8B8_UNORM,
    296                                             true, true);
    297       if (format)
    298          wsi_wl_format_add_modifier(format, modifier);
    299       if (srgb_format)
    300          wsi_wl_format_add_modifier(srgb_format, modifier);
    301 
    302       srgb_format = wsi_wl_display_add_vk_format(display, formats,
    303                                                  VK_FORMAT_R8G8B8A8_SRGB,
    304                                                  false, true);
    305       format = wsi_wl_display_add_vk_format(display, formats,
    306                                             VK_FORMAT_R8G8B8A8_UNORM,
    307                                             false, true);
    308       break;
    309    case DRM_FORMAT_ABGR8888:
    310       srgb_format = wsi_wl_display_add_vk_format(display, formats,
    311                                                  VK_FORMAT_R8G8B8A8_SRGB,
    312                                                  true, false);
    313       format = wsi_wl_display_add_vk_format(display, formats,
    314                                             VK_FORMAT_R8G8B8A8_UNORM,
    315                                             true, false);
    316       break;
    317    case DRM_FORMAT_XRGB8888:
    318       srgb_format = wsi_wl_display_add_vk_format(display, formats,
    319                                                  VK_FORMAT_B8G8R8_SRGB,
    320                                                  true, true);
    321       format = wsi_wl_display_add_vk_format(display, formats,
    322                                             VK_FORMAT_B8G8R8_UNORM,
    323                                             true, true);
    324       if (format)
    325          wsi_wl_format_add_modifier(format, modifier);
    326       if (srgb_format)
    327          wsi_wl_format_add_modifier(srgb_format, modifier);
    328 
    329       srgb_format = wsi_wl_display_add_vk_format(display, formats,
    330                                                  VK_FORMAT_B8G8R8A8_SRGB,
    331                                                  false, true);
    332       format = wsi_wl_display_add_vk_format(display, formats,
    333                                             VK_FORMAT_B8G8R8A8_UNORM,
    334                                             false, true);
    335       break;
    336    case DRM_FORMAT_ARGB8888:
    337       srgb_format = wsi_wl_display_add_vk_format(display, formats,
    338                                                  VK_FORMAT_B8G8R8A8_SRGB,
    339                                                  true, false);
    340       format = wsi_wl_display_add_vk_format(display, formats,
    341                                             VK_FORMAT_B8G8R8A8_UNORM,
    342                                             true, false);
    343       break;
    344    }
    345 
    346    if (format)
    347       wsi_wl_format_add_modifier(format, modifier);
    348    if (srgb_format)
    349       wsi_wl_format_add_modifier(srgb_format, modifier);
    350 }
    351 
    352 static void
    353 wsi_wl_display_add_wl_shm_format(struct wsi_wl_display *display,
    354                                  struct u_vector *formats,
    355                                  uint32_t wl_shm_format)
    356 {
    357    switch (wl_shm_format) {
    358    case WL_SHM_FORMAT_XBGR8888:
    359       wsi_wl_display_add_vk_format(display, formats,
    360                                    VK_FORMAT_R8G8B8_SRGB,
    361                                    true, true);
    362       wsi_wl_display_add_vk_format(display, formats,
    363                                    VK_FORMAT_R8G8B8_UNORM,
    364                                    true, true);
    365       wsi_wl_display_add_vk_format(display, formats,
    366                                    VK_FORMAT_R8G8B8A8_SRGB,
    367                                    false, true);
    368       wsi_wl_display_add_vk_format(display, formats,
    369                                    VK_FORMAT_R8G8B8A8_UNORM,
    370                                    false, true);
    371       break;
    372    case WL_SHM_FORMAT_ABGR8888:
    373       wsi_wl_display_add_vk_format(display, formats,
    374                                    VK_FORMAT_R8G8B8A8_SRGB,
    375                                    true, false);
    376       wsi_wl_display_add_vk_format(display, formats,
    377                                    VK_FORMAT_R8G8B8A8_UNORM,
    378                                    true, false);
    379       break;
    380    case WL_SHM_FORMAT_XRGB8888:
    381       wsi_wl_display_add_vk_format(display, formats,
    382                                    VK_FORMAT_B8G8R8_SRGB,
    383                                    true, true);
    384       wsi_wl_display_add_vk_format(display, formats,
    385                                    VK_FORMAT_B8G8R8_UNORM,
    386                                    true, true);
    387       wsi_wl_display_add_vk_format(display, formats,
    388                                    VK_FORMAT_B8G8R8A8_SRGB,
    389                                    false, true);
    390       wsi_wl_display_add_vk_format(display, formats,
    391                                    VK_FORMAT_B8G8R8A8_UNORM,
    392                                    false, true);
    393       break;
    394    case WL_SHM_FORMAT_ARGB8888:
    395       wsi_wl_display_add_vk_format(display, formats,
    396                                    VK_FORMAT_B8G8R8A8_SRGB,
    397                                    true, false);
    398       wsi_wl_display_add_vk_format(display, formats,
    399                                    VK_FORMAT_B8G8R8A8_UNORM,
    400                                    true, false);
    401       break;
    402    }
    403 }
    404 
    405 static uint32_t
    406 wl_drm_format_for_vk_format(VkFormat vk_format, bool alpha)
    407 {
    408    switch (vk_format) {
    409 #if 0
    410    case VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT:
    411       return alpha ? DRM_FORMAT_ARGB4444 : DRM_FORMAT_XRGB4444;
    412    case VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT:
    413       return alpha ? DRM_FORMAT_ABGR4444 : DRM_FORMAT_XBGR4444;
    414 #endif
    415 #if MESA_LITTLE_ENDIAN
    416    case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
    417       return alpha ? DRM_FORMAT_RGBA4444 : DRM_FORMAT_RGBX4444;
    418    case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
    419       return alpha ? DRM_FORMAT_BGRA4444 : DRM_FORMAT_BGRX4444;
    420    case VK_FORMAT_R5G6B5_UNORM_PACK16:
    421       return DRM_FORMAT_RGB565;
    422    case VK_FORMAT_B5G6R5_UNORM_PACK16:
    423       return DRM_FORMAT_BGR565;
    424    case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
    425       return alpha ? DRM_FORMAT_ARGB1555 : DRM_FORMAT_XRGB1555;
    426    case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
    427       return alpha ? DRM_FORMAT_RGBA5551 : DRM_FORMAT_RGBX5551;
    428    case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
    429       return alpha ? DRM_FORMAT_BGRA5551 : DRM_FORMAT_BGRX5551;
    430    case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
    431       return alpha ? DRM_FORMAT_ARGB2101010 : DRM_FORMAT_XRGB2101010;
    432    case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
    433       return alpha ? DRM_FORMAT_ABGR2101010 : DRM_FORMAT_XBGR2101010;
    434 #endif
    435    case VK_FORMAT_R8G8B8_UNORM:
    436    case VK_FORMAT_R8G8B8_SRGB:
    437       return DRM_FORMAT_XBGR8888;
    438    case VK_FORMAT_R8G8B8A8_UNORM:
    439    case VK_FORMAT_R8G8B8A8_SRGB:
    440       return alpha ? DRM_FORMAT_ABGR8888 : DRM_FORMAT_XBGR8888;
    441    case VK_FORMAT_B8G8R8_UNORM:
    442    case VK_FORMAT_B8G8R8_SRGB:
    443       return DRM_FORMAT_BGRX8888;
    444    case VK_FORMAT_B8G8R8A8_UNORM:
    445    case VK_FORMAT_B8G8R8A8_SRGB:
    446       return alpha ? DRM_FORMAT_ARGB8888 : DRM_FORMAT_XRGB8888;
    447 
    448    default:
    449       assert(!"Unsupported Vulkan format");
    450       return 0;
    451    }
    452 }
    453 
    454 static uint32_t
    455 wl_shm_format_for_vk_format(VkFormat vk_format, bool alpha)
    456 {
    457    switch (vk_format) {
    458    case VK_FORMAT_R8G8B8A8_UNORM:
    459    case VK_FORMAT_R8G8B8A8_SRGB:
    460       return alpha ? WL_SHM_FORMAT_ABGR8888 : WL_SHM_FORMAT_XBGR8888;
    461    case VK_FORMAT_B8G8R8A8_UNORM:
    462    case VK_FORMAT_B8G8R8A8_SRGB:
    463       return alpha ? WL_SHM_FORMAT_ARGB8888 : WL_SHM_FORMAT_XRGB8888;
    464    case VK_FORMAT_R8G8B8_UNORM:
    465    case VK_FORMAT_R8G8B8_SRGB:
    466       return WL_SHM_FORMAT_XBGR8888;
    467    case VK_FORMAT_B8G8R8_UNORM:
    468    case VK_FORMAT_B8G8R8_SRGB:
    469       return WL_SHM_FORMAT_XRGB8888;
    470 
    471    default:
    472       assert(!"Unsupported Vulkan format");
    473       return 0;
    474    }
    475 }
    476 
    477 static void
    478 dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
    479                      uint32_t format)
    480 {
    481    /* Formats are implicitly advertised by the modifier event, so we ignore
    482     * them here. */
    483 }
    484 
    485 static void
    486 dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
    487                        uint32_t format, uint32_t modifier_hi,
    488                        uint32_t modifier_lo)
    489 {
    490    struct wsi_wl_display *display = data;
    491    uint64_t modifier;
    492 
    493    modifier = ((uint64_t) modifier_hi << 32) | modifier_lo;
    494    wsi_wl_display_add_drm_format_modifier(display, &display->formats,
    495                                           format, modifier);
    496 }
    497 
    498 static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {
    499    dmabuf_handle_format,
    500    dmabuf_handle_modifier,
    501 };
    502 
    503 static void
    504 shm_handle_format(void *data, struct wl_shm *shm, uint32_t format)
    505 {
    506    struct wsi_wl_display *display = data;
    507 
    508    wsi_wl_display_add_wl_shm_format(display, &display->formats, format);
    509 }
    510 
    511 static const struct wl_shm_listener shm_listener = {
    512    .format = shm_handle_format
    513 };
    514 
    515 static void
    516 registry_handle_global(void *data, struct wl_registry *registry,
    517                        uint32_t name, const char *interface, uint32_t version)
    518 {
    519    struct wsi_wl_display *display = data;
    520 
    521    if (display->sw) {
    522       if (strcmp(interface, "wl_shm") == 0) {
    523          display->wl_shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
    524          wl_shm_add_listener(display->wl_shm, &shm_listener, display);
    525       }
    526       return;
    527    }
    528 
    529    if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0 && version >= 3) {
    530       display->wl_dmabuf =
    531          wl_registry_bind(registry, name, &zwp_linux_dmabuf_v1_interface, 3);
    532       zwp_linux_dmabuf_v1_add_listener(display->wl_dmabuf,
    533                                        &dmabuf_listener, display);
    534    }
    535 }
    536 
    537 static void
    538 registry_handle_global_remove(void *data, struct wl_registry *registry,
    539                               uint32_t name)
    540 { /* No-op */ }
    541 
    542 static const struct wl_registry_listener registry_listener = {
    543    registry_handle_global,
    544    registry_handle_global_remove
    545 };
    546 
    547 static void
    548 wsi_wl_display_finish(struct wsi_wl_display *display)
    549 {
    550    assert(display->refcount == 0);
    551 
    552    struct wsi_wl_format *f;
    553    u_vector_foreach(f, &display->formats)
    554       u_vector_finish(&f->modifiers);
    555    u_vector_finish(&display->formats);
    556    if (display->wl_shm)
    557       wl_shm_destroy(display->wl_shm);
    558    if (display->wl_dmabuf)
    559       zwp_linux_dmabuf_v1_destroy(display->wl_dmabuf);
    560    if (display->wl_display_wrapper)
    561       wl_proxy_wrapper_destroy(display->wl_display_wrapper);
    562    if (display->queue)
    563       wl_event_queue_destroy(display->queue);
    564 }
    565 
    566 static VkResult
    567 wsi_wl_display_init(struct wsi_wayland *wsi_wl,
    568                     struct wsi_wl_display *display,
    569                     struct wl_display *wl_display,
    570                     bool get_format_list, bool sw)
    571 {
    572    VkResult result = VK_SUCCESS;
    573    memset(display, 0, sizeof(*display));
    574 
    575    if (!u_vector_init(&display->formats, 8, sizeof(struct wsi_wl_format)))
    576       return VK_ERROR_OUT_OF_HOST_MEMORY;
    577 
    578    display->wsi_wl = wsi_wl;
    579    display->wl_display = wl_display;
    580    display->sw = sw;
    581 
    582    display->queue = wl_display_create_queue(wl_display);
    583    if (!display->queue) {
    584       result = VK_ERROR_OUT_OF_HOST_MEMORY;
    585       goto fail;
    586    }
    587 
    588    display->wl_display_wrapper = wl_proxy_create_wrapper(wl_display);
    589    if (!display->wl_display_wrapper) {
    590       result = VK_ERROR_OUT_OF_HOST_MEMORY;
    591       goto fail;
    592    }
    593 
    594    wl_proxy_set_queue((struct wl_proxy *) display->wl_display_wrapper,
    595                       display->queue);
    596 
    597    struct wl_registry *registry =
    598       wl_display_get_registry(display->wl_display_wrapper);
    599    if (!registry) {
    600       result = VK_ERROR_OUT_OF_HOST_MEMORY;
    601       goto fail;
    602    }
    603 
    604    wl_registry_add_listener(registry, &registry_listener, display);
    605 
    606    /* Round-trip to get wl_shm and zwp_linux_dmabuf_v1 globals */
    607    wl_display_roundtrip_queue(display->wl_display, display->queue);
    608    if (!display->wl_dmabuf && !display->wl_shm) {
    609       result = VK_ERROR_SURFACE_LOST_KHR;
    610       goto fail_registry;
    611    }
    612 
    613    /* Caller doesn't expect us to query formats/modifiers, so return */
    614    if (!get_format_list)
    615       goto out;
    616 
    617    /* Round-trip again to get formats and modifiers */
    618    wl_display_roundtrip_queue(display->wl_display, display->queue);
    619 
    620    if (wsi_wl->wsi->force_bgra8_unorm_first) {
    621       /* Find BGRA8_UNORM in the list and swap it to the first position if we
    622        * can find it.  Some apps get confused if SRGB is first in the list.
    623        */
    624       struct wsi_wl_format *first_fmt = u_vector_head(&display->formats);
    625       struct wsi_wl_format *f, tmp_fmt;
    626       f = find_format(&display->formats, VK_FORMAT_B8G8R8A8_UNORM);
    627       if (f) {
    628          tmp_fmt = *f;
    629          *f = *first_fmt;
    630          *first_fmt = tmp_fmt;
    631       }
    632    }
    633 
    634 out:
    635    /* We don't need this anymore */
    636    wl_registry_destroy(registry);
    637 
    638    display->refcount = 0;
    639 
    640    return VK_SUCCESS;
    641 
    642 fail_registry:
    643    if (registry)
    644       wl_registry_destroy(registry);
    645 
    646 fail:
    647    wsi_wl_display_finish(display);
    648    return result;
    649 }
    650 
    651 static VkResult
    652 wsi_wl_display_create(struct wsi_wayland *wsi, struct wl_display *wl_display,
    653                       bool sw,
    654                       struct wsi_wl_display **display_out)
    655 {
    656    struct wsi_wl_display *display =
    657       vk_alloc(wsi->alloc, sizeof(*display), 8,
    658                VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    659    if (!display)
    660       return VK_ERROR_OUT_OF_HOST_MEMORY;
    661 
    662    VkResult result = wsi_wl_display_init(wsi, display, wl_display, true,
    663                                          sw);
    664    if (result != VK_SUCCESS) {
    665       vk_free(wsi->alloc, display);
    666       return result;
    667    }
    668 
    669    display->refcount++;
    670    *display_out = display;
    671 
    672    return result;
    673 }
    674 
    675 static struct wsi_wl_display *
    676 wsi_wl_display_ref(struct wsi_wl_display *display)
    677 {
    678    display->refcount++;
    679    return display;
    680 }
    681 
    682 static void
    683 wsi_wl_display_unref(struct wsi_wl_display *display)
    684 {
    685    if (display->refcount-- > 1)
    686       return;
    687 
    688    struct wsi_wayland *wsi = display->wsi_wl;
    689    wsi_wl_display_finish(display);
    690    vk_free(wsi->alloc, display);
    691 }
    692 
    693 VKAPI_ATTR VkBool32 VKAPI_CALL
    694 wsi_GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
    695                                                    uint32_t queueFamilyIndex,
    696                                                    struct wl_display *wl_display)
    697 {
    698    VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice);
    699    struct wsi_device *wsi_device = pdevice->wsi_device;
    700    struct wsi_wayland *wsi =
    701       (struct wsi_wayland *)wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND];
    702 
    703    struct wsi_wl_display display;
    704    VkResult ret = wsi_wl_display_init(wsi, &display, wl_display, false,
    705                                       wsi_device->sw);
    706    if (ret == VK_SUCCESS)
    707       wsi_wl_display_finish(&display);
    708 
    709    return ret == VK_SUCCESS;
    710 }
    711 
    712 static VkResult
    713 wsi_wl_surface_get_support(VkIcdSurfaceBase *surface,
    714                            struct wsi_device *wsi_device,
    715                            uint32_t queueFamilyIndex,
    716                            VkBool32* pSupported)
    717 {
    718    *pSupported = true;
    719 
    720    return VK_SUCCESS;
    721 }
    722 
    723 static const VkPresentModeKHR present_modes[] = {
    724    VK_PRESENT_MODE_MAILBOX_KHR,
    725    VK_PRESENT_MODE_FIFO_KHR,
    726 };
    727 
    728 static VkResult
    729 wsi_wl_surface_get_capabilities(VkIcdSurfaceBase *surface,
    730                                 struct wsi_device *wsi_device,
    731                                 VkSurfaceCapabilitiesKHR* caps)
    732 {
    733    /* For true mailbox mode, we need at least 4 images:
    734     *  1) One to scan out from
    735     *  2) One to have queued for scan-out
    736     *  3) One to be currently held by the Wayland compositor
    737     *  4) One to render to
    738     */
    739    caps->minImageCount = 4;
    740    /* There is no real maximum */
    741    caps->maxImageCount = 0;
    742 
    743    caps->currentExtent = (VkExtent2D) { UINT32_MAX, UINT32_MAX };
    744    caps->minImageExtent = (VkExtent2D) { 1, 1 };
    745    caps->maxImageExtent = (VkExtent2D) {
    746       wsi_device->maxImageDimension2D,
    747       wsi_device->maxImageDimension2D,
    748    };
    749 
    750    caps->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
    751    caps->currentTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
    752    caps->maxImageArrayLayers = 1;
    753 
    754    caps->supportedCompositeAlpha =
    755       VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR |
    756       VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR;
    757 
    758    caps->supportedUsageFlags =
    759       VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
    760       VK_IMAGE_USAGE_SAMPLED_BIT |
    761       VK_IMAGE_USAGE_TRANSFER_DST_BIT |
    762       VK_IMAGE_USAGE_STORAGE_BIT |
    763       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    764 
    765    return VK_SUCCESS;
    766 }
    767 
    768 static VkResult
    769 wsi_wl_surface_get_capabilities2(VkIcdSurfaceBase *surface,
    770                                  struct wsi_device *wsi_device,
    771                                  const void *info_next,
    772                                  VkSurfaceCapabilities2KHR* caps)
    773 {
    774    assert(caps->sType == VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR);
    775 
    776    VkResult result =
    777       wsi_wl_surface_get_capabilities(surface, wsi_device,
    778                                       &caps->surfaceCapabilities);
    779 
    780    vk_foreach_struct(ext, caps->pNext) {
    781       switch (ext->sType) {
    782       case VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR: {
    783          VkSurfaceProtectedCapabilitiesKHR *protected = (void *)ext;
    784          protected->supportsProtected = VK_FALSE;
    785          break;
    786       }
    787 
    788       default:
    789          /* Ignored */
    790          break;
    791       }
    792    }
    793 
    794    return result;
    795 }
    796 
    797 static VkResult
    798 wsi_wl_surface_get_formats(VkIcdSurfaceBase *icd_surface,
    799 			   struct wsi_device *wsi_device,
    800                            uint32_t* pSurfaceFormatCount,
    801                            VkSurfaceFormatKHR* pSurfaceFormats)
    802 {
    803    VkIcdSurfaceWayland *surface = (VkIcdSurfaceWayland *)icd_surface;
    804    struct wsi_wayland *wsi =
    805       (struct wsi_wayland *)wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND];
    806 
    807    struct wsi_wl_display display;
    808    if (wsi_wl_display_init(wsi, &display, surface->display, true,
    809                            wsi_device->sw))
    810       return VK_ERROR_SURFACE_LOST_KHR;
    811 
    812    VK_OUTARRAY_MAKE(out, pSurfaceFormats, pSurfaceFormatCount);
    813 
    814    struct wsi_wl_format *disp_fmt;
    815    u_vector_foreach(disp_fmt, &display.formats) {
    816       /* Skip formats for which we can't support both alpha & opaque
    817        * formats.
    818        */
    819       if (!disp_fmt->has_opaque_format ||
    820           !disp_fmt->has_alpha_format)
    821          continue;
    822 
    823       vk_outarray_append(&out, out_fmt) {
    824          out_fmt->format = disp_fmt->vk_format;
    825          out_fmt->colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
    826       }
    827    }
    828 
    829    wsi_wl_display_finish(&display);
    830 
    831    return vk_outarray_status(&out);
    832 }
    833 
    834 static VkResult
    835 wsi_wl_surface_get_formats2(VkIcdSurfaceBase *icd_surface,
    836 			    struct wsi_device *wsi_device,
    837                             const void *info_next,
    838                             uint32_t* pSurfaceFormatCount,
    839                             VkSurfaceFormat2KHR* pSurfaceFormats)
    840 {
    841    VkIcdSurfaceWayland *surface = (VkIcdSurfaceWayland *)icd_surface;
    842    struct wsi_wayland *wsi =
    843       (struct wsi_wayland *)wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND];
    844 
    845    struct wsi_wl_display display;
    846    if (wsi_wl_display_init(wsi, &display, surface->display, true,
    847                            wsi_device->sw))
    848       return VK_ERROR_SURFACE_LOST_KHR;
    849 
    850    VK_OUTARRAY_MAKE(out, pSurfaceFormats, pSurfaceFormatCount);
    851 
    852    struct wsi_wl_format *disp_fmt;
    853    u_vector_foreach(disp_fmt, &display.formats) {
    854       /* Skip formats for which we can't support both alpha & opaque
    855        * formats.
    856        */
    857       if (!disp_fmt->has_opaque_format ||
    858           !disp_fmt->has_alpha_format)
    859          continue;
    860 
    861       vk_outarray_append(&out, out_fmt) {
    862          out_fmt->surfaceFormat.format = disp_fmt->vk_format;
    863          out_fmt->surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
    864       }
    865    }
    866 
    867    wsi_wl_display_finish(&display);
    868 
    869    return vk_outarray_status(&out);
    870 }
    871 
    872 static VkResult
    873 wsi_wl_surface_get_present_modes(VkIcdSurfaceBase *surface,
    874                                  uint32_t* pPresentModeCount,
    875                                  VkPresentModeKHR* pPresentModes)
    876 {
    877    if (pPresentModes == NULL) {
    878       *pPresentModeCount = ARRAY_SIZE(present_modes);
    879       return VK_SUCCESS;
    880    }
    881 
    882    *pPresentModeCount = MIN2(*pPresentModeCount, ARRAY_SIZE(present_modes));
    883    typed_memcpy(pPresentModes, present_modes, *pPresentModeCount);
    884 
    885    if (*pPresentModeCount < ARRAY_SIZE(present_modes))
    886       return VK_INCOMPLETE;
    887    else
    888       return VK_SUCCESS;
    889 }
    890 
    891 static VkResult
    892 wsi_wl_surface_get_present_rectangles(VkIcdSurfaceBase *surface,
    893                                       struct wsi_device *wsi_device,
    894                                       uint32_t* pRectCount,
    895                                       VkRect2D* pRects)
    896 {
    897    VK_OUTARRAY_MAKE(out, pRects, pRectCount);
    898 
    899    vk_outarray_append(&out, rect) {
    900       /* We don't know a size so just return the usual "I don't know." */
    901       *rect = (VkRect2D) {
    902          .offset = { 0, 0 },
    903          .extent = { UINT32_MAX, UINT32_MAX },
    904       };
    905    }
    906 
    907    return vk_outarray_status(&out);
    908 }
    909 
    910 VKAPI_ATTR VkResult VKAPI_CALL
    911 wsi_CreateWaylandSurfaceKHR(VkInstance _instance,
    912                             const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
    913                             const VkAllocationCallbacks *pAllocator,
    914                             VkSurfaceKHR *pSurface)
    915 {
    916    VK_FROM_HANDLE(vk_instance, instance, _instance);
    917    VkIcdSurfaceWayland *surface;
    918 
    919    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR);
    920 
    921    surface = vk_alloc2(&instance->alloc, pAllocator, sizeof *surface, 8,
    922                        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    923    if (surface == NULL)
    924       return VK_ERROR_OUT_OF_HOST_MEMORY;
    925 
    926    surface->base.platform = VK_ICD_WSI_PLATFORM_WAYLAND;
    927    surface->display = pCreateInfo->display;
    928    surface->surface = pCreateInfo->surface;
    929 
    930    *pSurface = VkIcdSurfaceBase_to_handle(&surface->base);
    931 
    932    return VK_SUCCESS;
    933 }
    934 
    935 struct wsi_wl_image {
    936    struct wsi_image                             base;
    937    struct wl_buffer *                           buffer;
    938    bool                                         busy;
    939    void *                                       data_ptr;
    940    uint32_t                                     data_size;
    941 };
    942 
    943 struct wsi_wl_swapchain {
    944    struct wsi_swapchain                         base;
    945 
    946    struct wsi_wl_display                        *display;
    947 
    948    struct wl_surface *                          surface;
    949 
    950    struct wl_callback *                         frame;
    951 
    952    VkExtent2D                                   extent;
    953    VkFormat                                     vk_format;
    954    uint32_t                                     drm_format;
    955    uint32_t                                     shm_format;
    956 
    957    uint32_t                                     num_drm_modifiers;
    958    const uint64_t *                             drm_modifiers;
    959 
    960    VkPresentModeKHR                             present_mode;
    961    bool                                         fifo_ready;
    962 
    963    struct wsi_wl_image                          images[0];
    964 };
    965 VK_DEFINE_NONDISP_HANDLE_CASTS(wsi_wl_swapchain, base.base, VkSwapchainKHR,
    966                                VK_OBJECT_TYPE_SWAPCHAIN_KHR)
    967 
    968 static struct wsi_image *
    969 wsi_wl_swapchain_get_wsi_image(struct wsi_swapchain *wsi_chain,
    970                                uint32_t image_index)
    971 {
    972    struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)wsi_chain;
    973    return &chain->images[image_index].base;
    974 }
    975 
    976 static VkResult
    977 wsi_wl_swapchain_acquire_next_image(struct wsi_swapchain *wsi_chain,
    978                                     const VkAcquireNextImageInfoKHR *info,
    979                                     uint32_t *image_index)
    980 {
    981    struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)wsi_chain;
    982    struct timespec start_time, end_time;
    983    struct timespec rel_timeout;
    984    int wl_fd = wl_display_get_fd(chain->display->wl_display);
    985 
    986    timespec_from_nsec(&rel_timeout, info->timeout);
    987 
    988    clock_gettime(CLOCK_MONOTONIC, &start_time);
    989    timespec_add(&end_time, &rel_timeout, &start_time);
    990 
    991    while (1) {
    992       /* Try to dispatch potential events. */
    993       int ret = wl_display_dispatch_queue_pending(chain->display->wl_display,
    994                                                   chain->display->queue);
    995       if (ret < 0)
    996          return VK_ERROR_OUT_OF_DATE_KHR;
    997 
    998       /* Try to find a free image. */
    999       for (uint32_t i = 0; i < chain->base.image_count; i++) {
   1000          if (!chain->images[i].busy) {
   1001             /* We found a non-busy image */
   1002             *image_index = i;
   1003             chain->images[i].busy = true;
   1004             return VK_SUCCESS;
   1005          }
   1006       }
   1007 
   1008       /* Check for timeout. */
   1009       struct timespec current_time;
   1010       clock_gettime(CLOCK_MONOTONIC, &current_time);
   1011       if (timespec_after(&current_time, &end_time))
   1012          return VK_NOT_READY;
   1013 
   1014       /* Try to read events from the server. */
   1015       ret = wl_display_prepare_read_queue(chain->display->wl_display,
   1016                                           chain->display->queue);
   1017       if (ret < 0) {
   1018          /* Another thread might have read events for our queue already. Go
   1019           * back to dispatch them.
   1020           */
   1021          if (errno == EAGAIN)
   1022             continue;
   1023          return VK_ERROR_OUT_OF_DATE_KHR;
   1024       }
   1025 
   1026       struct pollfd pollfd = {
   1027          .fd = wl_fd,
   1028          .events = POLLIN
   1029       };
   1030       timespec_sub(&rel_timeout, &end_time, &current_time);
   1031       ret = ppoll(&pollfd, 1, &rel_timeout, NULL);
   1032       if (ret <= 0) {
   1033          int lerrno = errno;
   1034          wl_display_cancel_read(chain->display->wl_display);
   1035          if (ret < 0) {
   1036             /* If ppoll() was interrupted, try again. */
   1037             if (lerrno == EINTR || lerrno == EAGAIN)
   1038                continue;
   1039             return VK_ERROR_OUT_OF_DATE_KHR;
   1040          }
   1041          assert(ret == 0);
   1042          continue;
   1043       }
   1044 
   1045       ret = wl_display_read_events(chain->display->wl_display);
   1046       if (ret < 0)
   1047          return VK_ERROR_OUT_OF_DATE_KHR;
   1048    }
   1049 }
   1050 
   1051 static void
   1052 frame_handle_done(void *data, struct wl_callback *callback, uint32_t serial)
   1053 {
   1054    struct wsi_wl_swapchain *chain = data;
   1055 
   1056    chain->frame = NULL;
   1057    chain->fifo_ready = true;
   1058 
   1059    wl_callback_destroy(callback);
   1060 }
   1061 
   1062 static const struct wl_callback_listener frame_listener = {
   1063    frame_handle_done,
   1064 };
   1065 
   1066 static VkResult
   1067 wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain,
   1068                                uint32_t image_index,
   1069                                const VkPresentRegionKHR *damage)
   1070 {
   1071    struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)wsi_chain;
   1072 
   1073    if (chain->display->sw) {
   1074       struct wsi_wl_image *image = &chain->images[image_index];
   1075       void *dptr = image->data_ptr;
   1076       void *sptr;
   1077       chain->base.wsi->MapMemory(chain->base.device,
   1078                                  image->base.memory,
   1079                                  0, 0, 0, &sptr);
   1080 
   1081       for (unsigned r = 0; r < chain->extent.height; r++) {
   1082          memcpy(dptr, sptr, image->base.row_pitches[0]);
   1083          dptr += image->base.row_pitches[0];
   1084          sptr += image->base.row_pitches[0];
   1085       }
   1086       chain->base.wsi->UnmapMemory(chain->base.device,
   1087                                    image->base.memory);
   1088 
   1089    }
   1090    if (chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR) {
   1091       while (!chain->fifo_ready) {
   1092          int ret = wl_display_dispatch_queue(chain->display->wl_display,
   1093                                              chain->display->queue);
   1094          if (ret < 0)
   1095             return VK_ERROR_OUT_OF_DATE_KHR;
   1096       }
   1097    }
   1098 
   1099    assert(image_index < chain->base.image_count);
   1100    wl_surface_attach(chain->surface, chain->images[image_index].buffer, 0, 0);
   1101 
   1102    if (wl_surface_get_version(chain->surface) >= 4 && damage &&
   1103        damage->pRectangles && damage->rectangleCount > 0) {
   1104       for (unsigned i = 0; i < damage->rectangleCount; i++) {
   1105          const VkRectLayerKHR *rect = &damage->pRectangles[i];
   1106          assert(rect->layer == 0);
   1107          wl_surface_damage_buffer(chain->surface,
   1108                                   rect->offset.x, rect->offset.y,
   1109                                   rect->extent.width, rect->extent.height);
   1110       }
   1111    } else {
   1112       wl_surface_damage(chain->surface, 0, 0, INT32_MAX, INT32_MAX);
   1113    }
   1114 
   1115    if (chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR) {
   1116       chain->frame = wl_surface_frame(chain->surface);
   1117       wl_callback_add_listener(chain->frame, &frame_listener, chain);
   1118       chain->fifo_ready = false;
   1119    }
   1120 
   1121    chain->images[image_index].busy = true;
   1122    wl_surface_commit(chain->surface);
   1123    wl_display_flush(chain->display->wl_display);
   1124 
   1125    return VK_SUCCESS;
   1126 }
   1127 
   1128 static void
   1129 buffer_handle_release(void *data, struct wl_buffer *buffer)
   1130 {
   1131    struct wsi_wl_image *image = data;
   1132 
   1133    assert(image->buffer == buffer);
   1134 
   1135    image->busy = false;
   1136 }
   1137 
   1138 static const struct wl_buffer_listener buffer_listener = {
   1139    buffer_handle_release,
   1140 };
   1141 
   1142 static VkResult
   1143 wsi_wl_image_init(struct wsi_wl_swapchain *chain,
   1144                   struct wsi_wl_image *image,
   1145                   const VkSwapchainCreateInfoKHR *pCreateInfo,
   1146                   const VkAllocationCallbacks* pAllocator)
   1147 {
   1148    struct wsi_wl_display *display = chain->display;
   1149    VkResult result;
   1150 
   1151    memset(image, 0, sizeof(*image));
   1152 
   1153    result = wsi_create_native_image(&chain->base, pCreateInfo,
   1154                                     chain->num_drm_modifiers > 0 ? 1 : 0,
   1155                                     &chain->num_drm_modifiers,
   1156                                     &chain->drm_modifiers, NULL, &image->base);
   1157 
   1158    if (result != VK_SUCCESS)
   1159       return result;
   1160 
   1161    if (display->sw) {
   1162       int fd, stride;
   1163 
   1164       stride = image->base.row_pitches[0];
   1165       image->data_size = stride * chain->extent.height;
   1166 
   1167       /* Create a shareable buffer */
   1168       fd = os_create_anonymous_file(image->data_size, NULL);
   1169       if (fd < 0)
   1170          goto fail_image;
   1171 
   1172       image->data_ptr = mmap(NULL, image->data_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
   1173       if (image->data_ptr == MAP_FAILED) {
   1174          close(fd);
   1175          goto fail_image;
   1176       }
   1177       /* Share it in a wl_buffer */
   1178       struct wl_shm_pool *pool = wl_shm_create_pool(display->wl_shm, fd, image->data_size);
   1179       wl_proxy_set_queue((struct wl_proxy *)pool, display->queue);
   1180       image->buffer = wl_shm_pool_create_buffer(pool, 0, chain->extent.width,
   1181                                                 chain->extent.height, stride,
   1182                                                 chain->shm_format);
   1183       wl_shm_pool_destroy(pool);
   1184       close(fd);
   1185    } else {
   1186       assert(display->wl_dmabuf);
   1187 
   1188       struct zwp_linux_buffer_params_v1 *params =
   1189          zwp_linux_dmabuf_v1_create_params(display->wl_dmabuf);
   1190       if (!params)
   1191          goto fail_image;
   1192 
   1193       for (int i = 0; i < image->base.num_planes; i++) {
   1194          zwp_linux_buffer_params_v1_add(params,
   1195                                         image->base.fds[i],
   1196                                         i,
   1197                                         image->base.offsets[i],
   1198                                         image->base.row_pitches[i],
   1199                                         image->base.drm_modifier >> 32,
   1200                                         image->base.drm_modifier & 0xffffffff);
   1201          close(image->base.fds[i]);
   1202       }
   1203 
   1204       image->buffer =
   1205          zwp_linux_buffer_params_v1_create_immed(params,
   1206                                                  chain->extent.width,
   1207                                                  chain->extent.height,
   1208                                                  chain->drm_format,
   1209                                                  0);
   1210       zwp_linux_buffer_params_v1_destroy(params);
   1211    }
   1212 
   1213    if (!image->buffer)
   1214       goto fail_image;
   1215 
   1216    wl_buffer_add_listener(image->buffer, &buffer_listener, image);
   1217 
   1218    return VK_SUCCESS;
   1219 
   1220 fail_image:
   1221    wsi_destroy_image(&chain->base, &image->base);
   1222 
   1223    return VK_ERROR_OUT_OF_HOST_MEMORY;
   1224 }
   1225 
   1226 static VkResult
   1227 wsi_wl_swapchain_destroy(struct wsi_swapchain *wsi_chain,
   1228                          const VkAllocationCallbacks *pAllocator)
   1229 {
   1230    struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)wsi_chain;
   1231 
   1232    for (uint32_t i = 0; i < chain->base.image_count; i++) {
   1233       if (chain->images[i].buffer) {
   1234          wl_buffer_destroy(chain->images[i].buffer);
   1235          wsi_destroy_image(&chain->base, &chain->images[i].base);
   1236          if (chain->images[i].data_ptr)
   1237             munmap(chain->images[i].data_ptr, chain->images[i].data_size);
   1238       }
   1239    }
   1240 
   1241    if (chain->frame)
   1242       wl_callback_destroy(chain->frame);
   1243    if (chain->surface)
   1244       wl_proxy_wrapper_destroy(chain->surface);
   1245 
   1246    if (chain->display)
   1247       wsi_wl_display_unref(chain->display);
   1248 
   1249    wsi_swapchain_finish(&chain->base);
   1250 
   1251    vk_free(pAllocator, chain);
   1252 
   1253    return VK_SUCCESS;
   1254 }
   1255 
   1256 static VkResult
   1257 wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
   1258                                 VkDevice device,
   1259                                 struct wsi_device *wsi_device,
   1260                                 const VkSwapchainCreateInfoKHR* pCreateInfo,
   1261                                 const VkAllocationCallbacks* pAllocator,
   1262                                 struct wsi_swapchain **swapchain_out)
   1263 {
   1264    VkIcdSurfaceWayland *surface = (VkIcdSurfaceWayland *)icd_surface;
   1265    struct wsi_wayland *wsi =
   1266       (struct wsi_wayland *)wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND];
   1267    struct wsi_wl_swapchain *chain;
   1268    VkResult result;
   1269 
   1270    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
   1271 
   1272    int num_images = pCreateInfo->minImageCount;
   1273 
   1274    size_t size = sizeof(*chain) + num_images * sizeof(chain->images[0]);
   1275    chain = vk_zalloc(pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   1276    if (chain == NULL)
   1277       return VK_ERROR_OUT_OF_HOST_MEMORY;
   1278 
   1279    result = wsi_swapchain_init(wsi_device, &chain->base, device,
   1280                                pCreateInfo, pAllocator);
   1281    if (result != VK_SUCCESS) {
   1282       vk_free(pAllocator, chain);
   1283       return result;
   1284    }
   1285 
   1286    bool alpha = pCreateInfo->compositeAlpha ==
   1287                       VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR;
   1288 
   1289    chain->base.destroy = wsi_wl_swapchain_destroy;
   1290    chain->base.get_wsi_image = wsi_wl_swapchain_get_wsi_image;
   1291    chain->base.acquire_next_image = wsi_wl_swapchain_acquire_next_image;
   1292    chain->base.queue_present = wsi_wl_swapchain_queue_present;
   1293    chain->base.present_mode = wsi_swapchain_get_present_mode(wsi_device, pCreateInfo);
   1294    chain->base.image_count = num_images;
   1295    chain->extent = pCreateInfo->imageExtent;
   1296    chain->vk_format = pCreateInfo->imageFormat;
   1297    if (wsi_device->sw)
   1298       chain->shm_format = wl_shm_format_for_vk_format(chain->vk_format, alpha);
   1299    else
   1300       chain->drm_format = wl_drm_format_for_vk_format(chain->vk_format, alpha);
   1301 
   1302    if (pCreateInfo->oldSwapchain) {
   1303       /* If we have an oldSwapchain parameter, copy the display struct over
   1304        * from the old one so we don't have to fully re-initialize it.
   1305        */
   1306       VK_FROM_HANDLE(wsi_wl_swapchain, old_chain, pCreateInfo->oldSwapchain);
   1307       chain->display = wsi_wl_display_ref(old_chain->display);
   1308    } else {
   1309       chain->display = NULL;
   1310       result = wsi_wl_display_create(wsi, surface->display,
   1311                                      wsi_device->sw, &chain->display);
   1312       if (result != VK_SUCCESS)
   1313          goto fail;
   1314    }
   1315 
   1316    chain->surface = wl_proxy_create_wrapper(surface->surface);
   1317    if (!chain->surface) {
   1318       result = VK_ERROR_OUT_OF_HOST_MEMORY;
   1319       goto fail;
   1320    }
   1321    wl_proxy_set_queue((struct wl_proxy *) chain->surface,
   1322                       chain->display->queue);
   1323 
   1324    chain->num_drm_modifiers = 0;
   1325    chain->drm_modifiers = 0;
   1326 
   1327    /* Use explicit DRM format modifiers when both the server and the driver
   1328     * support them.
   1329     */
   1330    if (chain->display->wl_dmabuf && chain->base.wsi->supports_modifiers) {
   1331       struct wsi_wl_format *f = find_format(&chain->display->formats, chain->vk_format);
   1332       if (f) {
   1333          chain->drm_modifiers = u_vector_tail(&f->modifiers);
   1334          chain->num_drm_modifiers = u_vector_length(&f->modifiers);
   1335       }
   1336    }
   1337 
   1338    chain->fifo_ready = true;
   1339 
   1340    for (uint32_t i = 0; i < chain->base.image_count; i++) {
   1341       result = wsi_wl_image_init(chain, &chain->images[i],
   1342                                  pCreateInfo, pAllocator);
   1343       if (result != VK_SUCCESS)
   1344          goto fail;
   1345       chain->images[i].busy = false;
   1346    }
   1347 
   1348    *swapchain_out = &chain->base;
   1349 
   1350    return VK_SUCCESS;
   1351 
   1352 fail:
   1353    wsi_wl_swapchain_destroy(&chain->base, pAllocator);
   1354 
   1355    return result;
   1356 }
   1357 
   1358 VkResult
   1359 wsi_wl_init_wsi(struct wsi_device *wsi_device,
   1360                 const VkAllocationCallbacks *alloc,
   1361                 VkPhysicalDevice physical_device)
   1362 {
   1363    struct wsi_wayland *wsi;
   1364    VkResult result;
   1365 
   1366    wsi = vk_alloc(alloc, sizeof(*wsi), 8,
   1367                    VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
   1368    if (!wsi) {
   1369       result = VK_ERROR_OUT_OF_HOST_MEMORY;
   1370       goto fail;
   1371    }
   1372 
   1373    wsi->physical_device = physical_device;
   1374    wsi->alloc = alloc;
   1375    wsi->wsi = wsi_device;
   1376 
   1377    wsi->base.get_support = wsi_wl_surface_get_support;
   1378    wsi->base.get_capabilities2 = wsi_wl_surface_get_capabilities2;
   1379    wsi->base.get_formats = wsi_wl_surface_get_formats;
   1380    wsi->base.get_formats2 = wsi_wl_surface_get_formats2;
   1381    wsi->base.get_present_modes = wsi_wl_surface_get_present_modes;
   1382    wsi->base.get_present_rectangles = wsi_wl_surface_get_present_rectangles;
   1383    wsi->base.create_swapchain = wsi_wl_surface_create_swapchain;
   1384 
   1385    wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND] = &wsi->base;
   1386 
   1387    return VK_SUCCESS;
   1388 
   1389 fail:
   1390    wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND] = NULL;
   1391 
   1392    return result;
   1393 }
   1394 
   1395 void
   1396 wsi_wl_finish_wsi(struct wsi_device *wsi_device,
   1397                   const VkAllocationCallbacks *alloc)
   1398 {
   1399    struct wsi_wayland *wsi =
   1400       (struct wsi_wayland *)wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND];
   1401    if (!wsi)
   1402       return;
   1403 
   1404    vk_free(alloc, wsi);
   1405 }
   1406