Flutter Engine
The Flutter Engine
vulkan_proc_table.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/vulkan/procs/vulkan_proc_table.h"
6
7#include <utility>
8
9#include "flutter/fml/logging.h"
10
11#define ACQUIRE_PROC(name, context) \
12 if (!(name = AcquireProc("vk" #name, context))) { \
13 return false; \
14 }
15
16#define ACQUIRE_PROC_EITHER(name, name2, context) \
17 if (!(name = AcquireProc("vk" #name, context)) && \
18 !(name2 = AcquireProc("vk" #name2, context))) { \
19 return false; \
20 }
21
22namespace vulkan {
23
25
27 : handle_(nullptr), acquired_mandatory_proc_addresses_(false) {
28 acquired_mandatory_proc_addresses_ = OpenLibraryHandle(so_path) &&
29 SetupGetInstanceProcAddress() &&
30 SetupLoaderProcAddresses();
31}
32
35 : handle_(nullptr), acquired_mandatory_proc_addresses_(false) {
37 acquired_mandatory_proc_addresses_ = SetupLoaderProcAddresses();
38}
39
41 CloseLibraryHandle();
42}
43
45 return acquired_mandatory_proc_addresses_;
46}
47
49 return instance_ && device_;
50}
51
53 return instance_;
54}
55
57 return device_;
58}
59
60bool VulkanProcTable::SetupGetInstanceProcAddress() {
61 if (!handle_) {
62 return true;
63 }
64
67 FML_DLOG(WARNING) << "Could not acquire vkGetInstanceProcAddr.";
68 return false;
69 }
70
71 return true;
72}
73
77 }
78
79 auto instance_proc =
80 const_cast<uint8_t*>(handle_->ResolveSymbol("vkGetInstanceProcAddr"));
81 return reinterpret_cast<PFN_vkGetInstanceProcAddr>(instance_proc);
82}
83
84bool VulkanProcTable::SetupLoaderProcAddresses() {
85 VulkanHandle<VkInstance> null_instance(VK_NULL_HANDLE, nullptr);
86
87 ACQUIRE_PROC(CreateInstance, null_instance);
88 ACQUIRE_PROC(EnumerateInstanceExtensionProperties, null_instance);
89 ACQUIRE_PROC(EnumerateInstanceLayerProperties, null_instance);
90
91 return true;
92}
93
95 const VulkanHandle<VkInstance>& handle) {
96 ACQUIRE_PROC(CreateDevice, handle);
97 ACQUIRE_PROC(DestroyDevice, handle);
98 ACQUIRE_PROC(DestroyInstance, handle);
99 ACQUIRE_PROC(EnumerateDeviceLayerProperties, handle);
100 ACQUIRE_PROC(EnumeratePhysicalDevices, handle);
101 ACQUIRE_PROC(GetDeviceProcAddr, handle);
102 ACQUIRE_PROC(GetPhysicalDeviceFeatures, handle);
103 ACQUIRE_PROC(GetPhysicalDeviceQueueFamilyProperties, handle);
104 ACQUIRE_PROC(GetPhysicalDeviceProperties, handle);
105 ACQUIRE_PROC(GetPhysicalDeviceMemoryProperties, handle);
106 ACQUIRE_PROC_EITHER(GetPhysicalDeviceMemoryProperties2,
107 GetPhysicalDeviceMemoryProperties2KHR, handle);
108
109#if FML_OS_ANDROID
110 ACQUIRE_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR, handle);
111 ACQUIRE_PROC(GetPhysicalDeviceSurfaceFormatsKHR, handle);
112 ACQUIRE_PROC(GetPhysicalDeviceSurfacePresentModesKHR, handle);
113 ACQUIRE_PROC(GetPhysicalDeviceSurfaceSupportKHR, handle);
114 ACQUIRE_PROC(DestroySurfaceKHR, handle);
115 ACQUIRE_PROC(CreateAndroidSurfaceKHR, handle);
116#endif // FML_OS_ANDROID
117
118 // The debug report functions are optional. We don't want proc acquisition to
119 // fail here because the optional methods were not present (since ACQUIRE_PROC
120 // returns false on failure). Wrap the optional proc acquisitions in an
121 // anonymous lambda and invoke it. We don't really care about the result since
122 // users of Debug reporting functions check for their presence explicitly.
123 [this, &handle]() -> bool {
124 ACQUIRE_PROC(CreateDebugReportCallbackEXT, handle);
125 ACQUIRE_PROC(DestroyDebugReportCallbackEXT, handle);
126 return true;
127 }();
128
129 instance_ = VulkanHandle<VkInstance>{handle, nullptr};
130 return true;
131}
132
134 const VulkanHandle<VkDevice>& handle) {
135 ACQUIRE_PROC(AllocateCommandBuffers, handle);
136 ACQUIRE_PROC(AllocateMemory, handle);
137 ACQUIRE_PROC(BeginCommandBuffer, handle);
138 ACQUIRE_PROC(BindImageMemory, handle);
139 ACQUIRE_PROC(CmdPipelineBarrier, handle);
140 ACQUIRE_PROC(CreateCommandPool, handle);
141 ACQUIRE_PROC(CreateFence, handle);
142 ACQUIRE_PROC(CreateImage, handle);
143 ACQUIRE_PROC(CreateSemaphore, handle);
144 ACQUIRE_PROC(DestroyCommandPool, handle);
145 ACQUIRE_PROC(DestroyFence, handle);
146 ACQUIRE_PROC(DestroyImage, handle);
147 ACQUIRE_PROC(DestroySemaphore, handle);
148 ACQUIRE_PROC(DeviceWaitIdle, handle);
149 ACQUIRE_PROC(EndCommandBuffer, handle);
150 ACQUIRE_PROC(FreeCommandBuffers, handle);
151 ACQUIRE_PROC(FreeMemory, handle);
152 ACQUIRE_PROC(GetDeviceQueue, handle);
153 ACQUIRE_PROC(GetImageMemoryRequirements, handle);
154 ACQUIRE_PROC(QueueSubmit, handle);
155 ACQUIRE_PROC(QueueWaitIdle, handle);
156 ACQUIRE_PROC(ResetCommandBuffer, handle);
157 ACQUIRE_PROC(ResetFences, handle);
158 ACQUIRE_PROC(WaitForFences, handle);
159 ACQUIRE_PROC(MapMemory, handle);
160 ACQUIRE_PROC(UnmapMemory, handle);
161 ACQUIRE_PROC(FlushMappedMemoryRanges, handle);
162 ACQUIRE_PROC(InvalidateMappedMemoryRanges, handle);
163 ACQUIRE_PROC(BindBufferMemory, handle);
164 ACQUIRE_PROC(GetBufferMemoryRequirements, handle);
165 ACQUIRE_PROC(CreateBuffer, handle);
166 ACQUIRE_PROC(DestroyBuffer, handle);
167 ACQUIRE_PROC(CmdCopyBuffer, handle);
168
169 ACQUIRE_PROC_EITHER(GetBufferMemoryRequirements2,
170 GetBufferMemoryRequirements2KHR, handle);
171 ACQUIRE_PROC_EITHER(GetImageMemoryRequirements2,
172 GetImageMemoryRequirements2KHR, handle);
173 ACQUIRE_PROC_EITHER(BindBufferMemory2, BindBufferMemory2KHR, handle);
174 ACQUIRE_PROC_EITHER(BindImageMemory2, BindImageMemory2KHR, handle);
175
176#ifndef TEST_VULKAN_PROCS
177#if FML_OS_ANDROID
178 ACQUIRE_PROC(AcquireNextImageKHR, handle);
179 ACQUIRE_PROC(CreateSwapchainKHR, handle);
180 ACQUIRE_PROC(DestroySwapchainKHR, handle);
181 ACQUIRE_PROC(GetSwapchainImagesKHR, handle);
182 ACQUIRE_PROC(QueuePresentKHR, handle);
183#endif // FML_OS_ANDROID
184#if OS_FUCHSIA
185 ACQUIRE_PROC(ImportSemaphoreZirconHandleFUCHSIA, handle);
186 ACQUIRE_PROC(GetSemaphoreZirconHandleFUCHSIA, handle);
187 ACQUIRE_PROC(GetMemoryZirconHandleFUCHSIA, handle);
188 ACQUIRE_PROC(CreateBufferCollectionFUCHSIA, handle);
189 ACQUIRE_PROC(DestroyBufferCollectionFUCHSIA, handle);
190 ACQUIRE_PROC(SetBufferCollectionImageConstraintsFUCHSIA, handle);
191 ACQUIRE_PROC(GetBufferCollectionPropertiesFUCHSIA, handle);
192#endif // OS_FUCHSIA
193#endif // TEST_VULKAN_PROCS
194 device_ = VulkanHandle<VkDevice>{handle, nullptr};
195 return true;
196}
197
198bool VulkanProcTable::OpenLibraryHandle(const char* path) {
200 if (!handle_) {
201 FML_DLOG(ERROR) << "Could not open Vulkan library handle: " << path;
202 return false;
203 }
204 return true;
205}
206
207bool VulkanProcTable::CloseLibraryHandle() {
208 handle_ = nullptr;
209 return true;
210}
211
213 const char* proc_name,
214 const VulkanHandle<VkInstance>& instance) const {
215 if (proc_name == nullptr || !GetInstanceProcAddr) {
216 return nullptr;
217 }
218
219 // A VK_NULL_HANDLE as the instance is an acceptable parameter.
220 return reinterpret_cast<PFN_vkVoidFunction>(
221 GetInstanceProcAddr(instance, proc_name));
222}
223
225 const char* proc_name,
226 const VulkanHandle<VkDevice>& device) const {
227 if (proc_name == nullptr || !device || !GetDeviceProcAddr) {
228 return nullptr;
229 }
230
231 return GetDeviceProcAddr(device, proc_name);
232}
233
234} // namespace vulkan
static fml::RefPtr< NativeLibrary > Create(const char *path)
const uint8_t * ResolveSymbol(const char *symbol)
bool SetupInstanceProcAddresses(const VulkanHandle< VkInstance > &instance)
PFN_vkVoidFunction AcquireProc(const char *proc_name, const VulkanHandle< VkInstance > &instance) const
PFN_vkGetInstanceProcAddr NativeGetInstanceProcAddr() const
bool HasAcquiredMandatoryProcAddresses() const
PFN_vkGetInstanceProcAddr GetInstanceProcAddr
bool AreInstanceProcsSetup() const
bool SetupDeviceProcAddresses(const VulkanHandle< VkDevice > &device)
decltype(vkGetInstanceProcAddr) * get_instance_proc_addr
VkDevice device
Definition: main.cc:53
VkInstance instance
Definition: main.cc:48
#define FML_DLOG(severity)
Definition: logging.h:102
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
fuchsia::ui::composition::ParentViewportWatcherHandle handle_
#define ERROR(message)
Definition: elf_loader.cc:260
void(VKAPI_PTR * PFN_vkVoidFunction)(void)
Definition: vulkan_core.h:2992
#define VK_NULL_HANDLE
Definition: vulkan_core.h:46
PFN_vkVoidFunction(VKAPI_PTR * PFN_vkGetInstanceProcAddr)(VkInstance instance, const char *pName)
Definition: vulkan_core.h:3989
#define ACQUIRE_PROC(name, context)
#define ACQUIRE_PROC_EITHER(name, name2, context)