vulkan/wsi/wayland: take ownership of wsi_wl_surface when creating chain
When we create a swapchain, take ownership of a struct wsi_wl_surface. When the chain gets destroyed, the ownership is dropped. We can safely do that because only a single swapchain can be associated with the surface at a time, according to vkCreateSwapchainKHR spec: "If pCreateInfo->oldSwapchain is VK_NULL_HANDLE, and the native window referred to by pCreateInfo->surface is already associated with a Vulkan swapchain, VK_ERROR_NATIVE_WINDOW_IN_USE_KHR must be returned." Reviewed-by: Simon Ser <contact@emersion.fr> Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12226>
This commit is contained in:

committed by
Marge Bot

parent
abc464f3a9
commit
ba571c3657
@@ -103,6 +103,8 @@ enum wsi_wl_buffer_type {
|
||||
|
||||
struct wsi_wl_surface {
|
||||
VkIcdSurfaceWayland base;
|
||||
|
||||
struct wsi_wl_swapchain *chain;
|
||||
};
|
||||
|
||||
struct wsi_wl_swapchain {
|
||||
@@ -112,6 +114,8 @@ struct wsi_wl_swapchain {
|
||||
|
||||
struct wl_surface *surface;
|
||||
|
||||
struct wsi_wl_surface *wsi_wl_surface;
|
||||
|
||||
struct wl_callback *frame;
|
||||
|
||||
VkExtent2D extent;
|
||||
@@ -1253,6 +1257,8 @@ wsi_wl_swapchain_chain_free(struct wsi_wl_swapchain *chain,
|
||||
wl_callback_destroy(chain->frame);
|
||||
if (chain->surface)
|
||||
wl_proxy_wrapper_destroy(chain->surface);
|
||||
if (chain->wsi_wl_surface)
|
||||
chain->wsi_wl_surface->chain = NULL;
|
||||
|
||||
if (chain->display)
|
||||
wsi_wl_display_unref(chain->display);
|
||||
@@ -1283,6 +1289,8 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
||||
struct wsi_swapchain **swapchain_out)
|
||||
{
|
||||
VkIcdSurfaceWayland *surface = (VkIcdSurfaceWayland *)icd_surface;
|
||||
struct wsi_wl_surface *wsi_wl_surface =
|
||||
wl_container_of((VkIcdSurfaceWayland *)icd_surface, wsi_wl_surface, base);
|
||||
struct wsi_wayland *wsi =
|
||||
(struct wsi_wayland *)wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND];
|
||||
struct wsi_wl_swapchain *chain;
|
||||
@@ -1306,6 +1314,31 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t size = sizeof(*chain) + num_images * sizeof(chain->images[0]);
|
||||
chain = vk_zalloc(pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (chain == NULL) {
|
||||
wsi_wl_display_unref(display);
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
/* We are taking ownership of the wsi_wl_surface, so remove ownership from
|
||||
* oldSwapchain.
|
||||
*
|
||||
* If the surface is currently owned by a swapchain that is not
|
||||
* oldSwapchain we should return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR. There's
|
||||
* an open issue tracking that:
|
||||
*
|
||||
* https://gitlab.freedesktop.org/mesa/mesa/-/issues/7467
|
||||
*/
|
||||
if (pCreateInfo->oldSwapchain) {
|
||||
VK_FROM_HANDLE(wsi_wl_swapchain, old_chain, pCreateInfo->oldSwapchain);
|
||||
old_chain->wsi_wl_surface = NULL;
|
||||
}
|
||||
|
||||
/* Take ownership of the wsi_wl_surface */
|
||||
chain->wsi_wl_surface = wsi_wl_surface;
|
||||
wsi_wl_surface->chain = chain;
|
||||
|
||||
enum wsi_wl_buffer_type buffer_type;
|
||||
struct wsi_base_image_params *image_params = NULL;
|
||||
struct wsi_cpu_image_params cpu_image_params;
|
||||
@@ -1347,13 +1380,6 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
||||
image_params = &drm_image_params.base;
|
||||
}
|
||||
|
||||
size_t size = sizeof(*chain) + num_images * sizeof(chain->images[0]);
|
||||
chain = vk_zalloc(pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (chain == NULL) {
|
||||
wsi_wl_display_unref(display);
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
result = wsi_swapchain_init(wsi_device, &chain->base, device,
|
||||
pCreateInfo, image_params, pAllocator);
|
||||
if (result != VK_SUCCESS) {
|
||||
|
Reference in New Issue
Block a user