anv/clear: Handle ClearImage on 3-D images
[mesa.git] / src / intel / vulkan / anv_wsi.c
index c5911a3635b111be549f856fc2c08cfb9f683c2f..006944a7e25063d10d1a4c3dbb1f3ddc4450957a 100644 (file)
 #include "anv_wsi.h"
 
 VkResult
-anv_init_wsi(struct anv_instance *instance)
+anv_init_wsi(struct anv_physical_device *physical_device)
 {
    VkResult result;
 
-   result = anv_x11_init_wsi(instance);
+   memset(physical_device->wsi, 0, sizeof(physical_device->wsi));
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+   result = anv_x11_init_wsi(physical_device);
    if (result != VK_SUCCESS)
       return result;
+#endif
 
-#ifdef HAVE_WAYLAND_PLATFORM
-   result = anv_wl_init_wsi(instance);
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+   result = anv_wl_init_wsi(physical_device);
    if (result != VK_SUCCESS) {
-      anv_x11_finish_wsi(instance);
+#ifdef VK_USE_PLATFORM_XCB_KHR
+      anv_x11_finish_wsi(physical_device);
+#endif
       return result;
    }
 #endif
@@ -44,12 +50,14 @@ anv_init_wsi(struct anv_instance *instance)
 }
 
 void
-anv_finish_wsi(struct anv_instance *instance)
+anv_finish_wsi(struct anv_physical_device *physical_device)
 {
-#ifdef HAVE_WAYLAND_PLATFORM
-   anv_wl_finish_wsi(instance);
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+   anv_wl_finish_wsi(physical_device);
+#endif
+#ifdef VK_USE_PLATFORM_XCB_KHR
+   anv_x11_finish_wsi(physical_device);
 #endif
-   anv_x11_finish_wsi(instance);
 }
 
 void anv_DestroySurfaceKHR(
@@ -71,7 +79,7 @@ VkResult anv_GetPhysicalDeviceSurfaceSupportKHR(
 {
    ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
    ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
-   struct anv_wsi_interface *iface = device->instance->wsi[surface->platform];
+   struct anv_wsi_interface *iface = device->wsi[surface->platform];
 
    return iface->get_support(surface, device, queueFamilyIndex, pSupported);
 }
@@ -83,7 +91,7 @@ VkResult anv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
 {
    ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
    ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
-   struct anv_wsi_interface *iface = device->instance->wsi[surface->platform];
+   struct anv_wsi_interface *iface = device->wsi[surface->platform];
 
    return iface->get_capabilities(surface, device, pSurfaceCapabilities);
 }
@@ -96,7 +104,7 @@ VkResult anv_GetPhysicalDeviceSurfaceFormatsKHR(
 {
    ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
    ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
-   struct anv_wsi_interface *iface = device->instance->wsi[surface->platform];
+   struct anv_wsi_interface *iface = device->wsi[surface->platform];
 
    return iface->get_formats(surface, device, pSurfaceFormatCount,
                              pSurfaceFormats);
@@ -110,7 +118,7 @@ VkResult anv_GetPhysicalDeviceSurfacePresentModesKHR(
 {
    ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
    ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
-   struct anv_wsi_interface *iface = device->instance->wsi[surface->platform];
+   struct anv_wsi_interface *iface = device->wsi[surface->platform];
 
    return iface->get_present_modes(surface, device, pPresentModeCount,
                                    pPresentModes);
@@ -124,7 +132,8 @@ VkResult anv_CreateSwapchainKHR(
 {
    ANV_FROM_HANDLE(anv_device, device, _device);
    ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, pCreateInfo->surface);
-   struct anv_wsi_interface *iface = device->instance->wsi[surface->platform];
+   struct anv_wsi_interface *iface =
+      device->instance->physicalDevice.wsi[surface->platform];
    struct anv_swapchain *swapchain;
 
    VkResult result = iface->create_swapchain(surface, device, pCreateInfo,
@@ -132,6 +141,14 @@ VkResult anv_CreateSwapchainKHR(
    if (result != VK_SUCCESS)
       return result;
 
+   if (pAllocator)
+      swapchain->alloc = *pAllocator;
+   else
+      swapchain->alloc = device->alloc;
+
+   for (unsigned i = 0; i < ARRAY_SIZE(swapchain->fences); i++)
+      swapchain->fences[i] = VK_NULL_HANDLE;
+
    *pSwapchain = anv_swapchain_to_handle(swapchain);
 
    return VK_SUCCESS;
@@ -144,6 +161,11 @@ void anv_DestroySwapchainKHR(
 {
    ANV_FROM_HANDLE(anv_swapchain, swapchain, _swapchain);
 
+   for (unsigned i = 0; i < ARRAY_SIZE(swapchain->fences); i++) {
+      if (swapchain->fences[i] != VK_NULL_HANDLE)
+         anv_DestroyFence(device, swapchain->fences[i], pAllocator);
+   }
+
    swapchain->destroy(swapchain, pAllocator);
 }
 
@@ -185,11 +207,36 @@ VkResult anv_QueuePresentKHR(
 
       assert(swapchain->device == queue->device);
 
+      if (swapchain->fences[0] == VK_NULL_HANDLE) {
+         result = anv_CreateFence(anv_device_to_handle(queue->device),
+            &(VkFenceCreateInfo) {
+               .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+               .flags = 0,
+            }, &swapchain->alloc, &swapchain->fences[0]);
+         if (result != VK_SUCCESS)
+            return result;
+      } else {
+         anv_ResetFences(anv_device_to_handle(queue->device),
+                         1, &swapchain->fences[0]);
+      }
+
+      anv_QueueSubmit(_queue, 0, NULL, swapchain->fences[0]);
+
       result = swapchain->queue_present(swapchain, queue,
                                         pPresentInfo->pImageIndices[i]);
       /* TODO: What if one of them returns OUT_OF_DATE? */
       if (result != VK_SUCCESS)
          return result;
+
+      VkFence last = swapchain->fences[2];
+      swapchain->fences[2] = swapchain->fences[1];
+      swapchain->fences[1] = swapchain->fences[0];
+      swapchain->fences[0] = last;
+
+      if (last != VK_NULL_HANDLE) {
+         anv_WaitForFences(anv_device_to_handle(queue->device),
+                           1, &last, true, 1);
+      }
    }
 
    return VK_SUCCESS;