vulkan/wsi/display: Wrap wsi_display_fence in a vk_sync

This gets rid of the bespoke vfunc interface in the WSI code.
Eventually, I'd love to get rid of wsi_display_fence entirely but
this at least makes it a lot more palatable.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Acked-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13427>
This commit is contained in:
Jason Ekstrand 2021-10-21 11:50:10 -05:00
parent b1addc425a
commit e3fda7ae78
6 changed files with 105 additions and 35 deletions

View File

@ -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;
};
};

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -27,13 +27,15 @@
#include <xf86drm.h>
#include <xf86drmMode.h>
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