Flutter Impeller
pipeline_cache_data_vk_unittests.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 #include "flutter/fml/build_config.h"
6 #include "flutter/fml/file.h"
7 #include "flutter/testing/testing.h"
13 
14 namespace impeller::testing {
15 
16 TEST(PipelineCacheDataVKTest, CanTestHeaderCompatibility) {
17  {
20  EXPECT_EQ(a.abi, sizeof(void*));
21 #ifdef FML_ARCH_CPU_64_BITS
22  EXPECT_EQ(a.abi, 8u);
23 #elif FML_ARCH_CPU_32_BITS
24  EXPECT_EQ(a.abi, 4u);
25 #endif
26  EXPECT_TRUE(a.IsCompatibleWith(b));
27  }
28  // Different data sizes don't matter.
29  {
32  a.data_size = b.data_size + 100u;
33  EXPECT_TRUE(a.IsCompatibleWith(b));
34  }
35  // Magic, Driver, vendor, ABI, and UUID matter.
36  {
39  b.magic = 100;
40  EXPECT_FALSE(a.IsCompatibleWith(b));
41  }
42  {
45  b.driver_version = 100;
46  EXPECT_FALSE(a.IsCompatibleWith(b));
47  }
48  {
51  b.vendor_id = 100;
52  EXPECT_FALSE(a.IsCompatibleWith(b));
53  }
54  {
57  b.device_id = 100;
58  EXPECT_FALSE(a.IsCompatibleWith(b));
59  }
60  {
63  b.abi = a.abi / 2u;
64  EXPECT_FALSE(a.IsCompatibleWith(b));
65  }
66  {
69  for (size_t i = 0; i < VK_UUID_SIZE; i++) {
70  b.uuid[i] = a.uuid[i] + 1;
71  }
72  EXPECT_FALSE(a.IsCompatibleWith(b));
73  }
74 }
75 
76 TEST(PipelineCacheDataVKTest, CanCreateFromDeviceProperties) {
77  vk::PhysicalDeviceProperties props;
78  std::array<uint8_t, 16> uuid{
79  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
80  };
81  props.pipelineCacheUUID = uuid;
82  props.deviceID = 10;
83  props.vendorID = 11;
84  props.driverVersion = 12;
85  PipelineCacheHeaderVK header(props, 99);
86  EXPECT_EQ(uuid.size(), std::size(header.uuid));
87  EXPECT_EQ(props.deviceID, header.device_id);
88  EXPECT_EQ(props.vendorID, header.vendor_id);
89  EXPECT_EQ(props.driverVersion, header.driver_version);
90  for (size_t i = 0; i < uuid.size(); i++) {
91  EXPECT_EQ(header.uuid[i], uuid.at(i));
92  }
93 }
94 
97 
98 TEST_P(PipelineCacheDataVKPlaygroundTest, CanPersistAndRetrievePipelineCache) {
99  fml::ScopedTemporaryDirectory temp_dir;
100  const auto& surface_context = SurfaceContextVK::Cast(*GetContext());
101  const auto& context_vk = ContextVK::Cast(*surface_context.GetParent());
102  const auto& caps = CapabilitiesVK::Cast(*context_vk.GetCapabilities());
103 
104  {
105  auto cache = context_vk.GetDevice().createPipelineCacheUnique({});
106  ASSERT_EQ(cache.result, vk::Result::eSuccess);
107  ASSERT_FALSE(fml::FileExists(temp_dir.fd(), "flutter.impeller.vkcache"));
108  ASSERT_TRUE(PipelineCacheDataPersist(
109  temp_dir.fd(), caps.GetPhysicalDeviceProperties(), cache.value));
110  }
111  ASSERT_TRUE(fml::FileExists(temp_dir.fd(), "flutter.impeller.vkcache"));
112 
113  auto mapping = PipelineCacheDataRetrieve(temp_dir.fd(),
114  caps.GetPhysicalDeviceProperties());
115  ASSERT_NE(mapping, nullptr);
116  // Assert that the utility has stripped away the cache header giving us clean
117  // pipeline cache bootstrap information.
118  vk::PipelineCacheHeaderVersionOne vk_cache_header;
119  ASSERT_GE(mapping->GetSize(), sizeof(vk_cache_header));
120  std::memcpy(&vk_cache_header, mapping->GetMapping(), sizeof(vk_cache_header));
121  ASSERT_EQ(vk_cache_header.headerVersion,
122  vk::PipelineCacheHeaderVersion::eOne);
123 }
124 
126  IntegrityChecksArePerformedOnPersistedData) {
127  fml::ScopedTemporaryDirectory temp_dir;
128  const auto& surface_context = SurfaceContextVK::Cast(*GetContext());
129  const auto& context_vk = ContextVK::Cast(*surface_context.GetParent());
130  const auto& caps = CapabilitiesVK::Cast(*context_vk.GetCapabilities());
131 
132  {
133  auto cache = context_vk.GetDevice().createPipelineCacheUnique({});
134  ASSERT_EQ(cache.result, vk::Result::eSuccess);
135  ASSERT_FALSE(fml::FileExists(temp_dir.fd(), "flutter.impeller.vkcache"));
136  ASSERT_TRUE(PipelineCacheDataPersist(
137  temp_dir.fd(), caps.GetPhysicalDeviceProperties(), cache.value));
138  }
139  ASSERT_TRUE(fml::FileExists(temp_dir.fd(), "flutter.impeller.vkcache"));
140  auto incompatible_caps = caps.GetPhysicalDeviceProperties();
141  // Simulate a driver version bump.
142  incompatible_caps.driverVersion =
143  caps.GetPhysicalDeviceProperties().driverVersion + 1u;
144  auto mapping = PipelineCacheDataRetrieve(temp_dir.fd(), incompatible_caps);
145  ASSERT_EQ(mapping, nullptr);
146 }
147 
148 } // namespace impeller::testing
static SurfaceContextVK & Cast(Context &base)
Definition: backend_cast.h:13
TEST(AllocationSizeTest, CanCreateTypedAllocations)
TEST_P(AiksTest, DrawAtlasNoColor)
INSTANTIATE_VULKAN_PLAYGROUND_SUITE(DriverInfoVKTest)
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...
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.