Vulkan overlay: use the corresponding image index for each swapchain
[mesa.git] / src / vulkan / wsi / wsi_common.c
index 3abffe3dee70df38b7fc88b021673ae119542af2..0adf54eab8f3a46e6e8a255b9ee1f44f8501a50e 100644 (file)
@@ -42,7 +42,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));
 
@@ -90,11 +90,13 @@ wsi_device_init(struct wsi_device *wsi,
    WSI_GET_CB(FreeMemory);
    WSI_GET_CB(FreeCommandBuffers);
    WSI_GET_CB(GetBufferMemoryRequirements);
+   WSI_GET_CB(GetImageDrmFormatModifierPropertiesEXT);
    WSI_GET_CB(GetImageMemoryRequirements);
    WSI_GET_CB(GetImageSubresourceLayout);
    WSI_GET_CB(GetMemoryFdKHR);
    WSI_GET_CB(GetPhysicalDeviceFormatProperties);
    WSI_GET_CB(GetPhysicalDeviceFormatProperties2KHR);
+   WSI_GET_CB(GetPhysicalDeviceImageFormatProperties2);
    WSI_GET_CB(ResetFences);
    WSI_GET_CB(QueueSubmit);
    WSI_GET_CB(WaitForFences);
@@ -135,13 +137,21 @@ wsi_device_init(struct wsi_device *wsi,
       if (driCheckOption(dri_options, "adaptive_sync", DRI_BOOL))
          wsi->enable_adaptive_sync = driQueryOptionb(dri_options,
                                                      "adaptive_sync");
+
+      if (driCheckOption(dri_options, "vk_wsi_force_bgra8_unorm_first",  DRI_BOOL)) {
+         wsi->force_bgra8_unorm_first =
+            driQueryOptionb(dri_options, "vk_wsi_force_bgra8_unorm_first");
+      }
    }
 
    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
@@ -345,23 +355,68 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
    for (int i = 0; i < ARRAY_SIZE(image->fds); i++)
       image->fds[i] = -1;
 
-   struct wsi_image_create_info image_wsi_info = {
-      .sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
-      .pNext = NULL,
+   VkImageCreateInfo image_info = {
+      .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+      .flags = 0,
+      .imageType = VK_IMAGE_TYPE_2D,
+      .format = pCreateInfo->imageFormat,
+      .extent = {
+         .width = pCreateInfo->imageExtent.width,
+         .height = pCreateInfo->imageExtent.height,
+         .depth = 1,
+      },
+      .mipLevels = 1,
+      .arrayLayers = 1,
+      .samples = VK_SAMPLE_COUNT_1_BIT,
+      .tiling = VK_IMAGE_TILING_OPTIMAL,
+      .usage = pCreateInfo->imageUsage,
+      .sharingMode = pCreateInfo->imageSharingMode,
+      .queueFamilyIndexCount = pCreateInfo->queueFamilyIndexCount,
+      .pQueueFamilyIndices = pCreateInfo->pQueueFamilyIndices,
+      .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;
+
    uint32_t image_modifier_count = 0, modifier_prop_count = 0;
-   struct wsi_format_modifier_properties *modifier_props = NULL;
+   struct VkDrmFormatModifierPropertiesEXT *modifier_props = NULL;
    uint64_t *image_modifiers = NULL;
    if (num_modifier_lists == 0) {
       /* If we don't have modifiers, fall back to the legacy "scanout" flag */
-      image_wsi_info.scanout = true;
+      image_wsi_info = (struct wsi_image_create_info) {
+         .sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
+         .scanout = true,
+      };
+      __vk_append_struct(&image_info, &image_wsi_info);
    } else {
       /* The winsys can't request modifiers if we don't support them. */
       assert(wsi->supports_modifiers);
-      struct wsi_format_modifier_properties_list modifier_props_list = {
-         .sType = VK_STRUCTURE_TYPE_WSI_FORMAT_MODIFIER_PROPERTIES_LIST_MESA,
-         .pNext = NULL,
+      struct VkDrmFormatModifierPropertiesListEXT modifier_props_list = {
+         .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
       };
       VkFormatProperties2 format_props = {
          .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
@@ -370,10 +425,10 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
       wsi->GetPhysicalDeviceFormatProperties2KHR(wsi->pdevice,
                                                  pCreateInfo->imageFormat,
                                                  &format_props);
-      assert(modifier_props_list.modifier_count > 0);
+      assert(modifier_props_list.drmFormatModifierCount > 0);
       modifier_props = vk_alloc(&chain->alloc,
                                 sizeof(*modifier_props) *
-                                modifier_props_list.modifier_count,
+                                modifier_props_list.drmFormatModifierCount,
                                 8,
                                 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
       if (!modifier_props) {
@@ -381,11 +436,50 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
          goto fail;
       }
 
-      modifier_props_list.modifier_properties = modifier_props;
+      modifier_props_list.pDrmFormatModifierProperties = modifier_props;
       wsi->GetPhysicalDeviceFormatProperties2KHR(wsi->pdevice,
                                                  pCreateInfo->imageFormat,
                                                  &format_props);
-      modifier_prop_count = modifier_props_list.modifier_count;
+
+      /* Call GetImageFormatProperties with every modifier and filter the list
+       * down to those that we know work.
+       */
+      modifier_prop_count = 0;
+      for (uint32_t i = 0; i < modifier_props_list.drmFormatModifierCount; i++) {
+         VkPhysicalDeviceImageDrmFormatModifierInfoEXT mod_info = {
+            .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
+            .drmFormatModifier = modifier_props[i].drmFormatModifier,
+            .sharingMode = pCreateInfo->imageSharingMode,
+            .queueFamilyIndexCount = pCreateInfo->queueFamilyIndexCount,
+            .pQueueFamilyIndices = pCreateInfo->pQueueFamilyIndices,
+         };
+         VkPhysicalDeviceImageFormatInfo2 format_info = {
+            .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
+            .format = pCreateInfo->imageFormat,
+            .type = VK_IMAGE_TYPE_2D,
+            .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
+            .usage = pCreateInfo->imageUsage,
+            .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,
+         };
+         __vk_append_struct(&format_info, &mod_info);
+         result = wsi->GetPhysicalDeviceImageFormatProperties2(wsi->pdevice,
+                                                               &format_info,
+                                                               &format_props);
+         if (result == VK_SUCCESS)
+            modifier_props[modifier_prop_count++] = modifier_props[i];
+      }
 
       uint32_t max_modifier_count = 0;
       for (uint32_t l = 0; l < num_modifier_lists; l++)
@@ -408,7 +502,7 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
           */
          for (uint32_t i = 0; i < num_modifiers[l]; i++) {
             for (uint32_t j = 0; j < modifier_prop_count; j++) {
-               if (modifier_props[j].modifier == modifiers[l][i])
+               if (modifier_props[j].drmFormatModifier == modifiers[l][i])
                   image_modifiers[image_modifier_count++] = modifiers[l][i];
             }
          }
@@ -419,8 +513,13 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
       }
 
       if (image_modifier_count > 0) {
-         image_wsi_info.modifier_count = image_modifier_count;
-         image_wsi_info.modifiers = image_modifiers;
+         image_modifier_list = (VkImageDrmFormatModifierListCreateInfoEXT) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT,
+            .drmFormatModifierCount = image_modifier_count,
+            .pDrmFormatModifiers = image_modifiers,
+         };
+         image_info.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
+         __vk_append_struct(&image_info, &image_modifier_list);
       } else {
          /* TODO: Add a proper error here */
          assert(!"Failed to find a supported modifier!  This should never "
@@ -430,27 +529,6 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
       }
    }
 
-   const VkImageCreateInfo image_info = {
-      .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
-      .pNext = &image_wsi_info,
-      .flags = 0,
-      .imageType = VK_IMAGE_TYPE_2D,
-      .format = pCreateInfo->imageFormat,
-      .extent = {
-         .width = pCreateInfo->imageExtent.width,
-         .height = pCreateInfo->imageExtent.height,
-         .depth = 1,
-      },
-      .mipLevels = 1,
-      .arrayLayers = 1,
-      .samples = VK_SAMPLE_COUNT_1_BIT,
-      .tiling = VK_IMAGE_TILING_OPTIMAL,
-      .usage = pCreateInfo->imageUsage,
-      .sharingMode = pCreateInfo->imageSharingMode,
-      .queueFamilyIndexCount = pCreateInfo->queueFamilyIndexCount,
-      .pQueueFamilyIndices = pCreateInfo->pQueueFamilyIndices,
-      .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
-   };
    result = wsi->CreateImage(chain->device, &image_info,
                              &chain->alloc, &image->image);
    if (result != VK_SUCCESS)
@@ -504,12 +582,20 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
       goto fail;
 
    if (num_modifier_lists > 0) {
-      image->drm_modifier = wsi->image_get_modifier(image->image);
+      VkImageDrmFormatModifierPropertiesEXT image_mod_props = {
+         .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
+      };
+      result = wsi->GetImageDrmFormatModifierPropertiesEXT(chain->device,
+                                                           image->image,
+                                                           &image_mod_props);
+      if (result != VK_SUCCESS)
+         goto fail;
+      image->drm_modifier = image_mod_props.drmFormatModifier;
       assert(image->drm_modifier != DRM_FORMAT_MOD_INVALID);
 
       for (uint32_t j = 0; j < modifier_prop_count; j++) {
-         if (modifier_props[j].modifier == image->drm_modifier) {
-            image->num_planes = modifier_props[j].modifier_plane_count;
+         if (modifier_props[j].drmFormatModifier == image->drm_modifier) {
+            image->num_planes = modifier_props[j].drmFormatModifierPlaneCount;
             break;
          }
       }
@@ -1004,7 +1090,28 @@ wsi_common_acquire_next_image2(const struct wsi_device *wsi,
 {
    WSI_FROM_HANDLE(wsi_swapchain, swapchain, pAcquireInfo->swapchain);
 
-   return swapchain->acquire_next_image(swapchain, pAcquireInfo, pImageIndex);
+   VkResult result = swapchain->acquire_next_image(swapchain, pAcquireInfo,
+                                                   pImageIndex);
+   if (result != VK_SUCCESS)
+      return result;
+
+   if (pAcquireInfo->semaphore != VK_NULL_HANDLE &&
+       wsi->signal_semaphore_for_memory != NULL) {
+      struct wsi_image *image =
+         swapchain->get_wsi_image(swapchain, *pImageIndex);
+      wsi->signal_semaphore_for_memory(device, pAcquireInfo->semaphore,
+                                       image->memory);
+   }
+
+   if (pAcquireInfo->fence != VK_NULL_HANDLE &&
+       wsi->signal_fence_for_memory != NULL) {
+      struct wsi_image *image =
+         swapchain->get_wsi_image(swapchain, *pImageIndex);
+      wsi->signal_fence_for_memory(device, pAcquireInfo->fence,
+                                   image->memory);
+   }
+
+   return VK_SUCCESS;
 }
 
 VkResult
@@ -1036,10 +1143,16 @@ wsi_common_queue_present(const struct wsi_device *wsi,
          if (result != VK_SUCCESS)
             goto fail_present;
       } else {
-         wsi->WaitForFences(device, 1, &swapchain->fences[image_index],
-                            true, 1);
+         result =
+            wsi->WaitForFences(device, 1, &swapchain->fences[image_index],
+                               true, ~0ull);
+         if (result != VK_SUCCESS)
+            goto fail_present;
 
-         wsi->ResetFences(device, 1, &swapchain->fences[image_index]);
+         result =
+            wsi->ResetFences(device, 1, &swapchain->fences[image_index]);
+         if (result != VK_SUCCESS)
+            goto fail_present;
       }
 
       struct wsi_image *image =