1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <mutex>
17 #include <malloc.h>
18 #include <string>
19 #include <vector>
20 #include "swapchain.h"
21 #include "driver_loader.h"
22 #include "vulkan/vk_ohos_native_buffer.h"
23 #include "wrapper_log.h"
24
25 namespace vulkan {
26 namespace driver {
27 DriverLoader DriverLoader::loader_;
28 PFN_vkGetDeviceProcAddr pfn_vkGetDeviceProcAddr = nullptr;
29 PFN_vkGetPhysicalDeviceProperties2KHR fpn_vkGetPhysicalDeviceProperties2KHR = nullptr;
30 PFN_vkCreateDevice pfn_vkCreateDevice = nullptr;
31 PFN_vkGetNativeFenceFdOpenHarmony pfn_vkGetNativeFenceFdOpenHarmony = nullptr;
32 PFN_vkGetPhysicalDeviceProperties pfn_vkGetPhysicalDeviceProperties = nullptr;
33 PFN_vkGetPhysicalDeviceFeatures pfn_vkGetPhysicalDeviceFeatures = nullptr;
34 PFN_vkGetPhysicalDeviceMemoryProperties pfn_vkGetPhysicalDeviceMemoryProperties = nullptr;
35 PFN_vkGetPhysicalDeviceQueueFamilyProperties pfn_vkGetPhysicalDeviceQueueFamilyProperties = nullptr;
36
IsSupportedVulkan()37 bool IsSupportedVulkan()
38 {
39 DriverLoader::Load();
40 return DriverLoader::IsSupportedVulkan();
41 }
42
CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)43 VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
44 const VkAllocationCallbacks* pAllocator,
45 VkInstance* pInstance)
46 {
47 if (!DriverLoader::Load()) {
48 return VK_ERROR_INITIALIZATION_FAILED;
49 }
50 if (pAllocator == nullptr) {
51 pAllocator = &GetDefaultAllocator();
52 }
53 VkResult result = VK_SUCCESS;
54
55 result = DriverLoader::GetVulkanFuncs().PFN_vkCreateInstance(pCreateInfo, pAllocator, pInstance);
56 if (result != VK_SUCCESS) {
57 return result;
58 }
59 pfn_vkGetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
60 DriverLoader::GetVulkanFuncs().PFN_vkGetInstanceProcAddr(*pInstance, "vkGetDeviceProcAddr"));
61 fpn_vkGetPhysicalDeviceProperties2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>(
62 DriverLoader::GetVulkanFuncs().PFN_vkGetInstanceProcAddr(*pInstance, "vkGetPhysicalDeviceProperties2KHR"));
63 pfn_vkCreateDevice = reinterpret_cast<PFN_vkCreateDevice>(
64 DriverLoader::GetVulkanFuncs().PFN_vkGetInstanceProcAddr(*pInstance, "vkCreateDevice"));
65 pfn_vkGetPhysicalDeviceProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(
66 DriverLoader::GetVulkanFuncs().PFN_vkGetInstanceProcAddr(*pInstance, "vkGetPhysicalDeviceProperties"));
67 pfn_vkGetPhysicalDeviceFeatures = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures>(
68 DriverLoader::GetVulkanFuncs().PFN_vkGetInstanceProcAddr(*pInstance, "vkGetPhysicalDeviceFeatures"));
69 pfn_vkGetPhysicalDeviceMemoryProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties>(
70 DriverLoader::GetVulkanFuncs().PFN_vkGetInstanceProcAddr(*pInstance, "vkGetPhysicalDeviceMemoryProperties"));
71 pfn_vkGetPhysicalDeviceQueueFamilyProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties>(
72 DriverLoader::GetVulkanFuncs().PFN_vkGetInstanceProcAddr(*pInstance,
73 "vkGetPhysicalDeviceQueueFamilyProperties"));
74 return VK_SUCCESS;
75 }
76
77
EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)78 VkResult EnumerateInstanceExtensionProperties(const char* pLayerName,
79 uint32_t* pPropertyCount, VkExtensionProperties* pProperties)
80 {
81 if (!DriverLoader::Load()) {
82 return VK_ERROR_INITIALIZATION_FAILED;
83 }
84
85 VkResult result = DriverLoader::GetVulkanFuncs().PFN_vkEnumerateInstanceExtensionProperties(
86 pLayerName, pPropertyCount, pProperties);
87 if (result != VK_SUCCESS) {
88 return result;
89 }
90 return VK_SUCCESS;
91 }
92
GetInstanceProcAddr(VkInstance instance,const char * pName)93 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName)
94 {
95 if (!DriverLoader::Load()) {
96 return nullptr;
97 }
98
99 if (std::strcmp(pName, "vkCreateOHOSSurfaceOpenHarmony") == 0) {
100 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::CreateOHOSSurfaceOpenHarmony);
101 }
102
103 if (std::strcmp(pName, "vkGetPhysicalDeviceSurfaceSupportKHR") == 0) {
104 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::GetPhysicalDeviceSurfaceSupportKHR);
105 }
106
107 if (std::strcmp(pName, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR") == 0) {
108 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::GetPhysicalDeviceSurfaceCapabilitiesKHR);
109 }
110
111 if (std::strcmp(pName, "vkGetPhysicalDeviceSurfaceFormatsKHR") == 0) {
112 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::GetPhysicalDeviceSurfaceFormatsKHR);
113 }
114
115 if (std::strcmp(pName, "vkGetPhysicalDeviceSurfacePresentModesKHR") == 0) {
116 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::GetPhysicalDeviceSurfacePresentModesKHR);
117 }
118
119 if (std::strcmp(pName, "vkDestroySurfaceKHR") == 0) {
120 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::DestroySurfaceKHR);
121 }
122
123 if (std::strcmp(pName, "vkCreateDevice") == 0) {
124 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::CreateDevice);
125 }
126
127 if (std::strcmp(pName, "vkDestroyInstance") == 0) {
128 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::DestroyInstance);
129 }
130
131 PFN_vkVoidFunction func = DriverLoader::GetVulkanFuncs().PFN_vkGetInstanceProcAddr(instance, pName);
132 if (!func) {
133 WLOGE("GetInstanceProcAddr %{public}s failed, please check", pName);
134 }
135
136 return func;
137 }
138
DestroyInstance(VkInstance instance,const VkAllocationCallbacks * pAllocator)139 void DestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator)
140 {
141 PFN_vkDestroyInstance pfn_vkDestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
142 DriverLoader::GetVulkanFuncs().PFN_vkGetInstanceProcAddr(instance, "vkDestroyInstance"));
143 if (pfn_vkDestroyInstance) {
144 pfn_vkDestroyInstance(instance, pAllocator);
145 }
146
147 if (!DriverLoader::Unload()) {
148 WLOGE("DriverLoader::Unload() failed");
149 }
150 }
151
CreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)152 VkResult CreateDevice(VkPhysicalDevice physicalDevice,
153 const VkDeviceCreateInfo* pCreateInfo,
154 const VkAllocationCallbacks* pAllocator,
155 VkDevice* pDevice)
156 {
157 VkResult result = VK_SUCCESS;
158 if (pfn_vkCreateDevice) {
159 std::vector<const char*> deviceExtensions;
160
161 auto& ext_names = (*pCreateInfo).ppEnabledExtensionNames;
162 auto& ext_count = (*pCreateInfo).enabledExtensionCount;
163 for (uint32_t i = 0; i < ext_count; i++) {
164 deviceExtensions.push_back(ext_names[i]);
165 }
166 deviceExtensions.push_back(VK_OHOS_NATIVE_BUFFER_EXTENSION_NAME);
167 deviceExtensions.push_back(VK_OPENHARMONY_EXTERNAL_MEMORY_OHOS_NATIVE_BUFFER_EXTENSION_NAME);
168 VkDeviceCreateInfo createInfo(*pCreateInfo);
169
170 createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
171 createInfo.ppEnabledExtensionNames = deviceExtensions.data();
172
173 result = pfn_vkCreateDevice(physicalDevice, &createInfo, pAllocator, pDevice);
174 }
175
176 if ((result == VK_SUCCESS) && (pfn_vkGetDeviceProcAddr != nullptr)) {
177 pfn_vkGetNativeFenceFdOpenHarmony= reinterpret_cast<PFN_vkGetNativeFenceFdOpenHarmony>(
178 pfn_vkGetDeviceProcAddr(*pDevice, "vkGetNativeFenceFdOpenHarmony"));
179 if (!pfn_vkGetNativeFenceFdOpenHarmony) {
180 WLOGE("vulkan::driver::CreateDevice Get vkGetNativeFenceFdOpenHarmony failed");
181 }
182 }
183
184 return result;
185 }
186
187
GetDeviceProcAddr(VkDevice device,const char * pName)188 PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName)
189 {
190 PFN_vkVoidFunction func = nullptr;
191
192 if (!pfn_vkGetDeviceProcAddr) {
193 WLOGE("pfn_vkGetDeviceProcAddr is null, please check");
194 return nullptr;
195 }
196 if (std::strcmp(pName, "vkCreateSwapchainKHR") == 0) {
197 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::CreateSwapchainKHR);
198 }
199
200 if (std::strcmp(pName, "vkDestroySwapchainKHR") == 0) {
201 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::DestroySwapchainKHR);
202 }
203
204 if (std::strcmp(pName, "vkGetSwapchainImagesKHR") == 0) {
205 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::GetSwapchainImagesKHR);
206 }
207
208 if (std::strcmp(pName, "vkAcquireNextImageKHR") == 0) {
209 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::AcquireNextImageKHR);
210 }
211
212 if (std::strcmp(pName, "vkAcquireNextImage2KHR") == 0) {
213 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::AcquireNextImage2KHR);
214 }
215
216 if (std::strcmp(pName, "vkQueuePresentKHR") == 0) {
217 return reinterpret_cast<PFN_vkVoidFunction>(vulkan::driver::QueuePresentKHR);
218 }
219 func = pfn_vkGetDeviceProcAddr(device, pName);
220 if (!func) {
221 WLOGE("GetDeviceProcAddr %{public}s is null, please check", pName);
222 }
223
224 return func;
225 }
226
DestroyImage(VkDevice device,VkImage image,const VkAllocationCallbacks * pAllocator)227 void DestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator)
228 {
229 PFN_vkDestroyImage destroyImage = reinterpret_cast<PFN_vkDestroyImage>(GetDeviceProcAddr(device, "vkDestroyImage"));
230 if (destroyImage) {
231 return destroyImage(device, image, pAllocator);
232 }
233 return;
234 }
235
CreateImage(VkDevice device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage)236 VkResult CreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo,
237 const VkAllocationCallbacks* pAllocator, VkImage* pImage)
238 {
239 PFN_vkCreateImage createImage = reinterpret_cast<PFN_vkCreateImage>(GetDeviceProcAddr(device, "vkCreateImage"));
240 if (createImage) {
241 return createImage(device, pCreateInfo, pAllocator, pImage);
242 }
243 return VK_ERROR_INITIALIZATION_FAILED;
244 }
245
QueryPresentationProperties(VkPhysicalDevice physicalDevice,VkPhysicalDevicePresentationPropertiesOpenHarmony * presentation_properties)246 void QueryPresentationProperties(
247 VkPhysicalDevice physicalDevice,
248 VkPhysicalDevicePresentationPropertiesOpenHarmony* presentation_properties)
249 {
250 VkPhysicalDeviceProperties2 properties = {
251 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
252 presentation_properties,
253 {},
254 };
255
256 presentation_properties->sType =
257 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_OPENHARMONY;
258 presentation_properties->pNext = nullptr;
259 presentation_properties->sharedImage = VK_FALSE;
260
261 GetPhysicalDeviceProperties2(physicalDevice, &properties);
262 }
263
GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties2 * pProperties)264 void GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties)
265 {
266 if (fpn_vkGetPhysicalDeviceProperties2KHR) {
267 fpn_vkGetPhysicalDeviceProperties2KHR(physicalDevice, pProperties);
268 }
269 }
270
SetNativeFenceFdOpenHarmony(VkDevice device,int nativeFenceFd,VkSemaphore semaphore,VkFence fence)271 VkResult SetNativeFenceFdOpenHarmony(VkDevice device,
272 int nativeFenceFd,
273 VkSemaphore semaphore,
274 VkFence fence)
275 {
276 PFN_vkSetNativeFenceFdOpenHarmony acquireImage = reinterpret_cast<PFN_vkSetNativeFenceFdOpenHarmony>(
277 GetDeviceProcAddr(device, "vkSetNativeFenceFdOpenHarmony"));
278 if (acquireImage) {
279 return acquireImage(device, nativeFenceFd, semaphore, fence);
280 }
281 return VK_ERROR_INITIALIZATION_FAILED;
282 }
283
GetNativeFenceFdOpenHarmony(VkQueue queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image,int * pNativeFenceFd)284 VkResult GetNativeFenceFdOpenHarmony(
285 VkQueue queue,
286 uint32_t waitSemaphoreCount,
287 const VkSemaphore* pWaitSemaphores,
288 VkImage image,
289 int* pNativeFenceFd)
290 {
291 if (pfn_vkGetNativeFenceFdOpenHarmony) {
292 return pfn_vkGetNativeFenceFdOpenHarmony(queue, waitSemaphoreCount, pWaitSemaphores, image, pNativeFenceFd);
293 }
294 return VK_ERROR_INITIALIZATION_FAILED;
295 }
296 } // namespace driver
297 } // namespace vulkan
298