vulkan: Add a vk_sync_wait_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 13:57:44 -04:00
committed by Marge Bot
parent b5045d6e42
commit 3c7e973d40
3 changed files with 90 additions and 43 deletions
+12 -43
View File
@@ -604,55 +604,24 @@ vk_queue_submit_final(struct vk_queue *queue,
*/
uint32_t wait_count = 0;
for (uint32_t i = 0; i < submit->wait_count; i++) {
/* A timeline wait on 0 is always a no-op */
if ((submit->waits[i].sync->flags & VK_SYNC_IS_TIMELINE) &&
submit->waits[i].wait_value == 0)
continue;
struct vk_sync_timeline_point *wait_point;
result = vk_sync_wait_unwrap(queue->base.device,
&submit->waits[i], &wait_point);
if (wait_point != NULL)
submit->_wait_points[i] = wait_point;
if (unlikely(result != VK_SUCCESS))
result = vk_queue_set_lost(queue, "Failed to unwrap sync wait");
/* Waits on dummy vk_syncs are no-ops */
if (vk_sync_type_is_dummy(submit->waits[i].sync->type)) {
if (submit->waits[i].sync == NULL) {
/* We are about to lose track of this wait, if it has a temporary
* we need to destroy it now, as vk_queue_submit_cleanup will not
* know about it */
if (submit->_wait_temps[i] != NULL) {
* or a wait point, we need to destroy it now, as
* vk_queue_submit_cleanup will not know about it
*/
if (submit->_wait_temps[i] != NULL)
vk_sync_destroy(queue->base.device, submit->_wait_temps[i]);
submit->waits[i].sync = NULL;
}
continue;
}
/* For emulated timelines, we have a binary vk_sync associated with
* each time point and pass the binary vk_sync to the driver.
*/
struct vk_sync_timeline *timeline =
vk_sync_as_timeline(submit->waits[i].sync);
if (timeline) {
assert(queue->base.device->timeline_mode ==
VK_DEVICE_TIMELINE_MODE_EMULATED);
result = vk_sync_timeline_get_point(queue->base.device, timeline,
submit->waits[i].wait_value,
&submit->_wait_points[i]);
if (unlikely(result != VK_SUCCESS)) {
result = vk_queue_set_lost(queue,
"Time point >= %"PRIu64" not found",
submit->waits[i].wait_value);
}
/* This can happen if the point is long past */
if (submit->_wait_points[i] == NULL)
continue;
submit->waits[i].sync = &submit->_wait_points[i]->sync;
submit->waits[i].wait_value = 0;
}
struct vk_sync_binary *binary =
vk_sync_as_binary(submit->waits[i].sync);
if (binary) {
submit->waits[i].sync = &binary->timeline;
submit->waits[i].wait_value = binary->next_point;
}
assert((submit->waits[i].sync->flags & VK_SYNC_IS_TIMELINE) ||
submit->waits[i].wait_value == 0);
+72
View File
@@ -34,6 +34,9 @@
#include "vk_device.h"
#include "vk_log.h"
#include "vk_physical_device.h"
#include "vk_sync_binary.h"
#include "vk_sync_dummy.h"
#include "vk_sync_timeline.h"
static void
vk_sync_type_validate(const struct vk_sync_type *type)
@@ -554,3 +557,72 @@ vk_sync_set_win32_export_params(struct vk_device *device,
return sync->type->set_win32_export_params(device, sync, security_attributes, access, name);
}
/**
* Unwraps a vk_sync_wait, removing any vk_sync_timeline or vk_sync_binary
* and replacing the sync with the actual driver primitive.
*
* After this is returns, wait->sync may be NULL, indicating no actual wait
* is needed and this wait can be discarded.
*
* If the sync is a timeline, the point will be returned in point_out.
* Otherwise point_out will be set to NULL.
*/
VkResult
vk_sync_wait_unwrap(struct vk_device *device,
struct vk_sync_wait *wait,
struct vk_sync_timeline_point **point_out)
{
*point_out = NULL;
if (wait->sync->flags & VK_SYNC_IS_TIMELINE) {
if (wait->wait_value == 0) {
*wait = (struct vk_sync_wait) { .sync = NULL };
return VK_SUCCESS;
}
} else {
assert(wait->wait_value == 0);
}
struct vk_sync_timeline *timeline = vk_sync_as_timeline(wait->sync);
if (timeline) {
assert(device->timeline_mode == VK_DEVICE_TIMELINE_MODE_EMULATED);
VkResult result = vk_sync_timeline_get_point(device, timeline,
wait->wait_value,
point_out);
if (unlikely(result != VK_SUCCESS)) {
/* vk_sync_timeline_get_point() returns VK_NOT_READY if no time
* point can be found. Turn that into an actual error.
*/
return vk_errorf(device, VK_ERROR_UNKNOWN,
"Time point >= %"PRIu64" not found",
wait->wait_value);
}
/* This can happen if the point is long past */
if (*point_out == NULL) {
*wait = (struct vk_sync_wait) { .sync = NULL };
return VK_SUCCESS;
}
wait->sync = &(*point_out)->sync;
wait->wait_value = 0;
}
struct vk_sync_binary *binary = vk_sync_as_binary(wait->sync);
if (binary) {
wait->sync = &binary->timeline;
wait->wait_value = binary->next_point;
}
if (vk_sync_type_is_dummy(wait->sync->type)) {
if (*point_out != NULL) {
vk_sync_timeline_point_unref(device, *point_out);
*point_out = NULL;
}
*wait = (struct vk_sync_wait) { .sync = NULL };
return VK_SUCCESS;
}
return VK_SUCCESS;
}
+6
View File
@@ -425,6 +425,12 @@ VkResult MUST_CHECK vk_sync_move(struct vk_device *device,
struct vk_sync *dst,
struct vk_sync *src);
struct vk_sync_timeline_point;
VkResult MUST_CHECK vk_sync_wait_unwrap(struct vk_device *device,
struct vk_sync_wait *wait,
struct vk_sync_timeline_point **point_out);
#ifdef __cplusplus
}
#endif