• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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