| Flutter Impeller |

context_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/synchronization/waitable_event.h"
6 #include "flutter/testing/testing.h" // IWYU pragma: keep
7 #include "impeller/renderer/backend/vulkan/command_pool_vk.h"
8 #include "impeller/renderer/backend/vulkan/context_vk.h"
9 #include "impeller/renderer/backend/vulkan/test/mock_vulkan.h"
10
11 namespace impeller {
12 namespace testing {
13
14 TEST(ContextVKTest, DeletesCommandPools) {
15 std::weak_ptr<ContextVK> weak_context;
16 std::weak_ptr<CommandPoolVK> weak_pool;
17 {
18 std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
19 auto const pool = context->GetCommandPoolRecycler()->Get();
20 weak_pool = pool;
21 weak_context = context;
22 ASSERT_TRUE(weak_pool.lock());
23 ASSERT_TRUE(weak_context.lock());
24 }
25 ASSERT_FALSE(weak_pool.lock());
26 ASSERT_FALSE(weak_context.lock());
27 }
28
29 TEST(ContextVKTest, DeletesCommandPoolsOnAllThreads) {
30 std::weak_ptr<ContextVK> weak_context;
31 std::weak_ptr<CommandPoolVK> weak_pool_main;
32
33 std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
34 weak_pool_main = context->GetCommandPoolRecycler()->Get();
35 weak_context = context;
36 ASSERT_TRUE(weak_pool_main.lock());
37 ASSERT_TRUE(weak_context.lock());
38
39 // Start a second thread that obtains a command pool.
40 fml::AutoResetWaitableEvent latch1, latch2;
41 std::weak_ptr<CommandPoolVK> weak_pool_thread;
42 std::thread thread([&]() {
43 weak_pool_thread = context->GetCommandPoolRecycler()->Get();
44 latch1.Signal();
45 latch2.Wait();
46 });
47
48 // Delete the ContextVK on the main thread.
49 latch1.Wait();
50 context.reset();
51 ASSERT_FALSE(weak_pool_main.lock());
52 ASSERT_FALSE(weak_context.lock());
53
54 // Stop the second thread and check that its command pool has been deleted.
55 latch2.Signal();
56 thread.join();
57 ASSERT_FALSE(weak_pool_thread.lock());
58 }
59
60 TEST(ContextVKTest, DeletePipelineAfterContext) {
61 std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline;
62 std::shared_ptr<std::vector<std::string>> functions;
63 {
64 std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
65 PipelineDescriptor pipeline_desc;
66 pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
67 PipelineFuture<PipelineDescriptor> pipeline_future =
68 context->GetPipelineLibrary()->GetPipeline(pipeline_desc);
69 pipeline = pipeline_future.Get();
70 ASSERT_TRUE(pipeline);
71 functions = GetMockVulkanFunctions(context->GetDevice());
72 ASSERT_TRUE(std::find(functions->begin(), functions->end(),
73 "vkCreateGraphicsPipelines") != functions->end());
74 }
75 ASSERT_TRUE(std::find(functions->begin(), functions->end(),
76 "vkDestroyDevice") != functions->end());
77 }
78
79 TEST(ContextVKTest, DeleteShaderFunctionAfterContext) {
80 std::shared_ptr<const ShaderFunction> shader_function;
81 std::shared_ptr<std::vector<std::string>> functions;
82 {
83 std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
84 PipelineDescriptor pipeline_desc;
85 pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
86 std::vector<uint8_t> data = {0x03, 0x02, 0x23, 0x07};
87 context->GetShaderLibrary()->RegisterFunction(
88 "foobar", ShaderStage::kFragment,
89 std::make_shared<fml::DataMapping>(data), [](bool) {});
90 shader_function = context->GetShaderLibrary()->GetFunction(
91 "foobar_fragment_main", ShaderStage::kFragment);
92 ASSERT_TRUE(shader_function);
93 functions = GetMockVulkanFunctions(context->GetDevice());
94 ASSERT_TRUE(std::find(functions->begin(), functions->end(),
95 "vkCreateShaderModule") != functions->end());
96 }
97 ASSERT_TRUE(std::find(functions->begin(), functions->end(),
98 "vkDestroyDevice") != functions->end());
99 }
100
101 TEST(ContextVKTest, DeletePipelineLibraryAfterContext) {
102 std::shared_ptr<PipelineLibrary> pipeline_library;
103 std::shared_ptr<std::vector<std::string>> functions;
104 {
105 std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
106 PipelineDescriptor pipeline_desc;
107 pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
108 pipeline_library = context->GetPipelineLibrary();
109 functions = GetMockVulkanFunctions(context->GetDevice());
110 ASSERT_TRUE(std::find(functions->begin(), functions->end(),
111 "vkCreatePipelineCache") != functions->end());
112 }
113 ASSERT_TRUE(std::find(functions->begin(), functions->end(),
114 "vkDestroyDevice") != functions->end());
115 }
116
117 TEST(ContextVKTest, CanCreateContextInAbsenceOfValidationLayers) {
118 // The mocked methods don't report the presence of a validation layer but we
119 // explicitly ask for validation. Context creation should continue anyway.
120 auto context = MockVulkanContextBuilder()
121 .SetSettingsCallback([](auto& settings) {
122 settings.enable_validation = true;
123 })
124 .Build();
125 ASSERT_NE(context, nullptr);
126 const CapabilitiesVK* capabilites_vk =
127 reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
128 ASSERT_FALSE(capabilites_vk->AreValidationsEnabled());
129 }
130
131 TEST(ContextVKTest, CanCreateContextWithValidationLayers) {
132 auto context =
133 MockVulkanContextBuilder()
134 .SetSettingsCallback(
135 [](auto& settings) { settings.enable_validation = true; })
136 .SetInstanceExtensions(
137 {"VK_KHR_surface", "VK_MVK_macos_surface", "VK_EXT_debug_utils"})
138 .SetInstanceLayers({"VK_LAYER_KHRONOS_validation"})
139 .Build();
140 ASSERT_NE(context, nullptr);
141 const CapabilitiesVK* capabilites_vk =
142 reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
143 ASSERT_TRUE(capabilites_vk->AreValidationsEnabled());
144 }
145
146 } // namespace testing
147 } // namespace impeller
impeller::PipelineDescriptor
Definition: pipeline_descriptor.h:29
impeller::PipelineFuture
Definition: pipeline.h:24
command_pool_vk.h
impeller::testing::TEST
TEST(CanvasRecorder, Save)
Definition: canvas_recorder_unittests.cc:61
impeller::ShaderStage::kFragment
@ kFragment
impeller::CapabilitiesVK
The Vulkan layers and extensions wrangler.
Definition: capabilities_vk.h:33
impeller::PipelineFuture::Get
const std::shared_ptr< Pipeline< T > > Get() const
Definition: pipeline.h:28
impeller::CapabilitiesVK::AreValidationsEnabled
bool AreValidationsEnabled() const
Definition: capabilities_vk.cc:62
context_vk.h
impeller
Definition: aiks_context.cc:10
impeller::PipelineDescriptor::SetVertexDescriptor
PipelineDescriptor & SetVertexDescriptor(std::shared_ptr< VertexDescriptor > vertex_descriptor)
Definition: pipeline_descriptor.cc:98