diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index b6b9239bc91..2e371626932 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -74,6 +74,7 @@ #include "vk_util.h" #include "vk_command_buffer.h" #include "vk_queue.h" +#include "vk_sync.h" #include "vk_log.h" /* Pre-declarations needed for WSI entrypoints */ @@ -3287,7 +3288,7 @@ struct anv_fence_impl { uint32_t syncobj; /** WSI fence */ - struct wsi_fence *fence_wsi; + struct vk_sync *sync_wsi; }; }; diff --git a/src/intel/vulkan/anv_queue.c b/src/intel/vulkan/anv_queue.c index 4bcfe99b801..d3155cedf66 100644 --- a/src/intel/vulkan/anv_queue.c +++ b/src/intel/vulkan/anv_queue.c @@ -1543,7 +1543,7 @@ anv_fence_impl_cleanup(struct anv_device *device, break; case ANV_FENCE_TYPE_WSI: - impl->fence_wsi->destroy(impl->fence_wsi); + vk_sync_destroy(&device->vk, impl->sync_wsi); break; default: @@ -1860,7 +1860,8 @@ anv_wait_for_wsi_fence(struct anv_device *device, struct anv_fence_impl *impl, uint64_t abs_timeout) { - return impl->fence_wsi->wait(impl->fence_wsi, abs_timeout); + return vk_sync_wait(&device->vk, impl->sync_wsi, 0, + VK_SYNC_WAIT_COMPLETE, abs_timeout); } static VkResult diff --git a/src/intel/vulkan/anv_wsi_display.c b/src/intel/vulkan/anv_wsi_display.c index 9f54d213e61..3528e29bbb8 100644 --- a/src/intel/vulkan/anv_wsi_display.c +++ b/src/intel/vulkan/anv_wsi_display.c @@ -48,7 +48,7 @@ anv_RegisterDeviceEventEXT(VkDevice _device, &device->physical->wsi_device, device_event_info, allocator, - &fence->permanent.fence_wsi, + &fence->permanent.sync_wsi, -1); if (ret == VK_SUCCESS) *_fence = anv_fence_to_handle(fence); @@ -77,7 +77,7 @@ anv_RegisterDisplayEventEXT(VkDevice _device, ret = wsi_register_display_event( _device, &device->physical->wsi_device, - display, display_event_info, allocator, &fence->permanent.fence_wsi, -1); + display, display_event_info, allocator, &fence->permanent.sync_wsi, -1); if (ret == VK_SUCCESS) *_fence = anv_fence_to_handle(fence); diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index 8f5e12dc2c1..63f21ef698b 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -82,11 +82,6 @@ struct wsi_memory_signal_submit_info { VkDeviceMemory memory; }; -struct wsi_fence { - VkResult (*wait)(struct wsi_fence *fence, uint64_t abs_timeout); - void (*destroy)(struct wsi_fence *fence); -}; - struct wsi_interface; struct driOptionCache; diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c index e32debfa771..4990b17cc67 100644 --- a/src/vulkan/wsi/wsi_common_display.c +++ b/src/vulkan/wsi/wsi_common_display.c @@ -48,6 +48,7 @@ #include "vk_device.h" #include "vk_instance.h" #include "vk_physical_device.h" +#include "vk_sync.h" #include "vk_util.h" #include "wsi_common_entrypoints.h" #include "wsi_common_private.h" @@ -149,7 +150,6 @@ struct wsi_display_swapchain { }; struct wsi_display_fence { - struct wsi_fence base; struct list_head link; struct wsi_display *wsi; bool event_received; @@ -159,6 +159,11 @@ struct wsi_display_fence { bool device_event; /* fence is used for device events */ }; +struct wsi_display_sync { + struct vk_sync sync; + struct wsi_display_fence *fence; +}; + static uint64_t fence_sequence; ICD_DEFINE_NONDISP_HANDLE_CASTS(wsi_display_mode, VkDisplayModeKHR) @@ -1510,10 +1515,8 @@ bail: } static VkResult -wsi_display_fence_wait(struct wsi_fence *fence_wsi, uint64_t timeout) +wsi_display_fence_wait(struct wsi_display_fence *fence, uint64_t timeout) { - struct wsi_display_fence *fence = (struct wsi_display_fence *) fence_wsi; - wsi_display_debug("%9lu wait fence %lu %ld\n", pthread_self(), fence->sequence, (int64_t) (timeout - os_time_get_nano())); @@ -1576,10 +1579,8 @@ static void wsi_display_fence_event_handler(struct wsi_display_fence *fence) } static void -wsi_display_fence_destroy(struct wsi_fence *fence_wsi) +wsi_display_fence_destroy(struct wsi_display_fence *fence) { - struct wsi_display_fence *fence = (struct wsi_display_fence *) fence_wsi; - /* Destroy hotplug fence list. */ if (fence->device_event) { mtx_lock(&fence->wsi->wait_mutex); @@ -1612,8 +1613,6 @@ wsi_display_fence_alloc(struct wsi_display *wsi, int sync_fd) } } - fence->base.wait = wsi_display_fence_wait; - fence->base.destroy = wsi_display_fence_destroy; fence->wsi = wsi; fence->event_received = false; fence->destroyed = false; @@ -1621,6 +1620,69 @@ wsi_display_fence_alloc(struct wsi_display *wsi, int sync_fd) return fence; } +static VkResult +wsi_display_sync_init(struct vk_device *device, + struct vk_sync *sync, + uint64_t initial_value) +{ + assert(initial_value == 0); + return VK_SUCCESS; +} + +static void +wsi_display_sync_finish(struct vk_device *device, + struct vk_sync *sync) +{ + struct wsi_display_sync *wsi_sync = + container_of(sync, struct wsi_display_sync, sync); + if (wsi_sync->fence) + wsi_display_fence_destroy(wsi_sync->fence); +} + +static VkResult +wsi_display_sync_wait(struct vk_device *device, + struct vk_sync *sync, + uint64_t wait_value, + enum vk_sync_wait_flags wait_flags, + uint64_t abs_timeout_ns) +{ + struct wsi_display_sync *wsi_sync = + container_of(sync, struct wsi_display_sync, sync); + + assert(wait_value == 0); + assert(wait_flags == VK_SYNC_WAIT_COMPLETE); + + return wsi_display_fence_wait(wsi_sync->fence, abs_timeout_ns); +} + +static const struct vk_sync_type wsi_display_sync_type = { + .size = sizeof(struct wsi_display_sync), + .features = VK_SYNC_FEATURE_BINARY | + VK_SYNC_FEATURE_CPU_WAIT, + .init = wsi_display_sync_init, + .finish = wsi_display_sync_finish, + .wait = wsi_display_sync_wait, +}; + +static VkResult +wsi_display_sync_create(struct vk_device *device, + struct wsi_display_fence *fence, + struct vk_sync **sync_out) +{ + VkResult result = vk_sync_create(device, &wsi_display_sync_type, + 0 /* flags */, + 0 /* initial_value */, sync_out); + if (result != VK_SUCCESS) + return result; + + struct wsi_display_sync *sync = + container_of(*sync_out, struct wsi_display_sync, sync); + + sync->fence = fence; + + return VK_SUCCESS; +} + static VkResult wsi_register_vblank_event(struct wsi_display_fence *fence, const struct wsi_device *wsi_device, @@ -2651,15 +2713,17 @@ wsi_DisplayPowerControlEXT(VkDevice _device, } VkResult -wsi_register_device_event(VkDevice device, +wsi_register_device_event(VkDevice _device, struct wsi_device *wsi_device, const VkDeviceEventInfoEXT *device_event_info, const VkAllocationCallbacks *allocator, - struct wsi_fence **fence_p, + struct vk_sync **sync_out, int sync_fd) { + VK_FROM_HANDLE(vk_device, device, _device); struct wsi_display *wsi = (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + VkResult ret = VK_SUCCESS; #ifdef HAVE_LIBUDEV /* Start listening for output change notifications. */ @@ -2683,18 +2747,21 @@ wsi_register_device_event(VkDevice device, if (!fence) return VK_ERROR_OUT_OF_HOST_MEMORY; - if (fence_p) - *fence_p = &fence->base; - else - fence->base.destroy(&fence->base); - fence->device_event = true; mtx_lock(&wsi->wait_mutex); list_addtail(&fence->link, &wsi_device->hotplug_fences); mtx_unlock(&wsi->wait_mutex); - return VK_SUCCESS; + if (sync_out) { + ret = wsi_display_sync_create(device, fence, sync_out); + if (ret != VK_SUCCESS) + wsi_display_fence_destroy(fence); + } else { + wsi_display_fence_destroy(fence); + } + + return ret; } VKAPI_ATTR VkResult VKAPI_CALL @@ -2707,14 +2774,15 @@ wsi_RegisterDeviceEventEXT(VkDevice device, } VkResult -wsi_register_display_event(VkDevice device, +wsi_register_display_event(VkDevice _device, struct wsi_device *wsi_device, VkDisplayKHR display, const VkDisplayEventInfoEXT *display_event_info, const VkAllocationCallbacks *allocator, - struct wsi_fence **fence_p, + struct vk_sync **sync_out, int sync_fd) { + VK_FROM_HANDLE(vk_device, device, _device); struct wsi_display *wsi = (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; struct wsi_display_fence *fence; @@ -2732,10 +2800,13 @@ wsi_register_display_event(VkDevice device, DRM_CRTC_SEQUENCE_RELATIVE, 1, NULL); if (ret == VK_SUCCESS) { - if (fence_p) - *fence_p = &fence->base; - else - fence->base.destroy(&fence->base); + if (sync_out) { + ret = wsi_display_sync_create(device, fence, sync_out); + if (ret != VK_SUCCESS) + wsi_display_fence_destroy(fence); + } else { + wsi_display_fence_destroy(fence); + } } else if (fence != NULL) { if (fence->syncobj) drmSyncobjDestroy(wsi->syncobj_fd, fence->syncobj); diff --git a/src/vulkan/wsi/wsi_common_display.h b/src/vulkan/wsi/wsi_common_display.h index 26a49f8e139..dd54b9b775f 100644 --- a/src/vulkan/wsi/wsi_common_display.h +++ b/src/vulkan/wsi/wsi_common_display.h @@ -27,13 +27,15 @@ #include #include +struct vk_sync; + /* VK_EXT_display_control */ VkResult wsi_register_device_event(VkDevice device, struct wsi_device *wsi_device, const VkDeviceEventInfoEXT *device_event_info, const VkAllocationCallbacks *allocator, - struct wsi_fence **fence, + struct vk_sync **sync, int sync_fd); VkResult @@ -42,7 +44,7 @@ wsi_register_display_event(VkDevice device, VkDisplayKHR display, const VkDisplayEventInfoEXT *display_event_info, const VkAllocationCallbacks *allocator, - struct wsi_fence **fence, + struct vk_sync **sync, int sync_fd); #endif