1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2017 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 "wsi_common_private.h" 25bf215546Sopenharmony_ci#include "wsi_common_entrypoints.h" 26bf215546Sopenharmony_ci#include "util/debug.h" 27bf215546Sopenharmony_ci#include "util/macros.h" 28bf215546Sopenharmony_ci#include "util/os_file.h" 29bf215546Sopenharmony_ci#include "util/xmlconfig.h" 30bf215546Sopenharmony_ci#include "vk_device.h" 31bf215546Sopenharmony_ci#include "vk_fence.h" 32bf215546Sopenharmony_ci#include "vk_format.h" 33bf215546Sopenharmony_ci#include "vk_instance.h" 34bf215546Sopenharmony_ci#include "vk_physical_device.h" 35bf215546Sopenharmony_ci#include "vk_queue.h" 36bf215546Sopenharmony_ci#include "vk_semaphore.h" 37bf215546Sopenharmony_ci#include "vk_sync.h" 38bf215546Sopenharmony_ci#include "vk_sync_dummy.h" 39bf215546Sopenharmony_ci#include "vk_util.h" 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci#include <time.h> 42bf215546Sopenharmony_ci#include <stdlib.h> 43bf215546Sopenharmony_ci#include <stdio.h> 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci#ifndef _WIN32 46bf215546Sopenharmony_ci#include <unistd.h> 47bf215546Sopenharmony_ci#endif 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ciuint64_t WSI_DEBUG; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_cistatic const struct debug_control debug_control[] = { 52bf215546Sopenharmony_ci { "buffer", WSI_DEBUG_BUFFER }, 53bf215546Sopenharmony_ci { "sw", WSI_DEBUG_SW }, 54bf215546Sopenharmony_ci { "noshm", WSI_DEBUG_NOSHM }, 55bf215546Sopenharmony_ci { "linear", WSI_DEBUG_LINEAR }, 56bf215546Sopenharmony_ci { NULL, }, 57bf215546Sopenharmony_ci}; 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ciVkResult 60bf215546Sopenharmony_ciwsi_device_init(struct wsi_device *wsi, 61bf215546Sopenharmony_ci VkPhysicalDevice pdevice, 62bf215546Sopenharmony_ci WSI_FN_GetPhysicalDeviceProcAddr proc_addr, 63bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 64bf215546Sopenharmony_ci int display_fd, 65bf215546Sopenharmony_ci const struct driOptionCache *dri_options, 66bf215546Sopenharmony_ci bool sw_device) 67bf215546Sopenharmony_ci{ 68bf215546Sopenharmony_ci const char *present_mode; 69bf215546Sopenharmony_ci UNUSED VkResult result; 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci WSI_DEBUG = parse_debug_string(getenv("MESA_VK_WSI_DEBUG"), debug_control); 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci memset(wsi, 0, sizeof(*wsi)); 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci wsi->instance_alloc = *alloc; 76bf215546Sopenharmony_ci wsi->pdevice = pdevice; 77bf215546Sopenharmony_ci wsi->sw = sw_device || (WSI_DEBUG & WSI_DEBUG_SW); 78bf215546Sopenharmony_ci wsi->wants_linear = (WSI_DEBUG & WSI_DEBUG_LINEAR) != 0; 79bf215546Sopenharmony_ci#define WSI_GET_CB(func) \ 80bf215546Sopenharmony_ci PFN_vk##func func = (PFN_vk##func)proc_addr(pdevice, "vk" #func) 81bf215546Sopenharmony_ci WSI_GET_CB(GetPhysicalDeviceExternalSemaphoreProperties); 82bf215546Sopenharmony_ci WSI_GET_CB(GetPhysicalDeviceProperties2); 83bf215546Sopenharmony_ci WSI_GET_CB(GetPhysicalDeviceMemoryProperties); 84bf215546Sopenharmony_ci WSI_GET_CB(GetPhysicalDeviceQueueFamilyProperties); 85bf215546Sopenharmony_ci#undef WSI_GET_CB 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci wsi->pci_bus_info.sType = 88bf215546Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT; 89bf215546Sopenharmony_ci VkPhysicalDeviceProperties2 pdp2 = { 90bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, 91bf215546Sopenharmony_ci .pNext = &wsi->pci_bus_info, 92bf215546Sopenharmony_ci }; 93bf215546Sopenharmony_ci GetPhysicalDeviceProperties2(pdevice, &pdp2); 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci wsi->maxImageDimension2D = pdp2.properties.limits.maxImageDimension2D; 96bf215546Sopenharmony_ci assert(pdp2.properties.limits.optimalBufferCopyRowPitchAlignment <= UINT32_MAX); 97bf215546Sopenharmony_ci wsi->optimalBufferCopyRowPitchAlignment = 98bf215546Sopenharmony_ci pdp2.properties.limits.optimalBufferCopyRowPitchAlignment; 99bf215546Sopenharmony_ci wsi->override_present_mode = VK_PRESENT_MODE_MAX_ENUM_KHR; 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci GetPhysicalDeviceMemoryProperties(pdevice, &wsi->memory_props); 102bf215546Sopenharmony_ci GetPhysicalDeviceQueueFamilyProperties(pdevice, &wsi->queue_family_count, NULL); 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci for (VkExternalSemaphoreHandleTypeFlags handle_type = 1; 105bf215546Sopenharmony_ci handle_type <= VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; 106bf215546Sopenharmony_ci handle_type <<= 1) { 107bf215546Sopenharmony_ci const VkPhysicalDeviceExternalSemaphoreInfo esi = { 108bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, 109bf215546Sopenharmony_ci .handleType = handle_type, 110bf215546Sopenharmony_ci }; 111bf215546Sopenharmony_ci VkExternalSemaphoreProperties esp = { 112bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES, 113bf215546Sopenharmony_ci }; 114bf215546Sopenharmony_ci GetPhysicalDeviceExternalSemaphoreProperties(pdevice, &esi, &esp); 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci if (esp.externalSemaphoreFeatures & 117bf215546Sopenharmony_ci VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) 118bf215546Sopenharmony_ci wsi->semaphore_export_handle_types |= handle_type; 119bf215546Sopenharmony_ci } 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci const struct vk_device_extension_table *supported_extensions = 122bf215546Sopenharmony_ci &vk_physical_device_from_handle(pdevice)->supported_extensions; 123bf215546Sopenharmony_ci wsi->has_import_memory_host = 124bf215546Sopenharmony_ci supported_extensions->EXT_external_memory_host; 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci list_inithead(&wsi->hotplug_fences); 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci#define WSI_GET_CB(func) \ 129bf215546Sopenharmony_ci wsi->func = (PFN_vk##func)proc_addr(pdevice, "vk" #func) 130bf215546Sopenharmony_ci WSI_GET_CB(AllocateMemory); 131bf215546Sopenharmony_ci WSI_GET_CB(AllocateCommandBuffers); 132bf215546Sopenharmony_ci WSI_GET_CB(BindBufferMemory); 133bf215546Sopenharmony_ci WSI_GET_CB(BindImageMemory); 134bf215546Sopenharmony_ci WSI_GET_CB(BeginCommandBuffer); 135bf215546Sopenharmony_ci WSI_GET_CB(CmdPipelineBarrier); 136bf215546Sopenharmony_ci WSI_GET_CB(CmdCopyImageToBuffer); 137bf215546Sopenharmony_ci WSI_GET_CB(CreateBuffer); 138bf215546Sopenharmony_ci WSI_GET_CB(CreateCommandPool); 139bf215546Sopenharmony_ci WSI_GET_CB(CreateFence); 140bf215546Sopenharmony_ci WSI_GET_CB(CreateImage); 141bf215546Sopenharmony_ci WSI_GET_CB(CreateSemaphore); 142bf215546Sopenharmony_ci WSI_GET_CB(DestroyBuffer); 143bf215546Sopenharmony_ci WSI_GET_CB(DestroyCommandPool); 144bf215546Sopenharmony_ci WSI_GET_CB(DestroyFence); 145bf215546Sopenharmony_ci WSI_GET_CB(DestroyImage); 146bf215546Sopenharmony_ci WSI_GET_CB(DestroySemaphore); 147bf215546Sopenharmony_ci WSI_GET_CB(EndCommandBuffer); 148bf215546Sopenharmony_ci WSI_GET_CB(FreeMemory); 149bf215546Sopenharmony_ci WSI_GET_CB(FreeCommandBuffers); 150bf215546Sopenharmony_ci WSI_GET_CB(GetBufferMemoryRequirements); 151bf215546Sopenharmony_ci WSI_GET_CB(GetImageDrmFormatModifierPropertiesEXT); 152bf215546Sopenharmony_ci WSI_GET_CB(GetImageMemoryRequirements); 153bf215546Sopenharmony_ci WSI_GET_CB(GetImageSubresourceLayout); 154bf215546Sopenharmony_ci if (!wsi->sw) 155bf215546Sopenharmony_ci WSI_GET_CB(GetMemoryFdKHR); 156bf215546Sopenharmony_ci WSI_GET_CB(GetPhysicalDeviceFormatProperties); 157bf215546Sopenharmony_ci WSI_GET_CB(GetPhysicalDeviceFormatProperties2KHR); 158bf215546Sopenharmony_ci WSI_GET_CB(GetPhysicalDeviceImageFormatProperties2); 159bf215546Sopenharmony_ci WSI_GET_CB(GetSemaphoreFdKHR); 160bf215546Sopenharmony_ci WSI_GET_CB(ResetFences); 161bf215546Sopenharmony_ci WSI_GET_CB(QueueSubmit); 162bf215546Sopenharmony_ci WSI_GET_CB(WaitForFences); 163bf215546Sopenharmony_ci WSI_GET_CB(MapMemory); 164bf215546Sopenharmony_ci WSI_GET_CB(UnmapMemory); 165bf215546Sopenharmony_ci#undef WSI_GET_CB 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_XCB_KHR 168bf215546Sopenharmony_ci result = wsi_x11_init_wsi(wsi, alloc, dri_options); 169bf215546Sopenharmony_ci if (result != VK_SUCCESS) 170bf215546Sopenharmony_ci goto fail; 171bf215546Sopenharmony_ci#endif 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_WAYLAND_KHR 174bf215546Sopenharmony_ci result = wsi_wl_init_wsi(wsi, alloc, pdevice); 175bf215546Sopenharmony_ci if (result != VK_SUCCESS) 176bf215546Sopenharmony_ci goto fail; 177bf215546Sopenharmony_ci#endif 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_WIN32_KHR 180bf215546Sopenharmony_ci result = wsi_win32_init_wsi(wsi, alloc, pdevice); 181bf215546Sopenharmony_ci if (result != VK_SUCCESS) 182bf215546Sopenharmony_ci goto fail; 183bf215546Sopenharmony_ci#endif 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_DISPLAY_KHR 186bf215546Sopenharmony_ci result = wsi_display_init_wsi(wsi, alloc, display_fd); 187bf215546Sopenharmony_ci if (result != VK_SUCCESS) 188bf215546Sopenharmony_ci goto fail; 189bf215546Sopenharmony_ci#endif 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci present_mode = getenv("MESA_VK_WSI_PRESENT_MODE"); 192bf215546Sopenharmony_ci if (present_mode) { 193bf215546Sopenharmony_ci if (!strcmp(present_mode, "fifo")) { 194bf215546Sopenharmony_ci wsi->override_present_mode = VK_PRESENT_MODE_FIFO_KHR; 195bf215546Sopenharmony_ci } else if (!strcmp(present_mode, "relaxed")) { 196bf215546Sopenharmony_ci wsi->override_present_mode = VK_PRESENT_MODE_FIFO_RELAXED_KHR; 197bf215546Sopenharmony_ci } else if (!strcmp(present_mode, "mailbox")) { 198bf215546Sopenharmony_ci wsi->override_present_mode = VK_PRESENT_MODE_MAILBOX_KHR; 199bf215546Sopenharmony_ci } else if (!strcmp(present_mode, "immediate")) { 200bf215546Sopenharmony_ci wsi->override_present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; 201bf215546Sopenharmony_ci } else { 202bf215546Sopenharmony_ci fprintf(stderr, "Invalid MESA_VK_WSI_PRESENT_MODE value!\n"); 203bf215546Sopenharmony_ci } 204bf215546Sopenharmony_ci } 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci if (dri_options) { 207bf215546Sopenharmony_ci if (driCheckOption(dri_options, "adaptive_sync", DRI_BOOL)) 208bf215546Sopenharmony_ci wsi->enable_adaptive_sync = driQueryOptionb(dri_options, 209bf215546Sopenharmony_ci "adaptive_sync"); 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci if (driCheckOption(dri_options, "vk_wsi_force_bgra8_unorm_first", DRI_BOOL)) { 212bf215546Sopenharmony_ci wsi->force_bgra8_unorm_first = 213bf215546Sopenharmony_ci driQueryOptionb(dri_options, "vk_wsi_force_bgra8_unorm_first"); 214bf215546Sopenharmony_ci } 215bf215546Sopenharmony_ci } 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci return VK_SUCCESS; 218bf215546Sopenharmony_ci#if defined(VK_USE_PLATFORM_XCB_KHR) || \ 219bf215546Sopenharmony_ci defined(VK_USE_PLATFORM_WAYLAND_KHR) || \ 220bf215546Sopenharmony_ci defined(VK_USE_PLATFORM_WIN32_KHR) || \ 221bf215546Sopenharmony_ci defined(VK_USE_PLATFORM_DISPLAY_KHR) 222bf215546Sopenharmony_cifail: 223bf215546Sopenharmony_ci wsi_device_finish(wsi, alloc); 224bf215546Sopenharmony_ci return result; 225bf215546Sopenharmony_ci#endif 226bf215546Sopenharmony_ci} 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_civoid 229bf215546Sopenharmony_ciwsi_device_finish(struct wsi_device *wsi, 230bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc) 231bf215546Sopenharmony_ci{ 232bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_DISPLAY_KHR 233bf215546Sopenharmony_ci wsi_display_finish_wsi(wsi, alloc); 234bf215546Sopenharmony_ci#endif 235bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_WAYLAND_KHR 236bf215546Sopenharmony_ci wsi_wl_finish_wsi(wsi, alloc); 237bf215546Sopenharmony_ci#endif 238bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_WIN32_KHR 239bf215546Sopenharmony_ci wsi_win32_finish_wsi(wsi, alloc); 240bf215546Sopenharmony_ci#endif 241bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_XCB_KHR 242bf215546Sopenharmony_ci wsi_x11_finish_wsi(wsi, alloc); 243bf215546Sopenharmony_ci#endif 244bf215546Sopenharmony_ci} 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 247bf215546Sopenharmony_ciwsi_DestroySurfaceKHR(VkInstance _instance, 248bf215546Sopenharmony_ci VkSurfaceKHR _surface, 249bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 250bf215546Sopenharmony_ci{ 251bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_instance, instance, _instance); 252bf215546Sopenharmony_ci ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci if (!surface) 255bf215546Sopenharmony_ci return; 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci vk_free2(&instance->alloc, pAllocator, surface); 258bf215546Sopenharmony_ci} 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_civoid 261bf215546Sopenharmony_ciwsi_device_setup_syncobj_fd(struct wsi_device *wsi_device, 262bf215546Sopenharmony_ci int fd) 263bf215546Sopenharmony_ci{ 264bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_DISPLAY_KHR 265bf215546Sopenharmony_ci wsi_display_setup_syncobj_fd(wsi_device, fd); 266bf215546Sopenharmony_ci#endif 267bf215546Sopenharmony_ci} 268bf215546Sopenharmony_ci 269bf215546Sopenharmony_ciVkResult 270bf215546Sopenharmony_ciwsi_swapchain_init(const struct wsi_device *wsi, 271bf215546Sopenharmony_ci struct wsi_swapchain *chain, 272bf215546Sopenharmony_ci VkDevice _device, 273bf215546Sopenharmony_ci const VkSwapchainCreateInfoKHR *pCreateInfo, 274bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 275bf215546Sopenharmony_ci bool use_buffer_blit) 276bf215546Sopenharmony_ci{ 277bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_device, device, _device); 278bf215546Sopenharmony_ci VkResult result; 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci memset(chain, 0, sizeof(*chain)); 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci vk_object_base_init(device, &chain->base, VK_OBJECT_TYPE_SWAPCHAIN_KHR); 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci chain->wsi = wsi; 285bf215546Sopenharmony_ci chain->device = _device; 286bf215546Sopenharmony_ci chain->alloc = *pAllocator; 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci chain->use_buffer_blit = use_buffer_blit || (WSI_DEBUG & WSI_DEBUG_BUFFER); 289bf215546Sopenharmony_ci if (wsi->sw && !wsi->wants_linear) 290bf215546Sopenharmony_ci chain->use_buffer_blit = true; 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci chain->buffer_blit_queue = VK_NULL_HANDLE; 293bf215546Sopenharmony_ci if (use_buffer_blit && wsi->get_buffer_blit_queue) 294bf215546Sopenharmony_ci chain->buffer_blit_queue = wsi->get_buffer_blit_queue(_device); 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci int cmd_pools_count = chain->buffer_blit_queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count; 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci chain->cmd_pools = 299bf215546Sopenharmony_ci vk_zalloc(pAllocator, sizeof(VkCommandPool) * cmd_pools_count, 8, 300bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 301bf215546Sopenharmony_ci if (!chain->cmd_pools) 302bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci for (uint32_t i = 0; i < cmd_pools_count; i++) { 305bf215546Sopenharmony_ci int queue_family_index = i; 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci if (chain->buffer_blit_queue != VK_NULL_HANDLE) { 308bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_queue, queue, chain->buffer_blit_queue); 309bf215546Sopenharmony_ci queue_family_index = queue->queue_family_index; 310bf215546Sopenharmony_ci } 311bf215546Sopenharmony_ci const VkCommandPoolCreateInfo cmd_pool_info = { 312bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, 313bf215546Sopenharmony_ci .pNext = NULL, 314bf215546Sopenharmony_ci .flags = 0, 315bf215546Sopenharmony_ci .queueFamilyIndex = queue_family_index, 316bf215546Sopenharmony_ci }; 317bf215546Sopenharmony_ci result = wsi->CreateCommandPool(_device, &cmd_pool_info, &chain->alloc, 318bf215546Sopenharmony_ci &chain->cmd_pools[i]); 319bf215546Sopenharmony_ci if (result != VK_SUCCESS) 320bf215546Sopenharmony_ci goto fail; 321bf215546Sopenharmony_ci } 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci return VK_SUCCESS; 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_cifail: 326bf215546Sopenharmony_ci wsi_swapchain_finish(chain); 327bf215546Sopenharmony_ci return result; 328bf215546Sopenharmony_ci} 329bf215546Sopenharmony_ci 330bf215546Sopenharmony_cistatic bool 331bf215546Sopenharmony_ciwsi_swapchain_is_present_mode_supported(struct wsi_device *wsi, 332bf215546Sopenharmony_ci const VkSwapchainCreateInfoKHR *pCreateInfo, 333bf215546Sopenharmony_ci VkPresentModeKHR mode) 334bf215546Sopenharmony_ci{ 335bf215546Sopenharmony_ci ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pCreateInfo->surface); 336bf215546Sopenharmony_ci struct wsi_interface *iface = wsi->wsi[surface->platform]; 337bf215546Sopenharmony_ci VkPresentModeKHR *present_modes; 338bf215546Sopenharmony_ci uint32_t present_mode_count; 339bf215546Sopenharmony_ci bool supported = false; 340bf215546Sopenharmony_ci VkResult result; 341bf215546Sopenharmony_ci 342bf215546Sopenharmony_ci result = iface->get_present_modes(surface, &present_mode_count, NULL); 343bf215546Sopenharmony_ci if (result != VK_SUCCESS) 344bf215546Sopenharmony_ci return supported; 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci present_modes = malloc(present_mode_count * sizeof(*present_modes)); 347bf215546Sopenharmony_ci if (!present_modes) 348bf215546Sopenharmony_ci return supported; 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci result = iface->get_present_modes(surface, &present_mode_count, 351bf215546Sopenharmony_ci present_modes); 352bf215546Sopenharmony_ci if (result != VK_SUCCESS) 353bf215546Sopenharmony_ci goto fail; 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci for (uint32_t i = 0; i < present_mode_count; i++) { 356bf215546Sopenharmony_ci if (present_modes[i] == mode) { 357bf215546Sopenharmony_ci supported = true; 358bf215546Sopenharmony_ci break; 359bf215546Sopenharmony_ci } 360bf215546Sopenharmony_ci } 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_cifail: 363bf215546Sopenharmony_ci free(present_modes); 364bf215546Sopenharmony_ci return supported; 365bf215546Sopenharmony_ci} 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_cienum VkPresentModeKHR 368bf215546Sopenharmony_ciwsi_swapchain_get_present_mode(struct wsi_device *wsi, 369bf215546Sopenharmony_ci const VkSwapchainCreateInfoKHR *pCreateInfo) 370bf215546Sopenharmony_ci{ 371bf215546Sopenharmony_ci if (wsi->override_present_mode == VK_PRESENT_MODE_MAX_ENUM_KHR) 372bf215546Sopenharmony_ci return pCreateInfo->presentMode; 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_ci if (!wsi_swapchain_is_present_mode_supported(wsi, pCreateInfo, 375bf215546Sopenharmony_ci wsi->override_present_mode)) { 376bf215546Sopenharmony_ci fprintf(stderr, "Unsupported MESA_VK_WSI_PRESENT_MODE value!\n"); 377bf215546Sopenharmony_ci return pCreateInfo->presentMode; 378bf215546Sopenharmony_ci } 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci return wsi->override_present_mode; 381bf215546Sopenharmony_ci} 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_civoid 384bf215546Sopenharmony_ciwsi_swapchain_finish(struct wsi_swapchain *chain) 385bf215546Sopenharmony_ci{ 386bf215546Sopenharmony_ci if (chain->fences) { 387bf215546Sopenharmony_ci for (unsigned i = 0; i < chain->image_count; i++) 388bf215546Sopenharmony_ci chain->wsi->DestroyFence(chain->device, chain->fences[i], &chain->alloc); 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_ci vk_free(&chain->alloc, chain->fences); 391bf215546Sopenharmony_ci } 392bf215546Sopenharmony_ci if (chain->buffer_blit_semaphores) { 393bf215546Sopenharmony_ci for (unsigned i = 0; i < chain->image_count; i++) 394bf215546Sopenharmony_ci chain->wsi->DestroySemaphore(chain->device, chain->buffer_blit_semaphores[i], &chain->alloc); 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_ci vk_free(&chain->alloc, chain->buffer_blit_semaphores); 397bf215546Sopenharmony_ci } 398bf215546Sopenharmony_ci chain->wsi->DestroySemaphore(chain->device, chain->dma_buf_semaphore, 399bf215546Sopenharmony_ci &chain->alloc); 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci int cmd_pools_count = chain->buffer_blit_queue != VK_NULL_HANDLE ? 402bf215546Sopenharmony_ci 1 : chain->wsi->queue_family_count; 403bf215546Sopenharmony_ci for (uint32_t i = 0; i < cmd_pools_count; i++) { 404bf215546Sopenharmony_ci chain->wsi->DestroyCommandPool(chain->device, chain->cmd_pools[i], 405bf215546Sopenharmony_ci &chain->alloc); 406bf215546Sopenharmony_ci } 407bf215546Sopenharmony_ci vk_free(&chain->alloc, chain->cmd_pools); 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci vk_object_base_finish(&chain->base); 410bf215546Sopenharmony_ci} 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ciVkResult 413bf215546Sopenharmony_ciwsi_configure_image(const struct wsi_swapchain *chain, 414bf215546Sopenharmony_ci const VkSwapchainCreateInfoKHR *pCreateInfo, 415bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags handle_types, 416bf215546Sopenharmony_ci struct wsi_image_info *info) 417bf215546Sopenharmony_ci{ 418bf215546Sopenharmony_ci memset(info, 0, sizeof(*info)); 419bf215546Sopenharmony_ci uint32_t queue_family_count = 1; 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci if (pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT) 422bf215546Sopenharmony_ci queue_family_count = pCreateInfo->queueFamilyIndexCount; 423bf215546Sopenharmony_ci 424bf215546Sopenharmony_ci /* 425bf215546Sopenharmony_ci * TODO: there should be no reason to allocate this, but 426bf215546Sopenharmony_ci * 15331 shows that games crashed without doing this. 427bf215546Sopenharmony_ci */ 428bf215546Sopenharmony_ci uint32_t *queue_family_indices = 429bf215546Sopenharmony_ci vk_alloc(&chain->alloc, 430bf215546Sopenharmony_ci sizeof(*queue_family_indices) * 431bf215546Sopenharmony_ci queue_family_count, 432bf215546Sopenharmony_ci 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 433bf215546Sopenharmony_ci if (!queue_family_indices) 434bf215546Sopenharmony_ci goto err_oom; 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci if (pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT) 437bf215546Sopenharmony_ci for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; i++) 438bf215546Sopenharmony_ci queue_family_indices[i] = pCreateInfo->pQueueFamilyIndices[i]; 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci info->create = (VkImageCreateInfo) { 441bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 442bf215546Sopenharmony_ci .flags = VK_IMAGE_CREATE_ALIAS_BIT, 443bf215546Sopenharmony_ci .imageType = VK_IMAGE_TYPE_2D, 444bf215546Sopenharmony_ci .format = pCreateInfo->imageFormat, 445bf215546Sopenharmony_ci .extent = { 446bf215546Sopenharmony_ci .width = pCreateInfo->imageExtent.width, 447bf215546Sopenharmony_ci .height = pCreateInfo->imageExtent.height, 448bf215546Sopenharmony_ci .depth = 1, 449bf215546Sopenharmony_ci }, 450bf215546Sopenharmony_ci .mipLevels = 1, 451bf215546Sopenharmony_ci .arrayLayers = 1, 452bf215546Sopenharmony_ci .samples = VK_SAMPLE_COUNT_1_BIT, 453bf215546Sopenharmony_ci .tiling = VK_IMAGE_TILING_OPTIMAL, 454bf215546Sopenharmony_ci .usage = pCreateInfo->imageUsage, 455bf215546Sopenharmony_ci .sharingMode = pCreateInfo->imageSharingMode, 456bf215546Sopenharmony_ci .queueFamilyIndexCount = queue_family_count, 457bf215546Sopenharmony_ci .pQueueFamilyIndices = queue_family_indices, 458bf215546Sopenharmony_ci .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, 459bf215546Sopenharmony_ci }; 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_ci if (handle_types != 0) { 462bf215546Sopenharmony_ci info->ext_mem = (VkExternalMemoryImageCreateInfo) { 463bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, 464bf215546Sopenharmony_ci .handleTypes = handle_types, 465bf215546Sopenharmony_ci }; 466bf215546Sopenharmony_ci __vk_append_struct(&info->create, &info->ext_mem); 467bf215546Sopenharmony_ci } 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_ci info->wsi = (struct wsi_image_create_info) { 470bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA, 471bf215546Sopenharmony_ci }; 472bf215546Sopenharmony_ci __vk_append_struct(&info->create, &info->wsi); 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_ci if (pCreateInfo->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) { 475bf215546Sopenharmony_ci info->create.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | 476bf215546Sopenharmony_ci VK_IMAGE_CREATE_EXTENDED_USAGE_BIT; 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_ci const VkImageFormatListCreateInfo *format_list_in = 479bf215546Sopenharmony_ci vk_find_struct_const(pCreateInfo->pNext, 480bf215546Sopenharmony_ci IMAGE_FORMAT_LIST_CREATE_INFO); 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_ci assume(format_list_in && format_list_in->viewFormatCount > 0); 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci const uint32_t view_format_count = format_list_in->viewFormatCount; 485bf215546Sopenharmony_ci VkFormat *view_formats = 486bf215546Sopenharmony_ci vk_alloc(&chain->alloc, sizeof(VkFormat) * view_format_count, 487bf215546Sopenharmony_ci 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 488bf215546Sopenharmony_ci if (!view_formats) 489bf215546Sopenharmony_ci goto err_oom; 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci ASSERTED bool format_found = false; 492bf215546Sopenharmony_ci for (uint32_t i = 0; i < format_list_in->viewFormatCount; i++) { 493bf215546Sopenharmony_ci if (pCreateInfo->imageFormat == format_list_in->pViewFormats[i]) 494bf215546Sopenharmony_ci format_found = true; 495bf215546Sopenharmony_ci view_formats[i] = format_list_in->pViewFormats[i]; 496bf215546Sopenharmony_ci } 497bf215546Sopenharmony_ci assert(format_found); 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci info->format_list = (VkImageFormatListCreateInfo) { 500bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO, 501bf215546Sopenharmony_ci .viewFormatCount = view_format_count, 502bf215546Sopenharmony_ci .pViewFormats = view_formats, 503bf215546Sopenharmony_ci }; 504bf215546Sopenharmony_ci __vk_append_struct(&info->create, &info->format_list); 505bf215546Sopenharmony_ci } 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci return VK_SUCCESS; 508bf215546Sopenharmony_ci 509bf215546Sopenharmony_cierr_oom: 510bf215546Sopenharmony_ci wsi_destroy_image_info(chain, info); 511bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 512bf215546Sopenharmony_ci} 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_civoid 515bf215546Sopenharmony_ciwsi_destroy_image_info(const struct wsi_swapchain *chain, 516bf215546Sopenharmony_ci struct wsi_image_info *info) 517bf215546Sopenharmony_ci{ 518bf215546Sopenharmony_ci vk_free(&chain->alloc, (void *)info->create.pQueueFamilyIndices); 519bf215546Sopenharmony_ci vk_free(&chain->alloc, (void *)info->format_list.pViewFormats); 520bf215546Sopenharmony_ci vk_free(&chain->alloc, (void *)info->drm_mod_list.pDrmFormatModifiers); 521bf215546Sopenharmony_ci vk_free(&chain->alloc, info->modifier_props); 522bf215546Sopenharmony_ci} 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_ciVkResult 525bf215546Sopenharmony_ciwsi_create_image(const struct wsi_swapchain *chain, 526bf215546Sopenharmony_ci const struct wsi_image_info *info, 527bf215546Sopenharmony_ci struct wsi_image *image) 528bf215546Sopenharmony_ci{ 529bf215546Sopenharmony_ci const struct wsi_device *wsi = chain->wsi; 530bf215546Sopenharmony_ci VkResult result; 531bf215546Sopenharmony_ci 532bf215546Sopenharmony_ci memset(image, 0, sizeof(*image)); 533bf215546Sopenharmony_ci 534bf215546Sopenharmony_ci#ifndef _WIN32 535bf215546Sopenharmony_ci image->dma_buf_fd = -1; 536bf215546Sopenharmony_ci#endif 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci result = wsi->CreateImage(chain->device, &info->create, 539bf215546Sopenharmony_ci &chain->alloc, &image->image); 540bf215546Sopenharmony_ci if (result != VK_SUCCESS) 541bf215546Sopenharmony_ci goto fail; 542bf215546Sopenharmony_ci 543bf215546Sopenharmony_ci result = info->create_mem(chain, info, image); 544bf215546Sopenharmony_ci if (result != VK_SUCCESS) 545bf215546Sopenharmony_ci goto fail; 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_ci result = wsi->BindImageMemory(chain->device, image->image, 548bf215546Sopenharmony_ci image->memory, 0); 549bf215546Sopenharmony_ci if (result != VK_SUCCESS) 550bf215546Sopenharmony_ci goto fail; 551bf215546Sopenharmony_ci 552bf215546Sopenharmony_ci if (info->finish_create) { 553bf215546Sopenharmony_ci result = info->finish_create(chain, info, image); 554bf215546Sopenharmony_ci if (result != VK_SUCCESS) 555bf215546Sopenharmony_ci goto fail; 556bf215546Sopenharmony_ci } 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci return VK_SUCCESS; 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_cifail: 561bf215546Sopenharmony_ci wsi_destroy_image(chain, image); 562bf215546Sopenharmony_ci return result; 563bf215546Sopenharmony_ci} 564bf215546Sopenharmony_ci 565bf215546Sopenharmony_civoid 566bf215546Sopenharmony_ciwsi_destroy_image(const struct wsi_swapchain *chain, 567bf215546Sopenharmony_ci struct wsi_image *image) 568bf215546Sopenharmony_ci{ 569bf215546Sopenharmony_ci const struct wsi_device *wsi = chain->wsi; 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci#ifndef _WIN32 572bf215546Sopenharmony_ci if (image->dma_buf_fd >= 0) 573bf215546Sopenharmony_ci close(image->dma_buf_fd); 574bf215546Sopenharmony_ci#endif 575bf215546Sopenharmony_ci 576bf215546Sopenharmony_ci if (image->cpu_map != NULL) { 577bf215546Sopenharmony_ci wsi->UnmapMemory(chain->device, image->buffer.buffer != VK_NULL_HANDLE ? 578bf215546Sopenharmony_ci image->buffer.memory : image->memory); 579bf215546Sopenharmony_ci } 580bf215546Sopenharmony_ci 581bf215546Sopenharmony_ci if (image->buffer.blit_cmd_buffers) { 582bf215546Sopenharmony_ci int cmd_buffer_count = 583bf215546Sopenharmony_ci chain->buffer_blit_queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count; 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci for (uint32_t i = 0; i < cmd_buffer_count; i++) { 586bf215546Sopenharmony_ci wsi->FreeCommandBuffers(chain->device, chain->cmd_pools[i], 587bf215546Sopenharmony_ci 1, &image->buffer.blit_cmd_buffers[i]); 588bf215546Sopenharmony_ci } 589bf215546Sopenharmony_ci vk_free(&chain->alloc, image->buffer.blit_cmd_buffers); 590bf215546Sopenharmony_ci } 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci wsi->FreeMemory(chain->device, image->memory, &chain->alloc); 593bf215546Sopenharmony_ci wsi->DestroyImage(chain->device, image->image, &chain->alloc); 594bf215546Sopenharmony_ci wsi->FreeMemory(chain->device, image->buffer.memory, &chain->alloc); 595bf215546Sopenharmony_ci wsi->DestroyBuffer(chain->device, image->buffer.buffer, &chain->alloc); 596bf215546Sopenharmony_ci} 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 599bf215546Sopenharmony_ciwsi_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, 600bf215546Sopenharmony_ci uint32_t queueFamilyIndex, 601bf215546Sopenharmony_ci VkSurfaceKHR _surface, 602bf215546Sopenharmony_ci VkBool32 *pSupported) 603bf215546Sopenharmony_ci{ 604bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 605bf215546Sopenharmony_ci ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 606bf215546Sopenharmony_ci struct wsi_device *wsi_device = device->wsi_device; 607bf215546Sopenharmony_ci struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci return iface->get_support(surface, wsi_device, 610bf215546Sopenharmony_ci queueFamilyIndex, pSupported); 611bf215546Sopenharmony_ci} 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 614bf215546Sopenharmony_ciwsi_GetPhysicalDeviceSurfaceCapabilitiesKHR( 615bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, 616bf215546Sopenharmony_ci VkSurfaceKHR _surface, 617bf215546Sopenharmony_ci VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) 618bf215546Sopenharmony_ci{ 619bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 620bf215546Sopenharmony_ci ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 621bf215546Sopenharmony_ci struct wsi_device *wsi_device = device->wsi_device; 622bf215546Sopenharmony_ci struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_ci VkSurfaceCapabilities2KHR caps2 = { 625bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR, 626bf215546Sopenharmony_ci }; 627bf215546Sopenharmony_ci 628bf215546Sopenharmony_ci VkResult result = iface->get_capabilities2(surface, wsi_device, NULL, &caps2); 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci if (result == VK_SUCCESS) 631bf215546Sopenharmony_ci *pSurfaceCapabilities = caps2.surfaceCapabilities; 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci return result; 634bf215546Sopenharmony_ci} 635bf215546Sopenharmony_ci 636bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 637bf215546Sopenharmony_ciwsi_GetPhysicalDeviceSurfaceCapabilities2KHR( 638bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, 639bf215546Sopenharmony_ci const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 640bf215546Sopenharmony_ci VkSurfaceCapabilities2KHR *pSurfaceCapabilities) 641bf215546Sopenharmony_ci{ 642bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 643bf215546Sopenharmony_ci ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface); 644bf215546Sopenharmony_ci struct wsi_device *wsi_device = device->wsi_device; 645bf215546Sopenharmony_ci struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 646bf215546Sopenharmony_ci 647bf215546Sopenharmony_ci return iface->get_capabilities2(surface, wsi_device, pSurfaceInfo->pNext, 648bf215546Sopenharmony_ci pSurfaceCapabilities); 649bf215546Sopenharmony_ci} 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 652bf215546Sopenharmony_ciwsi_GetPhysicalDeviceSurfaceCapabilities2EXT( 653bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, 654bf215546Sopenharmony_ci VkSurfaceKHR _surface, 655bf215546Sopenharmony_ci VkSurfaceCapabilities2EXT *pSurfaceCapabilities) 656bf215546Sopenharmony_ci{ 657bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 658bf215546Sopenharmony_ci ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 659bf215546Sopenharmony_ci struct wsi_device *wsi_device = device->wsi_device; 660bf215546Sopenharmony_ci struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_ci assert(pSurfaceCapabilities->sType == 663bf215546Sopenharmony_ci VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT); 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_ci struct wsi_surface_supported_counters counters = { 666bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_WSI_SURFACE_SUPPORTED_COUNTERS_MESA, 667bf215546Sopenharmony_ci .pNext = pSurfaceCapabilities->pNext, 668bf215546Sopenharmony_ci .supported_surface_counters = 0, 669bf215546Sopenharmony_ci }; 670bf215546Sopenharmony_ci 671bf215546Sopenharmony_ci VkSurfaceCapabilities2KHR caps2 = { 672bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR, 673bf215546Sopenharmony_ci .pNext = &counters, 674bf215546Sopenharmony_ci }; 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci VkResult result = iface->get_capabilities2(surface, wsi_device, NULL, &caps2); 677bf215546Sopenharmony_ci 678bf215546Sopenharmony_ci if (result == VK_SUCCESS) { 679bf215546Sopenharmony_ci VkSurfaceCapabilities2EXT *ext_caps = pSurfaceCapabilities; 680bf215546Sopenharmony_ci VkSurfaceCapabilitiesKHR khr_caps = caps2.surfaceCapabilities; 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci ext_caps->minImageCount = khr_caps.minImageCount; 683bf215546Sopenharmony_ci ext_caps->maxImageCount = khr_caps.maxImageCount; 684bf215546Sopenharmony_ci ext_caps->currentExtent = khr_caps.currentExtent; 685bf215546Sopenharmony_ci ext_caps->minImageExtent = khr_caps.minImageExtent; 686bf215546Sopenharmony_ci ext_caps->maxImageExtent = khr_caps.maxImageExtent; 687bf215546Sopenharmony_ci ext_caps->maxImageArrayLayers = khr_caps.maxImageArrayLayers; 688bf215546Sopenharmony_ci ext_caps->supportedTransforms = khr_caps.supportedTransforms; 689bf215546Sopenharmony_ci ext_caps->currentTransform = khr_caps.currentTransform; 690bf215546Sopenharmony_ci ext_caps->supportedCompositeAlpha = khr_caps.supportedCompositeAlpha; 691bf215546Sopenharmony_ci ext_caps->supportedUsageFlags = khr_caps.supportedUsageFlags; 692bf215546Sopenharmony_ci ext_caps->supportedSurfaceCounters = counters.supported_surface_counters; 693bf215546Sopenharmony_ci } 694bf215546Sopenharmony_ci 695bf215546Sopenharmony_ci return result; 696bf215546Sopenharmony_ci} 697bf215546Sopenharmony_ci 698bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 699bf215546Sopenharmony_ciwsi_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, 700bf215546Sopenharmony_ci VkSurfaceKHR _surface, 701bf215546Sopenharmony_ci uint32_t *pSurfaceFormatCount, 702bf215546Sopenharmony_ci VkSurfaceFormatKHR *pSurfaceFormats) 703bf215546Sopenharmony_ci{ 704bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 705bf215546Sopenharmony_ci ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 706bf215546Sopenharmony_ci struct wsi_device *wsi_device = device->wsi_device; 707bf215546Sopenharmony_ci struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 708bf215546Sopenharmony_ci 709bf215546Sopenharmony_ci return iface->get_formats(surface, wsi_device, 710bf215546Sopenharmony_ci pSurfaceFormatCount, pSurfaceFormats); 711bf215546Sopenharmony_ci} 712bf215546Sopenharmony_ci 713bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 714bf215546Sopenharmony_ciwsi_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, 715bf215546Sopenharmony_ci const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo, 716bf215546Sopenharmony_ci uint32_t *pSurfaceFormatCount, 717bf215546Sopenharmony_ci VkSurfaceFormat2KHR *pSurfaceFormats) 718bf215546Sopenharmony_ci{ 719bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 720bf215546Sopenharmony_ci ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface); 721bf215546Sopenharmony_ci struct wsi_device *wsi_device = device->wsi_device; 722bf215546Sopenharmony_ci struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 723bf215546Sopenharmony_ci 724bf215546Sopenharmony_ci return iface->get_formats2(surface, wsi_device, pSurfaceInfo->pNext, 725bf215546Sopenharmony_ci pSurfaceFormatCount, pSurfaceFormats); 726bf215546Sopenharmony_ci} 727bf215546Sopenharmony_ci 728bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 729bf215546Sopenharmony_ciwsi_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, 730bf215546Sopenharmony_ci VkSurfaceKHR _surface, 731bf215546Sopenharmony_ci uint32_t *pPresentModeCount, 732bf215546Sopenharmony_ci VkPresentModeKHR *pPresentModes) 733bf215546Sopenharmony_ci{ 734bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 735bf215546Sopenharmony_ci ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 736bf215546Sopenharmony_ci struct wsi_device *wsi_device = device->wsi_device; 737bf215546Sopenharmony_ci struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 738bf215546Sopenharmony_ci 739bf215546Sopenharmony_ci return iface->get_present_modes(surface, pPresentModeCount, 740bf215546Sopenharmony_ci pPresentModes); 741bf215546Sopenharmony_ci} 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 744bf215546Sopenharmony_ciwsi_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, 745bf215546Sopenharmony_ci VkSurfaceKHR _surface, 746bf215546Sopenharmony_ci uint32_t *pRectCount, 747bf215546Sopenharmony_ci VkRect2D *pRects) 748bf215546Sopenharmony_ci{ 749bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 750bf215546Sopenharmony_ci ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 751bf215546Sopenharmony_ci struct wsi_device *wsi_device = device->wsi_device; 752bf215546Sopenharmony_ci struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 753bf215546Sopenharmony_ci 754bf215546Sopenharmony_ci return iface->get_present_rectangles(surface, wsi_device, 755bf215546Sopenharmony_ci pRectCount, pRects); 756bf215546Sopenharmony_ci} 757bf215546Sopenharmony_ci 758bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 759bf215546Sopenharmony_ciwsi_CreateSwapchainKHR(VkDevice _device, 760bf215546Sopenharmony_ci const VkSwapchainCreateInfoKHR *pCreateInfo, 761bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 762bf215546Sopenharmony_ci VkSwapchainKHR *pSwapchain) 763bf215546Sopenharmony_ci{ 764bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_device, device, _device); 765bf215546Sopenharmony_ci ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pCreateInfo->surface); 766bf215546Sopenharmony_ci struct wsi_device *wsi_device = device->physical->wsi_device; 767bf215546Sopenharmony_ci struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 768bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc; 769bf215546Sopenharmony_ci struct wsi_swapchain *swapchain; 770bf215546Sopenharmony_ci 771bf215546Sopenharmony_ci if (pAllocator) 772bf215546Sopenharmony_ci alloc = pAllocator; 773bf215546Sopenharmony_ci else 774bf215546Sopenharmony_ci alloc = &device->alloc; 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_ci VkResult result = iface->create_swapchain(surface, _device, wsi_device, 777bf215546Sopenharmony_ci pCreateInfo, alloc, 778bf215546Sopenharmony_ci &swapchain); 779bf215546Sopenharmony_ci if (result != VK_SUCCESS) 780bf215546Sopenharmony_ci return result; 781bf215546Sopenharmony_ci 782bf215546Sopenharmony_ci swapchain->fences = vk_zalloc(alloc, 783bf215546Sopenharmony_ci sizeof (*swapchain->fences) * swapchain->image_count, 784bf215546Sopenharmony_ci sizeof (*swapchain->fences), 785bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 786bf215546Sopenharmony_ci if (!swapchain->fences) { 787bf215546Sopenharmony_ci swapchain->destroy(swapchain, alloc); 788bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 789bf215546Sopenharmony_ci } 790bf215546Sopenharmony_ci 791bf215546Sopenharmony_ci if (swapchain->buffer_blit_queue != VK_NULL_HANDLE) { 792bf215546Sopenharmony_ci swapchain->buffer_blit_semaphores = vk_zalloc(alloc, 793bf215546Sopenharmony_ci sizeof (*swapchain->buffer_blit_semaphores) * swapchain->image_count, 794bf215546Sopenharmony_ci sizeof (*swapchain->buffer_blit_semaphores), 795bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 796bf215546Sopenharmony_ci if (!swapchain->buffer_blit_semaphores) { 797bf215546Sopenharmony_ci swapchain->destroy(swapchain, alloc); 798bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 799bf215546Sopenharmony_ci } 800bf215546Sopenharmony_ci } 801bf215546Sopenharmony_ci 802bf215546Sopenharmony_ci *pSwapchain = wsi_swapchain_to_handle(swapchain); 803bf215546Sopenharmony_ci 804bf215546Sopenharmony_ci return VK_SUCCESS; 805bf215546Sopenharmony_ci} 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 808bf215546Sopenharmony_ciwsi_DestroySwapchainKHR(VkDevice _device, 809bf215546Sopenharmony_ci VkSwapchainKHR _swapchain, 810bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 811bf215546Sopenharmony_ci{ 812bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_device, device, _device); 813bf215546Sopenharmony_ci VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain); 814bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc; 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ci if (!swapchain) 817bf215546Sopenharmony_ci return; 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci if (pAllocator) 820bf215546Sopenharmony_ci alloc = pAllocator; 821bf215546Sopenharmony_ci else 822bf215546Sopenharmony_ci alloc = &device->alloc; 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_ci swapchain->destroy(swapchain, alloc); 825bf215546Sopenharmony_ci} 826bf215546Sopenharmony_ci 827bf215546Sopenharmony_ciVkResult 828bf215546Sopenharmony_ciwsi_common_get_images(VkSwapchainKHR _swapchain, 829bf215546Sopenharmony_ci uint32_t *pSwapchainImageCount, 830bf215546Sopenharmony_ci VkImage *pSwapchainImages) 831bf215546Sopenharmony_ci{ 832bf215546Sopenharmony_ci VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain); 833bf215546Sopenharmony_ci VK_OUTARRAY_MAKE_TYPED(VkImage, images, pSwapchainImages, pSwapchainImageCount); 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci for (uint32_t i = 0; i < swapchain->image_count; i++) { 836bf215546Sopenharmony_ci vk_outarray_append_typed(VkImage, &images, image) { 837bf215546Sopenharmony_ci *image = swapchain->get_wsi_image(swapchain, i)->image; 838bf215546Sopenharmony_ci } 839bf215546Sopenharmony_ci } 840bf215546Sopenharmony_ci 841bf215546Sopenharmony_ci return vk_outarray_status(&images); 842bf215546Sopenharmony_ci} 843bf215546Sopenharmony_ci 844bf215546Sopenharmony_ciVkImage 845bf215546Sopenharmony_ciwsi_common_get_image(VkSwapchainKHR _swapchain, uint32_t index) 846bf215546Sopenharmony_ci{ 847bf215546Sopenharmony_ci VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain); 848bf215546Sopenharmony_ci assert(index < swapchain->image_count); 849bf215546Sopenharmony_ci return swapchain->get_wsi_image(swapchain, index)->image; 850bf215546Sopenharmony_ci} 851bf215546Sopenharmony_ci 852bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 853bf215546Sopenharmony_ciwsi_GetSwapchainImagesKHR(VkDevice device, 854bf215546Sopenharmony_ci VkSwapchainKHR swapchain, 855bf215546Sopenharmony_ci uint32_t *pSwapchainImageCount, 856bf215546Sopenharmony_ci VkImage *pSwapchainImages) 857bf215546Sopenharmony_ci{ 858bf215546Sopenharmony_ci return wsi_common_get_images(swapchain, 859bf215546Sopenharmony_ci pSwapchainImageCount, 860bf215546Sopenharmony_ci pSwapchainImages); 861bf215546Sopenharmony_ci} 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 864bf215546Sopenharmony_ciwsi_AcquireNextImageKHR(VkDevice _device, 865bf215546Sopenharmony_ci VkSwapchainKHR swapchain, 866bf215546Sopenharmony_ci uint64_t timeout, 867bf215546Sopenharmony_ci VkSemaphore semaphore, 868bf215546Sopenharmony_ci VkFence fence, 869bf215546Sopenharmony_ci uint32_t *pImageIndex) 870bf215546Sopenharmony_ci{ 871bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_device, device, _device); 872bf215546Sopenharmony_ci 873bf215546Sopenharmony_ci const VkAcquireNextImageInfoKHR acquire_info = { 874bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR, 875bf215546Sopenharmony_ci .swapchain = swapchain, 876bf215546Sopenharmony_ci .timeout = timeout, 877bf215546Sopenharmony_ci .semaphore = semaphore, 878bf215546Sopenharmony_ci .fence = fence, 879bf215546Sopenharmony_ci .deviceMask = 0, 880bf215546Sopenharmony_ci }; 881bf215546Sopenharmony_ci 882bf215546Sopenharmony_ci return device->dispatch_table.AcquireNextImage2KHR(_device, &acquire_info, 883bf215546Sopenharmony_ci pImageIndex); 884bf215546Sopenharmony_ci} 885bf215546Sopenharmony_ci 886bf215546Sopenharmony_cistatic VkResult 887bf215546Sopenharmony_ciwsi_signal_semaphore_for_image(struct vk_device *device, 888bf215546Sopenharmony_ci const struct wsi_swapchain *chain, 889bf215546Sopenharmony_ci const struct wsi_image *image, 890bf215546Sopenharmony_ci VkSemaphore _semaphore) 891bf215546Sopenharmony_ci{ 892bf215546Sopenharmony_ci if (device->physical->supported_sync_types == NULL) 893bf215546Sopenharmony_ci return VK_SUCCESS; 894bf215546Sopenharmony_ci 895bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_semaphore, semaphore, _semaphore); 896bf215546Sopenharmony_ci 897bf215546Sopenharmony_ci vk_semaphore_reset_temporary(device, semaphore); 898bf215546Sopenharmony_ci 899bf215546Sopenharmony_ci#ifdef HAVE_LIBDRM 900bf215546Sopenharmony_ci VkResult result = wsi_create_sync_for_dma_buf_wait(chain, image, 901bf215546Sopenharmony_ci VK_SYNC_FEATURE_GPU_WAIT, 902bf215546Sopenharmony_ci &semaphore->temporary); 903bf215546Sopenharmony_ci if (result != VK_ERROR_FEATURE_NOT_PRESENT) 904bf215546Sopenharmony_ci return result; 905bf215546Sopenharmony_ci#endif 906bf215546Sopenharmony_ci 907bf215546Sopenharmony_ci if (chain->wsi->signal_semaphore_with_memory) { 908bf215546Sopenharmony_ci return device->create_sync_for_memory(device, image->memory, 909bf215546Sopenharmony_ci false /* signal_memory */, 910bf215546Sopenharmony_ci &semaphore->temporary); 911bf215546Sopenharmony_ci } else { 912bf215546Sopenharmony_ci return vk_sync_create(device, &vk_sync_dummy_type, 913bf215546Sopenharmony_ci 0 /* flags */, 0 /* initial_value */, 914bf215546Sopenharmony_ci &semaphore->temporary); 915bf215546Sopenharmony_ci } 916bf215546Sopenharmony_ci} 917bf215546Sopenharmony_ci 918bf215546Sopenharmony_cistatic VkResult 919bf215546Sopenharmony_ciwsi_signal_fence_for_image(struct vk_device *device, 920bf215546Sopenharmony_ci const struct wsi_swapchain *chain, 921bf215546Sopenharmony_ci const struct wsi_image *image, 922bf215546Sopenharmony_ci VkFence _fence) 923bf215546Sopenharmony_ci{ 924bf215546Sopenharmony_ci if (device->physical->supported_sync_types == NULL) 925bf215546Sopenharmony_ci return VK_SUCCESS; 926bf215546Sopenharmony_ci 927bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_fence, fence, _fence); 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_ci vk_fence_reset_temporary(device, fence); 930bf215546Sopenharmony_ci 931bf215546Sopenharmony_ci#ifdef HAVE_LIBDRM 932bf215546Sopenharmony_ci VkResult result = wsi_create_sync_for_dma_buf_wait(chain, image, 933bf215546Sopenharmony_ci VK_SYNC_FEATURE_CPU_WAIT, 934bf215546Sopenharmony_ci &fence->temporary); 935bf215546Sopenharmony_ci if (result != VK_ERROR_FEATURE_NOT_PRESENT) 936bf215546Sopenharmony_ci return result; 937bf215546Sopenharmony_ci#endif 938bf215546Sopenharmony_ci 939bf215546Sopenharmony_ci if (chain->wsi->signal_fence_with_memory) { 940bf215546Sopenharmony_ci return device->create_sync_for_memory(device, image->memory, 941bf215546Sopenharmony_ci false /* signal_memory */, 942bf215546Sopenharmony_ci &fence->temporary); 943bf215546Sopenharmony_ci } else { 944bf215546Sopenharmony_ci return vk_sync_create(device, &vk_sync_dummy_type, 945bf215546Sopenharmony_ci 0 /* flags */, 0 /* initial_value */, 946bf215546Sopenharmony_ci &fence->temporary); 947bf215546Sopenharmony_ci } 948bf215546Sopenharmony_ci} 949bf215546Sopenharmony_ci 950bf215546Sopenharmony_ciVkResult 951bf215546Sopenharmony_ciwsi_common_acquire_next_image2(const struct wsi_device *wsi, 952bf215546Sopenharmony_ci VkDevice _device, 953bf215546Sopenharmony_ci const VkAcquireNextImageInfoKHR *pAcquireInfo, 954bf215546Sopenharmony_ci uint32_t *pImageIndex) 955bf215546Sopenharmony_ci{ 956bf215546Sopenharmony_ci VK_FROM_HANDLE(wsi_swapchain, swapchain, pAcquireInfo->swapchain); 957bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_device, device, _device); 958bf215546Sopenharmony_ci 959bf215546Sopenharmony_ci VkResult result = swapchain->acquire_next_image(swapchain, pAcquireInfo, 960bf215546Sopenharmony_ci pImageIndex); 961bf215546Sopenharmony_ci if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) 962bf215546Sopenharmony_ci return result; 963bf215546Sopenharmony_ci struct wsi_image *image = 964bf215546Sopenharmony_ci swapchain->get_wsi_image(swapchain, *pImageIndex); 965bf215546Sopenharmony_ci 966bf215546Sopenharmony_ci if (pAcquireInfo->semaphore != VK_NULL_HANDLE) { 967bf215546Sopenharmony_ci VkResult signal_result = 968bf215546Sopenharmony_ci wsi_signal_semaphore_for_image(device, swapchain, image, 969bf215546Sopenharmony_ci pAcquireInfo->semaphore); 970bf215546Sopenharmony_ci if (signal_result != VK_SUCCESS) 971bf215546Sopenharmony_ci return signal_result; 972bf215546Sopenharmony_ci } 973bf215546Sopenharmony_ci 974bf215546Sopenharmony_ci if (pAcquireInfo->fence != VK_NULL_HANDLE) { 975bf215546Sopenharmony_ci VkResult signal_result = 976bf215546Sopenharmony_ci wsi_signal_fence_for_image(device, swapchain, image, 977bf215546Sopenharmony_ci pAcquireInfo->fence); 978bf215546Sopenharmony_ci if (signal_result != VK_SUCCESS) 979bf215546Sopenharmony_ci return signal_result; 980bf215546Sopenharmony_ci } 981bf215546Sopenharmony_ci 982bf215546Sopenharmony_ci if (wsi->set_memory_ownership) 983bf215546Sopenharmony_ci wsi->set_memory_ownership(swapchain->device, image->memory, true); 984bf215546Sopenharmony_ci 985bf215546Sopenharmony_ci return result; 986bf215546Sopenharmony_ci} 987bf215546Sopenharmony_ci 988bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 989bf215546Sopenharmony_ciwsi_AcquireNextImage2KHR(VkDevice _device, 990bf215546Sopenharmony_ci const VkAcquireNextImageInfoKHR *pAcquireInfo, 991bf215546Sopenharmony_ci uint32_t *pImageIndex) 992bf215546Sopenharmony_ci{ 993bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_device, device, _device); 994bf215546Sopenharmony_ci 995bf215546Sopenharmony_ci return wsi_common_acquire_next_image2(device->physical->wsi_device, 996bf215546Sopenharmony_ci _device, pAcquireInfo, pImageIndex); 997bf215546Sopenharmony_ci} 998bf215546Sopenharmony_ci 999bf215546Sopenharmony_ciVkResult 1000bf215546Sopenharmony_ciwsi_common_queue_present(const struct wsi_device *wsi, 1001bf215546Sopenharmony_ci VkDevice device, 1002bf215546Sopenharmony_ci VkQueue queue, 1003bf215546Sopenharmony_ci int queue_family_index, 1004bf215546Sopenharmony_ci const VkPresentInfoKHR *pPresentInfo) 1005bf215546Sopenharmony_ci{ 1006bf215546Sopenharmony_ci VkResult final_result = VK_SUCCESS; 1007bf215546Sopenharmony_ci 1008bf215546Sopenharmony_ci STACK_ARRAY(VkPipelineStageFlags, stage_flags, 1009bf215546Sopenharmony_ci MAX2(1, pPresentInfo->waitSemaphoreCount)); 1010bf215546Sopenharmony_ci for (uint32_t s = 0; s < MAX2(1, pPresentInfo->waitSemaphoreCount); s++) 1011bf215546Sopenharmony_ci stage_flags[s] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 1012bf215546Sopenharmony_ci 1013bf215546Sopenharmony_ci const VkPresentRegionsKHR *regions = 1014bf215546Sopenharmony_ci vk_find_struct_const(pPresentInfo->pNext, PRESENT_REGIONS_KHR); 1015bf215546Sopenharmony_ci 1016bf215546Sopenharmony_ci for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) { 1017bf215546Sopenharmony_ci VK_FROM_HANDLE(wsi_swapchain, swapchain, pPresentInfo->pSwapchains[i]); 1018bf215546Sopenharmony_ci uint32_t image_index = pPresentInfo->pImageIndices[i]; 1019bf215546Sopenharmony_ci VkResult result; 1020bf215546Sopenharmony_ci 1021bf215546Sopenharmony_ci if (swapchain->fences[image_index] == VK_NULL_HANDLE) { 1022bf215546Sopenharmony_ci const VkFenceCreateInfo fence_info = { 1023bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, 1024bf215546Sopenharmony_ci .pNext = NULL, 1025bf215546Sopenharmony_ci .flags = VK_FENCE_CREATE_SIGNALED_BIT, 1026bf215546Sopenharmony_ci }; 1027bf215546Sopenharmony_ci result = wsi->CreateFence(device, &fence_info, 1028bf215546Sopenharmony_ci &swapchain->alloc, 1029bf215546Sopenharmony_ci &swapchain->fences[image_index]); 1030bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1031bf215546Sopenharmony_ci goto fail_present; 1032bf215546Sopenharmony_ci 1033bf215546Sopenharmony_ci if (swapchain->use_buffer_blit && swapchain->buffer_blit_queue != VK_NULL_HANDLE) { 1034bf215546Sopenharmony_ci const VkSemaphoreCreateInfo sem_info = { 1035bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, 1036bf215546Sopenharmony_ci .pNext = NULL, 1037bf215546Sopenharmony_ci .flags = 0, 1038bf215546Sopenharmony_ci }; 1039bf215546Sopenharmony_ci result = wsi->CreateSemaphore(device, &sem_info, 1040bf215546Sopenharmony_ci &swapchain->alloc, 1041bf215546Sopenharmony_ci &swapchain->buffer_blit_semaphores[image_index]); 1042bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1043bf215546Sopenharmony_ci goto fail_present; 1044bf215546Sopenharmony_ci } 1045bf215546Sopenharmony_ci } else { 1046bf215546Sopenharmony_ci result = 1047bf215546Sopenharmony_ci wsi->WaitForFences(device, 1, &swapchain->fences[image_index], 1048bf215546Sopenharmony_ci true, ~0ull); 1049bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1050bf215546Sopenharmony_ci goto fail_present; 1051bf215546Sopenharmony_ci } 1052bf215546Sopenharmony_ci 1053bf215546Sopenharmony_ci result = wsi->ResetFences(device, 1, &swapchain->fences[image_index]); 1054bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1055bf215546Sopenharmony_ci goto fail_present; 1056bf215546Sopenharmony_ci 1057bf215546Sopenharmony_ci VkSubmitInfo submit_info = { 1058bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, 1059bf215546Sopenharmony_ci }; 1060bf215546Sopenharmony_ci 1061bf215546Sopenharmony_ci if (i == 0) { 1062bf215546Sopenharmony_ci /* We only need/want to wait on semaphores once. After that, we're 1063bf215546Sopenharmony_ci * guaranteed ordering since it all happens on the same queue. 1064bf215546Sopenharmony_ci */ 1065bf215546Sopenharmony_ci submit_info.waitSemaphoreCount = pPresentInfo->waitSemaphoreCount; 1066bf215546Sopenharmony_ci submit_info.pWaitSemaphores = pPresentInfo->pWaitSemaphores; 1067bf215546Sopenharmony_ci submit_info.pWaitDstStageMask = stage_flags; 1068bf215546Sopenharmony_ci } 1069bf215546Sopenharmony_ci 1070bf215546Sopenharmony_ci struct wsi_image *image = 1071bf215546Sopenharmony_ci swapchain->get_wsi_image(swapchain, image_index); 1072bf215546Sopenharmony_ci 1073bf215546Sopenharmony_ci VkQueue submit_queue = queue; 1074bf215546Sopenharmony_ci if (swapchain->use_buffer_blit) { 1075bf215546Sopenharmony_ci if (swapchain->buffer_blit_queue == VK_NULL_HANDLE) { 1076bf215546Sopenharmony_ci submit_info.commandBufferCount = 1; 1077bf215546Sopenharmony_ci submit_info.pCommandBuffers = 1078bf215546Sopenharmony_ci &image->buffer.blit_cmd_buffers[queue_family_index]; 1079bf215546Sopenharmony_ci } else { 1080bf215546Sopenharmony_ci /* If we are using a blit using the driver's private queue, then 1081bf215546Sopenharmony_ci * do an empty submit signalling a semaphore, and then submit the 1082bf215546Sopenharmony_ci * blit waiting on that. This ensures proper queue ordering of 1083bf215546Sopenharmony_ci * vkQueueSubmit() calls. 1084bf215546Sopenharmony_ci */ 1085bf215546Sopenharmony_ci submit_info.signalSemaphoreCount = 1; 1086bf215546Sopenharmony_ci submit_info.pSignalSemaphores = 1087bf215546Sopenharmony_ci &swapchain->buffer_blit_semaphores[image_index]; 1088bf215546Sopenharmony_ci 1089bf215546Sopenharmony_ci result = wsi->QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 1090bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1091bf215546Sopenharmony_ci goto fail_present; 1092bf215546Sopenharmony_ci 1093bf215546Sopenharmony_ci /* Now prepare the blit submit. It needs to then wait on the 1094bf215546Sopenharmony_ci * semaphore we signaled above. 1095bf215546Sopenharmony_ci */ 1096bf215546Sopenharmony_ci submit_queue = swapchain->buffer_blit_queue; 1097bf215546Sopenharmony_ci submit_info.waitSemaphoreCount = 1; 1098bf215546Sopenharmony_ci submit_info.pWaitSemaphores = submit_info.pSignalSemaphores; 1099bf215546Sopenharmony_ci submit_info.signalSemaphoreCount = 0; 1100bf215546Sopenharmony_ci submit_info.pSignalSemaphores = NULL; 1101bf215546Sopenharmony_ci submit_info.commandBufferCount = 1; 1102bf215546Sopenharmony_ci submit_info.pCommandBuffers = &image->buffer.blit_cmd_buffers[0]; 1103bf215546Sopenharmony_ci submit_info.pWaitDstStageMask = stage_flags; 1104bf215546Sopenharmony_ci } 1105bf215546Sopenharmony_ci } 1106bf215546Sopenharmony_ci 1107bf215546Sopenharmony_ci VkFence fence = swapchain->fences[image_index]; 1108bf215546Sopenharmony_ci 1109bf215546Sopenharmony_ci bool has_signal_dma_buf = false; 1110bf215546Sopenharmony_ci#ifdef HAVE_LIBDRM 1111bf215546Sopenharmony_ci result = wsi_prepare_signal_dma_buf_from_semaphore(swapchain, image); 1112bf215546Sopenharmony_ci if (result == VK_SUCCESS) { 1113bf215546Sopenharmony_ci assert(submit_info.signalSemaphoreCount == 0); 1114bf215546Sopenharmony_ci submit_info.signalSemaphoreCount = 1; 1115bf215546Sopenharmony_ci submit_info.pSignalSemaphores = &swapchain->dma_buf_semaphore; 1116bf215546Sopenharmony_ci has_signal_dma_buf = true; 1117bf215546Sopenharmony_ci } else if (result == VK_ERROR_FEATURE_NOT_PRESENT) { 1118bf215546Sopenharmony_ci result = VK_SUCCESS; 1119bf215546Sopenharmony_ci has_signal_dma_buf = false; 1120bf215546Sopenharmony_ci } else { 1121bf215546Sopenharmony_ci goto fail_present; 1122bf215546Sopenharmony_ci } 1123bf215546Sopenharmony_ci#endif 1124bf215546Sopenharmony_ci 1125bf215546Sopenharmony_ci struct wsi_memory_signal_submit_info mem_signal; 1126bf215546Sopenharmony_ci if (!has_signal_dma_buf) { 1127bf215546Sopenharmony_ci /* If we don't have dma-buf signaling, signal the memory object by 1128bf215546Sopenharmony_ci * chaining wsi_memory_signal_submit_info into VkSubmitInfo. 1129bf215546Sopenharmony_ci */ 1130bf215546Sopenharmony_ci result = VK_SUCCESS; 1131bf215546Sopenharmony_ci has_signal_dma_buf = false; 1132bf215546Sopenharmony_ci mem_signal = (struct wsi_memory_signal_submit_info) { 1133bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA, 1134bf215546Sopenharmony_ci .memory = image->memory, 1135bf215546Sopenharmony_ci }; 1136bf215546Sopenharmony_ci __vk_append_struct(&submit_info, &mem_signal); 1137bf215546Sopenharmony_ci } 1138bf215546Sopenharmony_ci 1139bf215546Sopenharmony_ci result = wsi->QueueSubmit(submit_queue, 1, &submit_info, fence); 1140bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1141bf215546Sopenharmony_ci goto fail_present; 1142bf215546Sopenharmony_ci 1143bf215546Sopenharmony_ci#ifdef HAVE_LIBDRM 1144bf215546Sopenharmony_ci if (has_signal_dma_buf) { 1145bf215546Sopenharmony_ci result = wsi_signal_dma_buf_from_semaphore(swapchain, image); 1146bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1147bf215546Sopenharmony_ci goto fail_present; 1148bf215546Sopenharmony_ci } 1149bf215546Sopenharmony_ci#else 1150bf215546Sopenharmony_ci assert(!has_signal_dma_buf); 1151bf215546Sopenharmony_ci#endif 1152bf215546Sopenharmony_ci 1153bf215546Sopenharmony_ci if (wsi->sw) 1154bf215546Sopenharmony_ci wsi->WaitForFences(device, 1, &swapchain->fences[image_index], 1155bf215546Sopenharmony_ci true, ~0ull); 1156bf215546Sopenharmony_ci 1157bf215546Sopenharmony_ci const VkPresentRegionKHR *region = NULL; 1158bf215546Sopenharmony_ci if (regions && regions->pRegions) 1159bf215546Sopenharmony_ci region = ®ions->pRegions[i]; 1160bf215546Sopenharmony_ci 1161bf215546Sopenharmony_ci result = swapchain->queue_present(swapchain, image_index, region); 1162bf215546Sopenharmony_ci if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) 1163bf215546Sopenharmony_ci goto fail_present; 1164bf215546Sopenharmony_ci 1165bf215546Sopenharmony_ci if (wsi->set_memory_ownership) { 1166bf215546Sopenharmony_ci VkDeviceMemory mem = swapchain->get_wsi_image(swapchain, image_index)->memory; 1167bf215546Sopenharmony_ci wsi->set_memory_ownership(swapchain->device, mem, false); 1168bf215546Sopenharmony_ci } 1169bf215546Sopenharmony_ci 1170bf215546Sopenharmony_ci fail_present: 1171bf215546Sopenharmony_ci if (pPresentInfo->pResults != NULL) 1172bf215546Sopenharmony_ci pPresentInfo->pResults[i] = result; 1173bf215546Sopenharmony_ci 1174bf215546Sopenharmony_ci /* Let the final result be our first unsuccessful result */ 1175bf215546Sopenharmony_ci if (final_result == VK_SUCCESS) 1176bf215546Sopenharmony_ci final_result = result; 1177bf215546Sopenharmony_ci } 1178bf215546Sopenharmony_ci 1179bf215546Sopenharmony_ci STACK_ARRAY_FINISH(stage_flags); 1180bf215546Sopenharmony_ci 1181bf215546Sopenharmony_ci return final_result; 1182bf215546Sopenharmony_ci} 1183bf215546Sopenharmony_ci 1184bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 1185bf215546Sopenharmony_ciwsi_QueuePresentKHR(VkQueue _queue, const VkPresentInfoKHR *pPresentInfo) 1186bf215546Sopenharmony_ci{ 1187bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_queue, queue, _queue); 1188bf215546Sopenharmony_ci 1189bf215546Sopenharmony_ci return wsi_common_queue_present(queue->base.device->physical->wsi_device, 1190bf215546Sopenharmony_ci vk_device_to_handle(queue->base.device), 1191bf215546Sopenharmony_ci _queue, 1192bf215546Sopenharmony_ci queue->queue_family_index, 1193bf215546Sopenharmony_ci pPresentInfo); 1194bf215546Sopenharmony_ci} 1195bf215546Sopenharmony_ci 1196bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 1197bf215546Sopenharmony_ciwsi_GetDeviceGroupPresentCapabilitiesKHR(VkDevice device, 1198bf215546Sopenharmony_ci VkDeviceGroupPresentCapabilitiesKHR *pCapabilities) 1199bf215546Sopenharmony_ci{ 1200bf215546Sopenharmony_ci memset(pCapabilities->presentMask, 0, 1201bf215546Sopenharmony_ci sizeof(pCapabilities->presentMask)); 1202bf215546Sopenharmony_ci pCapabilities->presentMask[0] = 0x1; 1203bf215546Sopenharmony_ci pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR; 1204bf215546Sopenharmony_ci 1205bf215546Sopenharmony_ci return VK_SUCCESS; 1206bf215546Sopenharmony_ci} 1207bf215546Sopenharmony_ci 1208bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 1209bf215546Sopenharmony_ciwsi_GetDeviceGroupSurfacePresentModesKHR(VkDevice device, 1210bf215546Sopenharmony_ci VkSurfaceKHR surface, 1211bf215546Sopenharmony_ci VkDeviceGroupPresentModeFlagsKHR *pModes) 1212bf215546Sopenharmony_ci{ 1213bf215546Sopenharmony_ci *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR; 1214bf215546Sopenharmony_ci 1215bf215546Sopenharmony_ci return VK_SUCCESS; 1216bf215546Sopenharmony_ci} 1217bf215546Sopenharmony_ci 1218bf215546Sopenharmony_ciVkResult 1219bf215546Sopenharmony_ciwsi_common_create_swapchain_image(const struct wsi_device *wsi, 1220bf215546Sopenharmony_ci const VkImageCreateInfo *pCreateInfo, 1221bf215546Sopenharmony_ci VkSwapchainKHR _swapchain, 1222bf215546Sopenharmony_ci VkImage *pImage) 1223bf215546Sopenharmony_ci{ 1224bf215546Sopenharmony_ci VK_FROM_HANDLE(wsi_swapchain, chain, _swapchain); 1225bf215546Sopenharmony_ci 1226bf215546Sopenharmony_ci#ifndef NDEBUG 1227bf215546Sopenharmony_ci const VkImageCreateInfo *swcInfo = &chain->image_info.create; 1228bf215546Sopenharmony_ci assert(pCreateInfo->flags == 0); 1229bf215546Sopenharmony_ci assert(pCreateInfo->imageType == swcInfo->imageType); 1230bf215546Sopenharmony_ci assert(pCreateInfo->format == swcInfo->format); 1231bf215546Sopenharmony_ci assert(pCreateInfo->extent.width == swcInfo->extent.width); 1232bf215546Sopenharmony_ci assert(pCreateInfo->extent.height == swcInfo->extent.height); 1233bf215546Sopenharmony_ci assert(pCreateInfo->extent.depth == swcInfo->extent.depth); 1234bf215546Sopenharmony_ci assert(pCreateInfo->mipLevels == swcInfo->mipLevels); 1235bf215546Sopenharmony_ci assert(pCreateInfo->arrayLayers == swcInfo->arrayLayers); 1236bf215546Sopenharmony_ci assert(pCreateInfo->samples == swcInfo->samples); 1237bf215546Sopenharmony_ci assert(pCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL); 1238bf215546Sopenharmony_ci assert(!(pCreateInfo->usage & ~swcInfo->usage)); 1239bf215546Sopenharmony_ci 1240bf215546Sopenharmony_ci vk_foreach_struct_const(ext, pCreateInfo->pNext) { 1241bf215546Sopenharmony_ci switch (ext->sType) { 1242bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO: { 1243bf215546Sopenharmony_ci const VkImageFormatListCreateInfo *iflci = 1244bf215546Sopenharmony_ci (const VkImageFormatListCreateInfo *)ext; 1245bf215546Sopenharmony_ci const VkImageFormatListCreateInfo *swc_iflci = 1246bf215546Sopenharmony_ci &chain->image_info.format_list; 1247bf215546Sopenharmony_ci 1248bf215546Sopenharmony_ci for (uint32_t i = 0; i < iflci->viewFormatCount; i++) { 1249bf215546Sopenharmony_ci bool found = false; 1250bf215546Sopenharmony_ci for (uint32_t j = 0; j < swc_iflci->viewFormatCount; j++) { 1251bf215546Sopenharmony_ci if (iflci->pViewFormats[i] == swc_iflci->pViewFormats[j]) { 1252bf215546Sopenharmony_ci found = true; 1253bf215546Sopenharmony_ci break; 1254bf215546Sopenharmony_ci } 1255bf215546Sopenharmony_ci } 1256bf215546Sopenharmony_ci assert(found); 1257bf215546Sopenharmony_ci } 1258bf215546Sopenharmony_ci break; 1259bf215546Sopenharmony_ci } 1260bf215546Sopenharmony_ci 1261bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR: 1262bf215546Sopenharmony_ci break; 1263bf215546Sopenharmony_ci 1264bf215546Sopenharmony_ci default: 1265bf215546Sopenharmony_ci assert(!"Unsupported image create extension"); 1266bf215546Sopenharmony_ci } 1267bf215546Sopenharmony_ci } 1268bf215546Sopenharmony_ci#endif 1269bf215546Sopenharmony_ci 1270bf215546Sopenharmony_ci return wsi->CreateImage(chain->device, &chain->image_info.create, 1271bf215546Sopenharmony_ci &chain->alloc, pImage); 1272bf215546Sopenharmony_ci} 1273bf215546Sopenharmony_ci 1274bf215546Sopenharmony_ciVkResult 1275bf215546Sopenharmony_ciwsi_common_bind_swapchain_image(const struct wsi_device *wsi, 1276bf215546Sopenharmony_ci VkImage vk_image, 1277bf215546Sopenharmony_ci VkSwapchainKHR _swapchain, 1278bf215546Sopenharmony_ci uint32_t image_idx) 1279bf215546Sopenharmony_ci{ 1280bf215546Sopenharmony_ci VK_FROM_HANDLE(wsi_swapchain, chain, _swapchain); 1281bf215546Sopenharmony_ci struct wsi_image *image = chain->get_wsi_image(chain, image_idx); 1282bf215546Sopenharmony_ci 1283bf215546Sopenharmony_ci return wsi->BindImageMemory(chain->device, vk_image, image->memory, 0); 1284bf215546Sopenharmony_ci} 1285bf215546Sopenharmony_ci 1286bf215546Sopenharmony_ciuint32_t 1287bf215546Sopenharmony_ciwsi_select_memory_type(const struct wsi_device *wsi, 1288bf215546Sopenharmony_ci VkMemoryPropertyFlags req_props, 1289bf215546Sopenharmony_ci VkMemoryPropertyFlags deny_props, 1290bf215546Sopenharmony_ci uint32_t type_bits) 1291bf215546Sopenharmony_ci{ 1292bf215546Sopenharmony_ci assert(type_bits != 0); 1293bf215546Sopenharmony_ci 1294bf215546Sopenharmony_ci VkMemoryPropertyFlags common_props = ~0; 1295bf215546Sopenharmony_ci u_foreach_bit(t, type_bits) { 1296bf215546Sopenharmony_ci const VkMemoryType type = wsi->memory_props.memoryTypes[t]; 1297bf215546Sopenharmony_ci 1298bf215546Sopenharmony_ci common_props &= type.propertyFlags; 1299bf215546Sopenharmony_ci 1300bf215546Sopenharmony_ci if (deny_props & type.propertyFlags) 1301bf215546Sopenharmony_ci continue; 1302bf215546Sopenharmony_ci 1303bf215546Sopenharmony_ci if (!(req_props & ~type.propertyFlags)) 1304bf215546Sopenharmony_ci return t; 1305bf215546Sopenharmony_ci } 1306bf215546Sopenharmony_ci 1307bf215546Sopenharmony_ci if ((deny_props & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) && 1308bf215546Sopenharmony_ci (common_props & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) { 1309bf215546Sopenharmony_ci /* If they asked for non-device-local and all the types are device-local 1310bf215546Sopenharmony_ci * (this is commonly true for UMA platforms), try again without denying 1311bf215546Sopenharmony_ci * device-local types 1312bf215546Sopenharmony_ci */ 1313bf215546Sopenharmony_ci deny_props &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; 1314bf215546Sopenharmony_ci return wsi_select_memory_type(wsi, req_props, deny_props, type_bits); 1315bf215546Sopenharmony_ci } 1316bf215546Sopenharmony_ci 1317bf215546Sopenharmony_ci unreachable("No memory type found"); 1318bf215546Sopenharmony_ci} 1319bf215546Sopenharmony_ci 1320bf215546Sopenharmony_ciuint32_t 1321bf215546Sopenharmony_ciwsi_select_device_memory_type(const struct wsi_device *wsi, 1322bf215546Sopenharmony_ci uint32_t type_bits) 1323bf215546Sopenharmony_ci{ 1324bf215546Sopenharmony_ci return wsi_select_memory_type(wsi, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 1325bf215546Sopenharmony_ci 0 /* deny_props */, type_bits); 1326bf215546Sopenharmony_ci} 1327bf215546Sopenharmony_ci 1328bf215546Sopenharmony_cistatic uint32_t 1329bf215546Sopenharmony_ciwsi_select_host_memory_type(const struct wsi_device *wsi, 1330bf215546Sopenharmony_ci uint32_t type_bits) 1331bf215546Sopenharmony_ci{ 1332bf215546Sopenharmony_ci return wsi_select_memory_type(wsi, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 1333bf215546Sopenharmony_ci 0 /* deny_props */, type_bits); 1334bf215546Sopenharmony_ci} 1335bf215546Sopenharmony_ci 1336bf215546Sopenharmony_ciVkResult 1337bf215546Sopenharmony_ciwsi_create_buffer_image_mem(const struct wsi_swapchain *chain, 1338bf215546Sopenharmony_ci const struct wsi_image_info *info, 1339bf215546Sopenharmony_ci struct wsi_image *image, 1340bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags handle_types, 1341bf215546Sopenharmony_ci bool implicit_sync) 1342bf215546Sopenharmony_ci{ 1343bf215546Sopenharmony_ci const struct wsi_device *wsi = chain->wsi; 1344bf215546Sopenharmony_ci VkResult result; 1345bf215546Sopenharmony_ci 1346bf215546Sopenharmony_ci const VkExternalMemoryBufferCreateInfo buffer_external_info = { 1347bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, 1348bf215546Sopenharmony_ci .pNext = NULL, 1349bf215546Sopenharmony_ci .handleTypes = handle_types, 1350bf215546Sopenharmony_ci }; 1351bf215546Sopenharmony_ci const VkBufferCreateInfo buffer_info = { 1352bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 1353bf215546Sopenharmony_ci .pNext = &buffer_external_info, 1354bf215546Sopenharmony_ci .size = info->linear_size, 1355bf215546Sopenharmony_ci .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT, 1356bf215546Sopenharmony_ci .sharingMode = VK_SHARING_MODE_EXCLUSIVE, 1357bf215546Sopenharmony_ci }; 1358bf215546Sopenharmony_ci result = wsi->CreateBuffer(chain->device, &buffer_info, 1359bf215546Sopenharmony_ci &chain->alloc, &image->buffer.buffer); 1360bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1361bf215546Sopenharmony_ci return result; 1362bf215546Sopenharmony_ci 1363bf215546Sopenharmony_ci VkMemoryRequirements reqs; 1364bf215546Sopenharmony_ci wsi->GetBufferMemoryRequirements(chain->device, image->buffer.buffer, &reqs); 1365bf215546Sopenharmony_ci assert(reqs.size <= info->linear_size); 1366bf215546Sopenharmony_ci 1367bf215546Sopenharmony_ci struct wsi_memory_allocate_info memory_wsi_info = { 1368bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA, 1369bf215546Sopenharmony_ci .pNext = NULL, 1370bf215546Sopenharmony_ci .implicit_sync = implicit_sync, 1371bf215546Sopenharmony_ci }; 1372bf215546Sopenharmony_ci VkMemoryDedicatedAllocateInfo buf_mem_dedicated_info = { 1373bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, 1374bf215546Sopenharmony_ci .pNext = &memory_wsi_info, 1375bf215546Sopenharmony_ci .image = VK_NULL_HANDLE, 1376bf215546Sopenharmony_ci .buffer = image->buffer.buffer, 1377bf215546Sopenharmony_ci }; 1378bf215546Sopenharmony_ci VkMemoryAllocateInfo buf_mem_info = { 1379bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 1380bf215546Sopenharmony_ci .pNext = &buf_mem_dedicated_info, 1381bf215546Sopenharmony_ci .allocationSize = info->linear_size, 1382bf215546Sopenharmony_ci .memoryTypeIndex = 1383bf215546Sopenharmony_ci info->select_buffer_memory_type(wsi, reqs.memoryTypeBits), 1384bf215546Sopenharmony_ci }; 1385bf215546Sopenharmony_ci 1386bf215546Sopenharmony_ci void *sw_host_ptr = NULL; 1387bf215546Sopenharmony_ci if (info->alloc_shm) 1388bf215546Sopenharmony_ci sw_host_ptr = info->alloc_shm(image, info->linear_size); 1389bf215546Sopenharmony_ci 1390bf215546Sopenharmony_ci VkExportMemoryAllocateInfo memory_export_info; 1391bf215546Sopenharmony_ci VkImportMemoryHostPointerInfoEXT host_ptr_info; 1392bf215546Sopenharmony_ci if (sw_host_ptr != NULL) { 1393bf215546Sopenharmony_ci host_ptr_info = (VkImportMemoryHostPointerInfoEXT) { 1394bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT, 1395bf215546Sopenharmony_ci .pHostPointer = sw_host_ptr, 1396bf215546Sopenharmony_ci .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, 1397bf215546Sopenharmony_ci }; 1398bf215546Sopenharmony_ci __vk_append_struct(&buf_mem_info, &host_ptr_info); 1399bf215546Sopenharmony_ci } else if (handle_types != 0) { 1400bf215546Sopenharmony_ci memory_export_info = (VkExportMemoryAllocateInfo) { 1401bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, 1402bf215546Sopenharmony_ci .handleTypes = handle_types, 1403bf215546Sopenharmony_ci }; 1404bf215546Sopenharmony_ci __vk_append_struct(&buf_mem_info, &memory_export_info); 1405bf215546Sopenharmony_ci } 1406bf215546Sopenharmony_ci 1407bf215546Sopenharmony_ci result = wsi->AllocateMemory(chain->device, &buf_mem_info, 1408bf215546Sopenharmony_ci &chain->alloc, &image->buffer.memory); 1409bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1410bf215546Sopenharmony_ci return result; 1411bf215546Sopenharmony_ci 1412bf215546Sopenharmony_ci result = wsi->BindBufferMemory(chain->device, image->buffer.buffer, 1413bf215546Sopenharmony_ci image->buffer.memory, 0); 1414bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1415bf215546Sopenharmony_ci return result; 1416bf215546Sopenharmony_ci 1417bf215546Sopenharmony_ci wsi->GetImageMemoryRequirements(chain->device, image->image, &reqs); 1418bf215546Sopenharmony_ci 1419bf215546Sopenharmony_ci const VkMemoryDedicatedAllocateInfo memory_dedicated_info = { 1420bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, 1421bf215546Sopenharmony_ci .pNext = NULL, 1422bf215546Sopenharmony_ci .image = image->image, 1423bf215546Sopenharmony_ci .buffer = VK_NULL_HANDLE, 1424bf215546Sopenharmony_ci }; 1425bf215546Sopenharmony_ci const VkMemoryAllocateInfo memory_info = { 1426bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 1427bf215546Sopenharmony_ci .pNext = &memory_dedicated_info, 1428bf215546Sopenharmony_ci .allocationSize = reqs.size, 1429bf215546Sopenharmony_ci .memoryTypeIndex = 1430bf215546Sopenharmony_ci info->select_image_memory_type(wsi, reqs.memoryTypeBits), 1431bf215546Sopenharmony_ci }; 1432bf215546Sopenharmony_ci 1433bf215546Sopenharmony_ci result = wsi->AllocateMemory(chain->device, &memory_info, 1434bf215546Sopenharmony_ci &chain->alloc, &image->memory); 1435bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1436bf215546Sopenharmony_ci return result; 1437bf215546Sopenharmony_ci 1438bf215546Sopenharmony_ci image->num_planes = 1; 1439bf215546Sopenharmony_ci image->sizes[0] = info->linear_size; 1440bf215546Sopenharmony_ci image->row_pitches[0] = info->linear_stride; 1441bf215546Sopenharmony_ci image->offsets[0] = 0; 1442bf215546Sopenharmony_ci 1443bf215546Sopenharmony_ci return VK_SUCCESS; 1444bf215546Sopenharmony_ci} 1445bf215546Sopenharmony_ci 1446bf215546Sopenharmony_ciVkResult 1447bf215546Sopenharmony_ciwsi_finish_create_buffer_image(const struct wsi_swapchain *chain, 1448bf215546Sopenharmony_ci const struct wsi_image_info *info, 1449bf215546Sopenharmony_ci struct wsi_image *image) 1450bf215546Sopenharmony_ci{ 1451bf215546Sopenharmony_ci const struct wsi_device *wsi = chain->wsi; 1452bf215546Sopenharmony_ci VkResult result; 1453bf215546Sopenharmony_ci 1454bf215546Sopenharmony_ci int cmd_buffer_count = 1455bf215546Sopenharmony_ci chain->buffer_blit_queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count; 1456bf215546Sopenharmony_ci image->buffer.blit_cmd_buffers = 1457bf215546Sopenharmony_ci vk_zalloc(&chain->alloc, 1458bf215546Sopenharmony_ci sizeof(VkCommandBuffer) * cmd_buffer_count, 8, 1459bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 1460bf215546Sopenharmony_ci if (!image->buffer.blit_cmd_buffers) 1461bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 1462bf215546Sopenharmony_ci 1463bf215546Sopenharmony_ci for (uint32_t i = 0; i < cmd_buffer_count; i++) { 1464bf215546Sopenharmony_ci const VkCommandBufferAllocateInfo cmd_buffer_info = { 1465bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, 1466bf215546Sopenharmony_ci .pNext = NULL, 1467bf215546Sopenharmony_ci .commandPool = chain->cmd_pools[i], 1468bf215546Sopenharmony_ci .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1469bf215546Sopenharmony_ci .commandBufferCount = 1, 1470bf215546Sopenharmony_ci }; 1471bf215546Sopenharmony_ci result = wsi->AllocateCommandBuffers(chain->device, &cmd_buffer_info, 1472bf215546Sopenharmony_ci &image->buffer.blit_cmd_buffers[i]); 1473bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1474bf215546Sopenharmony_ci return result; 1475bf215546Sopenharmony_ci 1476bf215546Sopenharmony_ci const VkCommandBufferBeginInfo begin_info = { 1477bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 1478bf215546Sopenharmony_ci }; 1479bf215546Sopenharmony_ci wsi->BeginCommandBuffer(image->buffer.blit_cmd_buffers[i], &begin_info); 1480bf215546Sopenharmony_ci 1481bf215546Sopenharmony_ci VkImageMemoryBarrier img_mem_barrier = { 1482bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 1483bf215546Sopenharmony_ci .pNext = NULL, 1484bf215546Sopenharmony_ci .srcAccessMask = 0, 1485bf215546Sopenharmony_ci .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT, 1486bf215546Sopenharmony_ci .oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, 1487bf215546Sopenharmony_ci .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1488bf215546Sopenharmony_ci .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 1489bf215546Sopenharmony_ci .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 1490bf215546Sopenharmony_ci .image = image->image, 1491bf215546Sopenharmony_ci .subresourceRange = { 1492bf215546Sopenharmony_ci .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 1493bf215546Sopenharmony_ci .baseMipLevel = 0, 1494bf215546Sopenharmony_ci .levelCount = 1, 1495bf215546Sopenharmony_ci .baseArrayLayer = 0, 1496bf215546Sopenharmony_ci .layerCount = 1, 1497bf215546Sopenharmony_ci }, 1498bf215546Sopenharmony_ci }; 1499bf215546Sopenharmony_ci wsi->CmdPipelineBarrier(image->buffer.blit_cmd_buffers[i], 1500bf215546Sopenharmony_ci VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 1501bf215546Sopenharmony_ci VK_PIPELINE_STAGE_TRANSFER_BIT, 1502bf215546Sopenharmony_ci 0, 1503bf215546Sopenharmony_ci 0, NULL, 1504bf215546Sopenharmony_ci 0, NULL, 1505bf215546Sopenharmony_ci 1, &img_mem_barrier); 1506bf215546Sopenharmony_ci 1507bf215546Sopenharmony_ci struct VkBufferImageCopy buffer_image_copy = { 1508bf215546Sopenharmony_ci .bufferOffset = 0, 1509bf215546Sopenharmony_ci .bufferRowLength = info->linear_stride / 1510bf215546Sopenharmony_ci vk_format_get_blocksize(info->create.format), 1511bf215546Sopenharmony_ci .bufferImageHeight = 0, 1512bf215546Sopenharmony_ci .imageSubresource = { 1513bf215546Sopenharmony_ci .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 1514bf215546Sopenharmony_ci .mipLevel = 0, 1515bf215546Sopenharmony_ci .baseArrayLayer = 0, 1516bf215546Sopenharmony_ci .layerCount = 1, 1517bf215546Sopenharmony_ci }, 1518bf215546Sopenharmony_ci .imageOffset = { .x = 0, .y = 0, .z = 0 }, 1519bf215546Sopenharmony_ci .imageExtent = info->create.extent, 1520bf215546Sopenharmony_ci }; 1521bf215546Sopenharmony_ci wsi->CmdCopyImageToBuffer(image->buffer.blit_cmd_buffers[i], 1522bf215546Sopenharmony_ci image->image, 1523bf215546Sopenharmony_ci VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1524bf215546Sopenharmony_ci image->buffer.buffer, 1525bf215546Sopenharmony_ci 1, &buffer_image_copy); 1526bf215546Sopenharmony_ci 1527bf215546Sopenharmony_ci img_mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; 1528bf215546Sopenharmony_ci img_mem_barrier.dstAccessMask = 0; 1529bf215546Sopenharmony_ci img_mem_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 1530bf215546Sopenharmony_ci img_mem_barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; 1531bf215546Sopenharmony_ci wsi->CmdPipelineBarrier(image->buffer.blit_cmd_buffers[i], 1532bf215546Sopenharmony_ci VK_PIPELINE_STAGE_TRANSFER_BIT, 1533bf215546Sopenharmony_ci VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 1534bf215546Sopenharmony_ci 0, 1535bf215546Sopenharmony_ci 0, NULL, 1536bf215546Sopenharmony_ci 0, NULL, 1537bf215546Sopenharmony_ci 1, &img_mem_barrier); 1538bf215546Sopenharmony_ci 1539bf215546Sopenharmony_ci result = wsi->EndCommandBuffer(image->buffer.blit_cmd_buffers[i]); 1540bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1541bf215546Sopenharmony_ci return result; 1542bf215546Sopenharmony_ci } 1543bf215546Sopenharmony_ci 1544bf215546Sopenharmony_ci return VK_SUCCESS; 1545bf215546Sopenharmony_ci} 1546bf215546Sopenharmony_ci 1547bf215546Sopenharmony_ciVkResult 1548bf215546Sopenharmony_ciwsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain, 1549bf215546Sopenharmony_ci const VkSwapchainCreateInfoKHR *pCreateInfo, 1550bf215546Sopenharmony_ci uint32_t stride_align, uint32_t size_align, 1551bf215546Sopenharmony_ci struct wsi_image_info *info) 1552bf215546Sopenharmony_ci{ 1553bf215546Sopenharmony_ci const struct wsi_device *wsi = chain->wsi; 1554bf215546Sopenharmony_ci 1555bf215546Sopenharmony_ci assert(util_is_power_of_two_nonzero(stride_align)); 1556bf215546Sopenharmony_ci assert(util_is_power_of_two_nonzero(size_align)); 1557bf215546Sopenharmony_ci 1558bf215546Sopenharmony_ci VkResult result = wsi_configure_image(chain, pCreateInfo, 1559bf215546Sopenharmony_ci 0 /* handle_types */, info); 1560bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1561bf215546Sopenharmony_ci return result; 1562bf215546Sopenharmony_ci 1563bf215546Sopenharmony_ci info->create.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1564bf215546Sopenharmony_ci info->wsi.buffer_blit_src = true; 1565bf215546Sopenharmony_ci 1566bf215546Sopenharmony_ci const uint32_t cpp = vk_format_get_blocksize(pCreateInfo->imageFormat); 1567bf215546Sopenharmony_ci info->linear_stride = pCreateInfo->imageExtent.width * cpp; 1568bf215546Sopenharmony_ci info->linear_stride = ALIGN_POT(info->linear_stride, stride_align); 1569bf215546Sopenharmony_ci 1570bf215546Sopenharmony_ci /* Since we can pick the stride to be whatever we want, also align to the 1571bf215546Sopenharmony_ci * device's optimalBufferCopyRowPitchAlignment so we get efficient copies. 1572bf215546Sopenharmony_ci */ 1573bf215546Sopenharmony_ci assert(wsi->optimalBufferCopyRowPitchAlignment > 0); 1574bf215546Sopenharmony_ci info->linear_stride = ALIGN_POT(info->linear_stride, 1575bf215546Sopenharmony_ci wsi->optimalBufferCopyRowPitchAlignment); 1576bf215546Sopenharmony_ci 1577bf215546Sopenharmony_ci info->linear_size = info->linear_stride * pCreateInfo->imageExtent.height; 1578bf215546Sopenharmony_ci info->linear_size = ALIGN_POT(info->linear_size, size_align); 1579bf215546Sopenharmony_ci 1580bf215546Sopenharmony_ci info->finish_create = wsi_finish_create_buffer_image; 1581bf215546Sopenharmony_ci 1582bf215546Sopenharmony_ci return VK_SUCCESS; 1583bf215546Sopenharmony_ci} 1584bf215546Sopenharmony_ci 1585bf215546Sopenharmony_cistatic VkResult 1586bf215546Sopenharmony_ciwsi_create_cpu_linear_image_mem(const struct wsi_swapchain *chain, 1587bf215546Sopenharmony_ci const struct wsi_image_info *info, 1588bf215546Sopenharmony_ci struct wsi_image *image) 1589bf215546Sopenharmony_ci{ 1590bf215546Sopenharmony_ci const struct wsi_device *wsi = chain->wsi; 1591bf215546Sopenharmony_ci VkResult result; 1592bf215546Sopenharmony_ci 1593bf215546Sopenharmony_ci VkMemoryRequirements reqs; 1594bf215546Sopenharmony_ci wsi->GetImageMemoryRequirements(chain->device, image->image, &reqs); 1595bf215546Sopenharmony_ci 1596bf215546Sopenharmony_ci VkSubresourceLayout layout; 1597bf215546Sopenharmony_ci wsi->GetImageSubresourceLayout(chain->device, image->image, 1598bf215546Sopenharmony_ci &(VkImageSubresource) { 1599bf215546Sopenharmony_ci .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 1600bf215546Sopenharmony_ci .mipLevel = 0, 1601bf215546Sopenharmony_ci .arrayLayer = 0, 1602bf215546Sopenharmony_ci }, &layout); 1603bf215546Sopenharmony_ci assert(layout.offset == 0); 1604bf215546Sopenharmony_ci 1605bf215546Sopenharmony_ci const VkMemoryDedicatedAllocateInfo memory_dedicated_info = { 1606bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, 1607bf215546Sopenharmony_ci .image = image->image, 1608bf215546Sopenharmony_ci .buffer = VK_NULL_HANDLE, 1609bf215546Sopenharmony_ci }; 1610bf215546Sopenharmony_ci VkMemoryAllocateInfo memory_info = { 1611bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 1612bf215546Sopenharmony_ci .pNext = &memory_dedicated_info, 1613bf215546Sopenharmony_ci .allocationSize = reqs.size, 1614bf215546Sopenharmony_ci .memoryTypeIndex = 1615bf215546Sopenharmony_ci wsi_select_host_memory_type(wsi, reqs.memoryTypeBits), 1616bf215546Sopenharmony_ci }; 1617bf215546Sopenharmony_ci 1618bf215546Sopenharmony_ci void *sw_host_ptr = NULL; 1619bf215546Sopenharmony_ci if (info->alloc_shm) 1620bf215546Sopenharmony_ci sw_host_ptr = info->alloc_shm(image, layout.size); 1621bf215546Sopenharmony_ci 1622bf215546Sopenharmony_ci VkImportMemoryHostPointerInfoEXT host_ptr_info; 1623bf215546Sopenharmony_ci if (sw_host_ptr != NULL) { 1624bf215546Sopenharmony_ci host_ptr_info = (VkImportMemoryHostPointerInfoEXT) { 1625bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT, 1626bf215546Sopenharmony_ci .pHostPointer = sw_host_ptr, 1627bf215546Sopenharmony_ci .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, 1628bf215546Sopenharmony_ci }; 1629bf215546Sopenharmony_ci __vk_append_struct(&memory_info, &host_ptr_info); 1630bf215546Sopenharmony_ci } 1631bf215546Sopenharmony_ci 1632bf215546Sopenharmony_ci result = wsi->AllocateMemory(chain->device, &memory_info, 1633bf215546Sopenharmony_ci &chain->alloc, &image->memory); 1634bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1635bf215546Sopenharmony_ci return result; 1636bf215546Sopenharmony_ci 1637bf215546Sopenharmony_ci result = wsi->MapMemory(chain->device, image->memory, 1638bf215546Sopenharmony_ci 0, VK_WHOLE_SIZE, 0, &image->cpu_map); 1639bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1640bf215546Sopenharmony_ci return result; 1641bf215546Sopenharmony_ci 1642bf215546Sopenharmony_ci image->num_planes = 1; 1643bf215546Sopenharmony_ci image->sizes[0] = reqs.size; 1644bf215546Sopenharmony_ci image->row_pitches[0] = layout.rowPitch; 1645bf215546Sopenharmony_ci image->offsets[0] = 0; 1646bf215546Sopenharmony_ci 1647bf215546Sopenharmony_ci return VK_SUCCESS; 1648bf215546Sopenharmony_ci} 1649bf215546Sopenharmony_ci 1650bf215546Sopenharmony_cistatic VkResult 1651bf215546Sopenharmony_ciwsi_create_cpu_buffer_image_mem(const struct wsi_swapchain *chain, 1652bf215546Sopenharmony_ci const struct wsi_image_info *info, 1653bf215546Sopenharmony_ci struct wsi_image *image) 1654bf215546Sopenharmony_ci{ 1655bf215546Sopenharmony_ci VkResult result; 1656bf215546Sopenharmony_ci 1657bf215546Sopenharmony_ci result = wsi_create_buffer_image_mem(chain, info, image, 0, 1658bf215546Sopenharmony_ci false /* implicit_sync */); 1659bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1660bf215546Sopenharmony_ci return result; 1661bf215546Sopenharmony_ci 1662bf215546Sopenharmony_ci result = chain->wsi->MapMemory(chain->device, image->buffer.memory, 1663bf215546Sopenharmony_ci 0, VK_WHOLE_SIZE, 0, &image->cpu_map); 1664bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1665bf215546Sopenharmony_ci return result; 1666bf215546Sopenharmony_ci 1667bf215546Sopenharmony_ci return VK_SUCCESS; 1668bf215546Sopenharmony_ci} 1669bf215546Sopenharmony_ci 1670bf215546Sopenharmony_ciVkResult 1671bf215546Sopenharmony_ciwsi_configure_cpu_image(const struct wsi_swapchain *chain, 1672bf215546Sopenharmony_ci const VkSwapchainCreateInfoKHR *pCreateInfo, 1673bf215546Sopenharmony_ci uint8_t *(alloc_shm)(struct wsi_image *image, 1674bf215546Sopenharmony_ci unsigned size), 1675bf215546Sopenharmony_ci struct wsi_image_info *info) 1676bf215546Sopenharmony_ci{ 1677bf215546Sopenharmony_ci const VkExternalMemoryHandleTypeFlags handle_types = 1678bf215546Sopenharmony_ci alloc_shm ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT : 0; 1679bf215546Sopenharmony_ci 1680bf215546Sopenharmony_ci if (chain->use_buffer_blit) { 1681bf215546Sopenharmony_ci VkResult result = wsi_configure_buffer_image(chain, pCreateInfo, 1682bf215546Sopenharmony_ci 1 /* stride_align */, 1683bf215546Sopenharmony_ci 1 /* size_align */, 1684bf215546Sopenharmony_ci info); 1685bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1686bf215546Sopenharmony_ci return result; 1687bf215546Sopenharmony_ci 1688bf215546Sopenharmony_ci info->select_buffer_memory_type = wsi_select_host_memory_type; 1689bf215546Sopenharmony_ci info->select_image_memory_type = wsi_select_device_memory_type; 1690bf215546Sopenharmony_ci info->create_mem = wsi_create_cpu_buffer_image_mem; 1691bf215546Sopenharmony_ci } else { 1692bf215546Sopenharmony_ci VkResult result = wsi_configure_image(chain, pCreateInfo, 1693bf215546Sopenharmony_ci handle_types, info); 1694bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1695bf215546Sopenharmony_ci return result; 1696bf215546Sopenharmony_ci 1697bf215546Sopenharmony_ci /* Force the image to be linear */ 1698bf215546Sopenharmony_ci info->create.tiling = VK_IMAGE_TILING_LINEAR; 1699bf215546Sopenharmony_ci 1700bf215546Sopenharmony_ci info->create_mem = wsi_create_cpu_linear_image_mem; 1701bf215546Sopenharmony_ci } 1702bf215546Sopenharmony_ci 1703bf215546Sopenharmony_ci info->alloc_shm = alloc_shm; 1704bf215546Sopenharmony_ci 1705bf215546Sopenharmony_ci return VK_SUCCESS; 1706bf215546Sopenharmony_ci} 1707