diff options
Diffstat (limited to 'src/include/libplacebo/vulkan.h')
-rw-r--r-- | src/include/libplacebo/vulkan.h | 638 |
1 files changed, 638 insertions, 0 deletions
diff --git a/src/include/libplacebo/vulkan.h b/src/include/libplacebo/vulkan.h new file mode 100644 index 0000000..4e5db95 --- /dev/null +++ b/src/include/libplacebo/vulkan.h @@ -0,0 +1,638 @@ +/* + * This file is part of libplacebo. + * + * libplacebo is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libplacebo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef LIBPLACEBO_VULKAN_H_ +#define LIBPLACEBO_VULKAN_H_ + +#include <vulkan/vulkan.h> +#include <libplacebo/gpu.h> +#include <libplacebo/swapchain.h> + +PL_API_BEGIN + +#define PL_VK_MIN_VERSION VK_API_VERSION_1_2 + +// Structure representing a VkInstance. Using this is not required. +typedef const struct pl_vk_inst_t { + VkInstance instance; + + // The Vulkan API version supported by this VkInstance. + uint32_t api_version; + + // The associated vkGetInstanceProcAddr pointer. + PFN_vkGetInstanceProcAddr get_proc_addr; + + // The instance extensions that were successfully enabled, including + // extensions enabled by libplacebo internally. May contain duplicates. + const char * const *extensions; + int num_extensions; + + // The instance layers that were successfully enabled, including + // layers enabled by libplacebo internally. May contain duplicates. + const char * const *layers; + int num_layers; +} *pl_vk_inst; + +struct pl_vk_inst_params { + // If set, enable the debugging and validation layers. These should + // generally be lightweight and relatively harmless to enable. + bool debug; + + // If set, also enable GPU-assisted verification and best practices + // layers. (Note: May cause substantial slowdown and/or result in lots of + // false positive spam) + bool debug_extra; + + // If nonzero, restricts the Vulkan API version to be at most this. This + // is only really useful for explicitly testing backwards compatibility. + uint32_t max_api_version; + + // Pointer to a user-provided `vkGetInstanceProcAddr`. If this is NULL, + // libplacebo will use the directly linked version (if available). + PFN_vkGetInstanceProcAddr get_proc_addr; + + // Enables extra instance extensions. Instance creation will fail if these + // extensions are not all supported. The user may use this to enable e.g. + // windowing system integration. + const char * const *extensions; + int num_extensions; + + // Enables extra optional instance extensions. These are opportunistically + // enabled if supported by the device, but otherwise skipped. + const char * const *opt_extensions; + int num_opt_extensions; + + // Enables extra layers. Instance creation will fail if these layers are + // not all supported. + // + // NOTE: Layers needed for required/optional extensions are automatically + // enabled. The user does not specifically need to enable layers related + // to extension support. + const char * const *layers; + int num_layers; + + // Enables extra optional layers. These are opportunistically enabled if + // supported by the platform, but otherwise skipped. + const char * const *opt_layers; + int num_opt_layers; +}; + +#define pl_vk_inst_params(...) (&(struct pl_vk_inst_params) { __VA_ARGS__ }) +PL_API extern const struct pl_vk_inst_params pl_vk_inst_default_params; + +// Helper function to simplify instance creation. The user could also bypass +// these helpers and do it manually, but this function is provided as a +// convenience. It also sets up a debug callback which forwards all vulkan +// messages to the `pl_log` callback. +PL_API pl_vk_inst pl_vk_inst_create(pl_log log, const struct pl_vk_inst_params *params); +PL_API void pl_vk_inst_destroy(pl_vk_inst *inst); + +struct pl_vulkan_queue { + uint32_t index; // Queue family index + uint32_t count; // Queue family count +}; + +// Structure representing the actual vulkan device and associated GPU instance +typedef const struct pl_vulkan_t *pl_vulkan; +struct pl_vulkan_t { + pl_gpu gpu; + + // The vulkan objects in use. The user may use this for their own purposes, + // but please note that the lifetime is tied to the lifetime of the + // pl_vulkan object, and must not be destroyed by the user. Note that the + // created vulkan device may have any number of queues and queue family + // assignments; so using it for queue submission commands is ill-advised. + VkInstance instance; + VkPhysicalDevice phys_device; + VkDevice device; + + // The associated vkGetInstanceProcAddr pointer. + PFN_vkGetInstanceProcAddr get_proc_addr; + + // The Vulkan API version supported by this VkPhysicalDevice. + uint32_t api_version; + + // The device extensions that were successfully enabled, including + // extensions enabled by libplacebo internally. May contain duplicates. + const char * const *extensions; + int num_extensions; + + // The device features that were enabled at device creation time. + // + // Note: Whenever a feature flag is ambiguious between several alternative + // locations, for completeness' sake, we include both. + const VkPhysicalDeviceFeatures2 *features; + + // The explicit queue families we are using to provide a given capability. + struct pl_vulkan_queue queue_graphics; // provides VK_QUEUE_GRAPHICS_BIT + struct pl_vulkan_queue queue_compute; // provides VK_QUEUE_COMPUTE_BIT + struct pl_vulkan_queue queue_transfer; // provides VK_QUEUE_TRANSFER_BIT + + // Functions for locking a queue. These must be used to lock VkQueues for + // submission or other related operations when sharing the VkDevice between + // multiple threads, Using this on queue families or indices not contained + // in `queues` is undefined behavior. + void (*lock_queue)(pl_vulkan vk, uint32_t qf, uint32_t qidx); + void (*unlock_queue)(pl_vulkan vk, uint32_t qf, uint32_t qidx); + + // --- Deprecated fields + + // These are the same active queue families and their queue counts in list + // form. This list does not contain duplicates, nor any extra queues + // enabled at device creation time. Deprecated in favor of querying + // `vkGetPhysicalDeviceQueueFamilyProperties` directly. + const struct pl_vulkan_queue *queues PL_DEPRECATED; + int num_queues PL_DEPRECATED; +}; + +struct pl_vulkan_params { + // The vulkan instance. Optional, if NULL then libplacebo will internally + // create a VkInstance with the settings from `instance_params`. + // + // Note: The VkInstance provided by the user *MUST* be created with a + // VkApplicationInfo.apiVersion of PL_VK_MIN_VERSION or higher. + VkInstance instance; + + // Pointer to `vkGetInstanceProcAddr`. If this is NULL, libplacebo will + // use the directly linked version (if available). + // + // Note: This overwrites the same value from `instance_params`. + PFN_vkGetInstanceProcAddr get_proc_addr; + + // Configures the settings used for creating an internal vulkan instance. + // May be NULL. Ignored if `instance` is set. + const struct pl_vk_inst_params *instance_params; + + // When choosing the device, rule out all devices that don't support + // presenting to this surface. When creating a device, enable all extensions + // needed to ensure we can present to this surface. Optional. Only legal + // when specifying an existing VkInstance to use. + VkSurfaceKHR surface; + + // --- Physical device selection options + + // The vulkan physical device. May be set by the caller to indicate the + // physical device to use. Otherwise, libplacebo will pick the "best" + // available GPU, based on the advertised device type. (i.e., it will + // prefer discrete GPUs over integrated GPUs). Only legal when specifying + // an existing VkInstance to use. + VkPhysicalDevice device; + + // When choosing the device, only choose a device with this exact name. + // This overrides `allow_software`. No effect if `device` is set. Note: A + // list of devices and their names are logged at level PL_LOG_INFO. + const char *device_name; + + // When choosing the device, only choose a device with this exact UUID. + // This overrides `allow_software` and `device_name`. No effect if `device` + // is set. + uint8_t device_uuid[16]; + + // When choosing the device, controls whether or not to also allow software + // GPUs. No effect if `device` or `device_name` are set. + bool allow_software; + + // --- Logical device creation options + + // Controls whether or not to allow asynchronous transfers, using transfer + // queue families, if supported by the device. This can be significantly + // faster and more power efficient, and also allows streaming uploads in + // parallel with rendering commands. Enabled by default. + bool async_transfer; + + // Controls whether or not to allow asynchronous compute, using dedicated + // compute queue families, if supported by the device. On some devices, + // these can allow the GPU to schedule compute shaders in parallel with + // fragment shaders. Enabled by default. + bool async_compute; + + // Limits the number of queues to use. If left as 0, libplacebo will use as + // many queues as the device supports. Multiple queues can result in + // improved efficiency when submitting multiple commands that can entirely + // or partially execute in parallel. Defaults to 1, since using more queues + // can actually decrease performance. + // + // Note: libplacebo will always *create* logical devices with all available + // queues for a given QF enabled, regardless of this setting. + int queue_count; + + // Bitmask of extra queue families to enable. If set, then *all* queue + // families matching *any* of these flags will be enabled at device + // creation time. Setting this to VK_QUEUE_FLAG_BITS_MAX_ENUM effectively + // enables all queue families supported by the device. + VkQueueFlags extra_queues; + + // Enables extra device extensions. Device creation will fail if these + // extensions are not all supported. The user may use this to enable e.g. + // interop extensions. + const char * const *extensions; + int num_extensions; + + // Enables extra optional device extensions. These are opportunistically + // enabled if supported by the device, but otherwise skipped. + const char * const *opt_extensions; + int num_opt_extensions; + + // Optional extra features to enable at device creation time. These are + // opportunistically enabled if supported by the physical device, but + // otherwise kept disabled. + const VkPhysicalDeviceFeatures2 *features; + + // --- Misc/debugging options + + // Restrict specific features to e.g. work around driver bugs, or simply + // for testing purposes + int max_glsl_version; // limit the maximum GLSL version + uint32_t max_api_version; // limit the maximum vulkan API version +}; + +// Default/recommended parameters. Should generally be safe and efficient. +#define PL_VULKAN_DEFAULTS \ + .async_transfer = true, \ + .async_compute = true, \ + /* enabling multiple queues often decreases perf */ \ + .queue_count = 1, + +#define pl_vulkan_params(...) (&(struct pl_vulkan_params) { PL_VULKAN_DEFAULTS __VA_ARGS__ }) +PL_API extern const struct pl_vulkan_params pl_vulkan_default_params; + +// Creates a new vulkan device based on the given parameters and initializes +// a new GPU. If `params` is left as NULL, it defaults to +// &pl_vulkan_default_params. +// +// Thread-safety: Safe +PL_API pl_vulkan pl_vulkan_create(pl_log log, const struct pl_vulkan_params *params); + +// Destroys the vulkan device and all associated objects, except for the +// VkInstance provided by the user. +// +// Note that all resources allocated from this vulkan object (e.g. via the +// `vk->ra` or using `pl_vulkan_create_swapchain`) *must* be explicitly +// destroyed by the user before calling this. +// +// Also note that this function will block until all in-flight GPU commands are +// finished processing. You can avoid this by manually calling `pl_gpu_finish` +// before `pl_vulkan_destroy`. +PL_API void pl_vulkan_destroy(pl_vulkan *vk); + +// For a `pl_gpu` backed by `pl_vulkan`, this function can be used to retrieve +// the underlying `pl_vulkan`. Returns NULL for any other type of `gpu`. +PL_API pl_vulkan pl_vulkan_get(pl_gpu gpu); + +struct pl_vulkan_device_params { + // The instance to use. Required! + // + // Note: The VkInstance provided by the user *must* be created with a + // VkApplicationInfo.apiVersion of PL_VK_MIN_VERSION or higher. + VkInstance instance; + + // Mirrored from `pl_vulkan_params`. All of these fields are optional. + PFN_vkGetInstanceProcAddr get_proc_addr; + VkSurfaceKHR surface; + const char *device_name; + uint8_t device_uuid[16]; + bool allow_software; +}; + +#define pl_vulkan_device_params(...) (&(struct pl_vulkan_device_params) { __VA_ARGS__ }) + +// Helper function to choose the best VkPhysicalDevice, given a VkInstance. +// This uses the same logic as `pl_vulkan_create` uses internally. If no +// matching device was found, this returns VK_NULL_HANDLE. +PL_API VkPhysicalDevice pl_vulkan_choose_device(pl_log log, + const struct pl_vulkan_device_params *params); + +struct pl_vulkan_swapchain_params { + // The surface to use for rendering. Required, the user is in charge of + // creating this. Must belong to the same VkInstance as `vk->instance`. + VkSurfaceKHR surface; + + // The preferred presentation mode. See the vulkan documentation for more + // information about these. If the device/surface combination does not + // support this mode, libplacebo will fall back to VK_PRESENT_MODE_FIFO_KHR. + // + // Warning: Leaving this zero-initialized is the same as having specified + // VK_PRESENT_MODE_IMMEDIATE_KHR, which is probably not what the user + // wants! + VkPresentModeKHR present_mode; + + // Allow up to N in-flight frames. This essentially controls how many + // rendering commands may be queued up at the same time. See the + // documentation for `pl_swapchain_get_latency` for more information. For + // vulkan specifically, we are only able to wait until the GPU has finished + // rendering a frame - we are unable to wait until the display has actually + // finished displaying it. So this only provides a rough guideline. + // Optional, defaults to 3. + int swapchain_depth; + + // This suppresses automatic recreation of the swapchain when any call + // returns VK_SUBOPTIMAL_KHR. Normally, libplacebo will recreate the + // swapchain internally on the next `pl_swapchain_start_frame`. If enabled, + // clients are assumed to take care of swapchain recreations themselves, by + // calling `pl_swapchain_resize` as appropriate. libplacebo will tolerate + // the "suboptimal" status indefinitely. + bool allow_suboptimal; + + // Disable high-bit (10 or more) SDR formats. May help work around buggy + // drivers which don't dither properly when outputting high bit depth + // SDR backbuffers to 8-bit screens. + bool disable_10bit_sdr; +}; + +#define pl_vulkan_swapchain_params(...) (&(struct pl_vulkan_swapchain_params) { __VA_ARGS__ }) + +// Creates a new vulkan swapchain based on an existing VkSurfaceKHR. Using this +// function requires that the vulkan device was created with the +// VK_KHR_swapchain extension. The easiest way of accomplishing this is to set +// the `pl_vulkan_params.surface` explicitly at creation time. +PL_API pl_swapchain pl_vulkan_create_swapchain(pl_vulkan vk, + const struct pl_vulkan_swapchain_params *params); + +// This will return true if the vulkan swapchain is internally detected +// as being suboptimal (VK_SUBOPTIMAL_KHR). This might be of use to clients +// who have `params->allow_suboptimal` enabled. +PL_API bool pl_vulkan_swapchain_suboptimal(pl_swapchain sw); + +// Vulkan interop API, for sharing a single VkDevice (and associated vulkan +// resources) directly with the API user. The use of this API is a bit sketchy +// and requires careful communication of Vulkan API state. + +struct pl_vulkan_import_params { + // The vulkan instance. Required. + // + // Note: The VkInstance provided by the user *must* be created with a + // VkApplicationInfo.apiVersion of PL_VK_MIN_VERSION or higher. + VkInstance instance; + + // Pointer to `vkGetInstanceProcAddr`. If this is NULL, libplacebo will + // use the directly linked version (if available). + PFN_vkGetInstanceProcAddr get_proc_addr; + + // The physical device selected by the user. Required. + VkPhysicalDevice phys_device; + + // The logical device created by the user. Required. + VkDevice device; + + // --- Logical device parameters + + // List of all device-level extensions that were enabled. (Instance-level + // extensions need not be re-specified here, since it's guaranteed that any + // instance-level extensions that device-level extensions depend on were + // enabled at the instance level) + const char * const *extensions; + int num_extensions; + + // Enabled queue families. At least `queue_graphics` is required. + // + // It's okay for multiple queue families to be specified with the same + // index, e.g. in the event that a dedicated compute queue also happens to + // be the dedicated transfer queue. + // + // It's also okay to leave the queue struct as {0} in the event that no + // dedicated queue exists for a given operation type. libplacebo will + // automatically fall back to using e.g. the graphics queue instead. + struct pl_vulkan_queue queue_graphics; // must support VK_QUEUE_GRAPHICS_BIT + struct pl_vulkan_queue queue_compute; // must support VK_QUEUE_COMPUTE_BIT + struct pl_vulkan_queue queue_transfer; // must support VK_QUEUE_TRANSFER_BIT + + // Enabled VkPhysicalDeviceFeatures. The device *must* be created with + // all of the features in `pl_vulkan_required_features` enabled. + const VkPhysicalDeviceFeatures2 *features; + + // Functions for locking a queue. If set, these will be used instead of + // libplacebo's internal functions for `pl_vulkan.(un)lock_queue`. + void (*lock_queue)(void *ctx, uint32_t qf, uint32_t qidx); + void (*unlock_queue)(void *ctx, uint32_t qf, uint32_t qidx); + void *queue_ctx; + + // --- Misc/debugging options + + // Restrict specific features to e.g. work around driver bugs, or simply + // for testing purposes. See `pl_vulkan_params` for a description of these. + int max_glsl_version; + uint32_t max_api_version; +}; + +#define pl_vulkan_import_params(...) (&(struct pl_vulkan_import_params) { __VA_ARGS__ }) + +// For purely informative reasons, this contains a list of extensions and +// device features that libplacebo *can* make use of. These are all strictly +// optional, but provide a hint to the API user as to what might be worth +// enabling at device creation time. +// +// Note: This also includes physical device features provided by extensions. +// They are all provided using extension-specific features structs, rather +// than the more general purpose VkPhysicalDeviceVulkan11Features etc. +PL_API extern const char * const pl_vulkan_recommended_extensions[]; +PL_API extern const int pl_vulkan_num_recommended_extensions; +PL_API extern const VkPhysicalDeviceFeatures2 pl_vulkan_recommended_features; + +// A list of device features that are required by libplacebo. These +// *must* be provided by imported Vulkan devices. +// +// Note: `pl_vulkan_recommended_features` does not include this list. +PL_API extern const VkPhysicalDeviceFeatures2 pl_vulkan_required_features; + +// Import an existing VkDevice instead of creating a new one, and wrap it into +// a `pl_vulkan` abstraction. It's safe to `pl_vulkan_destroy` this, which will +// destroy application state related to libplacebo but leave the underlying +// VkDevice intact. +PL_API pl_vulkan pl_vulkan_import(pl_log log, const struct pl_vulkan_import_params *params); + +struct pl_vulkan_wrap_params { + // The image itself. It *must* be usable concurrently by all of the queue + // family indices listed in `pl_vulkan->queues`. Note that this requires + // the use of VK_SHARING_MODE_CONCURRENT if `pl_vulkan->num_queues` is + // greater than 1. If this is difficult to achieve for the user, then + // `async_transfer` / `async_compute` should be turned off, which + // guarantees the use of only one queue family. + VkImage image; + + // Which aspect of `image` to wrap. Only useful for wrapping individual + // sub-planes of planar images. If left as 0, it defaults to the entire + // image (i.e. the union of VK_IMAGE_ASPECT_PLANE_N_BIT for planar formats, + // and VK_IMAGE_ASPECT_COLOR_BIT otherwise). + VkImageAspectFlags aspect; + + // The image's dimensions (unused dimensions must be 0) + int width; + int height; + int depth; + + // The image's format. libplacebo will try to map this to an equivalent + // pl_fmt. If no compatible pl_fmt is found, wrapping will fail. + VkFormat format; + + // The usage flags the image was created with. libplacebo will set the + // pl_tex capabilities to include whatever it can, as determined by the set + // of enabled usage flags. + VkImageUsageFlags usage; + + // See `pl_tex_params` + void *user_data; + pl_debug_tag debug_tag; +}; + +#define pl_vulkan_wrap_params(...) (&(struct pl_vulkan_wrap_params) { \ + .debug_tag = PL_DEBUG_TAG, \ + __VA_ARGS__ \ + }) + +// Wraps an external VkImage into a pl_tex abstraction. By default, the image +// is considered "held" by the user and must be released before calling any +// pl_tex_* API calls on it (see `pl_vulkan_release`). +// +// This wrapper can be destroyed by simply calling `pl_tex_destroy` on it, +// which will not destroy the underlying VkImage. If a pl_tex wrapper is +// destroyed while an image is not currently being held by the user, that +// image is left in an undefined state. +// +// Wrapping the same VkImage multiple times is undefined behavior, as is trying +// to wrap an image belonging to a different VkDevice than the one in use by +// `gpu`. +// +// This function may fail, in which case it returns NULL. +PL_API pl_tex pl_vulkan_wrap(pl_gpu gpu, const struct pl_vulkan_wrap_params *params); + +// Analogous to `pl_vulkan_wrap`, this function takes any `pl_tex` (including +// ones created by `pl_tex_create`) and unwraps it to expose the underlying +// VkImage to the user. Unlike `pl_vulkan_wrap`, this `pl_tex` is *not* +// considered held after calling this function - the user must explicitly +// `pl_vulkan_hold` before accessing the VkImage. +// +// `out_format` and `out_flags` will be updated to hold the VkImage's +// format and usage flags. (Optional) +PL_API VkImage pl_vulkan_unwrap(pl_gpu gpu, pl_tex tex, + VkFormat *out_format, VkImageUsageFlags *out_flags); + +// Represents a vulkan semaphore/value pair (for compatibility with timeline +// semaphores). When using normal, binary semaphores, `value` may be ignored. +typedef struct pl_vulkan_sem { + VkSemaphore sem; + uint64_t value; +} pl_vulkan_sem; + +struct pl_vulkan_hold_params { + // The Vulkan image to hold. It will be marked as held. Attempting to + // perform any pl_tex_* operation (except pl_tex_destroy) on a held image + // is undefined behavior. + pl_tex tex; + + // The layout to transition the image to when holding. Alternatively, a + // pointer to receive the current image layout. If `out_layout` is + // provided, `layout` is ignored. + VkImageLayout layout; + VkImageLayout *out_layout; + + // The queue family index to transition the image to. This can be used with + // VK_QUEUE_FAMILY_EXTERNAL to transition the image to an external API. As + // a special case, if set to VK_QUEUE_FAMILY_IGNORED, libplacebo will not + // transition the image, even if this image was not set up for concurrent + // usage. Ignored for concurrent images. + uint32_t qf; + + // The semaphore to fire when the image is available for use. (Required) + pl_vulkan_sem semaphore; +}; + +#define pl_vulkan_hold_params(...) (&(struct pl_vulkan_hold_params) { __VA_ARGS__ }) + +// "Hold" a shared image, transferring control over the image to the user. +// Returns whether successful. +PL_API bool pl_vulkan_hold_ex(pl_gpu gpu, const struct pl_vulkan_hold_params *params); + +struct pl_vulkan_release_params { + // The image to be released. It must be marked as "held". Performing any + // operation on the VkImage underlying this `pl_tex` while it is not being + // held by the user is undefined behavior. + pl_tex tex; + + // The current layout of the image at the point in time when `semaphore` + // fires, or if no semaphore is specified, at the time of call. + VkImageLayout layout; + + // The queue family index to transition the image to. This can be used with + // VK_QUEUE_FAMILY_EXTERNAL to transition the image rom an external API. As + // a special case, if set to VK_QUEUE_FAMILY_IGNORED, libplacebo will not + // transition the image, even if this image was not set up for concurrent + // usage. Ignored for concurrent images. + uint32_t qf; + + // The semaphore to wait on before libplacebo will actually use or modify + // the image. (Optional) + // + // Note: the lifetime of `semaphore` is indeterminate, and destroying it + // while the texture is still depending on that semaphore is undefined + // behavior. + // + // Technically, the only way to be sure that it's safe to free is to use + // `pl_gpu_finish()` or similar (e.g. `pl_vulkan_destroy` or + // `vkDeviceWaitIdle`) after another operation involving `tex` has been + // emitted (or the texture has been destroyed). + // + // + // Warning: If `tex` is a planar image (`pl_fmt.num_planes > 0`), and + // `semaphore` is specified, it *must* be a timeline semaphore! Failure to + // respect this will result in undefined behavior. This warning does not + // apply to individual planes (as exposed by `pl_tex.planes`). + pl_vulkan_sem semaphore; +}; + +#define pl_vulkan_release_params(...) (&(struct pl_vulkan_release_params) { __VA_ARGS__ }) + +// "Release" a shared image, transferring control to libplacebo. +PL_API void pl_vulkan_release_ex(pl_gpu gpu, const struct pl_vulkan_release_params *params); + +struct pl_vulkan_sem_params { + // The type of semaphore to create. + VkSemaphoreType type; + + // For VK_SEMAPHORE_TYPE_TIMELINE, sets the initial timeline value. + uint64_t initial_value; + + // If set, exports this VkSemaphore to the handle given in `out_handle`. + // The user takes over ownership, and should manually close it before + // destroying this VkSemaphore (via `pl_vulkan_sem_destroy`). + enum pl_handle_type export_handle; + union pl_handle *out_handle; + + // Optional debug tag to identify this semaphore. + pl_debug_tag debug_tag; +}; + +#define pl_vulkan_sem_params(...) (&(struct pl_vulkan_sem_params) { \ + .debug_tag = PL_DEBUG_TAG, \ + __VA_ARGS__ \ + }) + +// Helper functions to create and destroy vulkan semaphores. Returns +// VK_NULL_HANDLE on failure. +PL_API VkSemaphore pl_vulkan_sem_create(pl_gpu gpu, const struct pl_vulkan_sem_params *params); +PL_API void pl_vulkan_sem_destroy(pl_gpu gpu, VkSemaphore *semaphore); + +// Backwards-compatibility wrappers for older versions of the API. +PL_DEPRECATED PL_API bool pl_vulkan_hold(pl_gpu gpu, pl_tex tex, VkImageLayout layout, + pl_vulkan_sem sem_out); +PL_DEPRECATED PL_API bool pl_vulkan_hold_raw(pl_gpu gpu, pl_tex tex, VkImageLayout *out_layout, + pl_vulkan_sem sem_out); +PL_DEPRECATED PL_API void pl_vulkan_release(pl_gpu gpu, pl_tex tex, VkImageLayout layout, + pl_vulkan_sem sem_in); + +PL_API_END + +#endif // LIBPLACEBO_VULKAN_H_ |