vulkan/wsi/wayland: introduce struct wsi_wl_surface

In the following commits we add dma-buf feedback support. In order to do
that, we need to keep the feedback tied to the lifetime of the surface,
instead of tied to the lifetime of the chain.

Why do we need this change?

   The reason is per-surface feedback and swapchain re-creation. If we
   receive feedback and return SUBOPTIMAL to the client in the next
   acquireNextImage() call, it may re-create the swapchain. If it
   doesn't pass us the oldSwapchain, we won't have access to the surface
   feedback data (as it was tied to the oldSwapchain). We could bind
   again to the surface feedback, but compositors may have a transient
   state when we bind to surface feedback, and send a non-optimal batch
   of dma-buf feedback which is updated when the drawing loop starts. So
   we would re-create the chain with this non-optimal batch, and after a
   few moments receive new feedback. This could potentially lead into an
   allocation loop, so it is not safe.

   Tying the feedback to the lifetime of the VkSurface we don't have to
   re-bind to the surface dma-buf feedback every time that the swapchain
   is re-created, avoiding this dangerous allocation loop described
   above.

So add struct wsi_wl_surface in order to add support for dma-buf
feedback. For now it is just the stub, but in the next commits we start
making use of that.

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:
Leandro Ribeiro
2022-10-04 17:43:24 -03:00
committed by Marge Bot
parent 149f7e4762
commit abc464f3a9
3 changed files with 32 additions and 3 deletions
+7
View File
@@ -257,6 +257,13 @@ wsi_DestroySurfaceKHR(VkInstance _instance,
if (!surface)
return;
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
if (surface->platform == VK_ICD_WSI_PLATFORM_WAYLAND) {
wsi_wl_surface_destroy(surface, _instance, pAllocator);
return;
}
#endif
vk_free2(&instance->alloc, pAllocator, surface);
}
+4
View File
@@ -168,6 +168,10 @@ struct wsi_swapchain {
bool
wsi_device_matches_drm_fd(const struct wsi_device *wsi, int drm_fd);
void
wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface, VkInstance _instance,
const VkAllocationCallbacks *pAllocator);
VkResult
wsi_swapchain_init(const struct wsi_device *wsi,
struct wsi_swapchain *chain,
+21 -3
View File
@@ -101,6 +101,10 @@ enum wsi_wl_buffer_type {
WSI_WL_BUFFER_SHM_MEMCPY,
};
struct wsi_wl_surface {
VkIcdSurfaceWayland base;
};
struct wsi_wl_swapchain {
struct wsi_swapchain base;
@@ -921,6 +925,17 @@ wsi_wl_surface_get_present_rectangles(VkIcdSurfaceBase *surface,
return vk_outarray_status(&out);
}
void
wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface, VkInstance _instance,
const VkAllocationCallbacks *pAllocator)
{
VK_FROM_HANDLE(vk_instance, instance, _instance);
struct wsi_wl_surface *wsi_wl_surface =
wl_container_of((VkIcdSurfaceWayland *)icd_surface, wsi_wl_surface, base);
vk_free2(&instance->alloc, pAllocator, wsi_wl_surface);
}
VKAPI_ATTR VkResult VKAPI_CALL
wsi_CreateWaylandSurfaceKHR(VkInstance _instance,
const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
@@ -928,15 +943,18 @@ wsi_CreateWaylandSurfaceKHR(VkInstance _instance,
VkSurfaceKHR *pSurface)
{
VK_FROM_HANDLE(vk_instance, instance, _instance);
struct wsi_wl_surface *wsi_wl_surface;
VkIcdSurfaceWayland *surface;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR);
surface = vk_alloc2(&instance->alloc, pAllocator, sizeof *surface, 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (surface == NULL)
wsi_wl_surface = vk_zalloc2(&instance->alloc, pAllocator, sizeof *wsi_wl_surface,
8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (wsi_wl_surface == NULL)
return VK_ERROR_OUT_OF_HOST_MEMORY;
surface = &wsi_wl_surface->base;
surface->base.platform = VK_ICD_WSI_PLATFORM_WAYLAND;
surface->display = pCreateInfo->display;
surface->surface = pCreateInfo->surface;