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 1dc161f..3154c9d 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 ce5d4c8..d7c4bda 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 888a91d..75bf4fe 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 2108f7f..671690d 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 cbf7e1b..7c69268 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 5669268..760522b 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];
 
@@ -1053,6 +1053,41 @@ x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index,
 }
 
 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,
                        uint32_t *image_index)
@@ -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