• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #include "wm/window.h"
33 
34 using namespace testing;
35 using namespace testing::ext;
36 
37 namespace OHOS::Rosen {
38 
39 typedef bool (*PFN_IsSupportedVulkan)();
40 
41 class VulkanWrapperApiTest : public testing::Test {
42 public:
SetUpTestCase()43     static void SetUpTestCase() {}
TearDownTestCase()44     static void TearDownTestCase()
45     {
46         if (libVulkan != nullptr) {
47             dlclose(libVulkan);
48             libVulkan = nullptr;
49         }
50     }
51 
52     static inline PFN_vkCreateInstance vkCreateInstance;
53     static inline PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
54     static inline PFN_vkCreateDevice vkCreateDevice;
55     static inline PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
56     static inline PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
57     static inline PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
58     static inline PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
59     static inline PFN_vkCreateOHOSSurfaceOpenHarmony vkCreateOHOSSurfaceOpenHarmony;
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     static inline PFN_IsSupportedVulkan fpIsSupportedVulkan;
70 
71     static inline void *libVulkan = nullptr;
72     static inline VkInstance instance = nullptr;
73     static inline VkSurfaceKHR surface = VK_NULL_HANDLE;
74     static inline VkPhysicalDevice physicalDevice = nullptr;
75     static inline VkDevice device = nullptr;
76     static inline VkSwapchainKHR swapChain = VK_NULL_HANDLE;
77     static inline bool isSupportedVulkan = false;
78 };
79 
80 /**
81  * @tc.name: dlopen libvulkan.so
82  * @tc.desc: dlopen libvulkan.so
83  * @tc.type: FUNC
84  * @tc.require: issueI5ODXM
85  */
86 HWTEST_F(VulkanWrapperApiTest, dlopen_Test, TestSize.Level1)
87 {
88 #ifdef __aarch64__
89     const char *path = "/system/lib64/libvulkan.so";
90 #else
91     const char *path = "/system/lib/libvulkan.so";
92 #endif
93     libVulkan = dlopen(path, RTLD_NOW | RTLD_LOCAL);
94     EXPECT_NE(libVulkan, nullptr);
95 }
96 
97 /**
98  * @tc.name: Load base function pointers
99  * @tc.desc: Load base function pointers
100  * @tc.type: FUNC
101  * @tc.require: issueI5ODXM
102  */
103 HWTEST_F(VulkanWrapperApiTest, LoadFuncPtr001, TestSize.Level1)
104 {
105     vkEnumerateInstanceExtensionProperties = reinterpret_cast<PFN_vkEnumerateInstanceExtensionProperties>(
106         dlsym(libVulkan, "vkEnumerateInstanceExtensionProperties"));
107     EXPECT_NE(vkEnumerateInstanceExtensionProperties, nullptr);
108     vkCreateInstance = reinterpret_cast<PFN_vkCreateInstance>(dlsym(libVulkan, "vkCreateInstance"));
109     EXPECT_NE(vkCreateInstance, nullptr);
110     vkGetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(dlsym(libVulkan, "vkGetInstanceProcAddr"));
111     EXPECT_NE(vkGetInstanceProcAddr, nullptr);
112     vkGetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(dlsym(libVulkan, "vkGetDeviceProcAddr"));
113     EXPECT_NE(vkGetDeviceProcAddr, nullptr);
114     fpIsSupportedVulkan = reinterpret_cast<PFN_IsSupportedVulkan>(dlsym(libVulkan, "IsSupportedVulkan"));
115     EXPECT_NE(fpIsSupportedVulkan, nullptr);
116     isSupportedVulkan = fpIsSupportedVulkan();
117     std::cout << "support vulkan :" << isSupportedVulkan << std::endl;
118 }
119 
120 /**
121  * @tc.name: create vkInstance
122  * @tc.desc: create vkInstance
123  * @tc.type: FUNC
124  * @tc.require: issueI5ODXM
125  */
126 HWTEST_F(VulkanWrapperApiTest, createVkInstance_Test, TestSize.Level1)
127 {
128     if (isSupportedVulkan) {
129         VkApplicationInfo appInfo = {};
130         appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
131         appInfo.pApplicationName = "pApplicationName";
132         appInfo.pEngineName = "pEngineName";
133         appInfo.apiVersion = VK_API_VERSION_1_0;
134 
135         std::vector<const char*> instanceExtensions = { VK_KHR_SURFACE_EXTENSION_NAME };
136         instanceExtensions.push_back(VK_OPENHARMONY_OHOS_SURFACE_EXTENSION_NAME);
137 
138         VkInstanceCreateInfo instanceCreateInfo = {};
139         instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
140         instanceCreateInfo.pNext = NULL;
141         instanceCreateInfo.pApplicationInfo = &appInfo;
142 
143         if (instanceExtensions.size() > 0) {
144             instanceCreateInfo.enabledExtensionCount = (uint32_t)instanceExtensions.size();
145             instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data();
146         }
147 
148         VkResult err = vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
149         EXPECT_EQ(err, VK_SUCCESS);
150         EXPECT_NE(instance, nullptr);
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: issueI5ODXM
159  */
160 HWTEST_F(VulkanWrapperApiTest, LoadFuncPtr002, 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         vkCreateOHOSSurfaceOpenHarmony = reinterpret_cast<PFN_vkCreateOHOSSurfaceOpenHarmony>(
170             vkGetInstanceProcAddr(instance, "vkCreateOHOSSurfaceOpenHarmony"));
171         EXPECT_NE(vkCreateOHOSSurfaceOpenHarmony, 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: issueI5ODXM
195  */
196 HWTEST_F(VulkanWrapperApiTest, 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: issueI5ODXM
227  */
228 HWTEST_F(VulkanWrapperApiTest, LoadFuncPtr003, 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: issueI5ODXM
253  */
254 HWTEST_F(VulkanWrapperApiTest, createSurface_Test, TestSize.Level1)
255 {
256     if (isSupportedVulkan) {
257         constexpr int windowLeft = 100;
258         constexpr int windowTop = 200;
259         constexpr int windowWidth = 360;
260         constexpr int windowHeight = 360;
261         OHOS::Rosen::Rect rect = {windowLeft, windowTop, windowWidth, windowHeight};
262         OHOS::sptr<OHOS::Rosen::WindowOption> option(new OHOS::Rosen::WindowOption());
263         option->SetDisplayId(0);
264         option->SetWindowRect(rect);
265         option->SetWindowType(OHOS::Rosen::WindowType::APP_MAIN_WINDOW_BASE);
266         option->SetWindowMode(OHOS::Rosen::WindowMode::WINDOW_MODE_FLOATING);
267         option->SetWindowName("createSurface_test");
268         OHOS::sptr<OHOS::Rosen::Window> window = OHOS::Rosen::Window::Create(option->GetWindowName(), option);
269         EXPECT_NE(window, nullptr);
270 
271         OHOS::Rosen::RSTransaction::FlushImplicitTransaction();
272         window->Show();
273 
274         auto surfaceNode = window->GetSurfaceNode();
275         OHOS::sptr<OHOS::Surface> surf = surfaceNode->GetSurface();
276         OHNativeWindow* nativeWindow = CreateNativeWindowFromSurface(&surf);
277         EXPECT_NE(nativeWindow, nullptr);
278         VkOHOSSurfaceCreateInfoOpenHarmony surfaceCreateInfo = {};
279         surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_OHOS_SURFACE_CREATE_INFO_OPENHARMONY;
280         surfaceCreateInfo.window = nativeWindow;
281         VkResult err = vkCreateOHOSSurfaceOpenHarmony(instance, &surfaceCreateInfo, NULL, &surface);
282         EXPECT_EQ(err, VK_SUCCESS);
283         EXPECT_NE(surface, VK_NULL_HANDLE);
284     }
285 }
286 
287 /**
288  * @tc.name: create swapChain
289  * @tc.desc: create swapChain
290  * @tc.type: FUNC
291  * @tc.require: issueI5ODXM
292  */
293 HWTEST_F(VulkanWrapperApiTest, createSwapChain_Test, TestSize.Level1)
294 {
295     if (isSupportedVulkan) {
296         VkSwapchainKHR oldSwapchain = swapChain;
297         VkSwapchainCreateInfoKHR swapchainCI = {};
298         swapchainCI.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
299         swapchainCI.surface = surface;
300         VkSurfaceCapabilitiesKHR surfCaps;
301         VkResult err = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &surfCaps);
302         EXPECT_EQ(err, VK_SUCCESS);
303         uint32_t desiredNumberOfSwapchainImages = surfCaps.minImageCount + 1;
304         swapchainCI.minImageCount = desiredNumberOfSwapchainImages;
305         swapchainCI.imageFormat = VK_FORMAT_B8G8R8A8_UNORM;
306         uint32_t formatCount;
307         err = fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, NULL);
308         EXPECT_EQ(err, VK_SUCCESS);
309         EXPECT_GT(formatCount, 0);
310         std::vector<VkSurfaceFormatKHR> surfaceFormats(formatCount);
311         err = fpGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, surfaceFormats.data());
312         EXPECT_EQ(err, VK_SUCCESS);
313         swapchainCI.imageColorSpace = surfaceFormats[0].colorSpace;
314         uint32_t width = 1280;
315         uint32_t height = 720;
316         swapchainCI.imageExtent = { width, height };
317         swapchainCI.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
318         swapchainCI.preTransform = (VkSurfaceTransformFlagBitsKHR)VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
319         swapchainCI.imageArrayLayers = 1;
320         swapchainCI.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
321         swapchainCI.queueFamilyIndexCount = 0;
322         swapchainCI.presentMode = VK_PRESENT_MODE_MAILBOX_KHR;
323         swapchainCI.oldSwapchain = oldSwapchain;
324         swapchainCI.clipped = VK_TRUE;
325         swapchainCI.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
326 
327         err = fpCreateSwapchainKHR(device, &swapchainCI, nullptr, &swapChain);
328         EXPECT_EQ(err, VK_SUCCESS);
329         EXPECT_NE(swapChain, VK_NULL_HANDLE);
330     }
331 }
332 }