| 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"
8 #include "impeller/playground/playground_test.h"
9 #include "impeller/renderer/backend/vulkan/capabilities_vk.h"
10 #include "impeller/renderer/backend/vulkan/context_vk.h"
11 #include "impeller/renderer/backend/vulkan/pipeline_cache_data_vk.h"
12 #include "impeller/renderer/backend/vulkan/surface_context_vk.h"
13
14 namespace impeller::testing {
15
16 TEST(PipelineCacheDataVKTest, CanTestHeaderCompatibility) {
17 {
18 PipelineCacheHeaderVK a;
19 PipelineCacheHeaderVK b;
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 {
30 PipelineCacheHeaderVK a;
31 PipelineCacheHeaderVK b;
32 a.data_size = b.data_size + 100u;
33 EXPECT_TRUE(a.IsCompatibleWith(b));
34 }
35 // Magic, Driver, vendor, ABI, and UUID matter.
36 {
37 PipelineCacheHeaderVK a;
38 PipelineCacheHeaderVK b;
39 b.magic = 100;
40 EXPECT_FALSE(a.IsCompatibleWith(b));
41 }
42 {
43 PipelineCacheHeaderVK a;
44 PipelineCacheHeaderVK b;
45 b.driver_version = 100;
46 EXPECT_FALSE(a.IsCompatibleWith(b));
47 }
48 {
49 PipelineCacheHeaderVK a;
50 PipelineCacheHeaderVK b;
51 b.vendor_id = 100;
52 EXPECT_FALSE(a.IsCompatibleWith(b));
53 }
54 {
55 PipelineCacheHeaderVK a;
56 PipelineCacheHeaderVK b;
57 b.device_id = 100;
58 EXPECT_FALSE(a.IsCompatibleWith(b));
59 }
60 {
61 PipelineCacheHeaderVK a;
62 PipelineCacheHeaderVK b;
63 b.abi = a.abi / 2u;
64 EXPECT_FALSE(a.IsCompatibleWith(b));
65 }
66 {
67 PipelineCacheHeaderVK a;
68 PipelineCacheHeaderVK b;
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
95 using PipelineCacheDataVKPlaygroundTest = PlaygroundTest;
96 INSTANTIATE_VULKAN_PLAYGROUND_SUITE(PipelineCacheDataVKPlaygroundTest);
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
125 TEST_P(PipelineCacheDataVKPlaygroundTest,
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
capabilities_vk.h
impeller::BackendCast< SurfaceContextVK, Context >::Cast
static SurfaceContextVK & Cast(Context &base)
Definition: backend_cast.h:13
impeller::PlaygroundTest
Definition: playground_test.h:22
impeller::saturated::b
SI b
Definition: saturated_math.h:87
impeller::testing
Definition: allocation_size_unittests.cc:8
impeller::testing::TEST
TEST(AllocationSizeTest, CanCreateTypedAllocations)
Definition: allocation_size_unittests.cc:10
impeller::testing::TEST_P
TEST_P(AiksTest, DrawAtlasNoColor)
Definition: aiks_dl_atlas_unittests.cc:60
impeller::testing::INSTANTIATE_VULKAN_PLAYGROUND_SUITE
INSTANTIATE_VULKAN_PLAYGROUND_SUITE(DriverInfoVKTest)
impeller::PipelineCacheDataRetrieve
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...
Definition: pipeline_cache_data_vk.cc:62
impeller::PipelineCacheDataPersist
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: pipeline_cache_data_vk.cc:16
pipeline_cache_data_vk.h
playground_test.h
context_vk.h
impeller::PipelineCacheHeaderVK
An Impeller specific header prepended to all pipeline cache information that is persisted on disk....
Definition: pipeline_cache_data_vk.h:23
impeller::PipelineCacheHeaderVK::abi
uint32_t abi
Definition: pipeline_cache_data_vk.h:34
impeller::PipelineCacheHeaderVK::data_size
uint64_t data_size
Definition: pipeline_cache_data_vk.h:36
impeller::PipelineCacheHeaderVK::driver_version
uint32_t driver_version
Definition: pipeline_cache_data_vk.h:29
impeller::PipelineCacheHeaderVK::device_id
uint32_t device_id
Definition: pipeline_cache_data_vk.h:31
impeller::PipelineCacheHeaderVK::IsCompatibleWith
bool IsCompatibleWith(const PipelineCacheHeaderVK &other) const
Determines whether the specified o is compatible with.
Definition: pipeline_cache_data_vk.cc:110
impeller::PipelineCacheHeaderVK::vendor_id
uint32_t vendor_id
Definition: pipeline_cache_data_vk.h:30
impeller::PipelineCacheHeaderVK::uuid
uint8_t uuid[VK_UUID_SIZE]
Definition: pipeline_cache_data_vk.h:35
surface_context_vk.h