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:
committed by
Marge Bot
parent
b5045d6e42
commit
3c7e973d40
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user