From 8004fa9c9501d91669ac51d32c9a9143286ca7ea Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 19 Jun 2020 16:37:51 +1000 Subject: [PATCH] vulkan/wsi: add sw support. (v2) 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 Part-of: --- src/amd/vulkan/radv_wsi.c | 3 +- src/freedreno/vulkan/tu_wsi.c | 3 +- src/intel/vulkan/anv_wsi.c | 3 +- src/vulkan/wsi/wsi_common.c | 35 ++++++++++------- src/vulkan/wsi/wsi_common.h | 7 +++- src/vulkan/wsi/wsi_common_x11.c | 68 +++++++++++++++++++++++++++------ 6 files changed, 90 insertions(+), 29 deletions(-) diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c index 1dc161f6791..3154c9d9305 100644 --- a/src/amd/vulkan/radv_wsi.c +++ b/src/amd/vulkan/radv_wsi.c @@ -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; diff --git a/src/freedreno/vulkan/tu_wsi.c b/src/freedreno/vulkan/tu_wsi.c index ce5d4c8ada3..d7c4bda9bbb 100644 --- a/src/freedreno/vulkan/tu_wsi.c +++ b/src/freedreno/vulkan/tu_wsi.c @@ -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; diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c index 888a91d8620..75bf4feadd3 100644 --- a/src/intel/vulkan/anv_wsi.c +++ b/src/intel/vulkan/anv_wsi.c @@ -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; diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c index 2108f7f703f..671690df9cc 100644 --- a/src/vulkan/wsi/wsi_common.c +++ b/src/vulkan/wsi/wsi_common.c @@ -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, }; diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index cbf7e1be14e..7c69268ea77 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -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, diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 566926845f9..760522b770f 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -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 -- 2.30.2