broadcom: Add vc5 CLIF dumping
[mesa.git] / src / intel / vulkan / anv_wsi.c
index 514a29f0b5c75b0cf3bfff8775b84238f2704796..fc0c2889d3d3b68ae043fdca805283f8e3bc6dcd 100644 (file)
  * IN THE SOFTWARE.
  */
 
-#include "anv_wsi.h"
+#include "anv_private.h"
+#include "wsi_common.h"
 #include "vk_format_info.h"
+#include "vk_util.h"
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+static const struct wsi_callbacks wsi_cbs = {
+   .get_phys_device_format_properties = anv_GetPhysicalDeviceFormatProperties,
+};
+#endif
+
 VkResult
 anv_init_wsi(struct anv_physical_device *physical_device)
 {
@@ -31,16 +40,18 @@ anv_init_wsi(struct anv_physical_device *physical_device)
    memset(physical_device->wsi_device.wsi, 0, sizeof(physical_device->wsi_device.wsi));
 
 #ifdef VK_USE_PLATFORM_XCB_KHR
-   result = anv_x11_init_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
+   result = wsi_x11_init_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
    if (result != VK_SUCCESS)
       return result;
 #endif
 
 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
-   result = anv_wl_init_wsi(physical_device);
+   result = wsi_wl_init_wsi(&physical_device->wsi_device, &physical_device->instance->alloc,
+                            anv_physical_device_to_handle(physical_device),
+                            &wsi_cbs);
    if (result != VK_SUCCESS) {
 #ifdef VK_USE_PLATFORM_XCB_KHR
-      anv_x11_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
+      wsi_x11_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
 #endif
       return result;
    }
@@ -53,10 +64,10 @@ void
 anv_finish_wsi(struct anv_physical_device *physical_device)
 {
 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
-   anv_wl_finish_wsi(physical_device);
+   wsi_wl_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
 #endif
 #ifdef VK_USE_PLATFORM_XCB_KHR
-   anv_x11_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
+   wsi_x11_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc);
 #endif
 }
 
@@ -66,7 +77,10 @@ void anv_DestroySurfaceKHR(
     const VkAllocationCallbacks*                 pAllocator)
 {
    ANV_FROM_HANDLE(anv_instance, instance, _instance);
-   ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
+   ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
+
+   if (!surface)
+      return;
 
    vk_free2(&instance->alloc, pAllocator, surface);
 }
@@ -78,12 +92,12 @@ VkResult anv_GetPhysicalDeviceSurfaceSupportKHR(
     VkBool32*                                   pSupported)
 {
    ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
-   ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
-   struct anv_wsi_interface *iface = device->wsi_device.wsi[surface->platform];
+   ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
+   struct wsi_interface *iface = device->wsi_device.wsi[surface->platform];
 
    return iface->get_support(surface, &device->wsi_device,
                              &device->instance->alloc,
-                             queueFamilyIndex, pSupported);
+                             queueFamilyIndex, device->local_fd, false, pSupported);
 }
 
 VkResult anv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
@@ -92,12 +106,25 @@ VkResult anv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
     VkSurfaceCapabilitiesKHR*                   pSurfaceCapabilities)
 {
    ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
-   ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
-   struct anv_wsi_interface *iface = device->wsi_device.wsi[surface->platform];
+   ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
+   struct wsi_interface *iface = device->wsi_device.wsi[surface->platform];
 
    return iface->get_capabilities(surface, pSurfaceCapabilities);
 }
 
