diff options
Diffstat (limited to 'thirdparty/swappy-frame-pacing/swappyVk.h')
-rw-r--r-- | thirdparty/swappy-frame-pacing/swappyVk.h | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/thirdparty/swappy-frame-pacing/swappyVk.h b/thirdparty/swappy-frame-pacing/swappyVk.h new file mode 100644 index 0000000000..020683cbc4 --- /dev/null +++ b/thirdparty/swappy-frame-pacing/swappyVk.h @@ -0,0 +1,420 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @defgroup swappyVk Swappy for Vulkan + * Vulkan part of Swappy. + * @{ + */ + +#pragma once + +#include "jni.h" +#include "swappy_common.h" + +#ifndef VK_NO_PROTOTYPES +#define VK_NO_PROTOTYPES 1 +#endif +#include <vulkan/vulkan.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Determine any Vulkan device extensions that must be enabled for a new + * VkDevice. + * + * Swappy-for-Vulkan (SwappyVk) benefits from certain Vulkan device extensions + * (e.g. VK_GOOGLE_display_timing). Before the application calls + * vkCreateDevice, SwappyVk needs to look at the list of available extensions + * (returned by vkEnumerateDeviceExtensionProperties) and potentially identify + * one or more extensions that the application must add to: + * + * - VkDeviceCreateInfo::enabledExtensionCount + * - VkDeviceCreateInfo::ppEnabledExtensionNames + * + * before the application calls vkCreateDevice. For each VkPhysicalDevice that + * the application will call vkCreateDevice for, the application must call this + * function, and then must add the identified extension(s) to the list that are + * enabled for the VkDevice. Similar to many Vulkan functions, this function + * can be called twice, once to identify the number of required extensions, and + * again with application-allocated memory that the function can write into. + * + * @param[in] physicalDevice - The VkPhysicalDevice associated with + * the available extensions. + * @param[in] availableExtensionCount - This is the returned value of + * pPropertyCount from vkEnumerateDeviceExtensionProperties. + * @param[in] pAvailableExtensions - This is the returned value of + * pProperties from vkEnumerateDeviceExtensionProperties. + * @param[inout] pRequiredExtensionCount - If pRequiredExtensions is nullptr, + * the function sets this to the number of extensions that are required. If + * pRequiredExtensions is non-nullptr, this is the number of required extensions + * that the function should write into pRequiredExtensions. + * @param[inout] pRequiredExtensions - If non-nullptr, this is + * application-allocated memory into which the function will write the names of + * required extensions. It is a pointer to an array of + * char* strings (i.e. the same as + * VkDeviceCreateInfo::ppEnabledExtensionNames). + */ +void SwappyVk_determineDeviceExtensions( + VkPhysicalDevice physicalDevice, uint32_t availableExtensionCount, + VkExtensionProperties* pAvailableExtensions, + uint32_t* pRequiredExtensionCount, char** pRequiredExtensions); + +/** + * @brief Tell Swappy the queueFamilyIndex used to create a specific VkQueue + * + * Swappy needs to know the queueFamilyIndex used for creating a specific + * VkQueue so it can use it when presenting. + * + * @param[in] device - The VkDevice associated with the queue + * @param[in] queue - A device queue. + * @param[in] queueFamilyIndex - The queue family index used to create the + * VkQueue. + * + */ +void SwappyVk_setQueueFamilyIndex(VkDevice device, VkQueue queue, + uint32_t queueFamilyIndex); + +// TBD: For now, SwappyVk assumes only one VkSwapchainKHR per VkDevice, and that +// applications don't re-create swapchains. Is this long-term sufficient? + +/** + * Internal init function. Do not call directly. + * See SwappyVk_initAndGetRefreshCycleDuration instead. + * @private + */ +bool SwappyVk_initAndGetRefreshCycleDuration_internal( + JNIEnv* env, jobject jactivity, VkPhysicalDevice physicalDevice, + VkDevice device, VkSwapchainKHR swapchain, uint64_t* pRefreshDuration); + +/** + * @brief Initialize SwappyVk for a given device and swapchain, and obtain the + * approximate time duration between vertical-blanking periods. + * + * Uses JNI to query AppVsyncOffset and PresentationDeadline. + * + * If your application presents to more than one swapchain at a time, you must + * call this for each swapchain before calling swappyVkSetSwapInterval() for it. + * + * The duration between vertical-blanking periods (an interval) is expressed as + * the approximate number of nanoseconds between vertical-blanking periods of + * the swapchain’s physical display. + * + * If the application converts this number to a fraction (e.g. 16,666,666 nsec + * to 0.016666666) and divides one by that fraction, it will be the approximate + * refresh rate of the display (e.g. 16,666,666 nanoseconds corresponds to a + * 60Hz display, 11,111,111 nsec corresponds to a 90Hz display). + * + * @param[in] env - JNIEnv that is assumed to be from AttachCurrentThread + * function + * @param[in] jactivity - NativeActivity object handle, used for JNI + * @param[in] physicalDevice - The VkPhysicalDevice associated with the + * swapchain + * @param[in] device - The VkDevice associated with the swapchain + * @param[in] swapchain - The VkSwapchainKHR the application wants Swappy to + * swap + * @param[out] pRefreshDuration - The returned refresh cycle duration + * + * @return bool - true if the value returned by pRefreshDuration is + * valid, otherwise false if an error. + */ +bool SwappyVk_initAndGetRefreshCycleDuration(JNIEnv* env, jobject jactivity, + VkPhysicalDevice physicalDevice, + VkDevice device, + VkSwapchainKHR swapchain, + uint64_t* pRefreshDuration); + +/** + * @brief Tell Swappy which ANativeWindow to use when calling to ANativeWindow_* + * API. + * @param[in] device - The VkDevice associated with the swapchain + * @param[in] swapchain - The VkSwapchainKHR the application wants Swappy to + * swap + * @param[in] window - The ANativeWindow that was used to create the + * VkSwapchainKHR + */ +void SwappyVk_setWindow(VkDevice device, VkSwapchainKHR swapchain, + ANativeWindow* window); + +/** + * @brief Tell Swappy the duration of that each presented image should be + * visible. + * + * If your application presents to more than one swapchain at a time, you must + * call this for each swapchain before presenting to it. + * + * @param[in] device - The VkDevice associated with the swapchain + * @param[in] swapchain - The VkSwapchainKHR the application wants Swappy to + * swap + * @param[in] swap_ns - The duration of that each presented image should be + * visible in nanoseconds + */ +void SwappyVk_setSwapIntervalNS(VkDevice device, VkSwapchainKHR swapchain, + uint64_t swap_ns); + +/** + * @brief Tell Swappy to present one or more images to corresponding swapchains. + * + * Swappy will call vkQueuePresentKHR for your application. Swappy may insert a + * struct to the pNext-chain of VkPresentInfoKHR, or it may insert other Vulkan + * commands in order to attempt to honor the desired swap interval. + * + * @note If your application presents to more than one swapchain at a time, and + * if you use a different swap interval for each swapchain, Swappy will attempt + * to honor the swap interval for each swapchain (being more successful on + * devices that support an underlying presentation-timing extension, such as + * VK_GOOGLE_display_timing). + * + * @param[in] queue - The VkQueue associated with the device and swapchain + * @param[in] pPresentInfo - A pointer to the VkPresentInfoKHR containing the + * information about what image(s) to present on which + * swapchain(s). + */ +VkResult SwappyVk_queuePresent(VkQueue queue, + const VkPresentInfoKHR* pPresentInfo); + +/** + * @brief Destroy the SwappyVk instance associated with a swapchain. + * + * This API is expected to be called before calling vkDestroySwapchainKHR() + * so Swappy can cleanup its internal state. + * + * @param[in] device - The VkDevice associated with SwappyVk + * @param[in] swapchain - The VkSwapchainKHR the application wants Swappy to + * destroy + */ +void SwappyVk_destroySwapchain(VkDevice device, VkSwapchainKHR swapchain); + +/** + * @brief Destroy any swapchains associated with the device and clean up the + * device's resources + * + * This function should be called after SwappyVk_destroySwapchain if you no + * longer need the device. + * + * @param[in] device - The VkDevice associated with SwappyVk + */ +void SwappyVk_destroyDevice(VkDevice device); + +/** + * @brief Enables Auto-Swap-Interval feature for all instances. + * + * By default this feature is enabled. Changing it is completely + * optional for fine-tuning swappy behaviour. + * + * @param[in] enabled - True means enable, false means disable + */ +void SwappyVk_setAutoSwapInterval(bool enabled); + +/** + * @brief Enables Auto-Pipeline-Mode feature for all instances. + * + * By default this feature is enabled. Changing it is completely + * optional for fine-tuning swappy behaviour. + * + * @param[in] enabled - True means enable, false means disable + */ +void SwappyVk_setAutoPipelineMode(bool enabled); + +/** + * @brief Sets the maximal swap duration for all instances. + * + * Sets the maximal duration for Auto-Swap-Interval in milliseconds. + * If SwappyVk is operating in Auto-Swap-Interval and the frame duration is + * longer than the provided duration, SwappyVk will not do any pacing and just + * submit the frame as soon as possible. + * + * @param[in] max_swap_ns - maximal swap duration in milliseconds. + */ +void SwappyVk_setMaxAutoSwapIntervalNS(uint64_t max_swap_ns); + +/** + * @brief The fence timeout parameter can be set for devices with faulty + * drivers. Its default value is 50,000,000. + */ +void SwappyVk_setFenceTimeoutNS(uint64_t fence_timeout_ns); + +/** + * @brief Get the fence timeout parameter, for devices with faulty + * drivers. Its default value is 50,000,000. + */ +uint64_t SwappyVk_getFenceTimeoutNS(); + +/** + * @brief Inject callback functions to be called each frame. + * + * @param[in] tracer - Collection of callback functions + */ +void SwappyVk_injectTracer(const SwappyTracer* tracer); + +/** + * @brief Remove callbacks that were previously added using + * SwappyVk_injectTracer. + * + * Only removes callbacks that were previously added using + * SwappyVK_injectTracer. If SwappyVK_injectTracker was not called with the + * tracer, then there is no effect. + * + * @param[in] tracer - Collection of callback functions + */ +void SwappyVk_uninjectTracer(const SwappyTracer* tracer); + +/** + * @brief A structure enabling you to provide your own Vulkan function wrappers + * by calling ::SwappyVk_setFunctionProvider. + * + * Usage of this functionality is optional. + */ +typedef struct SwappyVkFunctionProvider { + /** + * @brief Callback to initialize the function provider. + * + * This function is called by Swappy before any functions are requested. + * E.g. so you can call dlopen on the Vulkan library. + */ + bool (*init)(); + + /** + * @brief Callback to get the address of a function. + * + * This function is called by Swappy to get the address of a Vulkan + * function. + * @param name The null-terminated name of the function. + */ + void* (*getProcAddr)(const char* name); + + /** + * @brief Callback to close any resources owned by the function provider. + * + * This function is called by Swappy when no more functions will be + * requested, e.g. so you can call dlclose on the Vulkan library. + */ + void (*close)(); +} SwappyVkFunctionProvider; + +/** + * @brief Set the Vulkan function provider. + * + * This enables you to provide an object that will be used to look up Vulkan + * functions, e.g. to hook usage of these functions. + * + * To use this functionality, you *must* call this function before any others. + * + * Usage of this function is entirely optional. If you do not use it, the Vulkan + * functions required by Swappy will be dynamically loaded from libvulkan.so. + * + * @param[in] provider - provider object + */ +void SwappyVk_setFunctionProvider( + const SwappyVkFunctionProvider* pSwappyVkFunctionProvider); + +/** + * @brief Get the swap interval value, in nanoseconds, for a given swapchain. + * + * @param[in] swapchain - the swapchain to query + */ +uint64_t SwappyVk_getSwapIntervalNS(VkSwapchainKHR swapchain); + +/** + * @brief Get the supported refresh periods of this device. Call once with + * out_refreshrates set to nullptr to get the number of supported refresh + * periods, then call again passing that number as allocated_entries and + * an array of size equal to allocated_entries that will be filled with the + * refresh periods. + */ +int SwappyVk_getSupportedRefreshPeriodsNS(uint64_t* out_refreshrates, + int allocated_entries, + VkSwapchainKHR swapchain); +/** + * @brief Check if Swappy is enabled for the specified swapchain. + * + * @return false if SwappyVk_initAndGetRefreshCycleDuration was not + * called for the specified swapchain, true otherwise. + */ +bool SwappyVk_isEnabled(VkSwapchainKHR swapchain, bool* isEnabled); + +/** + * @brief Toggle statistics collection on/off + * + * By default, stats collection is off and there is no overhead related to + * stats. An app can turn on stats collection by calling + * `SwappyVk_enableStats(swapchain, true)`. Then, the app is expected to call + * ::SwappyVk_recordFrameStart for each frame before starting to do any CPU + * related work. Stats will be logged to logcat with a 'FrameStatistics' tag. An + * app can get the stats by calling ::SwappyVk_getStats. + * + * SwappyVk_initAndGetRefreshCycleDuration must have been called successfully + * before for this swapchain, otherwise there is no effect in this call. Frame + * stats are only available if the platform supports VK_GOOGLE_display_timing + * extension. + * + * @param[in] swapchain - The swapchain for which frame stat collection is + * configured. + * @param enabled - Whether to enable/disable frame stat collection. + */ +void SwappyVk_enableStats(VkSwapchainKHR swapchain, bool enabled); + +/** + * @brief Should be called if stats have been enabled with SwappyVk_enableStats. + * + * When stats collection is enabled with SwappyVk_enableStats, the app is + * expected to call this function for each frame before starting to do any CPU + * related work. It is assumed that this function will be called after a + * successful call to vkAcquireNextImageKHR. See ::SwappyVk_enableStats for more + * conditions. + * + * @param[in] queue - The VkQueue associated with the device and swapchain + * @param[in] swapchain - The swapchain where the frame is presented to. + * @param[in] image - The image in swapchain that corresponds to the frame. + + * @see SwappyVk_enableStats. + */ +void SwappyVk_recordFrameStart(VkQueue queue, VkSwapchainKHR swapchain, uint32_t image); + +/** + * @brief Returns the stats collected, if statistics collection was toggled on. + * + * Given that this API uses VkSwapchainKHR and the potential for this call to be + * done on different threads, all calls to ::SwappyVk_getStats + * must be externally synchronized with other SwappyVk calls. Unsynchronized + * calls may lead to undefined behavior. See ::SwappyVk_enableStats for more + * conditions. + * + * @param[in] swapchain - The swapchain for which stats are being queried. + * @param swappyStats - Pointer to a SwappyStats that will be populated with + * the collected stats. Cannot be NULL. + * @see SwappyStats + */ +void SwappyVk_getStats(VkSwapchainKHR swapchain, SwappyStats *swappyStats); + +/** + * @brief Clears the frame statistics collected so far. + * + * All the frame statistics collected are reset to 0, frame statistics are + * collected normally after this call. See ::SwappyVk_enableStats for more + * conditions. + * + * @param[in] swapchain - The swapchain for which stats are being cleared. + */ +void SwappyVk_clearStats(VkSwapchainKHR swapchain); + +#ifdef __cplusplus +} // extern "C" +#endif + +/** @} */ |