vulkan/wsi: add sw support. (v2)
authorDave Airlie <airlied@redhat.com>
Fri, 19 Jun 2020 06:37:51 +0000 (16:37 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 17 Aug 2020 04:30:50 +0000 (14:30 +1000)
This adds an option to the WSI support for a software path to be
used with the vulkan sw drivers. There is probably some changes
that could be made to improve this and use present, for now
just use put image.

v2: roll out flag across all drivers (Eric)

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6082>

src/amd/vulkan/radv_wsi.c
src/freedreno/vulkan/tu_wsi.c
src/intel/vulkan/anv_wsi.c
src/vulkan/wsi/wsi_common.c
src/vulkan/wsi/wsi_common.h
src/vulkan/wsi/wsi_common_x11.c

index 1dc161f6791d7120b39826160c641b40d0057ecf..3154c9d9305deb4c4774348eaf1bfd489031ce33 100644 (file)
@@ -57,7 +57,8 @@ radv_init_wsi(struct radv_physical_device *physical_device)
                                           radv_wsi_proc_addr,
                                           &physical_device->instance->alloc,
                                           physical_device->master_fd,
-                                          &physical_device->instance->dri_options);
+                                          &physical_device->instance->dri_options,
+                                          false);
        if (result != VK_SUCCESS)
                return result;
 
index ce5d4c8ada3925f919f7b55768ae7f4d5179d1b9..d7c4bda9bbb0ec045f19fbc5bf42f324e8d8d699 100644 (file)
@@ -44,7 +44,8 @@ tu_wsi_init(struct tu_physical_device *physical_device)
                             tu_physical_device_to_handle(physical_device),
                             tu_wsi_proc_addr,
                             &physical_device->instance->alloc,
-                            physical_device->master_fd, NULL);
+                            physical_device->master_fd, NULL,
+                            false);
    if (result != VK_SUCCESS)
       return result;
 
index 888a91d862033b8b7bcb42aaea27d75cec9bffdb..75bf4feadd3be30682b426290620f066e3806f59 100644 (file)
@@ -85,7 +85,8 @@ anv_init_wsi(struct anv_physical_device *physical_device)
                             anv_wsi_proc_addr,
                             &physical_device->instance->alloc,
                             physical_device->master_fd,
-                            &physical_device->instance->dri_options);
+                            &physical_device->instance->dri_options,
+                            false);
    if (result != VK_SUCCESS)
       return result;
 
