101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2017 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2101e04c3fSmrg * IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#include "wsi_common_private.h" 257ec681f3Smrg#include "wsi_common_entrypoints.h" 2601e04c3fSmrg#include "util/macros.h" 277ec681f3Smrg#include "util/os_file.h" 287ec681f3Smrg#include "util/os_time.h" 298a1362adSmaya#include "util/xmlconfig.h" 307ec681f3Smrg#include "vk_device.h" 317ec681f3Smrg#include "vk_instance.h" 327ec681f3Smrg#include "vk_physical_device.h" 337ec681f3Smrg#include "vk_queue.h" 3401e04c3fSmrg#include "vk_util.h" 3501e04c3fSmrg 368a1362adSmaya#include <time.h> 378a1362adSmaya#include <stdlib.h> 388a1362adSmaya#include <stdio.h> 3901e04c3fSmrg 4001e04c3fSmrgVkResult 4101e04c3fSmrgwsi_device_init(struct wsi_device *wsi, 4201e04c3fSmrg VkPhysicalDevice pdevice, 4301e04c3fSmrg WSI_FN_GetPhysicalDeviceProcAddr proc_addr, 4401e04c3fSmrg const VkAllocationCallbacks *alloc, 458a1362adSmaya int display_fd, 467ec681f3Smrg const struct driOptionCache *dri_options, 477ec681f3Smrg bool sw_device) 4801e04c3fSmrg{ 498a1362adSmaya const char *present_mode; 507ec681f3Smrg UNUSED VkResult result; 5101e04c3fSmrg 5201e04c3fSmrg memset(wsi, 0, sizeof(*wsi)); 5301e04c3fSmrg 5401e04c3fSmrg wsi->instance_alloc = *alloc; 5501e04c3fSmrg wsi->pdevice = pdevice; 567ec681f3Smrg wsi->sw = sw_device; 5701e04c3fSmrg#define WSI_GET_CB(func) \ 5801e04c3fSmrg PFN_vk##func func = (PFN_vk##func)proc_addr(pdevice, "vk" #func) 5901e04c3fSmrg WSI_GET_CB(GetPhysicalDeviceProperties2); 6001e04c3fSmrg WSI_GET_CB(GetPhysicalDeviceMemoryProperties); 6101e04c3fSmrg WSI_GET_CB(GetPhysicalDeviceQueueFamilyProperties); 6201e04c3fSmrg#undef WSI_GET_CB 6301e04c3fSmrg 6401e04c3fSmrg wsi->pci_bus_info.sType = 6501e04c3fSmrg VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT; 6601e04c3fSmrg VkPhysicalDeviceProperties2 pdp2 = { 6701e04c3fSmrg .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, 6801e04c3fSmrg .pNext = &wsi->pci_bus_info, 6901e04c3fSmrg }; 7001e04c3fSmrg GetPhysicalDeviceProperties2(pdevice, &pdp2); 7101e04c3fSmrg 728a1362adSmaya wsi->maxImageDimension2D = pdp2.properties.limits.maxImageDimension2D; 738a1362adSmaya wsi->override_present_mode = VK_PRESENT_MODE_MAX_ENUM_KHR; 748a1362adSmaya 7501e04c3fSmrg GetPhysicalDeviceMemoryProperties(pdevice, &wsi->memory_props); 7601e04c3fSmrg GetPhysicalDeviceQueueFamilyProperties(pdevice, &wsi->queue_family_count, NULL); 7701e04c3fSmrg 7801e04c3fSmrg#define WSI_GET_CB(func) \ 7901e04c3fSmrg wsi->func = (PFN_vk##func)proc_addr(pdevice, "vk" #func) 8001e04c3fSmrg WSI_GET_CB(AllocateMemory); 8101e04c3fSmrg WSI_GET_CB(AllocateCommandBuffers); 8201e04c3fSmrg WSI_GET_CB(BindBufferMemory); 8301e04c3fSmrg WSI_GET_CB(BindImageMemory); 8401e04c3fSmrg WSI_GET_CB(BeginCommandBuffer); 8501e04c3fSmrg WSI_GET_CB(CmdCopyImageToBuffer); 8601e04c3fSmrg WSI_GET_CB(CreateBuffer); 8701e04c3fSmrg WSI_GET_CB(CreateCommandPool); 8801e04c3fSmrg WSI_GET_CB(CreateFence); 8901e04c3fSmrg WSI_GET_CB(CreateImage); 9001e04c3fSmrg WSI_GET_CB(DestroyBuffer); 9101e04c3fSmrg WSI_GET_CB(DestroyCommandPool); 9201e04c3fSmrg WSI_GET_CB(DestroyFence); 9301e04c3fSmrg WSI_GET_CB(DestroyImage); 9401e04c3fSmrg WSI_GET_CB(EndCommandBuffer); 9501e04c3fSmrg WSI_GET_CB(FreeMemory); 9601e04c3fSmrg WSI_GET_CB(FreeCommandBuffers); 9701e04c3fSmrg WSI_GET_CB(GetBufferMemoryRequirements); 987ec681f3Smrg WSI_GET_CB(GetImageDrmFormatModifierPropertiesEXT); 9901e04c3fSmrg WSI_GET_CB(GetImageMemoryRequirements); 10001e04c3fSmrg WSI_GET_CB(GetImageSubresourceLayout); 1017ec681f3Smrg if (!wsi->sw) 1027ec681f3Smrg WSI_GET_CB(GetMemoryFdKHR); 10301e04c3fSmrg WSI_GET_CB(GetPhysicalDeviceFormatProperties); 10401e04c3fSmrg WSI_GET_CB(GetPhysicalDeviceFormatProperties2KHR); 1057ec681f3Smrg WSI_GET_CB(GetPhysicalDeviceImageFormatProperties2); 10601e04c3fSmrg WSI_GET_CB(ResetFences); 10701e04c3fSmrg WSI_GET_CB(QueueSubmit); 10801e04c3fSmrg WSI_GET_CB(WaitForFences); 1097ec681f3Smrg WSI_GET_CB(MapMemory); 1107ec681f3Smrg WSI_GET_CB(UnmapMemory); 11101e04c3fSmrg#undef WSI_GET_CB 11201e04c3fSmrg 11301e04c3fSmrg#ifdef VK_USE_PLATFORM_XCB_KHR 1148a1362adSmaya result = wsi_x11_init_wsi(wsi, alloc, dri_options); 11501e04c3fSmrg if (result != VK_SUCCESS) 11601e04c3fSmrg goto fail; 11701e04c3fSmrg#endif 11801e04c3fSmrg 11901e04c3fSmrg#ifdef VK_USE_PLATFORM_WAYLAND_KHR 12001e04c3fSmrg result = wsi_wl_init_wsi(wsi, alloc, pdevice); 12101e04c3fSmrg if (result != VK_SUCCESS) 12201e04c3fSmrg goto fail; 12301e04c3fSmrg#endif 12401e04c3fSmrg 1257ec681f3Smrg#ifdef VK_USE_PLATFORM_WIN32_KHR 1267ec681f3Smrg result = wsi_win32_init_wsi(wsi, alloc, pdevice); 1277ec681f3Smrg if (result != VK_SUCCESS) 1287ec681f3Smrg goto fail; 1297ec681f3Smrg#endif 1307ec681f3Smrg 13101e04c3fSmrg#ifdef VK_USE_PLATFORM_DISPLAY_KHR 13201e04c3fSmrg result = wsi_display_init_wsi(wsi, alloc, display_fd); 13301e04c3fSmrg if (result != VK_SUCCESS) 13401e04c3fSmrg goto fail; 13501e04c3fSmrg#endif 13601e04c3fSmrg 1378a1362adSmaya present_mode = getenv("MESA_VK_WSI_PRESENT_MODE"); 1388a1362adSmaya if (present_mode) { 1398a1362adSmaya if (!strcmp(present_mode, "fifo")) { 1408a1362adSmaya wsi->override_present_mode = VK_PRESENT_MODE_FIFO_KHR; 1417ec681f3Smrg } else if (!strcmp(present_mode, "relaxed")) { 1427ec681f3Smrg wsi->override_present_mode = VK_PRESENT_MODE_FIFO_RELAXED_KHR; 1438a1362adSmaya } else if (!strcmp(present_mode, "mailbox")) { 1448a1362adSmaya wsi->override_present_mode = VK_PRESENT_MODE_MAILBOX_KHR; 1458a1362adSmaya } else if (!strcmp(present_mode, "immediate")) { 1468a1362adSmaya wsi->override_present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; 1478a1362adSmaya } else { 1488a1362adSmaya fprintf(stderr, "Invalid MESA_VK_WSI_PRESENT_MODE value!\n"); 1498a1362adSmaya } 1508a1362adSmaya } 1518a1362adSmaya 1528a1362adSmaya if (dri_options) { 1538a1362adSmaya if (driCheckOption(dri_options, "adaptive_sync", DRI_BOOL)) 1548a1362adSmaya wsi->enable_adaptive_sync = driQueryOptionb(dri_options, 1558a1362adSmaya "adaptive_sync"); 1567ec681f3Smrg 1577ec681f3Smrg if (driCheckOption(dri_options, "vk_wsi_force_bgra8_unorm_first", DRI_BOOL)) { 1587ec681f3Smrg wsi->force_bgra8_unorm_first = 1597ec681f3Smrg driQueryOptionb(dri_options, "vk_wsi_force_bgra8_unorm_first"); 1607ec681f3Smrg } 1618a1362adSmaya } 1628a1362adSmaya 16301e04c3fSmrg return VK_SUCCESS; 1647ec681f3Smrg#if defined(VK_USE_PLATFORM_XCB_KHR) || \ 1657ec681f3Smrg defined(VK_USE_PLATFORM_WAYLAND_KHR) || \ 1667ec681f3Smrg defined(VK_USE_PLATFORM_WIN32_KHR) || \ 1677ec681f3Smrg defined(VK_USE_PLATFORM_DISPLAY_KHR) 16801e04c3fSmrgfail: 16901e04c3fSmrg wsi_device_finish(wsi, alloc); 17001e04c3fSmrg return result; 1717ec681f3Smrg#endif 17201e04c3fSmrg} 17301e04c3fSmrg 17401e04c3fSmrgvoid 17501e04c3fSmrgwsi_device_finish(struct wsi_device *wsi, 17601e04c3fSmrg const VkAllocationCallbacks *alloc) 17701e04c3fSmrg{ 17801e04c3fSmrg#ifdef VK_USE_PLATFORM_DISPLAY_KHR 17901e04c3fSmrg wsi_display_finish_wsi(wsi, alloc); 18001e04c3fSmrg#endif 18101e04c3fSmrg#ifdef VK_USE_PLATFORM_WAYLAND_KHR 18201e04c3fSmrg wsi_wl_finish_wsi(wsi, alloc); 18301e04c3fSmrg#endif 1847ec681f3Smrg#ifdef VK_USE_PLATFORM_WIN32_KHR 1857ec681f3Smrg wsi_win32_finish_wsi(wsi, alloc); 1867ec681f3Smrg#endif 18701e04c3fSmrg#ifdef VK_USE_PLATFORM_XCB_KHR 18801e04c3fSmrg wsi_x11_finish_wsi(wsi, alloc); 18901e04c3fSmrg#endif 19001e04c3fSmrg} 19101e04c3fSmrg 1927ec681f3SmrgVKAPI_ATTR void VKAPI_CALL 1937ec681f3Smrgwsi_DestroySurfaceKHR(VkInstance _instance, 1947ec681f3Smrg VkSurfaceKHR _surface, 1957ec681f3Smrg const VkAllocationCallbacks *pAllocator) 19601e04c3fSmrg{ 1977ec681f3Smrg VK_FROM_HANDLE(vk_instance, instance, _instance); 1987ec681f3Smrg ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 19901e04c3fSmrg 2007ec681f3Smrg if (!surface) 2017ec681f3Smrg return; 20201e04c3fSmrg 2037ec681f3Smrg vk_free2(&instance->alloc, pAllocator, surface); 20401e04c3fSmrg} 20501e04c3fSmrg 20601e04c3fSmrgVkResult 20701e04c3fSmrgwsi_swapchain_init(const struct wsi_device *wsi, 20801e04c3fSmrg struct wsi_swapchain *chain, 20901e04c3fSmrg VkDevice device, 21001e04c3fSmrg const VkSwapchainCreateInfoKHR *pCreateInfo, 21101e04c3fSmrg const VkAllocationCallbacks *pAllocator) 21201e04c3fSmrg{ 21301e04c3fSmrg VkResult result; 21401e04c3fSmrg 21501e04c3fSmrg memset(chain, 0, sizeof(*chain)); 21601e04c3fSmrg 2177ec681f3Smrg vk_object_base_init(NULL, &chain->base, VK_OBJECT_TYPE_SWAPCHAIN_KHR); 2187ec681f3Smrg 21901e04c3fSmrg chain->wsi = wsi; 22001e04c3fSmrg chain->device = device; 22101e04c3fSmrg chain->alloc = *pAllocator; 22201e04c3fSmrg chain->use_prime_blit = false; 22301e04c3fSmrg 22401e04c3fSmrg chain->cmd_pools = 22501e04c3fSmrg vk_zalloc(pAllocator, sizeof(VkCommandPool) * wsi->queue_family_count, 8, 22601e04c3fSmrg VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 22701e04c3fSmrg if (!chain->cmd_pools) 22801e04c3fSmrg return VK_ERROR_OUT_OF_HOST_MEMORY; 22901e04c3fSmrg 23001e04c3fSmrg for (uint32_t i = 0; i < wsi->queue_family_count; i++) { 23101e04c3fSmrg const VkCommandPoolCreateInfo cmd_pool_info = { 23201e04c3fSmrg .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, 23301e04c3fSmrg .pNext = NULL, 23401e04c3fSmrg .flags = 0, 23501e04c3fSmrg .queueFamilyIndex = i, 23601e04c3fSmrg }; 23701e04c3fSmrg result = wsi->CreateCommandPool(device, &cmd_pool_info, &chain->alloc, 23801e04c3fSmrg &chain->cmd_pools[i]); 23901e04c3fSmrg if (result != VK_SUCCESS) 24001e04c3fSmrg goto fail; 24101e04c3fSmrg } 24201e04c3fSmrg 24301e04c3fSmrg return VK_SUCCESS; 24401e04c3fSmrg 24501e04c3fSmrgfail: 24601e04c3fSmrg wsi_swapchain_finish(chain); 24701e04c3fSmrg return result; 24801e04c3fSmrg} 24901e04c3fSmrg 2508a1362adSmayastatic bool 2518a1362adSmayawsi_swapchain_is_present_mode_supported(struct wsi_device *wsi, 2528a1362adSmaya const VkSwapchainCreateInfoKHR *pCreateInfo, 2538a1362adSmaya VkPresentModeKHR mode) 2548a1362adSmaya{ 2558a1362adSmaya ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pCreateInfo->surface); 2568a1362adSmaya struct wsi_interface *iface = wsi->wsi[surface->platform]; 2578a1362adSmaya VkPresentModeKHR *present_modes; 2588a1362adSmaya uint32_t present_mode_count; 2598a1362adSmaya bool supported = false; 2608a1362adSmaya VkResult result; 2618a1362adSmaya 2628a1362adSmaya result = iface->get_present_modes(surface, &present_mode_count, NULL); 2638a1362adSmaya if (result != VK_SUCCESS) 2648a1362adSmaya return supported; 2658a1362adSmaya 2668a1362adSmaya present_modes = malloc(present_mode_count * sizeof(*present_modes)); 2678a1362adSmaya if (!present_modes) 2688a1362adSmaya return supported; 2698a1362adSmaya 2708a1362adSmaya result = iface->get_present_modes(surface, &present_mode_count, 2718a1362adSmaya present_modes); 2728a1362adSmaya if (result != VK_SUCCESS) 2738a1362adSmaya goto fail; 2748a1362adSmaya 2758a1362adSmaya for (uint32_t i = 0; i < present_mode_count; i++) { 2768a1362adSmaya if (present_modes[i] == mode) { 2778a1362adSmaya supported = true; 2788a1362adSmaya break; 2798a1362adSmaya } 2808a1362adSmaya } 2818a1362adSmaya 2828a1362adSmayafail: 2838a1362adSmaya free(present_modes); 2848a1362adSmaya return supported; 2858a1362adSmaya} 2868a1362adSmaya 2878a1362adSmayaenum VkPresentModeKHR 2888a1362adSmayawsi_swapchain_get_present_mode(struct wsi_device *wsi, 2898a1362adSmaya const VkSwapchainCreateInfoKHR *pCreateInfo) 2908a1362adSmaya{ 2918a1362adSmaya if (wsi->override_present_mode == VK_PRESENT_MODE_MAX_ENUM_KHR) 2928a1362adSmaya return pCreateInfo->presentMode; 2938a1362adSmaya 2948a1362adSmaya if (!wsi_swapchain_is_present_mode_supported(wsi, pCreateInfo, 2958a1362adSmaya wsi->override_present_mode)) { 2968a1362adSmaya fprintf(stderr, "Unsupported MESA_VK_WSI_PRESENT_MODE value!\n"); 2978a1362adSmaya return pCreateInfo->presentMode; 2988a1362adSmaya } 2998a1362adSmaya 3008a1362adSmaya return wsi->override_present_mode; 3018a1362adSmaya} 3028a1362adSmaya 30301e04c3fSmrgvoid 30401e04c3fSmrgwsi_swapchain_finish(struct wsi_swapchain *chain) 30501e04c3fSmrg{ 3067ec681f3Smrg if (chain->fences) { 3077ec681f3Smrg for (unsigned i = 0; i < chain->image_count; i++) 3087ec681f3Smrg chain->wsi->DestroyFence(chain->device, chain->fences[i], &chain->alloc); 3097ec681f3Smrg 3107ec681f3Smrg vk_free(&chain->alloc, chain->fences); 3117ec681f3Smrg } 31201e04c3fSmrg 31301e04c3fSmrg for (uint32_t i = 0; i < chain->wsi->queue_family_count; i++) { 31401e04c3fSmrg chain->wsi->DestroyCommandPool(chain->device, chain->cmd_pools[i], 31501e04c3fSmrg &chain->alloc); 31601e04c3fSmrg } 31701e04c3fSmrg vk_free(&chain->alloc, chain->cmd_pools); 31801e04c3fSmrg 3197ec681f3Smrg vk_object_base_finish(&chain->base); 32001e04c3fSmrg} 32101e04c3fSmrg 32201e04c3fSmrgvoid 32301e04c3fSmrgwsi_destroy_image(const struct wsi_swapchain *chain, 32401e04c3fSmrg struct wsi_image *image) 32501e04c3fSmrg{ 32601e04c3fSmrg const struct wsi_device *wsi = chain->wsi; 32701e04c3fSmrg 32801e04c3fSmrg if (image->prime.blit_cmd_buffers) { 32901e04c3fSmrg for (uint32_t i = 0; i < wsi->queue_family_count; i++) { 33001e04c3fSmrg wsi->FreeCommandBuffers(chain->device, chain->cmd_pools[i], 33101e04c3fSmrg 1, &image->prime.blit_cmd_buffers[i]); 33201e04c3fSmrg } 33301e04c3fSmrg vk_free(&chain->alloc, image->prime.blit_cmd_buffers); 33401e04c3fSmrg } 33501e04c3fSmrg 33601e04c3fSmrg wsi->FreeMemory(chain->device, image->memory, &chain->alloc); 33701e04c3fSmrg wsi->DestroyImage(chain->device, image->image, &chain->alloc); 33801e04c3fSmrg wsi->FreeMemory(chain->device, image->prime.memory, &chain->alloc); 33901e04c3fSmrg wsi->DestroyBuffer(chain->device, image->prime.buffer, &chain->alloc); 34001e04c3fSmrg} 34101e04c3fSmrg 3427ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 3437ec681f3Smrgwsi_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, 3447ec681f3Smrg uint32_t queueFamilyIndex, 3457ec681f3Smrg VkSurfaceKHR _surface, 3467ec681f3Smrg VkBool32 *pSupported) 34701e04c3fSmrg{ 3487ec681f3Smrg VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 34901e04c3fSmrg ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 3507ec681f3Smrg struct wsi_device *wsi_device = device->wsi_device; 35101e04c3fSmrg struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 35201e04c3fSmrg 35301e04c3fSmrg return iface->get_support(surface, wsi_device, 35401e04c3fSmrg queueFamilyIndex, pSupported); 35501e04c3fSmrg} 35601e04c3fSmrg 3577ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 3587ec681f3Smrgwsi_GetPhysicalDeviceSurfaceCapabilitiesKHR( 3597ec681f3Smrg VkPhysicalDevice physicalDevice, 3607ec681f3Smrg VkSurfaceKHR _surface, 3617ec681f3Smrg VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) 36201e04c3fSmrg{ 3637ec681f3Smrg VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 36401e04c3fSmrg ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 3657ec681f3Smrg struct wsi_device *wsi_device = device->wsi_device; 36601e04c3fSmrg struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 36701e04c3fSmrg 36801e04c3fSmrg VkSurfaceCapabilities2KHR caps2 = { 36901e04c3fSmrg .sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR, 37001e04c3fSmrg }; 37101e04c3fSmrg 3728a1362adSmaya VkResult result = iface->get_capabilities2(surface, wsi_device, NULL, &caps2); 37301e04c3fSmrg 37401e04c3fSmrg if (result == VK_SUCCESS) 37501e04c3fSmrg *pSurfaceCapabilities = caps2.surfaceCapabilities; 37601e04c3fSmrg 37701e04c3fSmrg return result; 37801e04c3fSmrg} 37901e04c3fSmrg 3807ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 3817ec681f3Smrgwsi_GetPhysicalDeviceSurfaceCapabilities2KHR( 3827ec681f3Smrg VkPhysicalDevice physicalDevice, 3837ec681f3Smrg const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 3847ec681f3Smrg VkSurfaceCapabilities2KHR *pSurfaceCapabilities) 38501e04c3fSmrg{ 3867ec681f3Smrg VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 38701e04c3fSmrg ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface); 3887ec681f3Smrg struct wsi_device *wsi_device = device->wsi_device; 38901e04c3fSmrg struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 39001e04c3fSmrg 3918a1362adSmaya return iface->get_capabilities2(surface, wsi_device, pSurfaceInfo->pNext, 39201e04c3fSmrg pSurfaceCapabilities); 39301e04c3fSmrg} 39401e04c3fSmrg 3957ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 3967ec681f3Smrgwsi_GetPhysicalDeviceSurfaceCapabilities2EXT( 3977ec681f3Smrg VkPhysicalDevice physicalDevice, 39801e04c3fSmrg VkSurfaceKHR _surface, 39901e04c3fSmrg VkSurfaceCapabilities2EXT *pSurfaceCapabilities) 40001e04c3fSmrg{ 4017ec681f3Smrg VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 40201e04c3fSmrg ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 4037ec681f3Smrg struct wsi_device *wsi_device = device->wsi_device; 40401e04c3fSmrg struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 40501e04c3fSmrg 40601e04c3fSmrg assert(pSurfaceCapabilities->sType == 40701e04c3fSmrg VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT); 40801e04c3fSmrg 40901e04c3fSmrg struct wsi_surface_supported_counters counters = { 41001e04c3fSmrg .sType = VK_STRUCTURE_TYPE_WSI_SURFACE_SUPPORTED_COUNTERS_MESA, 41101e04c3fSmrg .pNext = pSurfaceCapabilities->pNext, 41201e04c3fSmrg .supported_surface_counters = 0, 41301e04c3fSmrg }; 41401e04c3fSmrg 41501e04c3fSmrg VkSurfaceCapabilities2KHR caps2 = { 41601e04c3fSmrg .sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR, 41701e04c3fSmrg .pNext = &counters, 41801e04c3fSmrg }; 41901e04c3fSmrg 4208a1362adSmaya VkResult result = iface->get_capabilities2(surface, wsi_device, NULL, &caps2); 42101e04c3fSmrg 42201e04c3fSmrg if (result == VK_SUCCESS) { 42301e04c3fSmrg VkSurfaceCapabilities2EXT *ext_caps = pSurfaceCapabilities; 42401e04c3fSmrg VkSurfaceCapabilitiesKHR khr_caps = caps2.surfaceCapabilities; 42501e04c3fSmrg 42601e04c3fSmrg ext_caps->minImageCount = khr_caps.minImageCount; 42701e04c3fSmrg ext_caps->maxImageCount = khr_caps.maxImageCount; 42801e04c3fSmrg ext_caps->currentExtent = khr_caps.currentExtent; 42901e04c3fSmrg ext_caps->minImageExtent = khr_caps.minImageExtent; 43001e04c3fSmrg ext_caps->maxImageExtent = khr_caps.maxImageExtent; 43101e04c3fSmrg ext_caps->maxImageArrayLayers = khr_caps.maxImageArrayLayers; 43201e04c3fSmrg ext_caps->supportedTransforms = khr_caps.supportedTransforms; 43301e04c3fSmrg ext_caps->currentTransform = khr_caps.currentTransform; 43401e04c3fSmrg ext_caps->supportedCompositeAlpha = khr_caps.supportedCompositeAlpha; 43501e04c3fSmrg ext_caps->supportedUsageFlags = khr_caps.supportedUsageFlags; 43601e04c3fSmrg ext_caps->supportedSurfaceCounters = counters.supported_surface_counters; 43701e04c3fSmrg } 43801e04c3fSmrg 43901e04c3fSmrg return result; 44001e04c3fSmrg} 44101e04c3fSmrg 4427ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 4437ec681f3Smrgwsi_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, 4447ec681f3Smrg VkSurfaceKHR _surface, 4457ec681f3Smrg uint32_t *pSurfaceFormatCount, 4467ec681f3Smrg VkSurfaceFormatKHR *pSurfaceFormats) 44701e04c3fSmrg{ 4487ec681f3Smrg VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 44901e04c3fSmrg ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 4507ec681f3Smrg struct wsi_device *wsi_device = device->wsi_device; 45101e04c3fSmrg struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 45201e04c3fSmrg 45301e04c3fSmrg return iface->get_formats(surface, wsi_device, 45401e04c3fSmrg pSurfaceFormatCount, pSurfaceFormats); 45501e04c3fSmrg} 45601e04c3fSmrg 4577ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 4587ec681f3Smrgwsi_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, 4597ec681f3Smrg const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo, 4607ec681f3Smrg uint32_t *pSurfaceFormatCount, 4617ec681f3Smrg VkSurfaceFormat2KHR *pSurfaceFormats) 46201e04c3fSmrg{ 4637ec681f3Smrg VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 46401e04c3fSmrg ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface); 4657ec681f3Smrg struct wsi_device *wsi_device = device->wsi_device; 46601e04c3fSmrg struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 46701e04c3fSmrg 46801e04c3fSmrg return iface->get_formats2(surface, wsi_device, pSurfaceInfo->pNext, 46901e04c3fSmrg pSurfaceFormatCount, pSurfaceFormats); 47001e04c3fSmrg} 47101e04c3fSmrg 4727ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 4737ec681f3Smrgwsi_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, 4747ec681f3Smrg VkSurfaceKHR _surface, 4757ec681f3Smrg uint32_t *pPresentModeCount, 4767ec681f3Smrg VkPresentModeKHR *pPresentModes) 47701e04c3fSmrg{ 4787ec681f3Smrg VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 47901e04c3fSmrg ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 4807ec681f3Smrg struct wsi_device *wsi_device = device->wsi_device; 48101e04c3fSmrg struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 48201e04c3fSmrg 48301e04c3fSmrg return iface->get_present_modes(surface, pPresentModeCount, 48401e04c3fSmrg pPresentModes); 48501e04c3fSmrg} 48601e04c3fSmrg 4877ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 4887ec681f3Smrgwsi_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, 4897ec681f3Smrg VkSurfaceKHR _surface, 4907ec681f3Smrg uint32_t *pRectCount, 4917ec681f3Smrg VkRect2D *pRects) 49201e04c3fSmrg{ 4937ec681f3Smrg VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); 49401e04c3fSmrg ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); 4957ec681f3Smrg struct wsi_device *wsi_device = device->wsi_device; 49601e04c3fSmrg struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 49701e04c3fSmrg 49801e04c3fSmrg return iface->get_present_rectangles(surface, wsi_device, 49901e04c3fSmrg pRectCount, pRects); 50001e04c3fSmrg} 50101e04c3fSmrg 5027ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 5037ec681f3Smrgwsi_CreateSwapchainKHR(VkDevice _device, 5047ec681f3Smrg const VkSwapchainCreateInfoKHR *pCreateInfo, 5057ec681f3Smrg const VkAllocationCallbacks *pAllocator, 5067ec681f3Smrg VkSwapchainKHR *pSwapchain) 50701e04c3fSmrg{ 5087ec681f3Smrg VK_FROM_HANDLE(vk_device, device, _device); 50901e04c3fSmrg ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pCreateInfo->surface); 5107ec681f3Smrg struct wsi_device *wsi_device = device->physical->wsi_device; 5117ec681f3Smrg struct wsi_interface *iface = wsi_device->wsi[surface->platform]; 5127ec681f3Smrg const VkAllocationCallbacks *alloc; 51301e04c3fSmrg struct wsi_swapchain *swapchain; 51401e04c3fSmrg 5157ec681f3Smrg if (pAllocator) 5167ec681f3Smrg alloc = pAllocator; 5177ec681f3Smrg else 5187ec681f3Smrg alloc = &device->alloc; 5197ec681f3Smrg 5207ec681f3Smrg VkResult result = iface->create_swapchain(surface, _device, wsi_device, 5217ec681f3Smrg pCreateInfo, alloc, 52201e04c3fSmrg &swapchain); 52301e04c3fSmrg if (result != VK_SUCCESS) 52401e04c3fSmrg return result; 52501e04c3fSmrg 5267ec681f3Smrg swapchain->fences = vk_zalloc(alloc, 5277ec681f3Smrg sizeof (*swapchain->fences) * swapchain->image_count, 5287ec681f3Smrg sizeof (*swapchain->fences), 5297ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 5307ec681f3Smrg if (!swapchain->fences) { 5317ec681f3Smrg swapchain->destroy(swapchain, alloc); 5327ec681f3Smrg return VK_ERROR_OUT_OF_HOST_MEMORY; 5337ec681f3Smrg } 5347ec681f3Smrg 53501e04c3fSmrg *pSwapchain = wsi_swapchain_to_handle(swapchain); 53601e04c3fSmrg 53701e04c3fSmrg return VK_SUCCESS; 53801e04c3fSmrg} 53901e04c3fSmrg 5407ec681f3SmrgVKAPI_ATTR void VKAPI_CALL 5417ec681f3Smrgwsi_DestroySwapchainKHR(VkDevice _device, 5427ec681f3Smrg VkSwapchainKHR _swapchain, 5437ec681f3Smrg const VkAllocationCallbacks *pAllocator) 54401e04c3fSmrg{ 5457ec681f3Smrg VK_FROM_HANDLE(vk_device, device, _device); 5467ec681f3Smrg VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain); 5477ec681f3Smrg const VkAllocationCallbacks *alloc; 5487ec681f3Smrg 54901e04c3fSmrg if (!swapchain) 55001e04c3fSmrg return; 55101e04c3fSmrg 5527ec681f3Smrg if (pAllocator) 5537ec681f3Smrg alloc = pAllocator; 5547ec681f3Smrg else 5557ec681f3Smrg alloc = &device->alloc; 5567ec681f3Smrg 5577ec681f3Smrg swapchain->destroy(swapchain, alloc); 55801e04c3fSmrg} 55901e04c3fSmrg 56001e04c3fSmrgVkResult 56101e04c3fSmrgwsi_common_get_images(VkSwapchainKHR _swapchain, 56201e04c3fSmrg uint32_t *pSwapchainImageCount, 56301e04c3fSmrg VkImage *pSwapchainImages) 56401e04c3fSmrg{ 5657ec681f3Smrg VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain); 5667ec681f3Smrg VK_OUTARRAY_MAKE_TYPED(VkImage, images, pSwapchainImages, pSwapchainImageCount); 56701e04c3fSmrg 56801e04c3fSmrg for (uint32_t i = 0; i < swapchain->image_count; i++) { 5697ec681f3Smrg vk_outarray_append_typed(VkImage, &images, image) { 57001e04c3fSmrg *image = swapchain->get_wsi_image(swapchain, i)->image; 57101e04c3fSmrg } 57201e04c3fSmrg } 57301e04c3fSmrg 57401e04c3fSmrg return vk_outarray_status(&images); 57501e04c3fSmrg} 57601e04c3fSmrg 5777ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 5787ec681f3Smrgwsi_GetSwapchainImagesKHR(VkDevice device, 5797ec681f3Smrg VkSwapchainKHR swapchain, 5807ec681f3Smrg uint32_t *pSwapchainImageCount, 5817ec681f3Smrg VkImage *pSwapchainImages) 5827ec681f3Smrg{ 5837ec681f3Smrg return wsi_common_get_images(swapchain, 5847ec681f3Smrg pSwapchainImageCount, 5857ec681f3Smrg pSwapchainImages); 5867ec681f3Smrg} 5877ec681f3Smrg 5887ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 5897ec681f3Smrgwsi_AcquireNextImageKHR(VkDevice _device, 5907ec681f3Smrg VkSwapchainKHR swapchain, 5917ec681f3Smrg uint64_t timeout, 5927ec681f3Smrg VkSemaphore semaphore, 5937ec681f3Smrg VkFence fence, 5947ec681f3Smrg uint32_t *pImageIndex) 5957ec681f3Smrg{ 5967ec681f3Smrg VK_FROM_HANDLE(vk_device, device, _device); 5977ec681f3Smrg 5987ec681f3Smrg const VkAcquireNextImageInfoKHR acquire_info = { 5997ec681f3Smrg .sType = VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR, 6007ec681f3Smrg .swapchain = swapchain, 6017ec681f3Smrg .timeout = timeout, 6027ec681f3Smrg .semaphore = semaphore, 6037ec681f3Smrg .fence = fence, 6047ec681f3Smrg .deviceMask = 0, 6057ec681f3Smrg }; 6067ec681f3Smrg 6077ec681f3Smrg return device->dispatch_table.AcquireNextImage2KHR(_device, &acquire_info, 6087ec681f3Smrg pImageIndex); 6097ec681f3Smrg} 6107ec681f3Smrg 61101e04c3fSmrgVkResult 61201e04c3fSmrgwsi_common_acquire_next_image2(const struct wsi_device *wsi, 61301e04c3fSmrg VkDevice device, 61401e04c3fSmrg const VkAcquireNextImageInfoKHR *pAcquireInfo, 61501e04c3fSmrg uint32_t *pImageIndex) 61601e04c3fSmrg{ 6177ec681f3Smrg VK_FROM_HANDLE(wsi_swapchain, swapchain, pAcquireInfo->swapchain); 6187ec681f3Smrg 6197ec681f3Smrg VkResult result = swapchain->acquire_next_image(swapchain, pAcquireInfo, 6207ec681f3Smrg pImageIndex); 6217ec681f3Smrg if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) 6227ec681f3Smrg return result; 6237ec681f3Smrg 6247ec681f3Smrg if (wsi->set_memory_ownership) { 6257ec681f3Smrg VkDeviceMemory mem = swapchain->get_wsi_image(swapchain, *pImageIndex)->memory; 6267ec681f3Smrg wsi->set_memory_ownership(swapchain->device, mem, true); 6277ec681f3Smrg } 6287ec681f3Smrg 6297ec681f3Smrg if (pAcquireInfo->semaphore != VK_NULL_HANDLE && 6307ec681f3Smrg wsi->signal_semaphore_for_memory != NULL) { 6317ec681f3Smrg struct wsi_image *image = 6327ec681f3Smrg swapchain->get_wsi_image(swapchain, *pImageIndex); 6337ec681f3Smrg wsi->signal_semaphore_for_memory(device, pAcquireInfo->semaphore, 6347ec681f3Smrg image->memory); 6357ec681f3Smrg } 6367ec681f3Smrg 6377ec681f3Smrg if (pAcquireInfo->fence != VK_NULL_HANDLE && 6387ec681f3Smrg wsi->signal_fence_for_memory != NULL) { 6397ec681f3Smrg struct wsi_image *image = 6407ec681f3Smrg swapchain->get_wsi_image(swapchain, *pImageIndex); 6417ec681f3Smrg wsi->signal_fence_for_memory(device, pAcquireInfo->fence, 6427ec681f3Smrg image->memory); 6437ec681f3Smrg } 64401e04c3fSmrg 6457ec681f3Smrg return result; 6467ec681f3Smrg} 6477ec681f3Smrg 6487ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 6497ec681f3Smrgwsi_AcquireNextImage2KHR(VkDevice _device, 6507ec681f3Smrg const VkAcquireNextImageInfoKHR *pAcquireInfo, 6517ec681f3Smrg uint32_t *pImageIndex) 6527ec681f3Smrg{ 6537ec681f3Smrg VK_FROM_HANDLE(vk_device, device, _device); 6547ec681f3Smrg 6557ec681f3Smrg return wsi_common_acquire_next_image2(device->physical->wsi_device, 6567ec681f3Smrg _device, pAcquireInfo, pImageIndex); 65701e04c3fSmrg} 65801e04c3fSmrg 65901e04c3fSmrgVkResult 66001e04c3fSmrgwsi_common_queue_present(const struct wsi_device *wsi, 66101e04c3fSmrg VkDevice device, 66201e04c3fSmrg VkQueue queue, 66301e04c3fSmrg int queue_family_index, 66401e04c3fSmrg const VkPresentInfoKHR *pPresentInfo) 66501e04c3fSmrg{ 66601e04c3fSmrg VkResult final_result = VK_SUCCESS; 66701e04c3fSmrg 66801e04c3fSmrg const VkPresentRegionsKHR *regions = 66901e04c3fSmrg vk_find_struct_const(pPresentInfo->pNext, PRESENT_REGIONS_KHR); 67001e04c3fSmrg 67101e04c3fSmrg for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) { 6727ec681f3Smrg VK_FROM_HANDLE(wsi_swapchain, swapchain, pPresentInfo->pSwapchains[i]); 6737ec681f3Smrg uint32_t image_index = pPresentInfo->pImageIndices[i]; 67401e04c3fSmrg VkResult result; 67501e04c3fSmrg 6767ec681f3Smrg if (swapchain->fences[image_index] == VK_NULL_HANDLE) { 67701e04c3fSmrg const VkFenceCreateInfo fence_info = { 67801e04c3fSmrg .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, 67901e04c3fSmrg .pNext = NULL, 68001e04c3fSmrg .flags = 0, 68101e04c3fSmrg }; 68201e04c3fSmrg result = wsi->CreateFence(device, &fence_info, 68301e04c3fSmrg &swapchain->alloc, 6847ec681f3Smrg &swapchain->fences[image_index]); 68501e04c3fSmrg if (result != VK_SUCCESS) 68601e04c3fSmrg goto fail_present; 68701e04c3fSmrg } else { 6887ec681f3Smrg result = 6897ec681f3Smrg wsi->WaitForFences(device, 1, &swapchain->fences[image_index], 6907ec681f3Smrg true, ~0ull); 6917ec681f3Smrg if (result != VK_SUCCESS) 6927ec681f3Smrg goto fail_present; 6937ec681f3Smrg 6947ec681f3Smrg result = 6957ec681f3Smrg wsi->ResetFences(device, 1, &swapchain->fences[image_index]); 6967ec681f3Smrg if (result != VK_SUCCESS) 6977ec681f3Smrg goto fail_present; 69801e04c3fSmrg } 69901e04c3fSmrg 7007ec681f3Smrg struct wsi_image *image = 7017ec681f3Smrg swapchain->get_wsi_image(swapchain, image_index); 7027ec681f3Smrg 7037ec681f3Smrg struct wsi_memory_signal_submit_info mem_signal = { 7047ec681f3Smrg .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA, 7057ec681f3Smrg .pNext = NULL, 7067ec681f3Smrg .memory = image->memory, 7077ec681f3Smrg }; 7087ec681f3Smrg 70901e04c3fSmrg VkSubmitInfo submit_info = { 71001e04c3fSmrg .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, 7117ec681f3Smrg .pNext = &mem_signal, 71201e04c3fSmrg }; 71301e04c3fSmrg 71401e04c3fSmrg VkPipelineStageFlags *stage_flags = NULL; 71501e04c3fSmrg if (i == 0) { 71601e04c3fSmrg /* We only need/want to wait on semaphores once. After that, we're 71701e04c3fSmrg * guaranteed ordering since it all happens on the same queue. 71801e04c3fSmrg */ 71901e04c3fSmrg submit_info.waitSemaphoreCount = pPresentInfo->waitSemaphoreCount; 72001e04c3fSmrg submit_info.pWaitSemaphores = pPresentInfo->pWaitSemaphores; 72101e04c3fSmrg 72201e04c3fSmrg /* Set up the pWaitDstStageMasks */ 72301e04c3fSmrg stage_flags = vk_alloc(&swapchain->alloc, 72401e04c3fSmrg sizeof(VkPipelineStageFlags) * 72501e04c3fSmrg pPresentInfo->waitSemaphoreCount, 72601e04c3fSmrg 8, 72701e04c3fSmrg VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 72801e04c3fSmrg if (!stage_flags) { 72901e04c3fSmrg result = VK_ERROR_OUT_OF_HOST_MEMORY; 73001e04c3fSmrg goto fail_present; 73101e04c3fSmrg } 73201e04c3fSmrg for (uint32_t s = 0; s < pPresentInfo->waitSemaphoreCount; s++) 73301e04c3fSmrg stage_flags[s] = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; 73401e04c3fSmrg 73501e04c3fSmrg submit_info.pWaitDstStageMask = stage_flags; 73601e04c3fSmrg } 73701e04c3fSmrg 73801e04c3fSmrg if (swapchain->use_prime_blit) { 73901e04c3fSmrg /* If we are using prime blits, we need to perform the blit now. The 74001e04c3fSmrg * command buffer is attached to the image. 74101e04c3fSmrg */ 74201e04c3fSmrg submit_info.commandBufferCount = 1; 74301e04c3fSmrg submit_info.pCommandBuffers = 74401e04c3fSmrg &image->prime.blit_cmd_buffers[queue_family_index]; 7457ec681f3Smrg mem_signal.memory = image->prime.memory; 74601e04c3fSmrg } 74701e04c3fSmrg 7487ec681f3Smrg result = wsi->QueueSubmit(queue, 1, &submit_info, swapchain->fences[image_index]); 74901e04c3fSmrg vk_free(&swapchain->alloc, stage_flags); 75001e04c3fSmrg if (result != VK_SUCCESS) 75101e04c3fSmrg goto fail_present; 75201e04c3fSmrg 7537ec681f3Smrg if (wsi->sw) 7547ec681f3Smrg wsi->WaitForFences(device, 1, &swapchain->fences[image_index], 7557ec681f3Smrg true, ~0ull); 7567ec681f3Smrg 75701e04c3fSmrg const VkPresentRegionKHR *region = NULL; 75801e04c3fSmrg if (regions && regions->pRegions) 75901e04c3fSmrg region = ®ions->pRegions[i]; 76001e04c3fSmrg 7617ec681f3Smrg result = swapchain->queue_present(swapchain, image_index, region); 7627ec681f3Smrg if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) 76301e04c3fSmrg goto fail_present; 76401e04c3fSmrg 7657ec681f3Smrg if (wsi->set_memory_ownership) { 7667ec681f3Smrg VkDeviceMemory mem = swapchain->get_wsi_image(swapchain, image_index)->memory; 7677ec681f3Smrg wsi->set_memory_ownership(swapchain->device, mem, false); 76801e04c3fSmrg } 76901e04c3fSmrg 77001e04c3fSmrg fail_present: 77101e04c3fSmrg if (pPresentInfo->pResults != NULL) 77201e04c3fSmrg pPresentInfo->pResults[i] = result; 77301e04c3fSmrg 77401e04c3fSmrg /* Let the final result be our first unsuccessful result */ 77501e04c3fSmrg if (final_result == VK_SUCCESS) 77601e04c3fSmrg final_result = result; 77701e04c3fSmrg } 77801e04c3fSmrg 77901e04c3fSmrg return final_result; 78001e04c3fSmrg} 7818a1362adSmaya 7827ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 7837ec681f3Smrgwsi_QueuePresentKHR(VkQueue _queue, const VkPresentInfoKHR *pPresentInfo) 7847ec681f3Smrg{ 7857ec681f3Smrg VK_FROM_HANDLE(vk_queue, queue, _queue); 7867ec681f3Smrg 7877ec681f3Smrg return wsi_common_queue_present(queue->base.device->physical->wsi_device, 7887ec681f3Smrg vk_device_to_handle(queue->base.device), 7897ec681f3Smrg _queue, 7907ec681f3Smrg queue->queue_family_index, 7917ec681f3Smrg pPresentInfo); 7927ec681f3Smrg} 7937ec681f3Smrg 7948a1362adSmayauint64_t 7958a1362adSmayawsi_common_get_current_time(void) 7968a1362adSmaya{ 7977ec681f3Smrg return os_time_get_nano(); 7987ec681f3Smrg} 7997ec681f3Smrg 8007ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 8017ec681f3Smrgwsi_GetDeviceGroupPresentCapabilitiesKHR(VkDevice device, 8027ec681f3Smrg VkDeviceGroupPresentCapabilitiesKHR *pCapabilities) 8037ec681f3Smrg{ 8047ec681f3Smrg memset(pCapabilities->presentMask, 0, 8057ec681f3Smrg sizeof(pCapabilities->presentMask)); 8067ec681f3Smrg pCapabilities->presentMask[0] = 0x1; 8077ec681f3Smrg pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR; 8087ec681f3Smrg 8097ec681f3Smrg return VK_SUCCESS; 8107ec681f3Smrg} 8117ec681f3Smrg 8127ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 8137ec681f3Smrgwsi_GetDeviceGroupSurfacePresentModesKHR(VkDevice device, 8147ec681f3Smrg VkSurfaceKHR surface, 8157ec681f3Smrg VkDeviceGroupPresentModeFlagsKHR *pModes) 8167ec681f3Smrg{ 8177ec681f3Smrg *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR; 8187ec681f3Smrg 8197ec681f3Smrg return VK_SUCCESS; 8208a1362adSmaya} 821