diff options
Diffstat (limited to 'src/kosmickrisp/vulkan/kk_sync.c')
| -rw-r--r-- | src/kosmickrisp/vulkan/kk_sync.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/kosmickrisp/vulkan/kk_sync.c b/src/kosmickrisp/vulkan/kk_sync.c new file mode 100644 index 00000000000..f44200c379e --- /dev/null +++ b/src/kosmickrisp/vulkan/kk_sync.c @@ -0,0 +1,106 @@ +/* + * Copyright 2025 LunarG, Inc. + * Copyright 2025 Google LLC + * SPDX-License-Identifier: MIT + */ + +#include "kk_sync.h" + +#include "kk_device.h" + +#include "kosmickrisp/bridge/mtl_bridge.h" + +static VkResult +kk_timeline_init(struct vk_device *device, struct vk_sync *sync, + uint64_t initial_value) +{ + struct kk_sync_timeline *timeline = + container_of(sync, struct kk_sync_timeline, base); + + struct kk_device *dev = container_of(device, struct kk_device, vk); + timeline->mtl_handle = mtl_new_shared_event(dev->mtl_handle); + mtl_shared_event_set_signaled_value(timeline->mtl_handle, initial_value); + + return VK_SUCCESS; +} + +static void +kk_timeline_finish(struct vk_device *device, struct vk_sync *sync) +{ + struct kk_sync_timeline *timeline = + container_of(sync, struct kk_sync_timeline, base); + mtl_release(timeline->mtl_handle); +} + +static VkResult +kk_timeline_signal(struct vk_device *device, struct vk_sync *sync, + uint64_t value) +{ + struct kk_sync_timeline *timeline = + container_of(sync, struct kk_sync_timeline, base); + mtl_shared_event_set_signaled_value(timeline->mtl_handle, value); + return VK_SUCCESS; +} + +static VkResult +kk_timeline_get_value(struct vk_device *device, struct vk_sync *sync, + uint64_t *value) +{ + struct kk_sync_timeline *timeline = + container_of(sync, struct kk_sync_timeline, base); + *value = mtl_shared_event_get_signaled_value(timeline->mtl_handle); + return VK_SUCCESS; +} + +static VkResult +kk_timeline_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 kk_sync_timeline *timeline = + container_of(sync, struct kk_sync_timeline, base); + + /* abs_timeout_ns is the point in time when we should stop waiting, not the + * absolute time in ns. Therefore, we need to compute the delta from now to + * when we should stop waiting and convert to ms for Metal to be happy + * (Similar to what dzn does). + */ + uint64_t timeout_ms = 0u; + if (abs_timeout_ns == OS_TIMEOUT_INFINITE) { + timeout_ms = OS_TIMEOUT_INFINITE; + } else { + uint64_t cur_time = os_time_get_nano(); + uint64_t rel_timeout_ns = + abs_timeout_ns > cur_time ? abs_timeout_ns - cur_time : 0; + + timeout_ms = + (rel_timeout_ns / 1000000) + (rel_timeout_ns % 1000000 ? 1 : 0); + } + int completed = mtl_shared_event_wait_until_signaled_value( + timeline->mtl_handle, wait_value, timeout_ms); + + return completed != 0 ? VK_SUCCESS : VK_TIMEOUT; +} + +const struct vk_sync_type kk_sync_type = { + .size = sizeof(struct kk_sync_timeline), + .features = VK_SYNC_FEATURE_TIMELINE | VK_SYNC_FEATURE_GPU_WAIT | + VK_SYNC_FEATURE_CPU_WAIT | VK_SYNC_FEATURE_CPU_SIGNAL | + VK_SYNC_FEATURE_WAIT_PENDING | + VK_SYNC_FEATURE_WAIT_BEFORE_SIGNAL, + .init = kk_timeline_init, + .finish = kk_timeline_finish, + .signal = kk_timeline_signal, + .get_value = kk_timeline_get_value, + .reset = NULL, + .move = NULL, + .wait = kk_timeline_wait, + .wait_many = NULL, + .import_opaque_fd = NULL, + .export_opaque_fd = NULL, + .import_sync_file = NULL, + .export_sync_file = NULL, + .import_win32_handle = NULL, + .export_win32_handle = NULL, + .set_win32_export_params = NULL, +}; |