+VkResult anv_GetPhysicalDeviceSurfaceCapabilities2KHR(
+    VkPhysicalDevice                            physicalDevice,
+    const VkPhysicalDeviceSurfaceInfo2KHR*      pSurfaceInfo,
+    VkSurfaceCapabilities2KHR*                  pSurfaceCapabilities)
+{
+   ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
+   ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface);
+   struct wsi_interface *iface = device->wsi_device.wsi[surface->platform];
+
+   return iface->get_capabilities2(surface, pSurfaceInfo->pNext,
+                                   pSurfaceCapabilities);
+}
+
 VkResult anv_GetPhysicalDeviceSurfaceFormatsKHR(
     VkPhysicalDevice                            physicalDevice,
     VkSurfaceKHR                                _surface,
@@ -105,13 +132,27 @@ VkResult anv_GetPhysicalDeviceSurfaceFormatsKHR(
     VkSurfaceFormatKHR*                         pSurfaceFormats)
 {
    ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
-   ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
-   struct anv_wsi_interface *iface = device->wsi_device.wsi[surface->platform];
+   ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
+   struct wsi_interface *iface = device->wsi_device.wsi[surface->platform];
 
    return iface->get_formats(surface, &device->wsi_device, pSurfaceFormatCount,
                              pSurfaceFormats);
 }
 
+VkResult anv_GetPhysicalDeviceSurfaceFormats2KHR(
+    VkPhysicalDevice                            physicalDevice,
+    const VkPhysicalDeviceSurfaceInfo2KHR*      pSurfaceInfo,
+    uint32_t*                                   pSurfaceFormatCount,
+    VkSurfaceFormat2KHR*                        pSurfaceFormats)
+{
+   ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
+   ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface);
+   struct wsi_interface *iface = device->wsi_device.wsi[surface->platform];
+
+   return iface->get_formats2(surface, &device->wsi_device, pSurfaceInfo->pNext,
+                              pSurfaceFormatCount, pSurfaceFormats);
+}
+
 VkResult anv_GetPhysicalDeviceSurfacePresentModesKHR(
     VkPhysicalDevice                            physicalDevice,
     VkSurfaceKHR                                _surface,
@@ -119,8 +160,8 @@ VkResult anv_GetPhysicalDeviceSurfacePresentModesKHR(
     VkPresentModeKHR*                           pPresentModes)
 {
    ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
-   ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, _surface);
-   struct anv_wsi_interface *iface = device->wsi_device.wsi[surface->platform];
+   ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
+   struct wsi_interface *iface = device->wsi_device.wsi[surface->platform];
 
    return iface->get_present_modes(surface, pPresentModeCount,
                                    pPresentModes);
@@ -128,14 +169,16 @@ VkResult anv_GetPhysicalDeviceSurfacePresentModesKHR(
 
 
 static VkResult
-x11_anv_wsi_image_create(VkDevice device_h,
-                         const VkSwapchainCreateInfoKHR *pCreateInfo,
-                         const VkAllocationCallbacks* pAllocator,
-                         VkImage *image_p,
-                         VkDeviceMemory *memory_p,
-                         uint32_t *size,
-                         uint32_t *offset,
-                         uint32_t *row_pitch, int *fd_p)
+anv_wsi_image_create(VkDevice device_h,
+                     const VkSwapchainCreateInfoKHR *pCreateInfo,
+                     const VkAllocationCallbacks* pAllocator,
+                     bool different_gpu,
+                     bool linear,
+                     VkImage *image_p,
+                     VkDeviceMemory *memory_p,
+                     uint32_t *size,
+                     uint32_t *offset,
+                     uint32_t *row_pitch, int *fd_p)
 {
    struct anv_device *device = anv_device_from_handle(device_h);
    VkImage image_h;
@@ -187,27 +230,36 @@ x11_anv_wsi_image_create(VkDevice device_h,
       goto fail_create_image;
 
    memory = anv_device_memory_from_handle(memory_h);
-   memory->bo.is_winsys_bo = true;
 
-   anv_BindImageMemory(VK_NULL_HANDLE, image_h, memory_h, 0);
+   /* We need to set the WRITE flag on window system buffers so that GEM will
+    * know we're writing to them and synchronize uses on other rings (eg if
+    * the display server uses the blitter ring).
+    */
+   memory->bo->flags &= ~EXEC_OBJECT_ASYNC;
+   memory->bo->flags |= EXEC_OBJECT_WRITE;
+
+   anv_BindImageMemory(device_h, image_h, memory_h, 0);
+   assert(image->size == 0);
 
-   struct anv_surface *surface = &image->color_surface;
+   struct anv_surface *surface = &image->planes[0].surface;
    assert(surface->isl.tiling == ISL_TILING_X);
 
    *row_pitch = surface->isl.row_pitch;
-   int ret = anv_gem_set_tiling(device, memory->bo.gem_handle,
+   int ret = anv_gem_set_tiling(device, memory->bo->gem_handle,
                                 surface->isl.row_pitch, I915_TILING_X);
    if (ret) {
       /* FINISHME: Choose a better error. */
-      result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY,
+      result = vk_errorf(device->instance, device,
+                         VK_ERROR_OUT_OF_DEVICE_MEMORY,
                          "set_tiling failed: %m");
       goto fail_alloc_memory;
    }
 
-   int fd = anv_gem_handle_to_fd(device, memory->bo.gem_handle);
+   int fd = anv_gem_handle_to_fd(device, memory->bo->gem_handle);
    if (fd == -1) {
       /* FINISHME: Choose a better error. */
-      result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY,
+      result = vk_errorf(device->instance, device,
+                         VK_ERROR_OUT_OF_DEVICE_MEMORY,
                          "handle_to_fd failed: %m");
       goto fail_alloc_memory;
    }
@@ -216,7 +268,7 @@ x11_anv_wsi_image_create(VkDevice device_h,
    *memory_p = memory_h;
    *fd_p = fd;
    *size = image->size;
-   *offset = image->offset;
+   *offset = 0;
    return VK_SUCCESS;
 fail_alloc_memory:
    anv_FreeMemory(device_h, memory_h, pAllocator);
@@ -227,19 +279,19 @@ fail_create_image:
 }
 
 static void
-x11_anv_wsi_image_free(VkDevice device,
-                       const VkAllocationCallbacks* pAllocator,
-                       VkImage image_h,
-                       VkDeviceMemory memory_h)
+anv_wsi_image_free(VkDevice device,
+                   const VkAllocationCallbacks* pAllocator,
+                   VkImage image_h,
+                   VkDeviceMemory memory_h)
 {
    anv_DestroyImage(device, image_h, pAllocator);
 
    anv_FreeMemory(device, memory_h, pAllocator);
 }
 
-static const struct anv_wsi_image_fns anv_wsi_image_fns = {
-   .create_wsi_image = x11_anv_wsi_image_create,
-   .free_wsi_image = x11_anv_wsi_image_free,
+static const struct wsi_image_fns anv_wsi_image_fns = {
+   .create_wsi_image = anv_wsi_image_create,
+   .free_wsi_image = anv_wsi_image_free,
 };
 
 VkResult anv_CreateSwapchainKHR(
@@ -249,43 +301,57 @@ VkResult anv_CreateSwapchainKHR(
     VkSwapchainKHR*                              pSwapchain)
 {
    ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(_VkIcdSurfaceBase, surface, pCreateInfo->surface);
-   struct anv_wsi_interface *iface =
+   ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pCreateInfo->surface);
+   struct wsi_interface *iface =
       device->instance->physicalDevice.wsi_device.wsi[surface->platform];
-   struct anv_swapchain *swapchain;
+   struct wsi_swapchain *swapchain;
+   const VkAllocationCallbacks *alloc;
 
-   VkResult result = iface->create_swapchain(surface, device, pCreateInfo,
-                                             pAllocator, &anv_wsi_image_fns,
+   if (pAllocator)
+     alloc = pAllocator;
+   else
+     alloc = &device->alloc;
+   VkResult result = iface->create_swapchain(surface, _device,
+                                             &device->instance->physicalDevice.wsi_device,
+                                             device->instance->physicalDevice.local_fd,
+                                             pCreateInfo,
+                                             alloc, &anv_wsi_image_fns,
                                              &swapchain);
    if (result != VK_SUCCESS)
       return result;
 
-   if (pAllocator)
-      swapchain->alloc = *pAllocator;
-   else
-      swapchain->alloc = device->alloc;
+   swapchain->alloc = *alloc;
 
    for (unsigned i = 0; i < ARRAY_SIZE(swapchain->fences); i++)
       swapchain->fences[i] = VK_NULL_HANDLE;
 
-   *pSwapchain = anv_swapchain_to_handle(swapchain);
+   *pSwapchain = wsi_swapchain_to_handle(swapchain);
 
    return VK_SUCCESS;
 }
 
 void anv_DestroySwapchainKHR(
-    VkDevice                                     device,
+    VkDevice                                     _device,
     VkSwapchainKHR                               _swapchain,
     const VkAllocationCallbacks*                 pAllocator)
 {
-   ANV_FROM_HANDLE(anv_swapchain, swapchain, _swapchain);
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
+   const VkAllocationCallbacks *alloc;
+
+   if (!swapchain)
+      return;
 
+   if (pAllocator)
+     alloc = pAllocator;
+   else
+     alloc = &device->alloc;
    for (unsigned i = 0; i < ARRAY_SIZE(swapchain->fences); i++) {
       if (swapchain->fences[i] != VK_NULL_HANDLE)
-         anv_DestroyFence(device, swapchain->fences[i], pAllocator);
+         anv_DestroyFence(_device, swapchain->fences[i], pAllocator);
    }
 
-   swapchain->destroy(swapchain, pAllocator);
+   swapchain->destroy(swapchain, alloc);
 }
 
 VkResult anv_GetSwapchainImagesKHR(
@@ -294,24 +360,34 @@ VkResult anv_GetSwapchainImagesKHR(
     uint32_t*                                    pSwapchainImageCount,
     VkImage*                                     pSwapchainImages)
 {
-   ANV_FROM_HANDLE(anv_swapchain, swapchain, _swapchain);
+   ANV_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
 
    return swapchain->get_images(swapchain, pSwapchainImageCount,
                                 pSwapchainImages);
 }
 
 VkResult anv_AcquireNextImageKHR(
-    VkDevice                                     device,
+    VkDevice                                     _device,
     VkSwapchainKHR                               _swapchain,
     uint64_t                                     timeout,
     VkSemaphore                                  semaphore,
-    VkFence                                      fence,
+    VkFence                                      _fence,
     uint32_t*                                    pImageIndex)
 {
-   ANV_FROM_HANDLE(anv_swapchain, swapchain, _swapchain);
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain);
+   ANV_FROM_HANDLE(anv_fence, fence, _fence);
+
+   VkResult result = swapchain->acquire_next_image(swapchain, timeout,
+                                                   semaphore, pImageIndex);
+
+   /* Thanks to implicit sync, the image is ready immediately.  However, we
+    * should wait for the current GPU state to finish.
+    */
+   if (fence)
+      anv_QueueSubmit(anv_queue_to_handle(&device->queue), 0, NULL, _fence);
 
-   return swapchain->acquire_next_image(swapchain, timeout, semaphore,
-                                        pImageIndex);
+   return result;
 }
 
 VkResult anv_QueuePresentKHR(
@@ -319,21 +395,32 @@ VkResult anv_QueuePresentKHR(
     const VkPresentInfoKHR*                  pPresentInfo)
 {
    ANV_FROM_HANDLE(anv_queue, queue, _queue);
-   VkResult result;
+   VkResult result = VK_SUCCESS;
+
+   const VkPresentRegionsKHR *regions =
+      vk_find_struct_const(pPresentInfo->pNext, PRESENT_REGIONS_KHR);
 
    for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) {
-      ANV_FROM_HANDLE(anv_swapchain, swapchain, pPresentInfo->pSwapchains[i]);
+      ANV_FROM_HANDLE(wsi_swapchain, swapchain, pPresentInfo->pSwapchains[i]);
+      VkResult item_result;
+
+      const VkPresentRegionKHR *region = NULL;
+      if (regions && regions->pRegions)
+         region = &regions->pRegions[i];
 
       assert(anv_device_from_handle(swapchain->device) == queue->device);
 
       if (swapchain->fences[0] == VK_NULL_HANDLE) {
-         result = anv_CreateFence(anv_device_to_handle(queue->device),
+         item_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;
+         if (pPresentInfo->pResults != NULL)
+            pPresentInfo->pResults[i] = item_result;
+         result = result == VK_SUCCESS ? item_result : result;
+         if (item_result != VK_SUCCESS)
+            continue;
       } else {
          anv_ResetFences(anv_device_to_handle(queue->device),
                          1, &swapchain->fences[0]);
@@ -341,11 +428,15 @@ VkResult anv_QueuePresentKHR(
 
       anv_QueueSubmit(_queue, 0, NULL, swapchain->fences[0]);
 
-      result = swapchain->queue_present(swapchain,
-                                        pPresentInfo->pImageIndices[i]);
+      item_result = swapchain->queue_present(swapchain,
+                                             pPresentInfo->pImageIndices[i],
+                                             region);
       /* TODO: What if one of them returns OUT_OF_DATE? */
-      if (result != VK_SUCCESS)
-         return result;
+      if (pPresentInfo->pResults != NULL)
+         pPresentInfo->pResults[i] = item_result;
+      result = result == VK_SUCCESS ? item_result : result;
+      if (item_result != VK_SUCCESS)
+            continue;
 
       VkFence last = swapchain->fences[2];
       swapchain->fences[2] = swapchain->fences[1];