#include "vk_physical_device.h"
#include "vk_semaphore.h"
#include "vk_sync.h"
+#include "vk_sync_binary.h"
#include "vk_sync_timeline.h"
#include "vk_util.h"
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);
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_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;
+ }
}
result = queue->driver_submit(queue, submit);
--- /dev/null
+/*
+ * Copyright © 2021 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "vk_sync_binary.h"
+
+#include "vk_util.h"
+
+static struct vk_sync_binary *
+to_vk_sync_binary(struct vk_sync *sync)
+{
+ assert(sync->type->init == vk_sync_binary_init);
+
+ return container_of(sync, struct vk_sync_binary, sync);
+}
+
+VkResult
+vk_sync_binary_init(struct vk_device *device,
+ struct vk_sync *sync,
+ uint64_t initial_value)
+{
+ struct vk_sync_binary *binary = to_vk_sync_binary(sync);
+
+ const struct vk_sync_binary_type *btype =
+ container_of(binary->sync.type, struct vk_sync_binary_type, sync);
+
+ assert(!(sync->flags & VK_SYNC_IS_TIMELINE));
+ assert(!(sync->flags & VK_SYNC_IS_SHAREABLE));
+
+ binary->next_point = (initial_value == 0);
+
+ return vk_sync_init(device, &binary->timeline, btype->timeline_type,
+ VK_SYNC_IS_TIMELINE, 0 /* initial_value */);
+}
+
+static void
+vk_sync_binary_finish(struct vk_device *device,
+ struct vk_sync *sync)
+{
+ struct vk_sync_binary *binary = to_vk_sync_binary(sync);
+
+ vk_sync_finish(device, &binary->timeline);
+}
+
+static VkResult
+vk_sync_binary_reset(struct vk_device *device,
+ struct vk_sync *sync)
+{
+ struct vk_sync_binary *binary = to_vk_sync_binary(sync);
+
+ binary->next_point++;
+
+ return VK_SUCCESS;
+}
+
+static VkResult
+vk_sync_binary_signal(struct vk_device *device,
+ struct vk_sync *sync,
+ uint64_t value)
+{
+ struct vk_sync_binary *binary = to_vk_sync_binary(sync);
+
+ assert(value == 0);
+
+ return vk_sync_signal(device, &binary->timeline, binary->next_point);
+}
+
+static VkResult
+vk_sync_binary_wait_many(struct vk_device *device,
+ uint32_t wait_count,
+ const struct vk_sync_wait *waits,
+ enum vk_sync_wait_flags wait_flags,
+ uint64_t abs_timeout_ns)
+{
+ STACK_ARRAY(struct vk_sync_wait, timeline_waits, wait_count);
+
+ for (uint32_t i = 0; i < wait_count; i++) {
+ struct vk_sync_binary *binary = to_vk_sync_binary(waits[i].sync);
+
+ timeline_waits[i] = (struct vk_sync_wait) {
+ .sync = &binary->timeline,
+ .stage_mask = waits[i].stage_mask,
+ .wait_value = binary->next_point,
+ };
+ }
+
+ VkResult result = vk_sync_wait_many(device, wait_count, timeline_waits,
+ wait_flags, abs_timeout_ns);
+
+ STACK_ARRAY_FINISH(timeline_waits);
+
+ return result;
+}
+
+struct vk_sync_binary_type
+vk_sync_binary_get_type(const struct vk_sync_type *timeline_type)
+{
+ assert(timeline_type->features & VK_SYNC_FEATURE_TIMELINE);
+
+ return (struct vk_sync_binary_type) {
+ .sync = {
+ .size = offsetof(struct vk_sync_binary, timeline) +
+ timeline_type->size,
+ .features = VK_SYNC_FEATURE_BINARY |
+ VK_SYNC_FEATURE_GPU_WAIT |
+ VK_SYNC_FEATURE_CPU_WAIT |
+ VK_SYNC_FEATURE_CPU_RESET |
+ VK_SYNC_FEATURE_CPU_SIGNAL |
+ VK_SYNC_FEATURE_WAIT_ANY |
+ VK_SYNC_FEATURE_WAIT_PENDING,
+ .init = vk_sync_binary_init,
+ .finish = vk_sync_binary_finish,
+ .reset = vk_sync_binary_reset,
+ .signal = vk_sync_binary_signal,
+ .wait_many = vk_sync_binary_wait_many,
+ },
+ .timeline_type = timeline_type,
+ };
+}
--- /dev/null
+/*
+ * Copyright © 2021 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#ifndef VK_SYNC_BINARY_H
+#define VK_SYNC_BINARY_H
+
+#include "vk_sync.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct vk_sync_binary_type {
+ struct vk_sync_type sync;
+ const struct vk_sync_type *timeline_type;
+};
+
+struct vk_sync_binary_type
+vk_sync_binary_get_type(const struct vk_sync_type *timeline_type);
+
+/** Implements a binary vk_sync type on top of a timeline vk_sync
+ *
+ * This is useful when targeting Windows APIs such as D3D12 which only have
+ * timelines and have no concept of a binary synchronization object. Because
+ * binary vk_sync emulation requires tracking additional state (the next time
+ * point), fences and semaphores created from this type cannot support any of
+ * the sharing APIs.
+ */
+struct vk_sync_binary {
+ struct vk_sync sync;
+
+ uint64_t next_point;
+
+ struct vk_sync timeline;
+};
+
+VkResult vk_sync_binary_init(struct vk_device *device,
+ struct vk_sync *sync,
+ uint64_t initial_value);
+
+static inline bool
+vk_sync_type_is_vk_sync_binary(const struct vk_sync_type *type)
+{
+ return type->init == vk_sync_binary_init;
+}
+
+static inline struct vk_sync_binary *
+vk_sync_as_binary(struct vk_sync *sync)
+{
+ if (!vk_sync_type_is_vk_sync_binary(sync->type))
+ return NULL;
+
+ return container_of(sync, struct vk_sync_binary, sync);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VK_TIMELINE_H */