vulkan/wsi: replace all dup() with os_dupfd_cloexec()
[mesa.git] / src / vulkan / wsi / wsi_common.c
index 216b3cafc798496b2aa34c6b343ef8705e8be08b..d9906091ed9528d944cc18f9aee1a4ad68f6941b 100644 (file)
@@ -24,6 +24,7 @@
 #include "wsi_common_private.h"
 #include "drm-uapi/drm_fourcc.h"
 #include "util/macros.h"
+#include "util/os_file.h"
 #include "util/xmlconfig.h"
 #include "vk_util.h"
 
@@ -42,7 +43,7 @@ wsi_device_init(struct wsi_device *wsi,
                 const struct driOptionCache *dri_options)
 {
    const char *present_mode;
-   VkResult result;
+   UNUSED VkResult result;
 
    memset(wsi, 0, sizeof(*wsi));
 
@@ -145,10 +146,13 @@ wsi_device_init(struct wsi_device *wsi,
    }
 
    return VK_SUCCESS;
-
+#if defined(VK_USE_PLATFORM_XCB_KHR) || \
+   defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
+   defined(VK_USE_PLATFORM_DISPLAY_KHR)
 fail:
    wsi_device_finish(wsi, alloc);
    return result;
+#endif
 }
 
 void
@@ -203,6 +207,8 @@ wsi_swapchain_init(const struct wsi_device *wsi,
 
    memset(chain, 0, sizeof(*chain));
 
+   vk_object_base_init(NULL, &chain->base, VK_OBJECT_TYPE_SWAPCHAIN_KHR);
+
    chain->wsi = wsi;
    chain->device = device;
    chain->alloc = *pAllocator;
@@ -302,6 +308,8 @@ wsi_swapchain_finish(struct wsi_swapchain *chain)
                                      &chain->alloc);
    }
    vk_free(&chain->alloc, chain->cmd_pools);
+
+   vk_object_base_finish(&chain->base);
 }
 
 static uint32_t
@@ -373,6 +381,29 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
       .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
    };
 
+   VkImageFormatListCreateInfoKHR image_format_list;
+   if (pCreateInfo->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) {
+      image_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
+                          VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR;
+
+      const VkImageFormatListCreateInfoKHR *format_list =
+         vk_find_struct_const(pCreateInfo->pNext,
+                              IMAGE_FORMAT_LIST_CREATE_INFO_KHR);
+
+#ifndef NDEBUG
+      assume(format_list && format_list->viewFormatCount > 0);
+      bool format_found = false;
+      for (int i = 0; i < format_list->viewFormatCount; i++)
+         if (pCreateInfo->imageFormat == format_list->pViewFormats[i])
+            format_found = true;
+      assert(format_found);
+#endif
+
+      image_format_list = *format_list;
+      image_format_list.pNext = NULL;
+      __vk_append_struct(&image_info, &image_format_list);
+   }
+
    struct wsi_image_create_info image_wsi_info;
    VkImageDrmFormatModifierListCreateInfoEXT image_modifier_list;
 
@@ -433,8 +464,16 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
             .type = VK_IMAGE_TYPE_2D,
             .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
             .usage = pCreateInfo->imageUsage,
-            .flags = 0,
+            .flags = image_info.flags,
          };
+
+         VkImageFormatListCreateInfoKHR format_list;
+         if (image_info.flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
+            format_list = image_format_list;
+            format_list.pNext = NULL;
+            __vk_append_struct(&format_info, &format_list);
+         }
+
          VkImageFormatProperties2 format_props = {
             .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
             .pNext = NULL,
@@ -554,8 +593,10 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
       result = wsi->GetImageDrmFormatModifierPropertiesEXT(chain->device,
                                                            image->image,
                                                            &image_mod_props);
-      if (result != VK_SUCCESS)
+      if (result != VK_SUCCESS) {
+         close(fd);
          goto fail;
+      }
       image->drm_modifier = image_mod_props.drmFormatModifier;
       assert(image->drm_modifier != DRM_FORMAT_MOD_INVALID);
 
@@ -581,11 +622,12 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
          if (p == 0) {
             image->fds[p] = fd;
          } else {
-            image->fds[p] = dup(fd);
+            image->fds[p] = os_dupfd_cloexec(fd);
             if (image->fds[p] == -1) {
                for (uint32_t i = 0; i < p; i++)
-                  close(image->fds[p]);
+                  close(image->fds[i]);
 
+               result = VK_ERROR_OUT_OF_HOST_MEMORY;
                goto fail;
             }
          }
@@ -1024,7 +1066,7 @@ wsi_common_destroy_swapchain(VkDevice device,
                              VkSwapchainKHR _swapchain,
                              const VkAllocationCallbacks *pAllocator)
 {
-   WSI_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
+   VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
    if (!swapchain)
       return;
 
@@ -1036,7 +1078,7 @@ wsi_common_get_images(VkSwapchainKHR _swapchain,
                       uint32_t *pSwapchainImageCount,
                       VkImage *pSwapchainImages)
 {
-   WSI_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
+   VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
    VK_OUTARRAY_MAKE(images, pSwapchainImages, pSwapchainImageCount);
 
    for (uint32_t i = 0; i < swapchain->image_count; i++) {
@@ -1054,13 +1096,18 @@ wsi_common_acquire_next_image2(const struct wsi_device *wsi,
                                const VkAcquireNextImageInfoKHR *pAcquireInfo,
                                uint32_t *pImageIndex)
 {
-   WSI_FROM_HANDLE(wsi_swapchain, swapchain, pAcquireInfo->swapchain);
+   VK_FROM_HANDLE(wsi_swapchain, swapchain, pAcquireInfo->swapchain);
 
    VkResult result = swapchain->acquire_next_image(swapchain, pAcquireInfo,
                                                    pImageIndex);
    if (result != VK_SUCCESS)
       return result;
 
+   if (wsi->set_memory_ownership) {
+      VkDeviceMemory mem = swapchain->get_wsi_image(swapchain, *pImageIndex)->memory;
+      wsi->set_memory_ownership(swapchain->device, mem, true);
+   }
+
    if (pAcquireInfo->semaphore != VK_NULL_HANDLE &&
        wsi->signal_semaphore_for_memory != NULL) {
       struct wsi_image *image =
@@ -1093,7 +1140,7 @@ wsi_common_queue_present(const struct wsi_device *wsi,
       vk_find_struct_const(pPresentInfo->pNext, PRESENT_REGIONS_KHR);
 
    for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) {
-      WSI_FROM_HANDLE(wsi_swapchain, swapchain, pPresentInfo->pSwapchains[i]);
+      VK_FROM_HANDLE(wsi_swapchain, swapchain, pPresentInfo->pSwapchains[i]);
       uint32_t image_index = pPresentInfo->pImageIndices[i];
       VkResult result;
 
@@ -1182,6 +1229,11 @@ wsi_common_queue_present(const struct wsi_device *wsi,
       if (result != VK_SUCCESS)
          goto fail_present;
 
+      if (wsi->set_memory_ownership) {
+         VkDeviceMemory mem = swapchain->get_wsi_image(swapchain, image_index)->memory;
+         wsi->set_memory_ownership(swapchain->device, mem, false);
+      }
+
    fail_present:
       if (pPresentInfo->pResults != NULL)
          pPresentInfo->pResults[i] = result;