diff options
author | Dave Airlie <[email protected]> | 2016-11-23 12:59:55 +1000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2017-02-27 05:42:16 +1000 |
commit | f695735ed61ea2f11f0fdf032a8ad2c99b6b064c (patch) | |
tree | f15f9f19ed80a64e59e2ad754f610e8e6b343aec /src/vulkan/wsi/wsi_common_x11.c | |
parent | 336b05c49a6c6ce915bbd6629da17321ecb72bee (diff) |
vulkan/wsi/radv: add initial prime support (v1.1)
This is a complete rewrite of my previous rfc patches.
This adds the ability to present to a different GPU that rendering
using a driver side operation that can copy from the tiled to
linear shared image.
This does prime support completely in the swapchain present code,
and each queue has a precreated command buffer for each image
and for the each queue family. This means presenting should work
on graphics and compute queues and transfer in the future.
v1.1: initialise needs_linear_copy in swapchain.
Reviewed-by: Bas Nieuwenhuizen <[email protected]>
Tested-by: Mike Lothian <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/vulkan/wsi/wsi_common_x11.c')
-rw-r--r-- | src/vulkan/wsi/wsi_common_x11.c | 60 |
1 files changed, 55 insertions, 5 deletions
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 9e19b10fa0d..5655b5475d2 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -317,6 +317,7 @@ VkBool32 wsi_get_physical_device_xcb_presentation_support( VkAllocationCallbacks *alloc, uint32_t queueFamilyIndex, int fd, + bool can_handle_different_gpu, xcb_connection_t* connection, xcb_visualid_t visual_id) { @@ -332,8 +333,9 @@ VkBool32 wsi_get_physical_device_xcb_presentation_support( return false; } - if (!wsi_x11_check_dri3_compatible(connection, fd)) - return false; + if (!can_handle_different_gpu) + if (!wsi_x11_check_dri3_compatible(connection, fd)) + return false; unsigned visual_depth; if (!connection_get_visualtype(connection, visual_id, &visual_depth)) @@ -369,6 +371,7 @@ x11_surface_get_support(VkIcdSurfaceBase *icd_surface, const VkAllocationCallbacks *alloc, uint32_t queueFamilyIndex, int local_fd, + bool can_handle_different_gpu, VkBool32* pSupported) { xcb_connection_t *conn = x11_surface_get_connection(icd_surface); @@ -386,8 +389,9 @@ x11_surface_get_support(VkIcdSurfaceBase *icd_surface, return VK_SUCCESS; } - if (!wsi_x11_check_dri3_compatible(conn, local_fd)) - return false; + if (!can_handle_different_gpu) + if (!wsi_x11_check_dri3_compatible(conn, local_fd)) + return false; unsigned visual_depth; if (!get_visualtype_for_window(conn, window, &visual_depth)) { @@ -550,7 +554,9 @@ VkResult wsi_create_xlib_surface(const VkAllocationCallbacks *pAllocator, struct x11_image { VkImage image; + VkImage linear_image; // for prime VkDeviceMemory memory; + VkDeviceMemory linear_memory; // for prime xcb_pixmap_t pixmap; bool busy; struct xshmfence * shm_fence; @@ -607,6 +613,15 @@ x11_get_images(struct wsi_swapchain *anv_chain, return result; } +static void +x11_get_image_and_linear(struct wsi_swapchain *drv_chain, + int imageIndex, VkImage *image, VkImage *linear_image) +{ + struct x11_swapchain *chain = (struct x11_swapchain *)drv_chain; + *image = chain->images[imageIndex].image; + *linear_image = chain->images[imageIndex].linear_image; +} + static VkResult x11_handle_dri3_present_event(struct x11_swapchain *chain, xcb_present_generic_event_t *event) @@ -890,6 +905,8 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, result = chain->base.image_fns->create_wsi_image(device_h, pCreateInfo, pAllocator, + chain->base.needs_linear_copy, + false, &image->image, &image->memory, &size, @@ -899,6 +916,25 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, if (result != VK_SUCCESS) return result; + if (chain->base.needs_linear_copy) { + result = chain->base.image_fns->create_wsi_image(device_h, + pCreateInfo, + pAllocator, + chain->base.needs_linear_copy, + true, + &image->linear_image, + &image->linear_memory, + &size, + &offset, + &row_pitch, + &fd); + if (result != VK_SUCCESS) { + chain->base.image_fns->free_wsi_image(device_h, pAllocator, + image->image, image->memory); + return result; + } + } + image->pixmap = xcb_generate_id(chain->conn); cookie = @@ -939,8 +975,12 @@ fail_pixmap: cookie = xcb_free_pixmap(chain->conn, image->pixmap); xcb_discard_reply(chain->conn, cookie.sequence); + if (chain->base.needs_linear_copy) { + chain->base.image_fns->free_wsi_image(device_h, pAllocator, + image->linear_image, image->linear_memory); + } chain->base.image_fns->free_wsi_image(device_h, pAllocator, - image->image, image->memory); + image->image, image->memory); return result; } @@ -959,6 +999,10 @@ x11_image_finish(struct x11_swapchain *chain, cookie = xcb_free_pixmap(chain->conn, image->pixmap); xcb_discard_reply(chain->conn, cookie.sequence); + if (chain->base.needs_linear_copy) { + chain->base.image_fns->free_wsi_image(chain->base.device, pAllocator, + image->linear_image, image->linear_memory); + } chain->base.image_fns->free_wsi_image(chain->base.device, pAllocator, image->image, image->memory); } @@ -997,6 +1041,7 @@ static VkResult x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, VkDevice device, struct wsi_device *wsi_device, + int local_fd, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks* pAllocator, const struct wsi_image_fns *image_fns, @@ -1027,6 +1072,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, chain->base.device = device; chain->base.destroy = x11_swapchain_destroy; chain->base.get_images = x11_get_images; + chain->base.get_image_and_linear = x11_get_image_and_linear; chain->base.acquire_next_image = x11_acquire_next_image; chain->base.queue_present = x11_queue_present; chain->base.image_fns = image_fns; @@ -1043,6 +1089,10 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, free(geometry); + chain->base.needs_linear_copy = false; + if (!wsi_x11_check_dri3_compatible(conn, local_fd)) + chain->base.needs_linear_copy = true; + chain->event_id = xcb_generate_id(chain->conn); xcb_present_select_input(chain->conn, chain->event_id, chain->window, XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY | |