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 | |
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')
-rw-r--r-- | src/vulkan/wsi/wsi_common.h | 8 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common_wayland.c | 5 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common_x11.c | 60 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common_x11.h | 1 |
4 files changed, 69 insertions, 5 deletions
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index 7caabf50f4a..24828764554 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -35,6 +35,8 @@ struct wsi_image_fns { VkResult (*create_wsi_image)(VkDevice device_h, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, + bool needs_linear_copy, + bool linear, VkImage *image_p, VkDeviceMemory *memory_p, uint32_t *size_p, @@ -53,8 +55,11 @@ struct wsi_swapchain { VkAllocationCallbacks alloc; const struct wsi_image_fns *image_fns; VkFence fences[3]; + VkCommandBuffer *cmd_buffers; + VkCommandPool cmd_pools[3]; VkPresentModeKHR present_mode; uint32_t image_count; + bool needs_linear_copy; VkResult (*destroy)(struct wsi_swapchain *swapchain, const VkAllocationCallbacks *pAllocator); @@ -65,6 +70,7 @@ struct wsi_swapchain { uint32_t *image_index); VkResult (*queue_present)(struct wsi_swapchain *swap_chain, uint32_t image_index); + void (*get_image_and_linear)(struct wsi_swapchain *swapchain, int imageIndex, VkImage *image, VkImage *linear_image); }; struct wsi_interface { @@ -73,6 +79,7 @@ struct wsi_interface { const VkAllocationCallbacks *alloc, uint32_t queueFamilyIndex, int local_fd, + bool can_handle_different_gpu, VkBool32* pSupported); VkResult (*get_capabilities)(VkIcdSurfaceBase *surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); @@ -86,6 +93,7 @@ struct wsi_interface { VkResult (*create_swapchain)(VkIcdSurfaceBase *surface, VkDevice device, struct wsi_device *wsi_device, + int local_fd, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, const struct wsi_image_fns *image_fns, diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index e6490ee56b3..67ac0b8372e 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -352,6 +352,7 @@ wsi_wl_surface_get_support(VkIcdSurfaceBase *surface, const VkAllocationCallbacks *alloc, uint32_t queueFamilyIndex, int local_fd, + bool can_handle_different_gpu, VkBool32* pSupported) { *pSupported = true; @@ -637,6 +638,8 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, result = chain->base.image_fns->create_wsi_image(vk_device, pCreateInfo, pAllocator, + false, + false, &image->image, &image->memory, &size, @@ -694,6 +697,7 @@ static VkResult wsi_wl_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, @@ -724,6 +728,7 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, chain->base.image_fns = image_fns; chain->base.present_mode = pCreateInfo->presentMode; chain->base.image_count = num_images; + chain->base.needs_linear_copy = false; chain->surface = surface->surface; chain->extent = pCreateInfo->imageExtent; chain->vk_format = pCreateInfo->imageFormat; 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 | diff --git a/src/vulkan/wsi/wsi_common_x11.h b/src/vulkan/wsi/wsi_common_x11.h index 01f1d66eeaa..b33540856cb 100644 --- a/src/vulkan/wsi/wsi_common_x11.h +++ b/src/vulkan/wsi/wsi_common_x11.h @@ -30,6 +30,7 @@ VkBool32 wsi_get_physical_device_xcb_presentation_support( VkAllocationCallbacks *alloc, uint32_t queueFamilyIndex, int local_fd, + bool can_handle_different_gpu, xcb_connection_t* connection, xcb_visualid_t visual_id); |