| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_PIPELINE_CACHE_DATA_VK_H_ |
| #define FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_PIPELINE_CACHE_DATA_VK_H_ |
| |
| #include "flutter/fml/mapping.h" |
| #include "flutter/fml/unique_fd.h" |
| #include "impeller/renderer/backend/vulkan/vk.h" |
| |
| namespace impeller { |
| |
| //------------------------------------------------------------------------------ |
| /// @brief An Impeller specific header prepended to all pipeline cache |
| /// information that is persisted on disk. This information is used |
| /// to perform additional integrity checks that may have been missed |
| /// by the Vulkan driver. |
| /// |
| /// Inspired by |
| /// https://medium.com/@zeuxcg/creating-a-robust-pipeline-cache-with-vulkan-961d09416cda. |
| /// |
| struct PipelineCacheHeaderVK { |
| // This can be used by Impeller to manually invalidate all old caches. |
| uint32_t magic = 0xC0DEF00D; |
| // Notably, this field is missing from checks the Vulkan driver performs. For |
| // drivers that don't correctly check the UUID, explicitly disregarding caches |
| // generated by previous driver versions sidesteps some landmines. |
| uint32_t driver_version = 0; |
| uint32_t vendor_id = 0; |
| uint32_t device_id = 0; |
| // If applications are published as 32-bit and updated via the app store to be |
| // 64-bits, this check comes in handy to disregard previous caches. |
| uint32_t abi = sizeof(void*); |
| uint8_t uuid[VK_UUID_SIZE] = {}; |
| uint64_t data_size = 0; |
| |
| //---------------------------------------------------------------------------- |
| /// @brief Constructs a new empty instance. |
| /// |
| PipelineCacheHeaderVK(); |
| |
| //---------------------------------------------------------------------------- |
| /// @brief Constructs a new instance that will be compatible with the |
| /// given physical device properties. |
| /// |
| /// @param[in] props The properties. |
| /// @param[in] p_data_size The data size. |
| /// |
| explicit PipelineCacheHeaderVK(const VkPhysicalDeviceProperties& props, |
| uint64_t p_data_size); |
| |
| //---------------------------------------------------------------------------- |
| /// @brief Determines whether the specified o is compatible with. |
| /// |
| /// The size of the data following the header may be different and |
| /// is not part of compatibility checks. |
| /// |
| /// @param[in] other The other header. |
| /// |
| /// @return True if the specified header is compatible with this one, |
| /// False otherwise. The size of the data following the header may |
| /// be different. |
| /// |
| bool IsCompatibleWith(const PipelineCacheHeaderVK& other) const; |
| }; |
| |
| //------------------------------------------------------------------------------ |
| /// @brief Persist the pipeline cache to a file in the given cache |
| /// directory. This function performs integrity checks the Vulkan |
| /// driver may have missed. |
| /// |
| /// @warning The pipeline cache must be externally synchronized for most |
| /// complete results. If additional pipelines are being created |
| /// while this function is executing, this function may fail to |
| /// persist data. |
| /// |
| /// @param[in] cache_directory The cache directory |
| /// @param[in] props The physical device properties |
| /// @param[in] cache The cache |
| /// |
| /// @return If the cache data could be persisted to disk. |
| /// |
| bool PipelineCacheDataPersist(const fml::UniqueFD& cache_directory, |
| const VkPhysicalDeviceProperties& props, |
| const vk::UniquePipelineCache& cache); |
| |
| //------------------------------------------------------------------------------ |
| /// @brief Retrieve the previously persisted pipeline cache data. This |
| /// function provides integrity checks the Vulkan driver may have |
| /// missed. |
| /// |
| /// The data is stripped of any additional headers that perform |
| /// integrity checks. It can be used directly to construct a |
| /// pre-initialized Vulkan pipeline cache. |
| /// |
| /// @param[in] cache_directory The cache directory |
| /// @param[in] props The properties |
| /// |
| /// @return The cache data if it was found and checked to have passed |
| /// additional integrity checks. |
| /// |
| std::unique_ptr<fml::Mapping> PipelineCacheDataRetrieve( |
| const fml::UniqueFD& cache_directory, |
| const VkPhysicalDeviceProperties& props); |
| |
| } // namespace impeller |
| |
| #endif // FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_PIPELINE_CACHE_DATA_VK_H_ |