vulkan: Add a vk_sync_signal_unwrap() helper

Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36827>
This commit is contained in:
Faith Ekstrand 2025-08-15 14:35:41 -04:00 committed by Marge Bot
parent 8cffa9a7fd
commit 379cffc3bb
3 changed files with 55 additions and 24 deletions

View file

@ -615,30 +615,13 @@ vk_queue_submit_final(struct vk_queue *queue,
submit->wait_count = wait_count;
for (uint32_t i = 0; i < submit->signal_count; i++) {
assert((submit->signals[i].sync->flags & VK_SYNC_IS_TIMELINE) ||
submit->signals[i].signal_value == 0);
struct vk_sync_timeline *timeline =
vk_sync_as_timeline(submit->signals[i].sync);
if (timeline) {
assert(queue->base.device->timeline_mode ==
VK_DEVICE_TIMELINE_MODE_EMULATED);
result = vk_sync_timeline_alloc_point(queue->base.device, timeline,
submit->signals[i].signal_value,
&submit->_signal_points[i]);
if (unlikely(result != VK_SUCCESS))
result = vk_queue_set_lost(queue, "Failed allocate time point");
submit->signals[i].sync = &submit->_signal_points[i]->sync;
submit->signals[i].signal_value = 0;
}
struct vk_sync_binary *binary =
vk_sync_as_binary(submit->signals[i].sync);
if (binary) {
submit->signals[i].sync = &binary->timeline;
submit->signals[i].signal_value = ++binary->next_point;
}
struct vk_sync_timeline_point *signal_point;
result = vk_sync_signal_unwrap(queue->base.device,
&submit->signals[i], &signal_point);
if (signal_point != NULL)
submit->_signal_points[i] = signal_point;
if (unlikely(result != VK_SUCCESS))
result = vk_queue_set_lost(queue, "Failed to unwrap sync signal");
}
result = queue->driver_submit(queue, submit);

View file

@ -626,3 +626,47 @@ vk_sync_wait_unwrap(struct vk_device *device,
return VK_SUCCESS;
}
/**
* Unwraps a vk_sync_signal, removing any vk_sync_timeline or vk_sync_binary
* and replacing the sync with the actual driver primitive.
*
* If the sync is a timeline, the point will be returned in point_out. This
* point must be installed in the timeline after the actual signal has been
* submitted to the kernel driver. Otherwise point_out will be set to NULL.
*/
VkResult
vk_sync_signal_unwrap(struct vk_device *device,
struct vk_sync_signal *signal,
struct vk_sync_timeline_point **point_out)
{
if (signal->sync->flags & VK_SYNC_IS_TIMELINE)
assert(signal->signal_value > 0);
else
assert(signal->signal_value == 0);
*point_out = NULL;
struct vk_sync_timeline *timeline = vk_sync_as_timeline(signal->sync);
if (timeline) {
assert(device->timeline_mode == VK_DEVICE_TIMELINE_MODE_EMULATED);
VkResult result = vk_sync_timeline_alloc_point(device, timeline,
signal->signal_value,
point_out);
if (unlikely(result != VK_SUCCESS))
return result;
signal->sync = &(*point_out)->sync;
signal->signal_value = 0;
}
struct vk_sync_binary *binary = vk_sync_as_binary(signal->sync);
if (binary) {
signal->sync = &binary->timeline;
signal->signal_value = ++binary->next_point;
}
assert(!vk_sync_type_is_dummy(signal->sync->type));
return VK_SUCCESS;
}

View file

@ -431,6 +431,10 @@ VkResult MUST_CHECK vk_sync_wait_unwrap(struct vk_device *device,
struct vk_sync_wait *wait,
struct vk_sync_timeline_point **point_out);
VkResult MUST_CHECK vk_sync_signal_unwrap(struct vk_device *device,
struct vk_sync_signal *signal,
struct vk_sync_timeline_point **point_out);
#ifdef __cplusplus
}
#endif