Flutter Engine
 
Loading...
Searching...
No Matches
pipeline_cache_data_vk.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include "flutter/fml/file.h"
10
11namespace impeller {
12
13static constexpr const char* kPipelineCacheFileName =
14 "flutter.impeller.vkcache";
15
16bool PipelineCacheDataPersist(const fml::UniqueFD& cache_directory,
17 const VkPhysicalDeviceProperties& props,
18 const vk::UniquePipelineCache& cache) {
19 if (!cache_directory.is_valid()) {
20 return false;
21 }
22 size_t data_size = 0u;
23 if (cache.getOwner().getPipelineCacheData(*cache, &data_size, nullptr) !=
24 vk::Result::eSuccess) {
25 VALIDATION_LOG << "Could not fetch pipeline cache size.";
26 return false;
27 }
28 if (data_size == 0u) {
29 return true;
30 }
31 auto allocation = std::make_shared<Allocation>();
32 if (!allocation->Truncate(Bytes{sizeof(PipelineCacheHeaderVK) + data_size},
33 false)) {
34 VALIDATION_LOG << "Could not allocate pipeline cache data staging buffer.";
35 return false;
36 }
37 // Read the cache data and obtain the actual data size (which may be smaller
38 // than the original query for the data size if rendering operations happened
39 // after that call)
40 vk::Result lookup_result = cache.getOwner().getPipelineCacheData(
41 *cache, &data_size,
42 allocation->GetBuffer() + sizeof(PipelineCacheHeaderVK));
43
44 // Some drivers may return incomplete erroneously, but this is not an
45 // error condition as some/all data was still written.
46 if (lookup_result != vk::Result::eSuccess &&
47 lookup_result != vk::Result::eIncomplete) {
48 VALIDATION_LOG << "Could not copy pipeline cache data.";
49 return false;
50 }
51
52 const auto header = PipelineCacheHeaderVK{props, data_size};
53 std::memcpy(allocation->GetBuffer(), &header, sizeof(header));
54
55 fml::NonOwnedMapping allocation_mapping(
56 allocation->GetBuffer(), sizeof(PipelineCacheHeaderVK) + data_size);
57 if (!fml::WriteAtomically(cache_directory, kPipelineCacheFileName,
58 allocation_mapping)) {
59 VALIDATION_LOG << "Could not write cache file to disk.";
60 return false;
61 }
62 return true;
63}
64
65std::unique_ptr<fml::Mapping> PipelineCacheDataRetrieve(
66 const fml::UniqueFD& cache_directory,
67 const VkPhysicalDeviceProperties& props) {
68 if (!cache_directory.is_valid()) {
69 return nullptr;
70 }
71 std::shared_ptr<fml::FileMapping> on_disk_data =
73 if (!on_disk_data) {
74 return nullptr;
75 }
76 if (on_disk_data->GetSize() < sizeof(PipelineCacheHeaderVK)) {
77 VALIDATION_LOG << "Pipeline cache data size is too small.";
78 return nullptr;
79 }
80 auto on_disk_header = PipelineCacheHeaderVK{};
81 std::memcpy(&on_disk_header, //
82 on_disk_data->GetMapping(), //
83 sizeof(on_disk_header) //
84 );
85 const auto current_header = PipelineCacheHeaderVK{props, 0u};
86 if (!on_disk_header.IsCompatibleWith(current_header)) {
87 FML_LOG(WARNING)
88 << "Persisted pipeline cache is not compatible with current "
89 "Vulkan context. Ignoring.";
90 return nullptr;
91 }
92 // Zero sized data is known to cause issues.
93 if (on_disk_header.data_size == 0u) {
94 return nullptr;
95 }
96 return std::make_unique<fml::NonOwnedMapping>(
97 on_disk_data->GetMapping() + sizeof(on_disk_header),
98 on_disk_header.data_size, [on_disk_data](auto, auto) {});
99}
100
102
104 const VkPhysicalDeviceProperties& props,
105 uint64_t p_data_size)
106 : driver_version(props.driverVersion),
107 vendor_id(props.vendorID),
108 device_id(props.deviceID),
109 data_size(p_data_size) {
110 std::memcpy(uuid, props.pipelineCacheUUID, VK_UUID_SIZE);
111}
112
114 const PipelineCacheHeaderVK& o) const {
115 // Check for everything but the data size.
116 return magic == o.magic && //
118 vendor_id == o.vendor_id && //
119 device_id == o.device_id && //
120 abi == o.abi && //
121 std::memcmp(uuid, o.uuid, VK_UUID_SIZE) == 0;
122}
123
124} // namespace impeller
static std::unique_ptr< FileMapping > CreateReadOnly(const std::string &path)
Definition mapping.cc:20
bool is_valid() const
#define FML_LOG(severity)
Definition logging.h:101
bool WriteAtomically(const fml::UniqueFD &base_directory, const char *file_name, const Mapping &mapping)
std::unique_ptr< fml::Mapping > PipelineCacheDataRetrieve(const fml::UniqueFD &cache_directory, const VkPhysicalDeviceProperties &props)
Retrieve the previously persisted pipeline cache data. This function provides integrity checks the Vu...
static constexpr const char * kPipelineCacheFileName
bool PipelineCacheDataPersist(const fml::UniqueFD &cache_directory, const VkPhysicalDeviceProperties &props, const vk::UniquePipelineCache &cache)
Persist the pipeline cache to a file in the given cache directory. This function performs integrity c...
An Impeller specific header prepended to all pipeline cache information that is persisted on disk....
bool IsCompatibleWith(const PipelineCacheHeaderVK &other) const
Determines whether the specified o is compatible with.
PipelineCacheHeaderVK()
Constructs a new empty instance.
#define VALIDATION_LOG
Definition validation.h:91