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