From 29e3fc8eb1e6dbf1f95eb95130dabeeafb48a189 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 26 Sep 2022 12:03:28 -0500 Subject: [PATCH] vulkan/wsi: Support configuring swapchain images as part of swapchain init The eventual goal here is to move as much of the prime and blit logic out of the individual window-system back-ends as possible. Reviewed-by: Adam Jackson Part-of: --- src/vulkan/wsi/wsi_common.c | 87 +++++++++++++++++++++++++++++++++++++ src/vulkan/wsi/wsi_common_display.c | 2 +- src/vulkan/wsi/wsi_common_drm.c | 27 ++++++++++++ src/vulkan/wsi/wsi_common_private.h | 47 ++++++++++++++++++++ src/vulkan/wsi/wsi_common_wayland.c | 2 +- src/vulkan/wsi/wsi_common_win32.c | 2 +- src/vulkan/wsi/wsi_common_x11.c | 3 +- 7 files changed, 166 insertions(+), 4 deletions(-) diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c index 1afee99..79b8ea0 100644 --- a/src/vulkan/wsi/wsi_common.c +++ b/src/vulkan/wsi/wsi_common.c @@ -268,11 +268,59 @@ wsi_device_setup_syncobj_fd(struct wsi_device *wsi_device, #endif } +static bool +needs_buffer_blit(const struct wsi_device *wsi, + const struct wsi_base_image_params *params) +{ + switch (params->image_type) { + case WSI_IMAGE_TYPE_CPU: { + const struct wsi_cpu_image_params *cpu_params = + container_of(params, const struct wsi_cpu_image_params, base); + return wsi_cpu_image_needs_buffer_blit(wsi, cpu_params); + } +#ifdef HAVE_LIBDRM + case WSI_IMAGE_TYPE_DRM: { + const struct wsi_drm_image_params *drm_params = + container_of(params, const struct wsi_drm_image_params, base); + return wsi_drm_image_needs_buffer_blit(wsi, drm_params); + } +#endif + default: + unreachable("Invalid image type"); + } +} + +static VkResult +configure_image(const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const struct wsi_base_image_params *params, + struct wsi_image_info *info) +{ + switch (params->image_type) { + case WSI_IMAGE_TYPE_CPU: { + const struct wsi_cpu_image_params *cpu_params = + container_of(params, const struct wsi_cpu_image_params, base); + return wsi_configure_cpu_image_with_params(chain, pCreateInfo, + cpu_params, info); + } +#ifdef HAVE_LIBDRM + case WSI_IMAGE_TYPE_DRM: { + const struct wsi_drm_image_params *drm_params = + container_of(params, const struct wsi_drm_image_params, base); + return wsi_drm_configure_image(chain, pCreateInfo, drm_params, info); + } +#endif + default: + unreachable("Invalid image type"); + } +} + VkResult wsi_swapchain_init(const struct wsi_device *wsi, struct wsi_swapchain *chain, VkDevice _device, const VkSwapchainCreateInfoKHR *pCreateInfo, + const struct wsi_base_image_params *image_params, const VkAllocationCallbacks *pAllocator, bool use_buffer_blit) { @@ -291,6 +339,9 @@ wsi_swapchain_init(const struct wsi_device *wsi, if (wsi->sw && !wsi->wants_linear) chain->use_buffer_blit = true; + if (image_params != NULL && needs_buffer_blit(wsi, image_params)) + chain->use_buffer_blit = true; + chain->buffer_blit_queue = VK_NULL_HANDLE; if (use_buffer_blit && wsi->get_buffer_blit_queue) chain->buffer_blit_queue = wsi->get_buffer_blit_queue(_device); @@ -322,6 +373,15 @@ wsi_swapchain_init(const struct wsi_device *wsi, goto fail; } + if (image_params != NULL) { + result = configure_image(chain, pCreateInfo, image_params, + &chain->image_info); + if (result != VK_SUCCESS) + goto fail; + + chain->image_info_owned = true; + } + return VK_SUCCESS; fail: @@ -385,6 +445,9 @@ wsi_swapchain_get_present_mode(struct wsi_device *wsi, void wsi_swapchain_finish(struct wsi_swapchain *chain) { + if (chain->image_info_owned) + wsi_destroy_image_info(chain, &chain->image_info); + if (chain->fences) { for (unsigned i = 0; i < chain->image_count; i++) chain->wsi->DestroyFence(chain->device, chain->fences[i], &chain->alloc); @@ -1713,3 +1776,27 @@ wsi_configure_cpu_image(const struct wsi_swapchain *chain, return VK_SUCCESS; } + +bool +wsi_cpu_image_needs_buffer_blit(const struct wsi_device *wsi, + const struct wsi_cpu_image_params *params) +{ + if (WSI_DEBUG & WSI_DEBUG_BUFFER) + return true; + + if (wsi->wants_linear) + return false; + + return true; +} + +VkResult +wsi_configure_cpu_image_with_params(const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const struct wsi_cpu_image_params *params, + struct wsi_image_info *info) +{ + assert(params->base.image_type == WSI_IMAGE_TYPE_CPU); + + return wsi_configure_cpu_image(chain, pCreateInfo, params->alloc_shm, info); +} diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c index 418ef6e..14618fc 100644 --- a/src/vulkan/wsi/wsi_common_display.c +++ b/src/vulkan/wsi/wsi_common_display.c @@ -1952,7 +1952,7 @@ wsi_display_surface_create_swapchain( return VK_ERROR_OUT_OF_HOST_MEMORY; VkResult result = wsi_swapchain_init(wsi_device, &chain->base, device, - create_info, allocator, false); + create_info, NULL, allocator, false); if (result != VK_SUCCESS) { vk_free(allocator, chain); return result; diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c index ffbb335..052b963 100644 --- a/src/vulkan/wsi/wsi_common_drm.c +++ b/src/vulkan/wsi/wsi_common_drm.c @@ -618,3 +618,30 @@ wsi_configure_prime_image(UNUSED const struct wsi_swapchain *chain, return VK_SUCCESS; } + +bool +wsi_drm_image_needs_buffer_blit(const struct wsi_device *wsi, + const struct wsi_drm_image_params *params) +{ + return !params->same_gpu; +} + +VkResult +wsi_drm_configure_image(const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const struct wsi_drm_image_params *params, + struct wsi_image_info *info) +{ + assert(params->base.image_type == WSI_IMAGE_TYPE_DRM); + + if (!params->same_gpu) { + bool use_modifier = params->num_modifier_lists > 0; + return wsi_configure_prime_image(chain, pCreateInfo, use_modifier, info); + } else { + return wsi_configure_native_image(chain, pCreateInfo, + params->num_modifier_lists, + params->num_modifiers, + params->modifiers, + info); + } +} diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h index 0495098..eb4d8a1 100644 --- a/src/vulkan/wsi/wsi_common_private.h +++ b/src/vulkan/wsi/wsi_common_private.h @@ -38,6 +38,31 @@ struct wsi_swapchain; extern uint64_t WSI_DEBUG; +enum wsi_image_type { + WSI_IMAGE_TYPE_CPU, + WSI_IMAGE_TYPE_DRM, +}; + +struct wsi_base_image_params { + enum wsi_image_type image_type; +}; + +struct wsi_cpu_image_params { + struct wsi_base_image_params base; + + uint8_t *(*alloc_shm)(struct wsi_image *image, unsigned size); +}; + +struct wsi_drm_image_params { + struct wsi_base_image_params base; + + bool same_gpu; + + uint32_t num_modifier_lists; + const uint32_t *num_modifiers; + const uint64_t *const *modifiers; +}; + struct wsi_image_info { VkImageCreateInfo create; struct wsi_image_create_info wsi; @@ -112,6 +137,7 @@ struct wsi_swapchain { int signal_dma_buf_from_semaphore; VkSemaphore dma_buf_semaphore; + bool image_info_owned; struct wsi_image_info image_info; uint32_t image_count; @@ -147,6 +173,7 @@ wsi_swapchain_init(const struct wsi_device *wsi, struct wsi_swapchain *chain, VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, + const struct wsi_base_image_params *image_params, const VkAllocationCallbacks *pAllocator, bool use_buffer_blit); @@ -165,6 +192,16 @@ uint32_t wsi_select_device_memory_type(const struct wsi_device *wsi, uint32_t type_bits); +bool +wsi_drm_image_needs_buffer_blit(const struct wsi_device *wsi, + const struct wsi_drm_image_params *params); + +VkResult +wsi_drm_configure_image(const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const struct wsi_drm_image_params *params, + struct wsi_image_info *info); + VkResult wsi_configure_native_image(const struct wsi_swapchain *chain, const VkSwapchainCreateInfoKHR *pCreateInfo, @@ -186,6 +223,16 @@ wsi_configure_cpu_image(const struct wsi_swapchain *chain, unsigned size), struct wsi_image_info *info); +bool +wsi_cpu_image_needs_buffer_blit(const struct wsi_device *wsi, + const struct wsi_cpu_image_params *params); + +VkResult +wsi_configure_cpu_image_with_params(const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const struct wsi_cpu_image_params *params, + struct wsi_image_info *info); + VkResult wsi_create_buffer_image_mem(const struct wsi_swapchain *chain, const struct wsi_image_info *info, diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index 7faeb43..df914e0 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -1281,7 +1281,7 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, return VK_ERROR_OUT_OF_HOST_MEMORY; result = wsi_swapchain_init(wsi_device, &chain->base, device, - pCreateInfo, pAllocator, false); + pCreateInfo, NULL, pAllocator, false); if (result != VK_SUCCESS) { vk_free(pAllocator, chain); return result; diff --git a/src/vulkan/wsi/wsi_common_win32.c b/src/vulkan/wsi/wsi_common_win32.c index 2192bb2..ffd7f68 100644 --- a/src/vulkan/wsi/wsi_common_win32.c +++ b/src/vulkan/wsi/wsi_common_win32.c @@ -449,7 +449,7 @@ wsi_win32_surface_create_swapchain( return VK_ERROR_OUT_OF_HOST_MEMORY; VkResult result = wsi_swapchain_init(wsi_device, &chain->base, device, - create_info, allocator, false); + create_info, NULL, allocator, false); if (result != VK_SUCCESS) { vk_free(allocator, chain); return result; diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 2c9534c..8823117 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -2030,7 +2030,8 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, use_buffer_blit = true; result = wsi_swapchain_init(wsi_device, &chain->base, device, - pCreateInfo, pAllocator, use_buffer_blit); + pCreateInfo, NULL, pAllocator, + use_buffer_blit); if (result != VK_SUCCESS) goto fail_alloc; -- 2.7.4