git subrepo pull --force deps/lightrec
[pcsx_rearmed.git] / deps / libretro-common / include / libretro_vulkan.h
CommitLineData
3719602c
PC
1/* Copyright (C) 2010-2020 The RetroArch team
2 *
3 * ---------------------------------------------------------------------------------------------
4 * The following license statement only applies to this libretro API header (libretro_vulkan.h)
5 * ---------------------------------------------------------------------------------------------
6 *
7 * Permission is hereby granted, free of charge,
8 * to any person obtaining a copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation the rights to
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef LIBRETRO_VULKAN_H__
24#define LIBRETRO_VULKAN_H__
25
26#include <libretro.h>
27#include <vulkan/vulkan.h>
28
29#define RETRO_HW_RENDER_INTERFACE_VULKAN_VERSION 5
30#define RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION 2
31
32struct retro_vulkan_image
33{
34 VkImageView image_view;
35 VkImageLayout image_layout;
36 VkImageViewCreateInfo create_info;
37};
38
39typedef void (*retro_vulkan_set_image_t)(void *handle,
40 const struct retro_vulkan_image *image,
41 uint32_t num_semaphores,
42 const VkSemaphore *semaphores,
43 uint32_t src_queue_family);
44
45typedef uint32_t (*retro_vulkan_get_sync_index_t)(void *handle);
46typedef uint32_t (*retro_vulkan_get_sync_index_mask_t)(void *handle);
47typedef void (*retro_vulkan_set_command_buffers_t)(void *handle,
48 uint32_t num_cmd,
49 const VkCommandBuffer *cmd);
50typedef void (*retro_vulkan_wait_sync_index_t)(void *handle);
51typedef void (*retro_vulkan_lock_queue_t)(void *handle);
52typedef void (*retro_vulkan_unlock_queue_t)(void *handle);
53typedef void (*retro_vulkan_set_signal_semaphore_t)(void *handle, VkSemaphore semaphore);
54
55typedef const VkApplicationInfo *(*retro_vulkan_get_application_info_t)(void);
56
57struct retro_vulkan_context
58{
59 VkPhysicalDevice gpu;
60 VkDevice device;
61 VkQueue queue;
62 uint32_t queue_family_index;
63 VkQueue presentation_queue;
64 uint32_t presentation_queue_family_index;
65};
66
67/* This is only used in v1 of the negotiation interface.
68 * It is deprecated since it cannot express PDF2 features or optional extensions. */
69typedef bool (*retro_vulkan_create_device_t)(
70 struct retro_vulkan_context *context,
71 VkInstance instance,
72 VkPhysicalDevice gpu,
73 VkSurfaceKHR surface,
74 PFN_vkGetInstanceProcAddr get_instance_proc_addr,
75 const char **required_device_extensions,
76 unsigned num_required_device_extensions,
77 const char **required_device_layers,
78 unsigned num_required_device_layers,
79 const VkPhysicalDeviceFeatures *required_features);
80
81typedef void (*retro_vulkan_destroy_device_t)(void);
82
83/* v2 CONTEXT_NEGOTIATION_INTERFACE only. */
84typedef VkInstance (*retro_vulkan_create_instance_wrapper_t)(
85 void *opaque, const VkInstanceCreateInfo *create_info);
86
87/* v2 CONTEXT_NEGOTIATION_INTERFACE only. */
88typedef VkInstance (*retro_vulkan_create_instance_t)(
89 PFN_vkGetInstanceProcAddr get_instance_proc_addr,
90 const VkApplicationInfo *app,
91 retro_vulkan_create_instance_wrapper_t create_instance_wrapper,
92 void *opaque);
93
94/* v2 CONTEXT_NEGOTIATION_INTERFACE only. */
95typedef VkDevice (*retro_vulkan_create_device_wrapper_t)(
96 VkPhysicalDevice gpu, void *opaque,
97 const VkDeviceCreateInfo *create_info);
98
99/* v2 CONTEXT_NEGOTIATION_INTERFACE only. */
100typedef bool (*retro_vulkan_create_device2_t)(
101 struct retro_vulkan_context *context,
102 VkInstance instance,
103 VkPhysicalDevice gpu,
104 VkSurfaceKHR surface,
105 PFN_vkGetInstanceProcAddr get_instance_proc_addr,
106 retro_vulkan_create_device_wrapper_t create_device_wrapper,
107 void *opaque);
108
109/* Note on thread safety:
110 * The Vulkan API is heavily designed around multi-threading, and
111 * the libretro interface for it should also be threading friendly.
112 * A core should be able to build command buffers and submit
113 * command buffers to the GPU from any thread.
114 */
115
116struct retro_hw_render_context_negotiation_interface_vulkan
117{
118 /* Must be set to RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN. */
119 enum retro_hw_render_context_negotiation_interface_type interface_type;
120 /* Usually set to RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION,
121 * but can be lower depending on GET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_SUPPORT. */
122 unsigned interface_version;
123
124 /* If non-NULL, returns a VkApplicationInfo struct that the frontend can use instead of
125 * its "default" application info.
126 * VkApplicationInfo::apiVersion also controls the target core Vulkan version for instance level functionality.
127 * Lifetime of the returned pointer must remain until the retro_vulkan_context is initialized.
128 *
129 * NOTE: For optimal compatibility with e.g. Android which is very slow to update its loader,
130 * a core version of 1.1 should be requested. Features beyond that can be requested with extensions.
131 * Vulkan 1.0 is only appropriate for legacy cores, but is still supported.
132 * A frontend is free to bump the instance creation apiVersion as necessary if the frontend requires more advanced core features.
133 *
134 * v2: This function must not be NULL, and must not return NULL.
135 * v1: It was not clearly defined if this function could return NULL.
136 * Frontends should be defensive and provide a default VkApplicationInfo
137 * if this function returns NULL or if this function is NULL.
138 */
139 retro_vulkan_get_application_info_t get_application_info;
140
141 /* If non-NULL, the libretro core will choose one or more physical devices,
142 * create one or more logical devices and create one or more queues.
143 * The core must prepare a designated PhysicalDevice, Device, Queue and queue family index
144 * which the frontend will use for its internal operation.
145 *
146 * If gpu is not VK_NULL_HANDLE, the physical device provided to the frontend must be this PhysicalDevice if the call succeeds.
147 * The core is still free to use other physical devices for other purposes that are private to the core.
148 *
149 * The frontend will request certain extensions and layers for a device which is created.
150 * The core must ensure that the queue and queue_family_index support GRAPHICS and COMPUTE.
151 *
152 * If surface is not VK_NULL_HANDLE, the core must consider presentation when creating the queues.
153 * If presentation to "surface" is supported on the queue, presentation_queue must be equal to queue.
154 * If not, a second queue must be provided in presentation_queue and presentation_queue_index.
155 * If surface is not VK_NULL_HANDLE, the instance from frontend will have been created with supported for
156 * VK_KHR_surface extension.
157 *
158 * The core is free to set its own queue priorities.
159 * Device provided to frontend is owned by the frontend, but any additional device resources must be freed by core
160 * in destroy_device callback.
161 *
162 * If this function returns true, a PhysicalDevice, Device and Queues are initialized.
163 * If false, none of the above have been initialized and the frontend will attempt
164 * to fallback to "default" device creation, as if this function was never called.
165 */
166 retro_vulkan_create_device_t create_device;
167
168 /* If non-NULL, this callback is called similar to context_destroy for HW_RENDER_INTERFACE.
169 * However, it will be called even if context_reset was not called.
170 * This can happen if the context never succeeds in being created.
171 * destroy_device will always be called before the VkInstance
172 * of the frontend is destroyed if create_device was called successfully so that the core has a chance of
173 * tearing down its own device resources.
174 *
175 * Only auxillary resources should be freed here, i.e. resources which are not part of retro_vulkan_context.
176 * v2: Auxillary instance resources created during create_instance can also be freed here.
177 */
178 retro_vulkan_destroy_device_t destroy_device;
179
180 /* v2 API: If interface_version is < 2, fields below must be ignored.
181 * If the frontend does not support interface version 2, the v1 entry points will be used instead. */
182
183 /* If non-NULL, this is called to create an instance, otherwise a VkInstance is created by the frontend.
184 * v1 interface bug: The only way to enable instance features is through core versions signalled in VkApplicationInfo.
185 * The frontend may request that certain extensions and layers
186 * are enabled on the VkInstance. Application may add additional features.
187 * If app is non-NULL, apiVersion controls the minimum core version required by the application.
188 * Return a VkInstance or VK_NULL_HANDLE. The VkInstance is owned by the frontend.
189 *
190 * Rather than call vkCreateInstance directly, a core must call the CreateInstance wrapper provided with:
191 * VkInstance instance = create_instance_wrapper(opaque, &create_info);
192 * If the core wishes to create a private instance for whatever reason (relying on shared memory for example),
193 * it may call vkCreateInstance directly. */
194 retro_vulkan_create_instance_t create_instance;
195
196 /* If non-NULL and frontend recognizes negotiation interface >= 2, create_device2 takes precedence over create_device.
197 * Similar to create_device, but is extended to better understand new core versions and PDF2 feature enablement.
198 * Requirements for create_device2 are the same as create_device unless a difference is mentioned.
199 *
200 * v2 consideration:
201 * If the chosen gpu by frontend cannot be supported, a core must return false.
202 *
203 * NOTE: "Cannot be supported" is intentionally vaguely defined.
204 * Refusing to run on an iGPU for a very intensive core with desktop GPU as a minimum spec may be in the gray area.
205 * Not supporting optional features is not a good reason to reject a physical device, however.
206 *
207 * On device creation feature with explicit gpu, a frontend should fall back create_device2 with gpu == VK_NULL_HANDLE and let core
208 * decide on a supported device if possible.
209 *
210 * A core must assume that the explicitly provided GPU is the only guaranteed attempt it has to create a device.
211 * A fallback may not be attempted if there are particular reasons why only a specific physical device can work,
212 * but these situations should be esoteric and rare in nature, e.g. a libretro frontend is implemented with external memory
213 * and only LUID matching would work.
214 * Cores and frontends should ensure "best effort" when negotiating like this and appropriate logging is encouraged.
215 *
216 * v1 note: In the v1 version of create_device, it was never expected that create_device would fail like this,
217 * and frontends are not expected to attempt fall backs.
218 *
219 * Rather than call vkCreateDevice directly, a core must call the CreateDevice wrapper provided with:
220 * VkDevice device = create_device_wrapper(gpu, opaque, &create_info);
221 * If the core wishes to create a private device for whatever reason (relying on shared memory for example),
222 * it may call vkCreateDevice directly.
223 *
224 * This allows the frontend to add additional extensions that it requires as well as adjust the PDF2 pNext as required.
225 * It is also possible adjust the queue create infos in case the frontend desires to allocate some private queues.
226 *
227 * The get_instance_proc_addr provided in create_device2 must be the same as create_instance.
228 *
229 * NOTE: The frontend must not disable features requested by application.
230 * NOTE: The frontend must not add any robustness features as some API behavior may change (VK_EXT_descriptor_buffer comes to mind).
231 * I.e. robustBufferAccess and the like. (nullDescriptor from robustness2 is allowed to be enabled).
232 */
233 retro_vulkan_create_device2_t create_device2;
234};
235
236struct retro_hw_render_interface_vulkan
237{
238 /* Must be set to RETRO_HW_RENDER_INTERFACE_VULKAN. */
239 enum retro_hw_render_interface_type interface_type;
240 /* Must be set to RETRO_HW_RENDER_INTERFACE_VULKAN_VERSION. */
241 unsigned interface_version;
242
243 /* Opaque handle to the Vulkan backend in the frontend
244 * which must be passed along to all function pointers
245 * in this interface.
246 *
247 * The rationale for including a handle here (which libretro v1
248 * doesn't currently do in general) is:
249 *
250 * - Vulkan cores should be able to be freely threaded without lots of fuzz.
251 * This would break frontends which currently rely on TLS
252 * to deal with multiple cores loaded at the same time.
253 * - Fixing this in general is TODO for an eventual libretro v2.
254 */
255 void *handle;
256
257 /* The Vulkan instance the context is using. */
258 VkInstance instance;
259 /* The physical device used. */
260 VkPhysicalDevice gpu;
261 /* The logical device used. */
262 VkDevice device;
263
264 /* Allows a core to fetch all its needed symbols without having to link
265 * against the loader itself. */
266 PFN_vkGetDeviceProcAddr get_device_proc_addr;
267 PFN_vkGetInstanceProcAddr get_instance_proc_addr;
268
269 /* The queue the core must use to submit data.
270 * This queue and index must remain constant throughout the lifetime
271 * of the context.
272 *
273 * This queue will be the queue that supports graphics and compute
274 * if the device supports compute.
275 */
276 VkQueue queue;
277 unsigned queue_index;
278
279 /* Before calling retro_video_refresh_t with RETRO_HW_FRAME_BUFFER_VALID,
280 * set which image to use for this frame.
281 *
282 * If num_semaphores is non-zero, the frontend will wait for the
283 * semaphores provided to be signaled before using the results further
284 * in the pipeline.
285 *
286 * Semaphores provided by a single call to set_image will only be
287 * waited for once (waiting for a semaphore resets it).
288 * E.g. set_image, video_refresh, and then another
289 * video_refresh without set_image,
290 * but same image will only wait for semaphores once.
291 *
292 * For this reason, ownership transfer will only occur if semaphores
293 * are waited on for a particular frame in the frontend.
294 *
295 * Using semaphores is optional for synchronization purposes,
296 * but if not using
297 * semaphores, an image memory barrier in vkCmdPipelineBarrier
298 * should be used in the graphics_queue.
299 * Example:
300 *
301 * vkCmdPipelineBarrier(cmd,
302 * srcStageMask = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
303 * dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
304 * image_memory_barrier = {
305 * srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
306 * dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
307 * });
308 *
309 * The use of pipeline barriers instead of semaphores is encouraged
310 * as it is simpler and more fine-grained. A layout transition
311 * must generally happen anyways which requires a
312 * pipeline barrier.
313 *
314 * The image passed to set_image must have imageUsage flags set to at least
315 * VK_IMAGE_USAGE_TRANSFER_SRC_BIT and VK_IMAGE_USAGE_SAMPLED_BIT.
316 * The core will naturally want to use flags such as
317 * VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT and/or
318 * VK_IMAGE_USAGE_TRANSFER_DST_BIT depending
319 * on how the final image is created.
320 *
321 * The image must also have been created with MUTABLE_FORMAT bit set if
322 * 8-bit formats are used, so that the frontend can reinterpret sRGB
323 * formats as it sees fit.
324 *
325 * Images passed to set_image should be created with TILING_OPTIMAL.
326 * The image layout should be transitioned to either
327 * VK_IMAGE_LAYOUT_GENERIC or VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.
328 * The actual image layout used must be set in image_layout.
329 *
330 * The image must be a 2D texture which may or not be layered
331 * and/or mipmapped.
332 *
333 * The image must be suitable for linear sampling.
334 * While the image_view is typically the only field used,
335 * the frontend may want to reinterpret the texture as sRGB vs.
336 * non-sRGB for example so the VkImageViewCreateInfo used to
337 * create the image view must also be passed in.
338 *
339 * The data in the pointer to the image struct will not be copied
340 * as the pNext field in create_info cannot be reliably deep-copied.
341 * The image pointer passed to set_image must be valid until
342 * retro_video_refresh_t has returned.
343 *
344 * If frame duping is used when passing NULL to retro_video_refresh_t,
345 * the frontend is free to either use the latest image passed to
346 * set_image or reuse the older pointer passed to set_image the
347 * frame RETRO_HW_FRAME_BUFFER_VALID was last used.
348 *
349 * Essentially, the lifetime of the pointer passed to
350 * retro_video_refresh_t should be extended if frame duping is used
351 * so that the frontend can reuse the older pointer.
352 *
353 * The image itself however, must not be touched by the core until
354 * wait_sync_index has been completed later. The frontend may perform
355 * layout transitions on the image, so even read-only access is not defined.
356 * The exception to read-only rule is if GENERAL layout is used for the image.
357 * In this case, the frontend is not allowed to perform any layout transitions,
358 * so concurrent reads from core and frontend are allowed.
359 *
360 * If frame duping is used, or if set_command_buffers is used,
361 * the frontend will not wait for any semaphores.
362 *
363 * The src_queue_family is used to specify which queue family
364 * the image is currently owned by. If using multiple queue families
365 * (e.g. async compute), the frontend will need to acquire ownership of the
366 * image before rendering with it and release the image afterwards.
367 *
368 * If src_queue_family is equal to the queue family (queue_index),
369 * no ownership transfer will occur.
370 * Similarly, if src_queue_family is VK_QUEUE_FAMILY_IGNORED,
371 * no ownership transfer will occur.
372 *
373 * The frontend will always release ownership back to src_queue_family.
374 * Waiting for frontend to complete with wait_sync_index() ensures that
375 * the frontend has released ownership back to the application.
376 * Note that in Vulkan, transfering ownership is a two-part process.
377 *
378 * Example frame:
379 * - core releases ownership from src_queue_index to queue_index with VkImageMemoryBarrier.
380 * - core calls set_image with src_queue_index.
381 * - Frontend will acquire the image with src_queue_index -> queue_index as well, completing the ownership transfer.
382 * - Frontend renders the frame.
383 * - Frontend releases ownership with queue_index -> src_queue_index.
384 * - Next time image is used, core must acquire ownership from queue_index ...
385 *
386 * Since the frontend releases ownership, we cannot necessarily dupe the frame because
387 * the core needs to make the roundtrip of ownership transfer.
388 */
389 retro_vulkan_set_image_t set_image;
390
391 /* Get the current sync index for this frame which is obtained in
392 * frontend by calling e.g. vkAcquireNextImageKHR before calling
393 * retro_run().
394 *
395 * This index will correspond to which swapchain buffer is currently
396 * the active one.
397 *
398 * Knowing this index is very useful for maintaining safe asynchronous CPU
399 * and GPU operation without stalling.
400 *
401 * The common pattern for synchronization is to receive fences when
402 * submitting command buffers to Vulkan (vkQueueSubmit) and add this fence
403 * to a list of fences for frame number get_sync_index().
404 *
405 * Next time we receive the same get_sync_index(), we can wait for the
406 * fences from before, which will usually return immediately as the
407 * frontend will generally also avoid letting the GPU run ahead too much.
408 *
409 * After the fence has signaled, we know that the GPU has completed all
410 * GPU work related to work submitted in the frame we last saw get_sync_index().
411 *
412 * This means we can safely reuse or free resources allocated in this frame.
413 *
414 * In theory, even if we wait for the fences correctly, it is not technically
415 * safe to write to the image we earlier passed to the frontend since we're
416 * not waiting for the frontend GPU jobs to complete.
417 *
418 * The frontend will guarantee that the appropriate pipeline barrier
419 * in graphics_queue has been used such that
420 * VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT cannot
421 * start until the frontend is done with the image.
422 */
423 retro_vulkan_get_sync_index_t get_sync_index;
424
425 /* Returns a bitmask of how many swapchain images we currently have
426 * in the frontend.
427 *
428 * If bit #N is set in the return value, get_sync_index can return N.
429 * Knowing this value is useful for preallocating per-frame management
430 * structures ahead of time.
431 *
432 * While this value will typically remain constant throughout the
433 * applications lifecycle, it may for example change if the frontend
434 * suddently changes fullscreen state and/or latency.
435 *
436 * If this value ever changes, it is safe to assume that the device
437 * is completely idle and all synchronization objects can be deleted
438 * right away as desired.
439 */
440 retro_vulkan_get_sync_index_mask_t get_sync_index_mask;
441
442 /* Instead of submitting the command buffer to the queue first, the core
443 * can pass along its command buffer to the frontend, and the frontend
444 * will submit the command buffer together with the frontends command buffers.
445 *
446 * This has the advantage that the overhead of vkQueueSubmit can be
447 * amortized into a single call. For this mode, semaphores in set_image
448 * will be ignored, so vkCmdPipelineBarrier must be used to synchronize
449 * the core and frontend.
450 *
451 * The command buffers in set_command_buffers are only executed once,
452 * even if frame duping is used.
453 *
454 * If frame duping is used, set_image should be used for the frames
455 * which should be duped instead.
456 *
457 * Command buffers passed to the frontend with set_command_buffers
458 * must not actually be submitted to the GPU until retro_video_refresh_t
459 * is called.
460 *
461 * The frontend must submit the command buffer before submitting any
462 * other command buffers provided by set_command_buffers. */
463 retro_vulkan_set_command_buffers_t set_command_buffers;
464
465 /* Waits on CPU for device activity for the current sync index to complete.
466 * This is useful since the core will not have a relevant fence to sync with
467 * when the frontend is submitting the command buffers. */
468 retro_vulkan_wait_sync_index_t wait_sync_index;
469
470 /* If the core submits command buffers itself to any of the queues provided
471 * in this interface, the core must lock and unlock the frontend from
472 * racing on the VkQueue.
473 *
474 * Queue submission can happen on any thread.
475 * Even if queue submission happens on the same thread as retro_run(),
476 * the lock/unlock functions must still be called.
477 *
478 * NOTE: Queue submissions are heavy-weight. */
479 retro_vulkan_lock_queue_t lock_queue;
480 retro_vulkan_unlock_queue_t unlock_queue;
481
482 /* Sets a semaphore which is signaled when the image in set_image can safely be reused.
483 * The semaphore is consumed next call to retro_video_refresh_t.
484 * The semaphore will be signalled even for duped frames.
485 * The semaphore will be signalled only once, so set_signal_semaphore should be called every frame.
486 * The semaphore may be VK_NULL_HANDLE, which disables semaphore signalling for next call to retro_video_refresh_t.
487 *
488 * This is mostly useful to support use cases where you're rendering to a single image that
489 * is recycled in a ping-pong fashion with the frontend to save memory (but potentially less throughput).
490 */
491 retro_vulkan_set_signal_semaphore_t set_signal_semaphore;
492};
493
494#endif