blob: fa39062d7fe2582581958ae698e4d40b520144c8 [file] [log] [blame]
// 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_