Monado OpenXR Runtime
vk_submit_helpers.h
Go to the documentation of this file.
1// Copyright 2026, NVIDIA CORPORATION.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Helper utilities for Vulkan queue submission with mixed binary and timeline semaphores.
6 * @author Jakob Bornecrantz <tbornecrantz@nvidia.com>
7 * @ingroup aux_vk
8 *
9 * ## Usage Example
10 *
11 * @code{.c}
12 * // Initialize semaphore lists
13 * struct vk_semaphore_list_wait wait_sems = XRT_STRUCT_INIT;
14 * struct vk_semaphore_list_signal signal_sems = XRT_STRUCT_INIT;
15 *
16 * // Add semaphores (mix of binary and timeline)
17 * if (present_complete != VK_NULL_HANDLE) {
18 * vk_semaphore_list_wait_add_binary(&wait_sems, present_complete, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
19 * }
20 * vk_semaphore_list_signal_add_timeline(&signal_sems, render_complete, frame_id);
21 *
22 * // Prepare submit info
23 * struct vk_submit_info_builder builder;
24 * vk_submit_info_builder_prepare(&builder, &wait_sems, &cmd, 1, &signal_sems, NULL);
25 *
26 * // Submit to queue
27 * ret = vk->vkQueueSubmit(queue, 1, &builder.submit_info, fence);
28 * @endcode
29 */
30
31#pragma once
32
33#include "util/u_logging.h"
34#include "vk/vk_helpers.h"
35
36#include <assert.h>
37
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43
44/*!
45 * Maximum number of semaphores that can be accumulated in semaphore
46 * lists. Should be enough for typical compositor use cases.
47 */
48#define VK_SEMAPHORE_LIST_MAX_COUNT 4
49
50
51/*!
52 * Accumulator for wait semaphores to be used in VkSubmitInfo.
53 * Handles both binary and timeline semaphores, tracking their handles,
54 * values, and pipeline stage flags.
55 *
56 * Must be zero-initialized using XRT_STRUCT_INIT before use.
57 *
58 * @ingroup aux_vk
59 */
61{
62 //! Array of semaphore handles
64
65 //! Array of semaphore values (0 for binary, value for timeline)
67
68 //! Array of pipeline stage flags for each semaphore
69 VkPipelineStageFlags stages[VK_SEMAPHORE_LIST_MAX_COUNT];
70
71 //! Number of semaphores currently in the list
72 uint32_t count;
73};
74
75/*!
76 * Accumulator for signal semaphores to be used in VkSubmitInfo.
77 * Handles both binary and timeline semaphores, tracking their handles
78 * and values.
79 *
80 * Must be zero-initialized using XRT_STRUCT_INIT before use.
81 *
82 * @ingroup aux_vk
83 */
85{
86 //! Array of semaphore handles
88
89 //! Array of semaphore values (0 for binary, value for timeline)
91
92 //! Number of semaphores currently in the list
93 uint32_t count;
94};
95
96/*!
97 * Builder for VkSubmitInfo with optional timeline semaphore support.
98 * Simplifies creation of submit infos with mixed binary and timeline
99 * semaphores.
100 *
101 * @ingroup aux_vk
102 */
104{
105 //! The main submit info structure
106 VkSubmitInfo submit_info;
107
108#ifdef VK_KHR_timeline_semaphore
109 //! Timeline semaphore info (chained to submit_info if needed)
110 VkTimelineSemaphoreSubmitInfoKHR timeline_info;
111#endif
112};
113
114/*!
115 * Add a binary wait semaphore to the list.
116 * The value will be set to 0 (ignored for binary semaphores).
117 *
118 * @param list Wait semaphore list to add to
119 * @param semaphore Binary semaphore (must not be VK_NULL_HANDLE)
120 * @param stage Pipeline stage to wait at
121 *
122 * @ingroup aux_vk
123 */
124static inline void
126 VkSemaphore semaphore,
127 VkPipelineStageFlags stage)
128{
129 assert(semaphore != VK_NULL_HANDLE);
130 assert(list->count < VK_SEMAPHORE_LIST_MAX_COUNT);
131
132 if (list->count >= VK_SEMAPHORE_LIST_MAX_COUNT) {
133 U_LOG_E("vk_semaphore_list_wait_add_binary: list is full");
134 return;
135 }
136
137 list->semaphores[list->count] = semaphore;
138 list->values[list->count] = 0; // Ignored for binary
139 list->stages[list->count] = stage;
140 list->count++;
141}
142
143/*!
144 * Add a timeline wait semaphore to the list with a specific value.
145 *
146 * @param list Wait semaphore list to add to
147 * @param semaphore Timeline semaphore (must not be VK_NULL_HANDLE)
148 * @param value Timeline value to wait for
149 * @param stage Pipeline stage to wait at
150 *
151 * @ingroup aux_vk
152 */
153static inline void
155 VkSemaphore semaphore,
156 uint64_t value,
157 VkPipelineStageFlags stage)
158{
159 assert(semaphore != VK_NULL_HANDLE);
160 assert(list->count < VK_SEMAPHORE_LIST_MAX_COUNT);
161
162 if (list->count >= VK_SEMAPHORE_LIST_MAX_COUNT) {
163 U_LOG_E("vk_semaphore_list_wait_add_timeline: list is full");
164 return;
165 }
166
167 list->semaphores[list->count] = semaphore;
168 list->values[list->count] = value;
169 list->stages[list->count] = stage;
170 list->count++;
171}
172
173/*!
174 * Add a binary signal semaphore to the list.
175 * The value will be set to 0 (ignored for binary semaphores).
176 *
177 * @param list Signal semaphore list to add to
178 * @param semaphore Binary semaphore (must not be VK_NULL_HANDLE)
179 *
180 * @ingroup aux_vk
181 */
182static inline void
184{
185 assert(semaphore != VK_NULL_HANDLE);
186 assert(list->count < VK_SEMAPHORE_LIST_MAX_COUNT);
187
188 if (list->count >= VK_SEMAPHORE_LIST_MAX_COUNT) {
189 U_LOG_E("vk_semaphore_list_signal_add_binary: list is full");
190 return;
191 }
192
193 list->semaphores[list->count] = semaphore;
194 list->values[list->count] = 0; // Ignored for binary
195 list->count++;
196}
197
198/*!
199 * Add a timeline signal semaphore to the list with a specific value.
200 *
201 * @param list Signal semaphore list to add to
202 * @param semaphore Timeline semaphore (must not be VK_NULL_HANDLE)
203 * @param value Timeline value to signal
204 *
205 * @ingroup aux_vk
206 */
207static inline void
208vk_semaphore_list_signal_add_timeline(struct vk_semaphore_list_signal *list, VkSemaphore semaphore, uint64_t value)
209{
210 assert(semaphore != VK_NULL_HANDLE);
211 assert(list->count < VK_SEMAPHORE_LIST_MAX_COUNT);
212
213 if (list->count >= VK_SEMAPHORE_LIST_MAX_COUNT) {
214 U_LOG_E("vk_semaphore_list_signal_add_timeline: list is full");
215 return;
216 }
217
218 list->semaphores[list->count] = semaphore;
219 list->values[list->count] = value;
220 list->count++;
221}
222
223/*!
224 * Prepare a VkSubmitInfo from wait and signal semaphore lists.
225 * Automatically sets up VkTimelineSemaphoreSubmitInfoKHR if any
226 * timeline semaphores are present.
227 *
228 * @param builder Submit info builder to initialize
229 * @param wait_semaphores List of wait semaphores (can be NULL)
230 * @param command_buffers Array of command buffers to execute
231 * @param command_buffer_count Number of command buffers
232 * @param signal_semaphores List of signal semaphores (can be NULL)
233 * @param next Optional pNext chain to prepend to
234 * (builder will add timeline info if
235 * needed)
236 *
237 * @ingroup aux_vk
238 */
239void
241 const struct vk_semaphore_list_wait *wait_semaphores,
242 const VkCommandBuffer *command_buffers,
243 uint32_t command_buffer_count,
244 const struct vk_semaphore_list_signal *signal_semaphores,
245 const void *next);
246
247
248#ifdef __cplusplus
249}
250#endif
#define U_LOG_E(...)
Log a message at U_LOGGING_ERROR level, conditional on the global log level.
Definition: u_logging.h:442
void vk_submit_info_builder_prepare(struct vk_submit_info_builder *builder, const struct vk_semaphore_list_wait *wait_semaphores, const VkCommandBuffer *command_buffers, uint32_t command_buffer_count, const struct vk_semaphore_list_signal *signal_semaphores, const void *next)
Prepare a VkSubmitInfo from wait and signal semaphore lists.
Definition: vk_submit_helpers.c:15
static void vk_semaphore_list_signal_add_timeline(struct vk_semaphore_list_signal *list, VkSemaphore semaphore, uint64_t value)
Add a timeline signal semaphore to the list with a specific value.
Definition: vk_submit_helpers.h:208
static void vk_semaphore_list_wait_add_timeline(struct vk_semaphore_list_wait *list, VkSemaphore semaphore, uint64_t value, VkPipelineStageFlags stage)
Add a timeline wait semaphore to the list with a specific value.
Definition: vk_submit_helpers.h:154
static void vk_semaphore_list_wait_add_binary(struct vk_semaphore_list_wait *list, VkSemaphore semaphore, VkPipelineStageFlags stage)
Add a binary wait semaphore to the list.
Definition: vk_submit_helpers.h:125
static void vk_semaphore_list_signal_add_binary(struct vk_semaphore_list_signal *list, VkSemaphore semaphore)
Add a binary signal semaphore to the list.
Definition: vk_submit_helpers.h:183
Accumulator for signal semaphores to be used in VkSubmitInfo.
Definition: vk_submit_helpers.h:85
uint32_t count
Number of semaphores currently in the list.
Definition: vk_submit_helpers.h:93
uint64_t values[4]
Array of semaphore values (0 for binary, value for timeline)
Definition: vk_submit_helpers.h:90
VkSemaphore semaphores[4]
Array of semaphore handles.
Definition: vk_submit_helpers.h:87
Accumulator for wait semaphores to be used in VkSubmitInfo.
Definition: vk_submit_helpers.h:61
uint64_t values[4]
Array of semaphore values (0 for binary, value for timeline)
Definition: vk_submit_helpers.h:66
VkSemaphore semaphores[4]
Array of semaphore handles.
Definition: vk_submit_helpers.h:63
uint32_t count
Number of semaphores currently in the list.
Definition: vk_submit_helpers.h:72
VkPipelineStageFlags stages[4]
Array of pipeline stage flags for each semaphore.
Definition: vk_submit_helpers.h:69
Builder for VkSubmitInfo with optional timeline semaphore support.
Definition: vk_submit_helpers.h:104
VkSubmitInfo submit_info
The main submit info structure.
Definition: vk_submit_helpers.h:106
Basic logging functionality.
Common Vulkan code header.
#define VK_SEMAPHORE_LIST_MAX_COUNT
Maximum number of semaphores that can be accumulated in semaphore lists.
Definition: vk_submit_helpers.h:48