• 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, 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 #include <chrono>
16 #include <thread>
17 #include <unistd.h>
18 #include <window.h>
19 #include <gtest/gtest.h>
20 #include <dlfcn.h>
21 #include <iostream>
22 #include <string>
23 #include <vector>
24 
25 #include "refbase.h"
26 #include "surface.h"
27 #include "vulkan/vulkan.h"
28 #include "render_context/render_context.h"
29 #include "transaction/rs_transaction.h"
30 #include "ui/rs_surface_extractor.h"
31 #include "ui/rs_surface_node.h"
32 
33 using namespace testing;
34 using namespace testing::ext;
35 using namespace OHOS::Rosen;
36 
37 namespace vulkan::loader {
38 class VulkanLoaderSystemTest : public testing::Test {
39 public:
SetUpTestCase()40     static void SetUpTestCase() {}
TearDownTestCase()41     static void TearDownTestCase()
42     {
43         if (libVulkan_ != nullptr) {
44             dlclose(libVulkan_);
45             libVulkan_ = nullptr;
46         }
47     }
48     static inline void DLOpenLibVulkan();
49     static inline void TrytoCreateVkInstance();
50 
51     static inline PFN_vkCreateInstance vkCreateInstance;
52     static inline PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
53     static inline PFN_vkCreateDevice vkCreateDevice;
54     static inline PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
55     static inline PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
56     static inline PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
57     static inline PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
58     static inline PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
59     static inline PFN_vkCreateSurfaceOHOS vkCreateSurfaceOHOS;
60     static inline PFN_vkGetPhysicalDeviceSurfaceSupportKHR fpGetPhysicalDeviceSurfaceSupportKHR;
61     static inline PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fpGetPhysicalDeviceSurfaceCapabilitiesKHR;
62     static inline PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fpGetPhysicalDeviceSurfaceFormatsKHR;
63     static inline PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR;
64     static inline PFN_vkCreateSwapchainKHR fpCreateSwapchainKHR;
65     static inline PFN_vkDestroySwapchainKHR fpDestroySwapchainKHR;
66     static inline PFN_vkGetSwapchainImagesKHR fpGetSwapchainImagesKHR;
67     static inline PFN_vkAcquireNextImageKHR fpAcquireNextImageKHR;
68     static inline PFN_vkQueuePresentKHR fpQueuePresentKHR;
69 
70     static inline void *libVulkan_ = nullptr;
71     static inline VkInstance instance_ = nullptr;
72     static inline VkSurfaceKHR surface_ = VK_NULL_HANDLE;
73     static inline VkPhysicalDevice physicalDevice_ = nullptr;
74     static inline VkDevice device_ = nullptr;
75     static inline VkSwapchainKHR swapChain_ = VK_NULL_HANDLE;
76     static inline bool isSupportedVulkan_ = false;
77 };
78 
DLOpenLibVulkan()79 void VulkanLoaderSystemTest::DLOpenLibVulkan()
80 {
81 #ifdef __aarch64__
82     const char *path = "/system/lib64/libvulkan.so";
83 #else
84     const char *path = "/system/lib/libvulkan.so";
85 #endif
86     libVulkan_ = dlopen(path, RTLD_NOW | RTLD_LOCAL);
87     if (libVulkan_ == nullptr) {
88         std::cout << "dlerror: " << dlerror() << std::endl;
89         isSupportedVulkan_ = false;
90         return;
91     }
92     isSupportedVulkan_ = true;
93 }
94 
TrytoCreateVkInstance()95 void VulkanLoaderSystemTest::TrytoCreateVkInstance()
96 {
97     VkApplicationInfo appInfo = {};
98     appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
99     appInfo.pApplicationName = "pApplicationName";
100     appInfo.pEngineName = "pEngineName";
101     appInfo.apiVersion = VK_API_VERSION_1_0;
102 
103     std::vector<const char*> instanceExtensions = {
104         VK_KHR_SURFACE_EXTENSION_NAME,
105         VK_OHOS_SURFACE_EXTENSION_NAME
106     };
107 
108     VkInstanceCreateInfo instanceCreateInfo = {};
109     instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
110     instanceCreateInfo.pNext = NULL;
111     instanceCreateInfo.pApplicationInfo = &appInfo;
112 
113     instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(instanceExtensions.size());
114     instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data();
115 
116     VkResult result = vkCreateInstance(&instanceCreateInfo, nullptr, &instance_);
117     if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {
118         isSupportedVulkan_ = false;
119     } else {
120         isSupportedVulkan_ = true;
121     }
122     std::cout << "TrytoCreateVkInstance result: " << result << std::endl;
123 }
124 
125 /**
126  * @tc.name: Load base Vulkan functions
127  * @tc.desc: Load base Vulkan functions
128  * @tc.type: FUNC
129  * @tc.require: issueI6SKRO
130  */
131 HWTEST_F(VulkanLoaderSystemTest, LoadBaseFuncPtr, TestSize.Level1)
132 {
133     DLOpenLibVulkan();
134     if (isSupportedVulkan_) {
135         EXPECT_NE(libVulkan_, nullptr);
136 
137         // Load base functions
138         vkEnumerateInstanceExtensionProperties = reinterpret_cast<PFN_vkEnumerateInstanceExtensionProperties>(
139             dlsym(libVulkan_, "vkEnumerateInstanceExtensionProperties"));
140         EXPECT_NE(vkEnumerateInstanceExtensionProperties, nullptr);
141         vkEnumerateInstanceLayerProperties = reinterpret_cast<PFN_vkEnumerateInstanceLayerProperties>(
142             dlsym(libVulkan_, "vkEnumerateInstanceLayerProperties"));
143         EXPECT_NE(vkEnumerateInstanceLayerProperties, nullptr);
144         vkCreateInstance = reinterpret_cast<PFN_vkCreateInstance>(dlsym(libVulkan_, "vkCreateInstance"));
145         EXPECT_NE(vkCreateInstance, nullptr);
146         vkGetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(dlsym(libVulkan_, "vkGetInstanceProcAddr"));
147         EXPECT_NE(vkGetInstanceProcAddr, nullptr);
148         vkGetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(dlsym(libVulkan_, "vkGetDeviceProcAddr"));
149         EXPECT_NE(vkGetDeviceProcAddr, nullptr);
150         TrytoCreateVkInstance();
151     }
152 }
153 
154 /**
155  * @tc.name: Load instance based Vulkan function pointers
156  * @tc.desc: Load instance based Vulkan function pointers
157  * @tc.type: FUNC
158  * @tc.require: issueI6SKRO
159  */
160 HWTEST_F(VulkanLoaderSystemTest, LoadInstanceFuncPtr, TestSize.Level1)
161 {
162     if (isSupportedVulkan_) {
163         vkEnumeratePhysicalDevices = reinterpret_cast<PFN_vkEnumeratePhysicalDevices>(
164             vkGetInstanceProcAddr(instance_, "vkEnumeratePhysicalDevices"));
165         EXPECT_NE(vkEnumeratePhysicalDevices, nullptr);
166         vkCreateDevice = reinterpret_cast<PFN_vkCreateDevice>(
167             vkGetInstanceProcAddr(instance_, "vkCreateDevice"));
168         EXPECT_NE(vkCreateDevice, nullptr);
169         vkCreateSurfaceOHOS = reinterpret_cast<PFN_vkCreateSurfaceOHOS>(
170             vkGetInstanceProcAddr(instance_, "vkCreateSurfaceOHOS"));
171         EXPECT_NE(vkCreateSurfaceOHOS, nullptr);
172         vkDestroySurfaceKHR = reinterpret_cast<PFN_vkDestroySurfaceKHR>(
173             vkGetInstanceProcAddr(instance_, "vkDestroySurfaceKHR"));
174         EXPECT_NE(vkDestroySurfaceKHR, nullptr);
175         fpGetPhysicalDeviceSurfaceSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceSupportKHR>(
176             vkGetInstanceProcAddr(instance_, "vkGetPhysicalDeviceSurfaceSupportKHR"));
177         EXPECT_NE(fpGetPhysicalDeviceSurfaceSupportKHR, nullptr);
178         fpGetPhysicalDeviceSurfaceCapabilitiesKHR =  reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR>(
179             vkGetInstanceProcAddr(instance_, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"));
180         EXPECT_NE(fpGetPhysicalDeviceSurfaceCapabilitiesKHR, nullptr);
181         fpGetPhysicalDeviceSurfaceFormatsKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR>(
182             vkGetInstanceProcAddr(instance_, "vkGetPhysicalDeviceSurfaceFormatsKHR"));
183         EXPECT_NE(fpGetPhysicalDeviceSurfaceFormatsKHR, nullptr);
184         fpGetPhysicalDeviceSurfacePresentModesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR>(
185             vkGetInstanceProcAddr(instance_, "vkGetPhysicalDeviceSurfacePresentModesKHR"));
186         EXPECT_NE(fpGetPhysicalDeviceSurfacePresentModesKHR, nullptr);
187     }
188 }
189 
190 /**
191  * @tc.name: create device
192  * @tc.desc: create device
193  * @tc.type: FUNC
194  * @tc.require: issueI6SKRO
195  */
196 HWTEST_F(VulkanLoaderSystemTest, createDevice_Test, TestSize.Level1)
197 {
198     if (isSupportedVulkan_) {
199         uint32_t gpuCount = 0;
200         VkResult err = vkEnumeratePhysicalDevices(instance_, &gpuCount, nullptr);
201         EXPECT_EQ(err, VK_SUCCESS);
202         EXPECT_NE(gpuCount, 0);
203         std::vector<VkPhysicalDevice> physicalDevices(gpuCount);
204         err = vkEnumeratePhysicalDevices(instance_, &gpuCount, physicalDevices.data());
205         EXPECT_EQ(err, VK_SUCCESS);
206         physicalDevice_ = physicalDevices[0];
207 
208         std::vector<const char*> deviceExtensions;
209         deviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
210         VkDeviceCreateInfo deviceCreateInfo = {};
211         deviceCreateInfo.enabledExtensionCount = (uint32_t)deviceExtensions.size();
212         deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
213 
214         VkDevice logicalDevice;
215         err = vkCreateDevice(physicalDevice_, &deviceCreateInfo, nullptr, &logicalDevice);
216         EXPECT_EQ(err, VK_SUCCESS);
217         EXPECT_NE(logicalDevice, nullptr);
218         device_ = logicalDevice;
219     }
220 }
221 
222 /**
223  * @tc.name: Load device based Vulkan function pointers
224  * @tc.desc: Load device based Vulkan function pointers
225  * @tc.type: FUNC
226  * @tc.require: issueI6SKRO
227  */
228 HWTEST_F(VulkanLoaderSystemTest, LoadDeviceFuncPtr, TestSize.Level1)
229 {
230     if (isSupportedVulkan_) {
231         fpCreateSwapchainKHR = reinterpret_cast<PFN_vkCreateSwapchainKHR>(
232             vkGetDeviceProcAddr(device_, "vkCreateSwapchainKHR"));
233         EXPECT_NE(fpCreateSwapchainKHR, nullptr);
234         fpDestroySwapchainKHR = reinterpret_cast<PFN_vkDestroySwapchainKHR>(
235             vkGetDeviceProcAddr(device_, "vkDestroySwapchainKHR"));
236         EXPECT_NE(fpDestroySwapchainKHR, nullptr);
237         fpGetSwapchainImagesKHR = reinterpret_cast<PFN_vkGetSwapchainImagesKHR>(
238             vkGetDeviceProcAddr(device_, "vkGetSwapchainImagesKHR"));
239         EXPECT_NE(fpGetSwapchainImagesKHR, nullptr);
240         fpAcquireNextImageKHR = reinterpret_cast<PFN_vkAcquireNextImageKHR>(
241             vkGetDeviceProcAddr(device_, "vkAcquireNextImageKHR"));
242         EXPECT_NE(fpAcquireNextImageKHR, nullptr);
243         fpQueuePresentKHR = reinterpret_cast<PFN_vkQueuePresentKHR>(vkGetDeviceProcAddr(device_, "vkQueuePresentKHR"));
244         EXPECT_NE(fpQueuePresentKHR, nullptr);
245     }
246 }
247 
248 /**
249  * @tc.name: create surface
250  * @tc.desc: create surface
251  * @tc.type: FUNC
252  * @tc.require: issueI6SKRO
253  */
254 HWTEST_F(VulkanLoaderSystemTest, createSurface_Test, TestSize.Level1)
255 {
256     if (isSupportedVulkan_) {
257         struct RSSurfaceNodeConfig rsSurfaceNodeConfig;
258         rsSurfaceNodeConfig.SurfaceNodeName = "createSurface_test";
259         auto surfaceNode = RSSurfaceNode::Create(rsSurfaceNodeConfig, RSSurfaceNodeType::DEFAULT);
260         OHOS::sptr<OHOS::Surface> surf = surfaceNode->GetSurface();
261         OHNativeWindow* nativeWindow = CreateNativeWindowFromSurface(&surf);
262         EXPECT_NE(nativeWindow, nullptr);
263         VkSurfaceCreateInfoOHOS surfaceCreateInfo = {};
264         surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_SURFACE_CREATE_INFO_OHOS;
265         surfaceCreateInfo.window = nativeWindow;
266         VkResult err = vkCreateSurfaceOHOS(instance_, &surfaceCreateInfo, NULL, &surface_);
267         EXPECT_EQ(err, VK_SUCCESS);
268         EXPECT_NE(surface_, VK_NULL_HANDLE);
269     }
270 }
271 
272 /**
273  * @tc.name: create swapChain
274  * @tc.desc: create swapChain
275  * @tc.type: FUNC
276  * @tc.require: issueI6SKRO
277  */
278 HWTEST_F(VulkanLoaderSystemTest, createSwapChain_Test, TestSize.Level1)
279 {
280     if (isSupportedVulkan_) {
281         VkSwapchainKHR oldSwapchain = swapChain_;
282         VkSwapchainCreateInfoKHR swapchainCI = {};
283         swapchainCI.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
284         swapchainCI.surface = surface_;
285         VkSurfaceCapabilitiesKHR surfCaps;
286         VkResult err = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice_, surface_, &surfCaps);
287         EXPECT_EQ(err, VK_SUCCESS);
288         uint32_t desiredNumberOfSwapchainImages = surfCaps.minImageCount + 1;
289         swapchainCI.minImageCount = desiredNumberOfSwapchainImages;
290         swapchainCI.imageFormat = VK_FORMAT_B8G8R8A8_UNORM;
291         uint32_t formatCount;
292         err = fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice_, surface_, &formatCount, NULL);
293         EXPECT_EQ(err, VK_SUCCESS);
294         EXPECT_GT(formatCount, 0);
295         std::vector<VkSurfaceFormatKHR> surfaceFormats(formatCount);
296         err = fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice_, surface_, &formatCount, surfaceFormats.data());
297         EXPECT_EQ(err, VK_SUCCESS);
298         swapchainCI.imageColorSpace = surfaceFormats[0].colorSpace;
299         uint32_t width = 1280;
300         uint32_t height = 720;
301         swapchainCI.imageExtent = { width, height };
302         swapchainCI.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
303         swapchainCI.preTransform = (VkSurfaceTransformFlagBitsKHR)VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
304         swapchainCI.imageArrayLayers = 1;
305         swapchainCI.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
306         swapchainCI.queueFamilyIndexCount = 0;
307         swapchainCI.presentMode = VK_PRESENT_MODE_MAILBOX_KHR;
308         swapchainCI.oldSwapchain = oldSwapchain;
309         swapchainCI.clipped = VK_TRUE;
310         swapchainCI.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
311 
312         err = fpCreateSwapchainKHR(device_, &swapchainCI, nullptr, &swapChain_);
313         EXPECT_EQ(err, VK_SUCCESS);
314         EXPECT_NE(swapChain_, VK_NULL_HANDLE);
315     }
316 }
317 }