Flutter Impeller
pipeline_cache_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 
5 // FLUTTER_NOLINT: https://github.com/flutter/flutter/issues/123467
6 
8 
9 #include <sstream>
10 
11 #include "flutter/fml/mapping.h"
15 
16 namespace impeller {
17 
18 PipelineCacheVK::PipelineCacheVK(std::shared_ptr<const Capabilities> caps,
19  std::shared_ptr<DeviceHolderVK> device_holder,
20  fml::UniqueFD cache_directory)
21  : caps_(std::move(caps)),
22  device_holder_(device_holder),
23  cache_directory_(std::move(cache_directory)) {
24  if (!caps_ || !device_holder->GetDevice()) {
25  return;
26  }
27 
28  const auto& vk_caps = CapabilitiesVK::Cast(*caps_);
29 
30  auto existing_cache_data = PipelineCacheDataRetrieve(
31  cache_directory_, vk_caps.GetPhysicalDeviceProperties());
32 
33  vk::PipelineCacheCreateInfo cache_info;
34  if (existing_cache_data) {
35  cache_info.initialDataSize = existing_cache_data->GetSize();
36  cache_info.pInitialData = existing_cache_data->GetMapping();
37  }
38 
39  auto [result, existing_cache] =
40  device_holder->GetDevice().createPipelineCacheUnique(cache_info);
41 
42  if (result == vk::Result::eSuccess) {
43  cache_ = std::move(existing_cache);
44  } else {
45  // Even though we perform consistency checks because we don't trust the
46  // driver, the driver may have additional information that may cause it to
47  // reject the cache too.
48  FML_LOG(INFO) << "Existing pipeline cache was invalid: "
49  << vk::to_string(result) << ". Starting with a fresh cache.";
50  cache_info.pInitialData = nullptr;
51  cache_info.initialDataSize = 0u;
52  auto [result2, new_cache] =
53  device_holder->GetDevice().createPipelineCacheUnique(cache_info);
54  if (result2 == vk::Result::eSuccess) {
55  cache_ = std::move(new_cache);
56  } else {
57  VALIDATION_LOG << "Could not create new pipeline cache: "
58  << vk::to_string(result2);
59  }
60  }
61 
62  is_valid_ = !!cache_;
63 }
64 
66  std::shared_ptr<DeviceHolderVK> device_holder = device_holder_.lock();
67  if (device_holder) {
68  cache_.reset();
69  } else {
70  cache_.release();
71  }
72 }
73 
75  return is_valid_;
76 }
77 
79  const vk::GraphicsPipelineCreateInfo& info) {
80  std::shared_ptr<DeviceHolderVK> strong_device = device_holder_.lock();
81  if (!strong_device) {
82  return {};
83  }
84 
85  auto [result, pipeline] =
86  strong_device->GetDevice().createGraphicsPipelineUnique(*cache_, info);
87  if (result != vk::Result::eSuccess) {
88  VALIDATION_LOG << "Could not create graphics pipeline: "
89  << vk::to_string(result);
90  }
91  return std::move(pipeline);
92 }
93 
95  const vk::ComputePipelineCreateInfo& info) {
96  std::shared_ptr<DeviceHolderVK> strong_device = device_holder_.lock();
97  if (!strong_device) {
98  return {};
99  }
100 
101  auto [result, pipeline] =
102  strong_device->GetDevice().createComputePipelineUnique(*cache_, info);
103  if (result != vk::Result::eSuccess) {
104  VALIDATION_LOG << "Could not create compute pipeline: "
105  << vk::to_string(result);
106  }
107  return std::move(pipeline);
108 }
109 
111  if (!is_valid_) {
112  return;
113  }
114  const auto& vk_caps = CapabilitiesVK::Cast(*caps_);
115  PipelineCacheDataPersist(cache_directory_, //
116  vk_caps.GetPhysicalDeviceProperties(), //
117  cache_ //
118  );
119 }
120 
122  return CapabilitiesVK::Cast(caps_.get());
123 }
124 
125 } // namespace impeller
static CapabilitiesVK & Cast(Capabilities &base)
Definition: backend_cast.h:13
The Vulkan layers and extensions wrangler.
PipelineCacheVK(std::shared_ptr< const Capabilities > caps, std::shared_ptr< DeviceHolderVK > device_holder, fml::UniqueFD cache_directory)
vk::UniquePipeline CreatePipeline(const vk::GraphicsPipelineCreateInfo &info)
const CapabilitiesVK * GetCapabilities() const
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...
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...
Definition: comparable.h:95
#define VALIDATION_LOG
Definition: validation.h:91