Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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) {
199 handle_ = fml::NativeLibrary::Create(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
#define ACQUIRE_PROC(name, instance, device)
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 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
fuchsia::ui::composition::ParentViewportWatcherHandle handle_
#define ERROR(message)
void(VKAPI_PTR * PFN_vkVoidFunction)(void)
#define VK_NULL_HANDLE
Definition vulkan_core.h:46
PFN_vkVoidFunction(VKAPI_PTR * PFN_vkGetInstanceProcAddr)(VkInstance instance, const char *pName)
#define ACQUIRE_PROC_EITHER(name, name2, context)