index 2108f7f703fe8fc9a250e579ef2491e89e110bad..671690df9ccbde5caa9a39cdcfdddf69d0ce0c8f 100644 (file)
@@ -40,7 +40,8 @@ wsi_device_init(struct wsi_device *wsi,
                 WSI_FN_GetPhysicalDeviceProcAddr proc_addr,
                 const VkAllocationCallbacks *alloc,
                 int display_fd,
-                const struct driOptionCache *dri_options)
+                const struct driOptionCache *dri_options,
+                bool sw_device)
 {
    const char *present_mode;
    UNUSED VkResult result;
@@ -49,7 +50,7 @@ wsi_device_init(struct wsi_device *wsi,
 
    wsi->instance_alloc = *alloc;
    wsi->pdevice = pdevice;
-
+   wsi->sw = sw_device;
 #define WSI_GET_CB(func) \
    PFN_vk##func func = (PFN_vk##func)proc_addr(pdevice, "vk" #func)
    WSI_GET_CB(GetPhysicalDeviceProperties2);
@@ -94,13 +95,16 @@ wsi_device_init(struct wsi_device *wsi,
    WSI_GET_CB(GetImageDrmFormatModifierPropertiesEXT);
    WSI_GET_CB(GetImageMemoryRequirements);
    WSI_GET_CB(GetImageSubresourceLayout);
-   WSI_GET_CB(GetMemoryFdKHR);
+   if (!wsi->sw)
+      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);
+   WSI_GET_CB(MapMemory);
+   WSI_GET_CB(UnmapMemory);
 #undef WSI_GET_CB
 
 #ifdef VK_USE_PLATFORM_XCB_KHR
@@ -575,18 +579,21 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
    if (result != VK_SUCCESS)
       goto fail;
 
-   const VkMemoryGetFdInfoKHR memory_get_fd_info = {
-      .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
-      .pNext = NULL,
-      .memory = image->memory,
-      .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
-   };
-   int fd;
-   result = wsi->GetMemoryFdKHR(chain->device, &memory_get_fd_info, &fd);
-   if (result != VK_SUCCESS)
-      goto fail;
+   int fd = -1;
+   if (!wsi->sw) {
+      const VkMemoryGetFdInfoKHR memory_get_fd_info = {
+         .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
+         .pNext = NULL,
+         .memory = image->memory,
+         .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
+      };
+
+      result = wsi->GetMemoryFdKHR(chain->device, &memory_get_fd_info, &fd);
+      if (result != VK_SUCCESS)
+         goto fail;
+   }
 
-   if (num_modifier_lists > 0) {
+   if (!wsi->sw && num_modifier_lists > 0) {
       VkImageDrmFormatModifierPropertiesEXT image_mod_props = {
          .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT,
       };
index cbf7e1be14e59474770275b4c8ceea5c9ec0c604..7c69268ea77f94495587c41d057705cf31edc73d 100644 (file)
@@ -116,6 +116,8 @@ struct wsi_device {
       bool ensure_minImageCount;
    } x11;
 
+   bool sw;
+
    /* Signals the semaphore such that any wait on the semaphore will wait on
     * any reads or writes on the give memory object.  This is used to
     * implement the semaphore signal operation in vkAcquireNextImage.
@@ -177,6 +179,8 @@ struct wsi_device {
    WSI_CB(ResetFences);
    WSI_CB(QueueSubmit);
    WSI_CB(WaitForFences);
+   WSI_CB(MapMemory);
+   WSI_CB(UnmapMemory);
 #undef WSI_CB
 
     struct wsi_interface *                  wsi[VK_ICD_WSI_PLATFORM_MAX];
@@ -190,7 +194,8 @@ wsi_device_init(struct wsi_device *wsi,
                 WSI_FN_GetPhysicalDeviceProcAddr proc_addr,
                 const VkAllocationCallbacks *alloc,
                 int display_fd,
-                const struct driOptionCache *dri_options);
+                const struct driOptionCache *dri_options,
+                bool sw_device);
 
 void
 wsi_device_finish(struct wsi_device *wsi,
index 566926845f966cd5429aaafd968f51858b8d72bb..760522b770f95788f63459cc7c1c5f8a8ded8b74 100644 (file)
@@ -993,8 +993,8 @@ x11_acquire_next_image_from_queue(struct x11_swapchain *chain,
 }
 
 static VkResult
-x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index,
-                   uint32_t target_msc)
+x11_present_to_x11_dri3(struct x11_swapchain *chain, uint32_t image_index,
+                        uint32_t target_msc)
 {
    struct x11_image *image = &chain->images[image_index];
 
@@ -1052,6 +1052,41 @@ x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index,
    return x11_swapchain_result(chain, VK_SUCCESS);
 }
 
+static VkResult
+x11_present_to_x11_sw(struct x11_swapchain *chain, uint32_t image_index,
+                      uint32_t target_msc)
+{
+   struct x11_image *image = &chain->images[image_index];
+
+   xcb_void_cookie_t cookie;
+   void *myptr;
+   chain->base.wsi->MapMemory(chain->base.device,
+                              image->base.memory,
+                              0, 0, 0, &myptr);
+
+   cookie = xcb_put_image(chain->conn, XCB_IMAGE_FORMAT_Z_PIXMAP,
+                          chain->window,
+                          chain->gc,
+                         image->base.row_pitches[0] / 4,
+                          chain->extent.height,
+                          0,0,0,24,
+                          image->base.row_pitches[0] * chain->extent.height,
+                          myptr);
+
+   chain->base.wsi->UnmapMemory(chain->base.device, image->base.memory);
+   xcb_discard_reply(chain->conn, cookie.sequence);
+   xcb_flush(chain->conn);
+   return x11_swapchain_result(chain, VK_SUCCESS);
+}
+static VkResult
+x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index,
+                   uint32_t target_msc)
+{
+   if (chain->base.wsi->sw)
+      return x11_present_to_x11_sw(chain, image_index, target_msc);
+   return x11_present_to_x11_dri3(chain, image_index, target_msc);
+}
+
 static VkResult
 x11_acquire_next_image(struct wsi_swapchain *anv_chain,
                        const VkAcquireNextImageInfoKHR *info,
@@ -1064,6 +1099,10 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain,
    if (chain->status < 0)
       return chain->status;
 
+   if (chain->base.wsi->sw) {
+      *image_index = 0;
+      return VK_SUCCESS;
+   }
    if (chain->has_acquire_queue) {
       return x11_acquire_next_image_from_queue(chain, image_index, timeout);
    } else {
@@ -1183,6 +1222,10 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
    if (result < 0)
       return result;
 
+   if (chain->base.wsi->sw) {
+      image->busy = false;
+      return VK_SUCCESS;
+   }
    image->pixmap = xcb_generate_id(chain->conn);
 
 #ifdef HAVE_DRI3_MODIFIERS
@@ -1271,12 +1314,14 @@ x11_image_finish(struct x11_swapchain *chain,
 {
    xcb_void_cookie_t cookie;
 
-   cookie = xcb_sync_destroy_fence(chain->conn, image->sync_fence);
-   xcb_discard_reply(chain->conn, cookie.sequence);
-   xshmfence_unmap_shm(image->shm_fence);
+   if (!chain->base.wsi->sw) {
+      cookie = xcb_sync_destroy_fence(chain->conn, image->sync_fence);
+      xcb_discard_reply(chain->conn, cookie.sequence);
+      xshmfence_unmap_shm(image->shm_fence);
 
-   cookie = xcb_free_pixmap(chain->conn, image->pixmap);
-   xcb_discard_reply(chain->conn, cookie.sequence);
+      cookie = xcb_free_pixmap(chain->conn, image->pixmap);
+      xcb_discard_reply(chain->conn, cookie.sequence);
+   }
 
    wsi_destroy_image(&chain->base, &image->base);
 }
@@ -1497,8 +1542,9 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
    else
       chain->last_present_mode = XCB_PRESENT_COMPLETE_MODE_COPY;
 
-   if (!wsi_x11_check_dri3_compatible(wsi_device, conn))
-       chain->base.use_prime_blit = true;
+   if (!wsi_device->sw)
+      if (!wsi_x11_check_dri3_compatible(wsi_device, conn))
+         chain->base.use_prime_blit = true;
 
    chain->event_id = xcb_generate_id(chain->conn);
    xcb_present_select_input(chain->conn, chain->event_id, chain->window,
@@ -1546,8 +1592,8 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
          goto fail_init_images;
    }
 
-   if (chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR ||
-       chain->base.present_mode == VK_PRESENT_MODE_MAILBOX_KHR) {
+   if ((chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR ||
+       chain->base.present_mode == VK_PRESENT_MODE_MAILBOX_KHR) && !chain->base.wsi->sw) {
       chain->has_present_queue = true;
 
       /* Initialize our queues.  We make them base.image_count + 1 because we will