• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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, Hardware
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 <cstddef>
17 #include <vulkan/vulkan_core.h>
18 #include <window.h>
19 #include <gtest/gtest.h>
20 #include <dlfcn.h>
21 #include <iostream>
22 #include <string>
23 #include <vector>
24 #include <sstream>
25 
26 #include "refbase.h"
27 #include "surface.h"
28 #include "vulkan/vulkan.h"
29 #include "render_context/render_context.h"
30 #include "transaction/rs_transaction.h"
31 #include "ui/rs_surface_extractor.h"
32 #include "ui/rs_surface_node.h"
33 
34 using namespace testing;
35 using namespace testing::ext;
36 using namespace OHOS::Rosen;
37 
38 namespace vulkan::loader {
39 class VulkanLoaderUnitTest : public testing::Test {
40 public:
SetUpTestCase()41     static void SetUpTestCase() {}
42     static void TearDownTestCase();
SetUp()43     void SetUp() {}
TearDown()44     void TearDown() {}
45     uint32_t GetQueueFamilyIndex(VkQueueFlagBits queueFlags);
46     OHNativeWindow* CreateNativeWindow(std::string name);
47     VkSwapchainCreateInfoKHR GetSwapchainCreateInfo(
48         VkFormat imageFormat, VkColorSpaceKHR imageColorSpace,
49         VkSurfaceTransformFlagBitsKHR transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR);
50     static VkBool32 UserCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
51         VkDebugUtilsMessageTypeFlagsEXT messageType,
52         const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
53         void* pUserData);
54 
55     static inline void DLOpenLibVulkan();
56     static inline void TrytoCreateVkInstance();
57 
58     static inline PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
59     static inline PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties;
60     static inline PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
61     static inline PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties;
62     static inline PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT;
63     static inline PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT;
64     static inline PFN_vkCreateInstance vkCreateInstance;
65     static inline PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
66     static inline PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
67 
68     static inline PFN_vkDestroyInstance vkDestroyInstance;
69     static inline PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
70     static inline PFN_vkCreateDevice vkCreateDevice;
71     static inline PFN_vkDestroyDevice vkDestroyDevice;
72     static inline PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
73     static inline PFN_vkCreateSurfaceOHOS vkCreateSurfaceOHOS;
74     static inline PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fpGetPhysicalDeviceSurfaceCapabilitiesKHR;
75     static inline PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR;
76     static inline PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fpGetPhysicalDeviceSurfaceFormatsKHR;
77     static inline PFN_vkCreateSwapchainKHR fpCreateSwapchainKHR;
78     static inline PFN_vkDestroySwapchainKHR fpDestroySwapchainKHR;
79     static inline PFN_vkAcquireNextImage2KHR fpAcquireNextImage2KHR;
80     static inline PFN_vkQueuePresentKHR fpQueuePresentKHR;
81     static inline PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
82     static inline PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
83     static inline PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures;
84     static inline PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
85     static inline PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
86     static inline PFN_vkGetSwapchainImagesKHR fpGetSwapchainImagesKHR;
87 
88     static inline PFN_vkGetPhysicalDevicePresentRectanglesKHR fpGetPhysicalDevicePresentRectanglesKHR;
89     static inline PFN_vkGetPhysicalDeviceSurfaceFormats2KHR fpGetPhysicalDeviceSurfaceFormats2KHR;
90     static inline PFN_vkSetHdrMetadataEXT fpSetHdrMetadataEXT;
91 
92     static inline void *libVulkan_ = nullptr;
93     static inline VkInstance instance_ = nullptr;
94     static inline VkSurfaceKHR surface_ = VK_NULL_HANDLE;
95     static inline VkPhysicalDevice physicalDevice_ = nullptr;
96     static inline VkDevice device_ = nullptr;
97     static inline VkSurfaceCapabilitiesKHR surfCaps_ = {};
98     static inline VkSurfaceFormatKHR surfaceFormat_ = {};
99     static inline VkSwapchainKHR swapChain_ = VK_NULL_HANDLE;
100     static inline VkSwapchainKHR swapChain2_ = VK_NULL_HANDLE;
101     static inline VkSemaphore semaphore_ = VK_NULL_HANDLE;
102     static inline bool isSupportedVulkan_ = false;
103     static inline std::vector<VkQueueFamilyProperties> queueProps_;
104     static inline uint32_t queueCount_;
105     static inline VkDebugUtilsMessengerEXT debugUtilsMessenger = VK_NULL_HANDLE;
106     static inline std::stringstream debugMessage_;
107 
108     // V1.4.309 func pointers
109     static inline PFN_vkCmdBindDescriptorSets2 vkCmdBindDescriptorSets2;
110     static inline PFN_vkCmdBindIndexBuffer2 vkCmdBindIndexBuffer2;
111     static inline PFN_vkCmdPushConstants2 vkCmdPushConstants2;
112     static inline PFN_vkCmdPushDescriptorSet vkCmdPushDescriptorSet;
113     static inline PFN_vkCmdPushDescriptorSet2 vkCmdPushDescriptorSet2;
114     static inline PFN_vkCmdPushDescriptorSetWithTemplate vkCmdPushDescriptorSetWithTemplate;
115     static inline PFN_vkCmdPushDescriptorSetWithTemplate2 vkCmdPushDescriptorSetWithTemplate2;
116     static inline PFN_vkCmdSetLineStipple vkCmdSetLineStipple;
117     static inline PFN_vkCmdSetRenderingAttachmentLocations vkCmdSetRenderingAttachmentLocations;
118     static inline PFN_vkCmdSetRenderingInputAttachmentIndices vkCmdSetRenderingInputAttachmentIndices;
119     static inline PFN_vkCopyImageToImage vkCopyImageToImage;
120     static inline PFN_vkCopyImageToMemory vkCopyImageToMemory;
121     static inline PFN_vkCopyMemoryToImage vkCopyMemoryToImage;
122     static inline PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT;
123     static inline PFN_vkGetDeviceImageSubresourceLayout vkGetDeviceImageSubresourceLayout;
124     static inline PFN_vkGetImageSubresourceLayout2 vkGetImageSubresourceLayout2;
125     static inline PFN_vkGetRenderingAreaGranularity vkGetRenderingAreaGranularity;
126     static inline PFN_vkMapMemory2 vkMapMemory2;
127     static inline PFN_vkTransitionImageLayout vkTransitionImageLayout;
128     static inline PFN_vkUnmapMemory2 vkUnmapMemory2;
129 };
130 
DLOpenLibVulkan()131 void VulkanLoaderUnitTest::DLOpenLibVulkan()
132 {
133     const char *path = "libvulkan.so";
134     libVulkan_ = dlopen(path, RTLD_NOW | RTLD_LOCAL);
135     if (libVulkan_ == nullptr) {
136         std::cout << "dlerror: " << dlerror() << std::endl;
137         isSupportedVulkan_ = false;
138         return;
139     }
140     isSupportedVulkan_ = true;
141 }
142 
TrytoCreateVkInstance()143 void VulkanLoaderUnitTest::TrytoCreateVkInstance()
144 {
145     VkApplicationInfo appInfo = {};
146     appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
147     appInfo.pApplicationName = "pApplicationName";
148     appInfo.pEngineName = "pEngineName";
149     appInfo.apiVersion = VK_API_VERSION_1_0;
150 
151     std::vector<const char*> instanceExtensions = {
152         VK_KHR_SURFACE_EXTENSION_NAME,
153         VK_OHOS_SURFACE_EXTENSION_NAME,
154         VK_EXT_DEBUG_UTILS_EXTENSION_NAME
155     };
156 
157     VkInstanceCreateInfo instanceCreateInfo = {};
158     instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
159     instanceCreateInfo.pNext = NULL;
160     instanceCreateInfo.pApplicationInfo = &appInfo;
161 
162     instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(instanceExtensions.size());
163     instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data();
164 
165     VkResult result = vkCreateInstance(&instanceCreateInfo, nullptr, &instance_);
166     if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {
167         isSupportedVulkan_ = false;
168     } else {
169         isSupportedVulkan_ = true;
170     }
171     std::cout << "TrytoCreateVkInstance result: " << result << std::endl;
172 }
173 
GetSwapchainCreateInfo(VkFormat imageFormat,VkColorSpaceKHR imageColorSpace,VkSurfaceTransformFlagBitsKHR transform)174 VkSwapchainCreateInfoKHR VulkanLoaderUnitTest::GetSwapchainCreateInfo(
175     VkFormat imageFormat, VkColorSpaceKHR imageColorSpace, VkSurfaceTransformFlagBitsKHR transform)
176 {
177         VkSwapchainCreateInfoKHR swapchainCI = {};
178         swapchainCI.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
179         swapchainCI.surface = surface_;
180         uint32_t desiredNumberOfSwapchainImages = surfCaps_.minImageCount + 1;
181         if ((surfCaps_.maxImageCount > 0) &&
182             (desiredNumberOfSwapchainImages > surfCaps_.maxImageCount)) {
183             desiredNumberOfSwapchainImages = surfCaps_.maxImageCount;
184         }
185         swapchainCI.minImageCount = desiredNumberOfSwapchainImages;
186         swapchainCI.imageFormat = imageFormat;
187         swapchainCI.imageColorSpace = imageColorSpace;
188         uint32_t width = 1280;
189         uint32_t height = 720;
190         swapchainCI.imageExtent = { width, height };
191         swapchainCI.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
192         swapchainCI.preTransform = transform;
193         swapchainCI.imageArrayLayers = 1;
194         swapchainCI.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
195         swapchainCI.queueFamilyIndexCount = 0;
196         swapchainCI.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
197         swapchainCI.oldSwapchain = swapChain_;
198         swapchainCI.clipped = VK_TRUE;
199         swapchainCI.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
200 
201         return swapchainCI;
202 }
203 
CreateNativeWindow(std::string name)204 OHNativeWindow* VulkanLoaderUnitTest::CreateNativeWindow(std::string name)
205 {
206     struct RSSurfaceNodeConfig rsSurfaceNodeConfig;
207     rsSurfaceNodeConfig.SurfaceNodeName = "createSurface_test";
208     auto surfaceNode = RSSurfaceNode::Create(rsSurfaceNodeConfig, RSSurfaceNodeType::DEFAULT);
209     OHOS::sptr<OHOS::Surface> surf = surfaceNode->GetSurface();
210     OHNativeWindow* nativeWindow = CreateNativeWindowFromSurface(&surf);
211     return nativeWindow;
212 }
213 
GetQueueFamilyIndex(VkQueueFlagBits queueFlags)214 uint32_t VulkanLoaderUnitTest::GetQueueFamilyIndex(VkQueueFlagBits queueFlags)
215 {
216     decltype(queueProps_.size()) i = 0;
217     if (queueFlags & VK_QUEUE_COMPUTE_BIT) {
218         for (i = 0; i < queueProps_.size(); i++) {
219             if ((queueProps_[i].queueFlags & queueFlags) &&
220                 ((queueProps_[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)) {
221                 return i;
222             }
223         }
224     }
225     if (queueFlags & VK_QUEUE_TRANSFER_BIT) {
226         for (i = 0; i < queueProps_.size(); i++) {
227             if ((queueProps_[i].queueFlags & queueFlags) &&
228                 ((queueProps_[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0) &&
229                 ((queueProps_[i].queueFlags & VK_QUEUE_COMPUTE_BIT) == 0)) {
230                 return i;
231             }
232         }
233     }
234     for (i = 0; i < queueProps_.size(); i++) {
235         if (queueProps_[i].queueFlags & queueFlags) {
236             return i;
237         }
238     }
239     std::cout << "Could not find a matching queue family index" << std::endl;
240     return -1;
241 }
242 
UserCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,VkDebugUtilsMessageTypeFlagsEXT messageType,const VkDebugUtilsMessengerCallbackDataEXT * pCallbackData,void * pUserData)243 VkBool32 VulkanLoaderUnitTest::UserCallback(
244     VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
245     VkDebugUtilsMessageTypeFlagsEXT messageType,
246     const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
247     void* pUserData)
248 {
249     std::string prefix("");
250     if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
251         prefix = "ERROR: ";
252     } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
253         prefix = "WARN: ";
254     } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
255         prefix = "INFO: ";
256     } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) {
257         prefix = "DEBUG: ";
258     }
259     debugMessage_ << prefix << "[" << pCallbackData->messageIdNumber << "]["
260         << pCallbackData->pMessageIdName << "] : " << pCallbackData->pMessage;
261     return VK_FALSE;
262 }
263 
TearDownTestCase()264 void VulkanLoaderUnitTest::TearDownTestCase()
265 {
266     if (device_ != nullptr) {
267         if (swapChain_ != VK_NULL_HANDLE) {
268             fpDestroySwapchainKHR(device_, swapChain_, nullptr);
269         }
270         vkDestroyDevice(device_, nullptr);
271     }
272     if (instance_ != nullptr) {
273         if (surface_ != VK_NULL_HANDLE) {
274             vkDestroySurfaceKHR(instance_, surface_, nullptr);
275         }
276         vkDestroyInstance(instance_, nullptr);
277     }
278 }
279 
280 /**
281  * @tc.name: Load base Vulkan functions
282  * @tc.desc: Load base Vulkan functions
283  * @tc.type: FUNC
284  * @tc.require: issueI6SKRO
285  */
286 HWTEST_F(VulkanLoaderUnitTest, LoadBaseFuncPtr, TestSize.Level1)
287 {
288     DLOpenLibVulkan();
289     if (isSupportedVulkan_) {
290         EXPECT_NE(libVulkan_, nullptr);
291 
292         // Load base functions
293         vkEnumerateInstanceExtensionProperties = reinterpret_cast<PFN_vkEnumerateInstanceExtensionProperties>(
294             dlsym(libVulkan_, "vkEnumerateInstanceExtensionProperties"));
295         EXPECT_NE(vkEnumerateInstanceExtensionProperties, nullptr);
296         vkEnumerateInstanceLayerProperties = reinterpret_cast<PFN_vkEnumerateInstanceLayerProperties>(
297             dlsym(libVulkan_, "vkEnumerateInstanceLayerProperties"));
298         EXPECT_NE(vkEnumerateInstanceLayerProperties, nullptr);
299         vkEnumerateDeviceExtensionProperties = reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>(
300             dlsym(libVulkan_, "vkEnumerateDeviceExtensionProperties"));
301         EXPECT_NE(vkEnumerateDeviceExtensionProperties, nullptr);
302         vkEnumerateDeviceLayerProperties = reinterpret_cast<PFN_vkEnumerateDeviceLayerProperties>(
303             dlsym(libVulkan_, "vkEnumerateDeviceLayerProperties"));
304         EXPECT_NE(vkEnumerateDeviceLayerProperties, nullptr);
305         vkCreateInstance = reinterpret_cast<PFN_vkCreateInstance>(dlsym(libVulkan_, "vkCreateInstance"));
306         EXPECT_NE(vkCreateInstance, nullptr);
307         vkGetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(dlsym(libVulkan_, "vkGetInstanceProcAddr"));
308         EXPECT_NE(vkGetInstanceProcAddr, nullptr);
309         vkGetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(dlsym(libVulkan_, "vkGetDeviceProcAddr"));
310         EXPECT_NE(vkGetDeviceProcAddr, nullptr);
311         TrytoCreateVkInstance();
312     }
313 }
314 
315 /**
316  * @tc.name: Load 1.4.309 Vulkan functions
317  * @tc.desc: Load 1.4.309 Vulkan functions
318  * @tc.type: FUNC
319  * @tc.require: issueI6SKRO
320  */
321 HWTEST_F(VulkanLoaderUnitTest, LoadBaseFuncPtr1, TestSize.Level1)
322 {
323     if (isSupportedVulkan_) {
324         EXPECT_NE(libVulkan_, nullptr);
325         vkCmdBindDescriptorSets2 = reinterpret_cast<PFN_vkCmdBindDescriptorSets2>(
326             dlsym(libVulkan_, "vkCmdBindDescriptorSets2"));
327         vkCmdBindIndexBuffer2 = reinterpret_cast<PFN_vkCmdBindIndexBuffer2>(
328             dlsym(libVulkan_, "vkCmdBindIndexBuffer2"));
329         vkCmdPushConstants2 = reinterpret_cast<PFN_vkCmdPushConstants2>(
330             dlsym(libVulkan_, "vkCmdPushConstants2"));
331         vkCmdPushDescriptorSet = reinterpret_cast<PFN_vkCmdPushDescriptorSet>(
332             dlsym(libVulkan_, "vkCmdPushDescriptorSet"));
333         vkCmdPushDescriptorSet2 = reinterpret_cast<PFN_vkCmdPushDescriptorSet2>(
334             dlsym(libVulkan_, "vkCmdPushDescriptorSet2"));
335         vkCmdPushDescriptorSetWithTemplate = reinterpret_cast<PFN_vkCmdPushDescriptorSetWithTemplate>(
336             dlsym(libVulkan_, "vkCmdPushDescriptorSetWithTemplate"));
337         vkCmdPushDescriptorSetWithTemplate2 = reinterpret_cast<PFN_vkCmdPushDescriptorSetWithTemplate2>(
338             dlsym(libVulkan_, "vkCmdPushDescriptorSetWithTemplate2"));
339         vkCmdSetLineStipple = reinterpret_cast<PFN_vkCmdSetLineStipple>(
340             dlsym(libVulkan_, "vkCmdSetLineStipple"));
341         vkCmdSetRenderingAttachmentLocations = reinterpret_cast<PFN_vkCmdSetRenderingAttachmentLocations>(
342             dlsym(libVulkan_, "vkCmdSetRenderingAttachmentLocations"));
343         vkCmdSetRenderingInputAttachmentIndices = reinterpret_cast<PFN_vkCmdSetRenderingInputAttachmentIndices>(
344             dlsym(libVulkan_, "vkCmdSetRenderingInputAttachmentIndices"));
345         EXPECT_NE(vkCmdBindDescriptorSets2, nullptr);
346         EXPECT_NE(vkCmdBindIndexBuffer2, nullptr);
347         EXPECT_NE(vkCmdPushConstants2, nullptr);
348         EXPECT_NE(vkCmdPushDescriptorSet, nullptr);
349         EXPECT_NE(vkCmdPushDescriptorSet2, nullptr);
350         EXPECT_NE(vkCmdPushDescriptorSetWithTemplate, nullptr);
351         EXPECT_NE(vkCmdPushDescriptorSetWithTemplate2, nullptr);
352         EXPECT_NE(vkCmdSetLineStipple, nullptr);
353         EXPECT_NE(vkCmdSetRenderingAttachmentLocations, nullptr);
354         EXPECT_NE(vkCmdSetRenderingInputAttachmentIndices, nullptr);
355     }
356 }
357 
358 /**
359  * @tc.name: Load 1.4.309 Vulkan functions
360  * @tc.desc: Load 1.4.309 Vulkan functions
361  * @tc.type: FUNC
362  * @tc.require: issueI6SKRO
363  */
364 HWTEST_F(VulkanLoaderUnitTest, LoadBaseFuncPtr2, TestSize.Level1)
365 {
366     if (isSupportedVulkan_) {
367         EXPECT_NE(libVulkan_, nullptr);
368         vkCopyImageToImage = reinterpret_cast<PFN_vkCopyImageToImage>(
369             dlsym(libVulkan_, "vkCopyImageToImage"));
370         vkCopyImageToMemory = reinterpret_cast<PFN_vkCopyImageToMemory>(
371             dlsym(libVulkan_, "vkCopyImageToMemory"));
372         vkCopyMemoryToImage = reinterpret_cast<PFN_vkCopyMemoryToImage>(
373             dlsym(libVulkan_, "vkCopyMemoryToImage"));
374         vkCreateHeadlessSurfaceEXT = reinterpret_cast<PFN_vkCreateHeadlessSurfaceEXT>(
375             dlsym(libVulkan_, "vkCreateHeadlessSurfaceEXT"));
376         vkGetDeviceImageSubresourceLayout = reinterpret_cast<PFN_vkGetDeviceImageSubresourceLayout>(
377             dlsym(libVulkan_, "vkGetDeviceImageSubresourceLayout"));
378         vkGetImageSubresourceLayout2 = reinterpret_cast<PFN_vkGetImageSubresourceLayout2>(
379             dlsym(libVulkan_, "vkGetImageSubresourceLayout2"));
380         vkGetRenderingAreaGranularity = reinterpret_cast<PFN_vkGetRenderingAreaGranularity>(
381             dlsym(libVulkan_, "vkGetRenderingAreaGranularity"));
382         vkMapMemory2 = reinterpret_cast<PFN_vkMapMemory2>(
383             dlsym(libVulkan_, "vkMapMemory2"));
384         vkTransitionImageLayout = reinterpret_cast<PFN_vkTransitionImageLayout>(
385             dlsym(libVulkan_, "vkTransitionImageLayout"));
386         vkUnmapMemory2 = reinterpret_cast<PFN_vkUnmapMemory2>(
387             dlsym(libVulkan_, "vkUnmapMemory2"));
388 
389         EXPECT_NE(vkCopyImageToImage, nullptr);
390         EXPECT_NE(vkCopyImageToMemory, nullptr);
391         EXPECT_NE(vkCopyMemoryToImage, nullptr);
392         EXPECT_NE(vkCreateHeadlessSurfaceEXT, nullptr);
393         EXPECT_NE(vkGetDeviceImageSubresourceLayout, nullptr);
394         EXPECT_NE(vkGetImageSubresourceLayout2, nullptr);
395         EXPECT_NE(vkGetRenderingAreaGranularity, nullptr);
396         EXPECT_NE(vkMapMemory2, nullptr);
397         EXPECT_NE(vkTransitionImageLayout, nullptr);
398         EXPECT_NE(vkUnmapMemory2, nullptr);
399     }
400 }
401 
402 /**
403  * @tc.name: test vkEnumerateInstanceExtensionProperties
404  * @tc.desc: test vkEnumerateInstanceExtensionProperties
405  * @tc.type: FUNC
406  * @tc.require: issueI6SKRO
407  */
408 HWTEST_F(VulkanLoaderUnitTest, vkEnumerateInstanceExtensionProperties_Test, TestSize.Level1)
409 {
410     if (isSupportedVulkan_) {
411         uint32_t extCount = 0;
412         VkResult err = vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr);
413         EXPECT_EQ(err, VK_SUCCESS);
414         if (extCount > 0) {
415             std::vector<VkExtensionProperties> extensions(extCount);
416             err = vkEnumerateInstanceExtensionProperties(nullptr, &extCount, extensions.data());
417             EXPECT_EQ(err, VK_SUCCESS);
418         }
419     }
420 }
421 
422 /**
423  * @tc.name: test vkEnumerateInstanceLayerProperties
424  * @tc.desc: test vkEnumerateInstanceLayerProperties
425  * @tc.type: FUNC
426  * @tc.require: issueI6SKRO
427  */
428 HWTEST_F(VulkanLoaderUnitTest, vkEnumerateInstanceLayerProperties_Test, TestSize.Level1)
429 {
430     if (isSupportedVulkan_) {
431         uint32_t propertyCount = 0;
432         VkResult err = vkEnumerateInstanceLayerProperties(&propertyCount, nullptr);
433         EXPECT_EQ(err, VK_SUCCESS);
434         if (propertyCount > 0) {
435             std::vector<VkLayerProperties> properties(propertyCount);
436             err = vkEnumerateInstanceLayerProperties(&propertyCount, properties.data());
437             EXPECT_EQ(err, VK_SUCCESS);
438         }
439     }
440 }
441 
442 /**
443  * @tc.name: load instance based function pointer
444  * @tc.desc: load instance based function pointer
445  * @tc.type: FUNC
446  * @tc.require: issueI6SKRO
447  */
448 HWTEST_F(VulkanLoaderUnitTest, LoadInstanceFuncPtr, TestSize.Level1)
449 {
450     if (isSupportedVulkan_) {
451         vkDestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
452             vkGetInstanceProcAddr(instance_, "vkDestroyInstance"));
453         EXPECT_NE(vkDestroyInstance, nullptr);
454         vkEnumeratePhysicalDevices = reinterpret_cast<PFN_vkEnumeratePhysicalDevices>(
455             vkGetInstanceProcAddr(instance_, "vkEnumeratePhysicalDevices"));
456         EXPECT_NE(vkEnumeratePhysicalDevices, nullptr);
457         vkCreateDevice = reinterpret_cast<PFN_vkCreateDevice>(vkGetInstanceProcAddr(instance_, "vkCreateDevice"));
458         EXPECT_NE(vkCreateDevice, nullptr);
459         vkDestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(vkGetInstanceProcAddr(instance_, "vkDestroyDevice"));
460         EXPECT_NE(vkDestroyDevice, nullptr);
461         vkDestroySurfaceKHR = reinterpret_cast<PFN_vkDestroySurfaceKHR>(
462             vkGetInstanceProcAddr(instance_, "vkDestroySurfaceKHR"));
463         EXPECT_NE(vkDestroySurfaceKHR, nullptr);
464 
465         vkCreateSurfaceOHOS = reinterpret_cast<PFN_vkCreateSurfaceOHOS>(
466             vkGetInstanceProcAddr(instance_, "vkCreateSurfaceOHOS"));
467         EXPECT_NE(vkCreateSurfaceOHOS, nullptr);
468 
469         fpGetPhysicalDeviceSurfaceCapabilitiesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR>(
470             vkGetInstanceProcAddr(instance_, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"));
471         EXPECT_NE(fpGetPhysicalDeviceSurfaceCapabilitiesKHR, nullptr);
472         fpGetPhysicalDeviceSurfacePresentModesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR>(
473             vkGetInstanceProcAddr(instance_, "vkGetPhysicalDeviceSurfacePresentModesKHR"));
474         EXPECT_NE(fpGetPhysicalDeviceSurfacePresentModesKHR, nullptr);
475         fpGetPhysicalDeviceSurfaceFormatsKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR>(
476             vkGetInstanceProcAddr(instance_, "vkGetPhysicalDeviceSurfaceFormatsKHR"));
477         EXPECT_NE(fpGetPhysicalDeviceSurfaceFormatsKHR, nullptr);
478         vkGetPhysicalDeviceQueueFamilyProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties>(
479             vkGetInstanceProcAddr(instance_, "vkGetPhysicalDeviceQueueFamilyProperties"));
480         EXPECT_NE(vkGetPhysicalDeviceQueueFamilyProperties, nullptr);
481         vkGetPhysicalDeviceProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(
482             vkGetInstanceProcAddr(instance_, "vkGetPhysicalDeviceProperties"));
483         EXPECT_NE(vkGetPhysicalDeviceProperties, nullptr);
484         vkGetPhysicalDeviceFeatures = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures>(
485             vkGetInstanceProcAddr(instance_, "vkGetPhysicalDeviceFeatures"));
486         EXPECT_NE(vkGetPhysicalDeviceFeatures, nullptr);
487         vkGetPhysicalDeviceMemoryProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties>(
488             vkGetInstanceProcAddr(instance_, "vkGetPhysicalDeviceMemoryProperties"));
489         EXPECT_NE(vkGetPhysicalDeviceMemoryProperties, nullptr);
490         vkGetPhysicalDeviceSurfaceSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceSupportKHR>(
491             vkGetInstanceProcAddr(instance_, "vkGetPhysicalDeviceSurfaceSupportKHR"));
492         EXPECT_NE(vkGetPhysicalDeviceSurfaceSupportKHR, nullptr);
493         vkCreateDebugUtilsMessengerEXT = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>(
494             vkGetInstanceProcAddr(instance_, "vkCreateDebugUtilsMessengerEXT"));
495         EXPECT_NE(vkCreateDebugUtilsMessengerEXT, nullptr);
496         vkDestroyDebugUtilsMessengerEXT = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT>(
497             vkGetInstanceProcAddr(instance_, "vkDestroyDebugUtilsMessengerEXT"));
498         EXPECT_NE(vkDestroyDebugUtilsMessengerEXT, nullptr);
499     }
500 }
501 
502 /**
503  * @tc.name: test vkEnumeratePhysicalDevices
504  * @tc.desc: test vkEnumeratePhysicalDevices
505  * @tc.type: FUNC
506  * @tc.require: issueI6SKRO
507  */
508 HWTEST_F(VulkanLoaderUnitTest, vkEnumeratePhysicalDevices_Test, TestSize.Level1)
509 {
510     if (isSupportedVulkan_) {
511         EXPECT_NE(instance_, nullptr);
512 
513         uint32_t gpuCount = 0;
514         VkResult err = vkEnumeratePhysicalDevices(instance_, &gpuCount, nullptr);
515         EXPECT_EQ(err, VK_SUCCESS);
516         EXPECT_NE(gpuCount, 0);
517         std::vector<VkPhysicalDevice> physicalDevices(gpuCount);
518         err = vkEnumeratePhysicalDevices(instance_, &gpuCount, physicalDevices.data());
519         EXPECT_EQ(err, VK_SUCCESS);
520         physicalDevice_ = physicalDevices[0];
521         EXPECT_NE(physicalDevice_, nullptr);
522 
523         VkPhysicalDeviceProperties deviceProperties;
524         VkPhysicalDeviceFeatures deviceFeatures;
525         VkPhysicalDeviceMemoryProperties deviceMemoryProperties;
526         vkGetPhysicalDeviceProperties(physicalDevice_, &deviceProperties);
527         vkGetPhysicalDeviceFeatures(physicalDevice_, &deviceFeatures);
528         vkGetPhysicalDeviceMemoryProperties(physicalDevice_, &deviceMemoryProperties);
529     }
530 }
531 
532 /**
533  * @tc.name: test vkEnumerateDeviceExtensionProperties
534  * @tc.desc: test vkEnumerateDeviceExtensionProperties
535  * @tc.type: FUNC
536  * @tc.require: issueI6SKRO
537  */
538 HWTEST_F(VulkanLoaderUnitTest, vkEnumerateDeviceExtensionProperties_Test, TestSize.Level1)
539 {
540     if (isSupportedVulkan_) {
541         uint32_t extCount = 0;
542         VkResult err = vkEnumerateDeviceExtensionProperties(physicalDevice_, nullptr, &extCount, nullptr);
543         EXPECT_EQ(err, VK_SUCCESS);
544         if (extCount > 0) {
545             std::vector<VkExtensionProperties> extensions(extCount);
546             err = vkEnumerateDeviceExtensionProperties(physicalDevice_, nullptr, &extCount, extensions.data());
547             EXPECT_EQ(err, VK_SUCCESS);
548         }
549     }
550 }
551 
552 /**
553  * @tc.name: test vkEnumerateDeviceLayerProperties
554  * @tc.desc: test vkEnumerateDeviceLayerProperties
555  * @tc.type: FUNC
556  * @tc.require: issueI6SKRO
557  */
558 HWTEST_F(VulkanLoaderUnitTest, vkEnumerateDeviceLayerProperties_Test, TestSize.Level1)
559 {
560     if (isSupportedVulkan_) {
561         uint32_t propertyCount = 0;
562         VkResult err = vkEnumerateDeviceLayerProperties(physicalDevice_, &propertyCount, nullptr);
563         EXPECT_EQ(err, VK_SUCCESS);
564         if (propertyCount > 0) {
565             std::vector<VkLayerProperties> properties(propertyCount);
566             err = vkEnumerateDeviceLayerProperties(physicalDevice_, &propertyCount, properties.data());
567             EXPECT_EQ(err, VK_SUCCESS);
568         }
569     }
570 }
571 
572 /**
573  * @tc.name: test vkGetPhysicalDeviceQueueFamilyProperties
574  * @tc.desc: test vkGetPhysicalDeviceQueueFamilyProperties
575  * @tc.type: FUNC
576  * @tc.require: issueI6SKRO
577  */
578 HWTEST_F(VulkanLoaderUnitTest, vkGetPhysicalDeviceQueueFamilyProperties_Test, TestSize.Level1)
579 {
580     if (isSupportedVulkan_) {
581         vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice_, &queueCount_, NULL);
582         EXPECT_GT(queueCount_, 0);
583 
584         queueProps_.resize(queueCount_);
585         vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice_, &queueCount_, queueProps_.data());
586     }
587 }
588 
589 /**
590  * @tc.name: test vkCreateDevice
591  * @tc.desc: test vkCreateDevice
592  * @tc.type: FUNC
593  * @tc.require: issueI6SKRO
594  */
595 HWTEST_F(VulkanLoaderUnitTest, vkCreateDevice_Test, TestSize.Level1)
596 {
597     if (isSupportedVulkan_) {
598         EXPECT_NE(vkCreateDevice, nullptr);
599         EXPECT_NE(physicalDevice_, nullptr);
600 
601         VkDeviceCreateInfo deviceCreateInfo = {};
602         deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
603 
604         std::vector<VkDeviceQueueCreateInfo> queueCreateInfos{};
605         const float defaultQueuePriority(0.0f);
606         VkDeviceQueueCreateInfo queueInfo{};
607         queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
608         queueInfo.queueFamilyIndex = GetQueueFamilyIndex(VK_QUEUE_GRAPHICS_BIT);
609         queueInfo.queueCount = 1;
610         queueInfo.pQueuePriorities = &defaultQueuePriority;
611         queueCreateInfos.push_back(queueInfo);
612         deviceCreateInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
613         deviceCreateInfo.pQueueCreateInfos = queueCreateInfos.data();
614 
615         std::vector<const char*> deviceExtensions;
616         deviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
617         deviceExtensions.push_back(VK_EXT_HDR_METADATA_EXTENSION_NAME);
618         deviceCreateInfo.enabledExtensionCount = (uint32_t)deviceExtensions.size();
619         deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
620         VkDevice logicalDevice;
621         VkResult err = vkCreateDevice(physicalDevice_, &deviceCreateInfo, nullptr, &logicalDevice);
622         EXPECT_EQ(err, VK_SUCCESS);
623         EXPECT_NE(logicalDevice, nullptr);
624         device_ = logicalDevice;
625     }
626 }
627 
628 /**
629  * @tc.name: test vkCreateSurfaceOHOS
630  * @tc.desc: test vkCreateSurfaceOHOS
631  * @tc.type: FUNC
632  * @tc.require: issueI6SKRO
633  */
634 HWTEST_F(VulkanLoaderUnitTest, vkCreateSurfaceOHOS_Test, TestSize.Level1)
635 {
636     if (isSupportedVulkan_) {
637         EXPECT_NE(vkCreateSurfaceOHOS, nullptr);
638         EXPECT_NE(instance_, nullptr);
639 
640         OHNativeWindow* nativeWindow = CreateNativeWindow("createSurfaceUT");
641         EXPECT_NE(nativeWindow, nullptr);
642         VkSurfaceCreateInfoOHOS surfaceCreateInfo = {};
643         surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_SURFACE_CREATE_INFO_OHOS;
644         surfaceCreateInfo.window = nativeWindow;
645         VkResult err = vkCreateSurfaceOHOS(instance_, &surfaceCreateInfo, NULL, &surface_);
646         EXPECT_EQ(err, VK_SUCCESS);
647         EXPECT_NE(surface_, VK_NULL_HANDLE);
648     }
649 }
650 
651 /**
652  * @tc.name: test vkCreateSurfaceOHOS 2
653  * @tc.desc: test vkCreateSurfaceOHOS 2
654  * @tc.type: FUNC
655  * @tc.require: issueI6SKRO
656  */
657 HWTEST_F(VulkanLoaderUnitTest, vkCreateSurfaceOHOS_Test2, TestSize.Level1)
658 {
659     if (isSupportedVulkan_) {
660         EXPECT_NE(vkCreateSurfaceOHOS, nullptr);
661         EXPECT_NE(instance_, nullptr);
662 
663         VkSurfaceCreateInfoOHOS surfaceCreateInfo = {};
664         surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_SURFACE_CREATE_INFO_OHOS;
665         surfaceCreateInfo.window = nullptr;
666         VkSurfaceKHR surface2 = VK_NULL_HANDLE;
667         VkResult err = vkCreateSurfaceOHOS(instance_, &surfaceCreateInfo, NULL, &surface2);
668         EXPECT_NE(err, VK_SUCCESS);
669         EXPECT_EQ(surface2, VK_NULL_HANDLE);
670     }
671 }
672 
673 /**
674  * @tc.name: test vkGetPhysicalDeviceSurfaceSupportKHR
675  * @tc.desc: test vkGetPhysicalDeviceSurfaceSupportKHR
676  * @tc.type: FUNC
677  * @tc.require: issueI6SKRO
678  */
679 HWTEST_F(VulkanLoaderUnitTest, vkGetPhysicalDeviceSurfaceSupportKHR_Test, TestSize.Level1)
680 {
681     if (isSupportedVulkan_) {
682         std::vector<VkBool32> supportsPresent(queueCount_);
683         for (uint32_t i = 0; i < queueCount_; i++) {
684             vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice_, i, surface_, &supportsPresent[i]);
685             EXPECT_EQ(supportsPresent[i], VK_TRUE);
686         }
687     }
688 }
689 
690 /**
691  * @tc.name: load device based function pointer
692  * @tc.desc: load device based function pointer
693  * @tc.type: FUNC
694  * @tc.require: issueI6SKRO
695  */
696 HWTEST_F(VulkanLoaderUnitTest, LoadDeviceFuncPtr, TestSize.Level1)
697 {
698     if (isSupportedVulkan_) {
699         EXPECT_NE(device_, nullptr);
700 
701         fpCreateSwapchainKHR = reinterpret_cast<PFN_vkCreateSwapchainKHR>(
702             vkGetDeviceProcAddr(device_, "vkCreateSwapchainKHR"));
703         EXPECT_NE(fpCreateSwapchainKHR, nullptr);
704         fpDestroySwapchainKHR = reinterpret_cast<PFN_vkDestroySwapchainKHR>(
705             vkGetDeviceProcAddr(device_, "vkDestroySwapchainKHR"));
706         EXPECT_NE(fpDestroySwapchainKHR, nullptr);
707         fpAcquireNextImage2KHR = reinterpret_cast<PFN_vkAcquireNextImage2KHR>(
708             vkGetDeviceProcAddr(device_, "vkAcquireNextImage2KHR"));
709         EXPECT_NE(fpAcquireNextImage2KHR, nullptr);
710         fpQueuePresentKHR = reinterpret_cast<PFN_vkQueuePresentKHR>(
711             vkGetDeviceProcAddr(device_, "vkQueuePresentKHR"));
712         EXPECT_NE(fpQueuePresentKHR, nullptr);
713         fpGetSwapchainImagesKHR = reinterpret_cast<PFN_vkGetSwapchainImagesKHR>(
714             vkGetDeviceProcAddr(device_, "vkGetSwapchainImagesKHR"));
715         EXPECT_NE(fpGetSwapchainImagesKHR, nullptr);
716 
717         fpSetHdrMetadataEXT = reinterpret_cast<PFN_vkSetHdrMetadataEXT>(
718             vkGetDeviceProcAddr(device_, "vkSetHdrMetadataEXT"));
719         EXPECT_NE(fpSetHdrMetadataEXT, nullptr);
720     }
721 }
722 
723 /**
724  * @tc.name: test fpGetPhysicalDeviceSurfaceCapabilitiesKHR
725  * @tc.desc: test fpGetPhysicalDeviceSurfaceCapabilitiesKHR
726  * @tc.type: FUNC
727  * @tc.require: issueI6SKRO
728  */
729 HWTEST_F(VulkanLoaderUnitTest, fpGetPhysicalDeviceSurfaceCapabilitiesKHR_Test, TestSize.Level1)
730 {
731     if (isSupportedVulkan_) {
732         EXPECT_NE(fpGetPhysicalDeviceSurfaceCapabilitiesKHR, nullptr);
733         EXPECT_NE(physicalDevice_, nullptr);
734         EXPECT_NE(surface_, VK_NULL_HANDLE);
735 
736         VkResult err = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice_, surface_, &surfCaps_);
737         EXPECT_EQ(err, VK_SUCCESS);
738     }
739 }
740 
741 /**
742  * @tc.name: test fpGetPhysicalDeviceSurfacePresentModesKHR
743  * @tc.desc: test fpGetPhysicalDeviceSurfacePresentModesKHR
744  * @tc.type: FUNC
745  * @tc.require: issueI6SKRO
746  */
747 HWTEST_F(VulkanLoaderUnitTest, fpGetPhysicalDeviceSurfacePresentModesKHR_Test, TestSize.Level1)
748 {
749     if (isSupportedVulkan_) {
750         EXPECT_NE(fpGetPhysicalDeviceSurfacePresentModesKHR, nullptr);
751         EXPECT_NE(physicalDevice_, nullptr);
752         EXPECT_NE(surface_, VK_NULL_HANDLE);
753 
754         uint32_t presentModeCount;
755         VkResult err = fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice_, surface_, &presentModeCount, NULL);
756         EXPECT_EQ(err, VK_SUCCESS);
757         EXPECT_GT(presentModeCount, 0);
758 
759         std::vector<VkPresentModeKHR> presentModes(presentModeCount);
760         err = fpGetPhysicalDeviceSurfacePresentModesKHR(
761             physicalDevice_, surface_, &presentModeCount, presentModes.data());
762         EXPECT_EQ(err, VK_SUCCESS);
763     }
764 }
765 
766 /**
767  * @tc.name: test fpGetPhysicalDeviceSurfacePresentModesKHR FAIL
768  * @tc.desc: test fpGetPhysicalDeviceSurfacePresentModesKHR FAIL
769  * @tc.type: FUNC
770  * @tc.require: issueI6SKRO
771  */
772 HWTEST_F(VulkanLoaderUnitTest, fpGetPhysicalDeviceSurfacePresentModesKHR_FAIL_Test, TestSize.Level1)
773 {
774     if (isSupportedVulkan_) {
775         EXPECT_NE(fpGetPhysicalDeviceSurfacePresentModesKHR, nullptr);
776         EXPECT_NE(physicalDevice_, nullptr);
777         EXPECT_NE(surface_, VK_NULL_HANDLE);
778 
779         uint32_t presentModeCount = 1;
780         std::vector<VkPresentModeKHR> presentModes(presentModeCount);
781         VkResult err = fpGetPhysicalDeviceSurfacePresentModesKHR(
782             physicalDevice_, surface_, &presentModeCount, presentModes.data());
783         EXPECT_NE(err, VK_SUCCESS);
784     }
785 }
786 
787 /**
788  * @tc.name: test fpGetPhysicalDeviceSurfaceFormatsKHR
789  * @tc.desc: test fpGetPhysicalDeviceSurfaceFormatsKHR
790  * @tc.type: FUNC
791  * @tc.require: issueI6SKRO
792  */
793 HWTEST_F(VulkanLoaderUnitTest, fpGetPhysicalDeviceSurfaceFormatsKHR_Test, TestSize.Level1)
794 {
795     if (isSupportedVulkan_) {
796         EXPECT_NE(fpGetPhysicalDeviceSurfaceFormatsKHR, nullptr);
797         EXPECT_NE(physicalDevice_, nullptr);
798         EXPECT_NE(surface_, VK_NULL_HANDLE);
799 
800         uint32_t formatCount;
801         VkResult err = fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice_, surface_, &formatCount, NULL);
802         EXPECT_EQ(err, VK_SUCCESS);
803         EXPECT_GT(formatCount, 0);
804         std::vector<VkSurfaceFormatKHR> surfaceFormats(formatCount);
805         err = fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice_, surface_, &formatCount, surfaceFormats.data());
806         EXPECT_EQ(err, VK_SUCCESS);
807         surfaceFormat_ = surfaceFormats[0];
808     }
809 }
810 
811 /**
812  * @tc.name: test fpGetPhysicalDeviceSurfaceFormatsKHR FAIL
813  * @tc.desc: test fpGetPhysicalDeviceSurfaceFormatsKHR FAIL
814  * @tc.type: FUNC
815  * @tc.require: issueI6SKRO
816  */
817 HWTEST_F(VulkanLoaderUnitTest, fpGetPhysicalDeviceSurfaceFormatsKHR_FAIL_Test, TestSize.Level1)
818 {
819     if (isSupportedVulkan_) {
820         EXPECT_NE(fpGetPhysicalDeviceSurfaceFormatsKHR, nullptr);
821         EXPECT_NE(physicalDevice_, nullptr);
822         EXPECT_NE(surface_, VK_NULL_HANDLE);
823 
824         uint32_t formatCount = 1;
825         std::vector<VkSurfaceFormatKHR> surfaceFormats(formatCount);
826         VkResult err = fpGetPhysicalDeviceSurfaceFormatsKHR(
827             physicalDevice_, surface_, &formatCount, surfaceFormats.data());
828         EXPECT_NE(err, VK_SUCCESS);
829     }
830 }
831 
832 /**
833  * @tc.name: test fpCreateSwapchainKHR Success
834  * @tc.desc: test fpCreateSwapchainKHR Success
835  * @tc.type: FUNC
836  * @tc.require: issueI6SKRO
837  */
838 HWTEST_F(VulkanLoaderUnitTest, fpCreateSwapchainKHR_Success_Test, TestSize.Level1)
839 {
840     if (isSupportedVulkan_) {
841         EXPECT_NE(fpCreateSwapchainKHR, nullptr);
842         EXPECT_NE(device_, nullptr);
843         EXPECT_NE(surface_, VK_NULL_HANDLE);
844 
845         std::vector<VkFormat> pixelFormatArray = {
846             VK_FORMAT_R8G8B8A8_UNORM,
847             VK_FORMAT_R8G8B8A8_SRGB,
848         };
849         std::vector<VkColorSpaceKHR> colorDataspaceArray = {
850             VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
851             VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT,
852             VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT,
853             VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT,
854             VK_COLOR_SPACE_DCI_P3_LINEAR_EXT,
855             VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT,
856             VK_COLOR_SPACE_BT709_LINEAR_EXT,
857             VK_COLOR_SPACE_BT709_NONLINEAR_EXT,
858             VK_COLOR_SPACE_BT2020_LINEAR_EXT,
859             VK_COLOR_SPACE_HDR10_ST2084_EXT,
860             VK_COLOR_SPACE_DOLBYVISION_EXT,
861             VK_COLOR_SPACE_HDR10_HLG_EXT,
862             VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT,
863             VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT,
864             VK_COLORSPACE_SRGB_NONLINEAR_KHR,
865             VK_COLOR_SPACE_DCI_P3_LINEAR_EXT
866         };
867         std::vector<VkSurfaceTransformFlagBitsKHR> transformArray = {
868             VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
869             VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR,
870             VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR,
871             VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR,
872             VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR,
873             VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR,
874             VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR,
875             VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR,
876         };
877 
878         for (decltype(pixelFormatArray.size()) i = 0; i < pixelFormatArray.size(); i++) {
879             for (decltype(colorDataspaceArray.size()) j = 0; j < colorDataspaceArray.size(); j++) {
880                 for (decltype(transformArray.size()) k = 0; k < transformArray.size(); k++) {
881                     VkSwapchainCreateInfoKHR swapchainCI = GetSwapchainCreateInfo(
882                         pixelFormatArray[i], colorDataspaceArray[j], transformArray[k]);
883 
884                     VkSwapchainKHR swapChainSuccess = VK_NULL_HANDLE;
885                     VkSwapchainKHR swapChainSuccess2 = VK_NULL_HANDLE;
886 
887                     VkResult err = fpCreateSwapchainKHR(device_, &swapchainCI, nullptr, &swapChainSuccess);
888                     EXPECT_EQ(err, VK_SUCCESS);
889                     EXPECT_NE(swapChainSuccess, VK_NULL_HANDLE);
890 
891                     swapchainCI.oldSwapchain = swapChainSuccess;
892                     err = fpCreateSwapchainKHR(device_, &swapchainCI, nullptr, &swapChainSuccess2);
893                     EXPECT_EQ(err, VK_SUCCESS);
894                     EXPECT_NE(swapChainSuccess2, VK_NULL_HANDLE);
895                     fpDestroySwapchainKHR(device_, swapChainSuccess, nullptr);
896                     fpDestroySwapchainKHR(device_, swapChainSuccess2, nullptr);
897                 }
898             }
899         }
900     }
901 }
902 
903 /**
904  * @tc.name: test fpCreateSwapchainKHR fail
905  * @tc.desc: test fpCreateSwapchainKHR fail
906  * @tc.type: FUNC
907  * @tc.require: issueI6SKRO
908  */
909 HWTEST_F(VulkanLoaderUnitTest, fpCreateSwapchainKHR_Fail_Test, TestSize.Level1)
910 {
911     if (isSupportedVulkan_) {
912         EXPECT_NE(fpCreateSwapchainKHR, nullptr);
913         EXPECT_NE(device_, nullptr);
914         EXPECT_NE(surface_, VK_NULL_HANDLE);
915 
916         std::vector<VkColorSpaceKHR> colorDataspaceArray = {
917             VK_COLOR_SPACE_PASS_THROUGH_EXT,
918             VK_COLOR_SPACE_DISPLAY_NATIVE_AMD,
919             VK_COLOR_SPACE_MAX_ENUM_KHR
920         };
921 
922         for (decltype(colorDataspaceArray.size()) i = 0; i < colorDataspaceArray.size(); i++) {
923             VkSwapchainCreateInfoKHR swapchainCI = GetSwapchainCreateInfo(
924                 VK_FORMAT_R8G8B8A8_UNORM, colorDataspaceArray[i]);
925 
926             VkSwapchainKHR swapChainFail = VK_NULL_HANDLE;
927             VkSwapchainKHR swapChainFail2 = VK_NULL_HANDLE;
928 
929             VkResult err = fpCreateSwapchainKHR(device_, &swapchainCI, nullptr, &swapChainFail);
930             EXPECT_EQ(err, VK_SUCCESS);
931             EXPECT_NE(swapChainFail, VK_NULL_HANDLE);
932 
933             swapchainCI.oldSwapchain = swapChainFail;
934             err = fpCreateSwapchainKHR(device_, &swapchainCI, nullptr, &swapChainFail2);
935             EXPECT_EQ(err, VK_SUCCESS);
936             EXPECT_NE(swapChainFail2, VK_NULL_HANDLE);
937             fpDestroySwapchainKHR(device_, swapChainFail, nullptr);
938             fpDestroySwapchainKHR(device_, swapChainFail2, nullptr);
939         }
940     }
941 }
942 
943 /**
944  * @tc.name: test vkCreateDebugUtilsMessengerEXT
945  * @tc.desc: test vkCreateDebugUtilsMessengerEXT
946  * @tc.type: FUNC
947  * @tc.require: issueI6SKRO
948  */
949 HWTEST_F(VulkanLoaderUnitTest, vkCreateDebugUtilsMessengerEXT_Test, TestSize.Level1)
950 {
951     if (isSupportedVulkan_) {
952         EXPECT_NE(vkCreateDebugUtilsMessengerEXT, nullptr);
953         EXPECT_NE(fpCreateSwapchainKHR, nullptr);
954         EXPECT_NE(instance_, nullptr);
955         EXPECT_NE(device_, nullptr);
956 
957         VkDebugUtilsMessengerCreateInfoEXT createInfo{};
958         createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
959         createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
960                                      VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
961         createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
962                                  VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
963         createInfo.pfnUserCallback = UserCallback;
964         VkResult result = vkCreateDebugUtilsMessengerEXT(instance_, &createInfo, nullptr, &debugUtilsMessenger);
965         EXPECT_EQ(result, VK_SUCCESS);
966 
967         debugMessage_.str("");
968         VkSwapchainCreateInfoKHR swapchainCI = GetSwapchainCreateInfo(VK_FORMAT_MAX_ENUM, surfaceFormat_.colorSpace);
969         VkSwapchainKHR swapChain = VK_NULL_HANDLE;
970         result = fpCreateSwapchainKHR(device_, &swapchainCI, nullptr, &swapChain);
971         EXPECT_EQ(result, VK_SUCCESS);
972         EXPECT_NE(swapChain, VK_NULL_HANDLE);
973         fpDestroySwapchainKHR(device_, swapChain, nullptr);
974 
975         EXPECT_EQ((debugMessage_.str().find("unsupported swapchain format") != -1), true);
976     }
977 }
978 
979 /**
980  * @tc.name: test vkDestroyDebugUtilsMessengerEXT
981  * @tc.desc: test vkDestroyDebugUtilsMessengerEXT
982  * @tc.type: FUNC
983  * @tc.require: issueI6SKRO
984  */
985 HWTEST_F(VulkanLoaderUnitTest, vkDestroyDebugUtilsMessengerEXT_Test, TestSize.Level1)
986 {
987     if (isSupportedVulkan_) {
988         EXPECT_NE(vkDestroyDebugUtilsMessengerEXT, nullptr);
989         EXPECT_NE(instance_, nullptr);
990         EXPECT_NE(device_, nullptr);
991         EXPECT_NE(debugUtilsMessenger, VK_NULL_HANDLE);
992 
993         vkDestroyDebugUtilsMessengerEXT(instance_, debugUtilsMessenger, nullptr);
994 
995         debugMessage_.str("");
996         VkSwapchainCreateInfoKHR swapchainCI = GetSwapchainCreateInfo(VK_FORMAT_MAX_ENUM, surfaceFormat_.colorSpace);
997         VkSwapchainKHR swapChain = VK_NULL_HANDLE;
998         VkResult result = fpCreateSwapchainKHR(device_, &swapchainCI, nullptr, &swapChain);
999         EXPECT_EQ(result, VK_SUCCESS);
1000         EXPECT_NE(swapChain, VK_NULL_HANDLE);
1001         fpDestroySwapchainKHR(device_, swapChain, nullptr);
1002 
1003         EXPECT_EQ((debugMessage_.str() == ""), true);
1004     }
1005 }
1006 
1007 /**
1008  * @tc.name: test fpCreateSwapchainKHR
1009  * @tc.desc: test fpCreateSwapchainKHR
1010  * @tc.type: FUNC
1011  * @tc.require: issueI6SKRO
1012  */
1013 HWTEST_F(VulkanLoaderUnitTest, fpCreateSwapchainKHR_Test, TestSize.Level1)
1014 {
1015     if (isSupportedVulkan_) {
1016         EXPECT_NE(fpCreateSwapchainKHR, nullptr);
1017         EXPECT_NE(device_, nullptr);
1018         EXPECT_NE(surface_, VK_NULL_HANDLE);
1019 
1020         VkSwapchainCreateInfoKHR swapchainCI = GetSwapchainCreateInfo(
1021             VK_FORMAT_B8G8R8A8_UNORM, surfaceFormat_.colorSpace);
1022 
1023         VkResult err = fpCreateSwapchainKHR(device_, &swapchainCI, nullptr, &swapChain_);
1024         EXPECT_EQ(err, VK_SUCCESS);
1025         EXPECT_NE(swapChain_, VK_NULL_HANDLE);
1026 
1027         swapchainCI.oldSwapchain = swapChain_;
1028         err = fpCreateSwapchainKHR(device_, &swapchainCI, nullptr, &swapChain2_);
1029         EXPECT_EQ(err, VK_SUCCESS);
1030         EXPECT_NE(swapChain2_, VK_NULL_HANDLE);
1031     }
1032 }
1033 
1034 /**
1035  * @tc.name: test fpGetSwapchainImagesKHR
1036  * @tc.desc: test fpGetSwapchainImagesKHR
1037  * @tc.type: FUNC
1038  * @tc.require: issueI6SKRO
1039  */
1040 HWTEST_F(VulkanLoaderUnitTest, fpGetSwapchainImagesKHR_Test, TestSize.Level1)
1041 {
1042     if (isSupportedVulkan_) {
1043         uint32_t imageCount;
1044         std::vector<VkImage> images;
1045         VkResult err = fpGetSwapchainImagesKHR(device_, swapChain_, &imageCount, NULL);
1046         EXPECT_EQ(err, VK_SUCCESS);
1047         images.resize(imageCount);
1048         err = fpGetSwapchainImagesKHR(device_, swapChain_, &imageCount, images.data());
1049         EXPECT_EQ(err, VK_SUCCESS);
1050     }
1051 }
1052 
1053 /**
1054  * @tc.name: test fpGetSwapchainImagesKHR FAIL
1055  * @tc.desc: test fpGetSwapchainImagesKHR FAIL
1056  * @tc.type: FUNC
1057  * @tc.require: issueI6SKRO
1058  */
1059 HWTEST_F(VulkanLoaderUnitTest, fpGetSwapchainImagesKHR_FAIL_Test, TestSize.Level1)
1060 {
1061     if (isSupportedVulkan_) {
1062         uint32_t imageCount = 1;
1063         std::vector<VkImage> images(imageCount);
1064         VkResult err = fpGetSwapchainImagesKHR(device_, swapChain2_, &imageCount, images.data());
1065         EXPECT_NE(err, VK_SUCCESS);
1066     }
1067 }
1068 
1069 /**
1070  * @tc.name: test vkCreateSemaphore
1071  * @tc.desc: test vkCreateSemaphore
1072  * @tc.type: FUNC
1073  * @tc.require: issueI6SKRO
1074  */
1075 HWTEST_F(VulkanLoaderUnitTest, vkCreateSemaphore_Test, TestSize.Level1)
1076 {
1077     if (isSupportedVulkan_) {
1078         VkSemaphoreCreateInfo semaphoreCreateInfo {};
1079         semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1080         PFN_vkCreateSemaphore vkCreateSemaphore = reinterpret_cast<PFN_vkCreateSemaphore>(
1081             vkGetInstanceProcAddr(instance_, "vkCreateSemaphore"));
1082         EXPECT_NE(vkCreateSemaphore, nullptr);
1083         VkResult err = vkCreateSemaphore(device_, &semaphoreCreateInfo, nullptr, &semaphore_);
1084         EXPECT_EQ(err, VK_SUCCESS);
1085     }
1086 }
1087 
1088 /**
1089  * @tc.name: test fpAcquireNextImage2KHR
1090  * @tc.desc: test fpAcquireNextImage2KHR
1091  * @tc.type: FUNC
1092  * @tc.require: issueI6SKRO
1093  */
1094 HWTEST_F(VulkanLoaderUnitTest, fpAcquireNextImage2KHR_Test, TestSize.Level1)
1095 {
1096     if (isSupportedVulkan_) {
1097         VkAcquireNextImageInfoKHR pAcquireInfo;
1098         pAcquireInfo.swapchain = swapChain2_;
1099         pAcquireInfo.timeout = UINT64_MAX;
1100         pAcquireInfo.semaphore = semaphore_;
1101         pAcquireInfo.fence = (VkFence)nullptr;
1102         uint32_t imageIndex = 0;
1103         VkResult err = fpAcquireNextImage2KHR(device_, &pAcquireInfo, &imageIndex);
1104         EXPECT_EQ(err, VK_SUCCESS);
1105     }
1106 }
1107 
1108 /**
1109  * @tc.name: test fpQueuePresentKHR
1110  * @tc.desc: test fpQueuePresentKHR
1111  * @tc.type: FUNC
1112  * @tc.require: issueI6SKRO
1113  */
1114 HWTEST_F(VulkanLoaderUnitTest, fpQueuePresentKHR_Test, TestSize.Level1)
1115 {
1116     if (isSupportedVulkan_) {
1117         VkRectLayerKHR pRectangles = {};
1118 
1119         std::vector<VkPresentRegionKHR> pRegions;
1120         VkPresentRegionKHR pRegion;
1121         pRegion.rectangleCount = 1;
1122         pRegion.pRectangles = &pRectangles;
1123         pRegions.push_back(pRegion);
1124 
1125         VkPresentRegionsKHR presentRegions;
1126         presentRegions.sType = VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR;
1127         presentRegions.pNext = NULL;
1128         presentRegions.swapchainCount = 1;
1129         presentRegions.pRegions = pRegions.data();
1130 
1131         VkQueue queue = nullptr;
1132         PFN_vkGetDeviceQueue vkGetDeviceQueue = reinterpret_cast<PFN_vkGetDeviceQueue>(
1133             vkGetInstanceProcAddr(instance_, "vkGetDeviceQueue"));
1134         EXPECT_NE(vkGetDeviceQueue, nullptr);
1135         vkGetDeviceQueue(device_, 0, 0, &queue);
1136         EXPECT_NE(queue, nullptr);
1137         uint32_t imageIndex = 0;
1138         VkPresentInfoKHR presentInfo = {};
1139         presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
1140         presentInfo.pNext = &presentRegions;
1141         presentInfo.swapchainCount = 1;
1142         presentInfo.pSwapchains = &swapChain2_;
1143         presentInfo.pImageIndices = &imageIndex;
1144         EXPECT_NE(semaphore_, VK_NULL_HANDLE);
1145         presentInfo.pWaitSemaphores = &semaphore_;
1146         presentInfo.waitSemaphoreCount = 1;
1147         VkResult err = fpQueuePresentKHR(queue, &presentInfo);
1148         EXPECT_EQ(err, VK_SUCCESS);
1149     }
1150 }
1151 
1152 /**
1153  * @tc.name: test vkDestroySurfaceKHR nullptr
1154  * @tc.desc: test vkDestroySurfaceKHR nullptr
1155  * @tc.type: FUNC
1156  * @tc.require: issueI6SKRO
1157  */
1158 HWTEST_F(VulkanLoaderUnitTest, DestroySurface_NULL_Test, TestSize.Level1)
1159 {
1160     if (isSupportedVulkan_) {
1161         EXPECT_NE(vkDestroySurfaceKHR, nullptr);
1162         vkDestroySurfaceKHR(instance_, VK_NULL_HANDLE, nullptr);
1163     }
1164 }
1165 
1166 /**
1167  * @tc.name: test TranslateNativeToVulkanTransform
1168  * @tc.desc: test TranslateNativeToVulkanTransform
1169  * @tc.type: FUNC
1170  * @tc.require: issueI9EYX2
1171  */
1172 HWTEST_F(VulkanLoaderUnitTest, translateNativeToVulkanTransform_Test, TestSize.Level1)
1173 {
1174     if (isSupportedVulkan_) {
1175         EXPECT_NE(vkCreateSurfaceOHOS, nullptr);
1176         EXPECT_NE(instance_, nullptr);
1177 
1178         OHNativeWindow* nativeWindow = CreateNativeWindow("translateNativeToVulkanTransform_Test");
1179         EXPECT_NE(nativeWindow, nullptr);
1180         std::vector<OH_NativeBuffer_TransformType> transformArray = {
1181             NATIVEBUFFER_ROTATE_NONE,
1182             NATIVEBUFFER_ROTATE_90,
1183             NATIVEBUFFER_ROTATE_180,
1184             NATIVEBUFFER_ROTATE_270,
1185             NATIVEBUFFER_FLIP_H,
1186             NATIVEBUFFER_FLIP_V,
1187             NATIVEBUFFER_FLIP_H_ROT90,
1188             NATIVEBUFFER_FLIP_V_ROT90,
1189             NATIVEBUFFER_FLIP_H_ROT180,
1190             NATIVEBUFFER_FLIP_V_ROT180,
1191             NATIVEBUFFER_FLIP_H_ROT270,
1192             NATIVEBUFFER_FLIP_V_ROT270,
1193         };
1194         VkSurfaceKHR surface = VK_NULL_HANDLE;
1195         for (decltype(transformArray.size()) i = 0; i < transformArray.size(); i++) {
1196             int res = NativeWindowSetTransformHint(nativeWindow, transformArray[i]);
1197             EXPECT_EQ(res, OHOS::GSERROR_OK);
1198 
1199             VkSurfaceCreateInfoOHOS surfaceCreateInfo = {};
1200             surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_SURFACE_CREATE_INFO_OHOS;
1201             surfaceCreateInfo.window = nativeWindow;
1202             VkResult err = vkCreateSurfaceOHOS(instance_, &surfaceCreateInfo, NULL, &surface);
1203             EXPECT_EQ(err, VK_SUCCESS);
1204             EXPECT_NE(surface, VK_NULL_HANDLE);
1205 
1206 
1207             EXPECT_NE(fpGetPhysicalDeviceSurfaceCapabilitiesKHR, nullptr);
1208             EXPECT_NE(physicalDevice_, nullptr);
1209             EXPECT_NE(surface, VK_NULL_HANDLE);
1210 
1211             err = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice_, surface, &surfCaps_);
1212             EXPECT_EQ(err, VK_SUCCESS);
1213 
1214             vkDestroySurfaceKHR(instance_, surface, nullptr);
1215             surface = VK_NULL_HANDLE;
1216         }
1217     }
1218 }
1219 /**
1220  * @tc.name: test vkEnumerateDeviceExtensionProperties GetExtensionProperties
1221  * @tc.desc: test vkEnumerateDeviceExtensionProperties GetExtensionProperties
1222  * @tc.type: FUNC
1223  * @tc.require: issueI9EYX2
1224  */
1225 HWTEST_F(VulkanLoaderUnitTest, enumerateDeviceExtensionProperties_GetExtensionProperties_Test, TestSize.Level1)
1226 {
1227     if (isSupportedVulkan_) {
1228         uint32_t pPropertyCount = 0;
1229         const char* pLayerName = "VK_LAYER_OHOS_surface";
1230         VkResult err = vkEnumerateDeviceExtensionProperties(physicalDevice_, pLayerName, &pPropertyCount, nullptr);
1231         EXPECT_EQ(err, VK_SUCCESS);
1232         if (pPropertyCount > 0) {
1233             std::vector<VkExtensionProperties> pProperties(pPropertyCount);
1234             err = vkEnumerateDeviceExtensionProperties(
1235                 physicalDevice_, pLayerName, &pPropertyCount, pProperties.data());
1236             EXPECT_EQ(err, VK_SUCCESS);
1237         }
1238     }
1239 }
1240 
1241 } // vulkan::loader
1242