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
16 #include <cassert>
17 #include <cstdint>
18 #include <cstdio>
19 #include <limits>
20 #include <thread>
21 #include <unordered_map>
22 #include <vector>
23 #include <iostream>
24 #include <malloc.h>
25 #include <algorithm>
26 #include <new>
27 #include <securec.h>
28 #include <cstring>
29 #include <cinttypes>
30 #include <refbase.h>
31
32 #include <vulkan/vulkan_core.h>
33 #include <window.h>
34 #include <graphic_common.h>
35 #include <native_window.h>
36 #include <vulkan/vulkan.h>
37 #include "vk_dispatch_table_helper.h"
38 #include "vk_layer_dispatch_table.h"
39 #include "swapchain_layer_log.h"
40 #include "sync_fence.h"
41
42 #define SWAPCHAIN_SURFACE_NAME "VK_LAYER_OHOS_surface"
43
44 using namespace OHOS;
45
46 enum Extension {
47 OHOS_SURFACE,
48 OHOS_NATIVE_BUFFER,
49 KHR_SURFACE,
50 KHR_SWAPCHAIN,
51 EXTENSION_COUNT,
52 EXTENSION_UNKNOWN,
53 };
54
55 struct LayerData {
56 VkInstance instance = VK_NULL_HANDLE;
57 VkDevice device = VK_NULL_HANDLE;
58 uint32_t instanceVersion = VK_API_VERSION_1_0;
59 std::unique_ptr<VkLayerDispatchTable> deviceDispatchTable;
60 std::unique_ptr<VkLayerInstanceDispatchTable> instanceDispatchTable;
61 std::unordered_map<VkDebugUtilsMessengerEXT, VkDebugUtilsMessengerCreateInfoEXT> debugCallbacks;
62 PFN_vkSetDeviceLoaderData fpSetDeviceLoaderData = nullptr;
63 std::bitset<Extension::EXTENSION_COUNT> enabledExtensions;
64 };
65
66 namespace {
67 constexpr uint32_t MIN_BUFFER_SIZE = 3;
68 constexpr uint32_t MAX_BUFFER_SIZE = 32;
69 struct LoaderVkLayerDispatchTable;
70 typedef uintptr_t DispatchKey;
71
72 template <typename T>
GetDispatchKey(const T object)73 inline DispatchKey GetDispatchKey(const T object)
74 {
75 return reinterpret_cast<DispatchKey>(*reinterpret_cast<LoaderVkLayerDispatchTable* const*>(object));
76 }
77
GetChainInfo(const VkInstanceCreateInfo * pCreateInfo,VkLayerFunction func)78 VkLayerInstanceCreateInfo* GetChainInfo(const VkInstanceCreateInfo* pCreateInfo, VkLayerFunction func)
79 {
80 auto chainInfo = static_cast<const VkLayerInstanceCreateInfo*>(pCreateInfo->pNext);
81 while (chainInfo != nullptr) {
82 if (chainInfo->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chainInfo->function == func) {
83 return const_cast<VkLayerInstanceCreateInfo*>(chainInfo);
84 }
85 chainInfo = static_cast<const VkLayerInstanceCreateInfo*>(chainInfo->pNext);
86 }
87 SWLOGE("Failed to find VkLayerInstanceCreateInfo");
88 return nullptr;
89 }
90
GetChainInfo(const VkDeviceCreateInfo * pCreateInfo,VkLayerFunction func)91 VkLayerDeviceCreateInfo* GetChainInfo(const VkDeviceCreateInfo* pCreateInfo, VkLayerFunction func)
92 {
93 auto chainInfo = static_cast<const VkLayerDeviceCreateInfo*>(pCreateInfo->pNext);
94 while (chainInfo != nullptr) {
95 if (chainInfo->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chainInfo->function == func) {
96 return const_cast<VkLayerDeviceCreateInfo*>(chainInfo);
97 }
98 chainInfo = static_cast<const VkLayerDeviceCreateInfo*>(chainInfo->pNext);
99 }
100 SWLOGE("Failed to find VkLayerDeviceCreateInfo");
101 return nullptr;
102 }
103 } // namespace
104
105 #define VK_LAYER_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION)
106
ToUint32(uint64_t val)107 static inline uint32_t ToUint32(uint64_t val)
108 {
109 if (val > UINT32_MAX) {
110 SWLOGE("%{public}" PRIu64 " is too large to convert to uint32", val);
111 }
112 return static_cast<uint32_t>(val);
113 }
114
115 namespace SWAPCHAIN {
116 std::unordered_map<DispatchKey, LayerData*> g_layerDataMap;
117
GetLayerDataPtr(DispatchKey dataKey)118 LayerData* GetLayerDataPtr(DispatchKey dataKey)
119 {
120 LayerData* layerData = nullptr;
121 auto it = g_layerDataMap.find(dataKey);
122 if (it == g_layerDataMap.end()) {
123 layerData = new LayerData;
124 g_layerDataMap[dataKey] = layerData;
125 } else {
126 layerData = it->second;
127 }
128 return layerData;
129 }
130
FreeLayerDataPtr(DispatchKey dataKey)131 void FreeLayerDataPtr(DispatchKey dataKey)
132 {
133 auto it = g_layerDataMap.find(dataKey);
134 if (it == g_layerDataMap.end()) {
135 return;
136 }
137 delete it->second;
138 g_layerDataMap.erase(it);
139 }
140
DebugMessageToUserCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,const char * message)141 void DebugMessageToUserCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, const char* message)
142 {
143 VkDebugUtilsMessengerCallbackDataEXT callbackData = {};
144 callbackData.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
145 callbackData.pMessageIdName = "SwapchainLayer";
146 callbackData.pMessage = message;
147
148 for (auto [key, layerData] : g_layerDataMap) {
149 if (layerData->debugCallbacks.empty()) {
150 continue;
151 }
152 for (auto& callback : layerData->debugCallbacks) {
153 if (!(severity & callback.second.messageSeverity)) {
154 continue;
155 }
156 if (!(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT & callback.second.messageType)) {
157 continue;
158 }
159 callback.second.pfnUserCallback(severity, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
160 &callbackData, callback.second.pUserData);
161 }
162 }
163 }
164
GetExtensionProperties(const uint32_t count,const VkExtensionProperties * layerExtensions,uint32_t * pCount,VkExtensionProperties * pProperties)165 VkResult GetExtensionProperties(const uint32_t count, const VkExtensionProperties* layerExtensions,
166 uint32_t* pCount, VkExtensionProperties* pProperties)
167 {
168 if (pProperties == nullptr || layerExtensions == nullptr) {
169 *pCount = count;
170 return VK_SUCCESS;
171 }
172
173 uint32_t copySize = *pCount < count ? *pCount : count;
174 errno_t ret = memcpy_s(pProperties, copySize * sizeof(VkExtensionProperties),
175 layerExtensions, copySize * sizeof(VkExtensionProperties));
176 if (ret != EOK) {
177 return VK_INCOMPLETE;
178 }
179 *pCount = copySize;
180 if (copySize < count) {
181 return VK_INCOMPLETE;
182 }
183
184 return VK_SUCCESS;
185 }
186
GetLayerProperties(const uint32_t count,const VkLayerProperties * layerProperties,uint32_t * pCount,VkLayerProperties * pProperties)187 VkResult GetLayerProperties(const uint32_t count, const VkLayerProperties* layerProperties,
188 uint32_t* pCount, VkLayerProperties* pProperties)
189 {
190 if (pProperties == nullptr || layerProperties == nullptr) {
191 *pCount = count;
192 return VK_SUCCESS;
193 }
194
195 uint32_t copySize = *pCount < count ? *pCount : count;
196 errno_t ret = memcpy_s(pProperties, copySize * sizeof(VkLayerProperties),
197 layerProperties, copySize * sizeof(VkLayerProperties));
198 if (ret != EOK) {
199 return VK_INCOMPLETE;
200 }
201 *pCount = copySize;
202 if (copySize < count) {
203 return VK_INCOMPLETE;
204 }
205
206 return VK_SUCCESS;
207 }
208
209 static const VkExtensionProperties instanceExtensions[] = {
210 {
211 .extensionName = VK_KHR_SURFACE_EXTENSION_NAME,
212 .specVersion = 25,
213 },
214 {
215 .extensionName = VK_OHOS_SURFACE_EXTENSION_NAME,
216 .specVersion = 1,
217 }
218 };
219
220 static const VkExtensionProperties deviceExtensions[] = {{
221 .extensionName = VK_KHR_SWAPCHAIN_EXTENSION_NAME,
222 .specVersion = 70,
223 }};
224
225 constexpr VkLayerProperties swapchainLayer = {
226 SWAPCHAIN_SURFACE_NAME,
227 VK_LAYER_API_VERSION,
228 1,
229 "Vulkan Swapchain",
230 };
231
232 struct Surface {
233 NativeWindow* window;
234 VkSwapchainKHR swapchainHandle;
235 int32_t consumerUsage;
236 };
237
238 struct Swapchain {
SwapchainSWAPCHAIN::Swapchain239 Swapchain(Surface &surface, uint32_t numImages, VkPresentModeKHR presentMode, int preTransform)
240 : surface(surface), numImages(numImages), mailboxMode(presentMode == VK_PRESENT_MODE_MAILBOX_KHR),
241 preTransform(preTransform), frameTimestampsEnabled(false),
242 shared(presentMode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR ||
243 presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) {}
244
245 Surface &surface;
246 uint32_t numImages;
247 bool mailboxMode;
248 int preTransform;
249 bool frameTimestampsEnabled;
250 bool shared;
251
252 struct Image {
ImageSWAPCHAIN::Swapchain::Image253 Image() : image(VK_NULL_HANDLE), buffer(nullptr), requestFence(-1), releaseFence(-1), requested(false) {}
254 VkImage image;
255 NativeWindowBuffer* buffer;
256 int requestFence;
257 int releaseFence;
258 bool requested;
259 } images[MAX_BUFFER_SIZE];
260 };
261
262 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* funcName);
263 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance,
264 const char* funcName);
265
HandleFromSurface(Surface * surface)266 VkSurfaceKHR HandleFromSurface(Surface* surface)
267 {
268 return VkSurfaceKHR(reinterpret_cast<uint64_t>(surface));
269 }
270
SurfaceFromHandle(VkSurfaceKHR handle)271 Surface* SurfaceFromHandle(VkSurfaceKHR handle)
272 {
273 return reinterpret_cast<Surface*>(handle);
274 }
275
SwapchainFromHandle(VkSwapchainKHR handle)276 Swapchain* SwapchainFromHandle(VkSwapchainKHR handle)
277 {
278 return reinterpret_cast<Swapchain*>(handle);
279 }
280
HandleFromSwapchain(Swapchain * swapchain)281 VkSwapchainKHR HandleFromSwapchain(Swapchain* swapchain)
282 {
283 return VkSwapchainKHR(reinterpret_cast<uint64_t>(swapchain));
284 }
285
DefaultAllocate(void *,size_t size,size_t alignment,VkSystemAllocationScope)286 VKAPI_ATTR void* DefaultAllocate(void*, size_t size, size_t alignment, VkSystemAllocationScope)
287 {
288 void* ptr = nullptr;
289 int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
290 return ret == 0 ? ptr : nullptr;
291 }
292
DefaultReallocate(void *,void * ptr,size_t size,size_t alignment,VkSystemAllocationScope)293 VKAPI_ATTR void* DefaultReallocate(void*, void* ptr, size_t size, size_t alignment, VkSystemAllocationScope)
294 {
295 if (size == 0) {
296 free(ptr);
297 return nullptr;
298 }
299
300 size_t oldSize = ptr ? malloc_usable_size(ptr) : 0;
301 if (size <= oldSize) {
302 return ptr;
303 }
304
305 void* newPtr = nullptr;
306 if (posix_memalign(&newPtr, std::max(alignment, sizeof(void*)), size) != 0) {
307 return nullptr;
308 }
309
310 if (ptr != nullptr) {
311 auto ret = memcpy_s(newPtr, size, ptr, oldSize);
312 if (ret != EOK) {
313 free(newPtr);
314 return nullptr;
315 }
316 free(ptr);
317 }
318 return newPtr;
319 }
320
DefaultFree(void *,void * ptr)321 VKAPI_ATTR void DefaultFree(void*, void* ptr)
322 {
323 free(ptr);
324 }
325
GetDefaultAllocator()326 const VkAllocationCallbacks &GetDefaultAllocator()
327 {
328 static const VkAllocationCallbacks defaultAllocCallbacks = {
329 .pUserData = nullptr,
330 .pfnAllocation = DefaultAllocate,
331 .pfnReallocation = DefaultReallocate,
332 .pfnFree = DefaultFree,
333 };
334
335 return defaultAllocCallbacks;
336 }
337
GetColorDataspace(VkColorSpaceKHR colorspace)338 GraphicColorDataSpace GetColorDataspace(VkColorSpaceKHR colorspace)
339 {
340 switch (colorspace) {
341 case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR:
342 return GRAPHIC_BT709_SRGB_FULL;
343 case VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT:
344 return GRAPHIC_DCI_P3_GAMMA26_FULL;
345 case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT:
346 return GRAPHIC_BT709_LINEAR_EXTENDED;
347 case VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT:
348 return GRAPHIC_BT709_SRGB_EXTENDED;
349 case VK_COLOR_SPACE_DCI_P3_LINEAR_EXT:
350 return GRAPHIC_DCI_P3_LINEAR_FULL;
351 case VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT:
352 return GRAPHIC_DCI_P3_GAMMA26_FULL;
353 case VK_COLOR_SPACE_BT709_LINEAR_EXT:
354 return GRAPHIC_BT709_LINEAR_FULL;
355 case VK_COLOR_SPACE_BT709_NONLINEAR_EXT:
356 return GRAPHIC_BT709_SRGB_FULL;
357 case VK_COLOR_SPACE_BT2020_LINEAR_EXT:
358 return GRAPHIC_BT2020_LINEAR_FULL;
359 case VK_COLOR_SPACE_HDR10_ST2084_EXT:
360 return GRAPHIC_BT2020_ST2084_FULL;
361 case VK_COLOR_SPACE_DOLBYVISION_EXT:
362 return GRAPHIC_BT2020_ST2084_FULL;
363 case VK_COLOR_SPACE_HDR10_HLG_EXT:
364 return GRAPHIC_BT2020_HLG_FULL;
365 case VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT:
366 return static_cast<GraphicColorDataSpace>(GRAPHIC_GAMUT_ADOBE_RGB |
367 GRAPHIC_TRANSFORM_FUNC_LINEAR | GRAPHIC_PRECISION_FULL);
368 case VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT:
369 return GRAPHIC_ADOBE_RGB_GAMMA22_FULL;
370 default:
371 return GRAPHIC_COLOR_DATA_SPACE_UNKNOWN;
372 }
373 }
374
IsFencePending(int fd)375 static bool IsFencePending(int fd)
376 {
377 if (fd < 0) {
378 return false;
379 }
380 errno = 0;
381 sptr<OHOS::SyncFence> syncFence = new OHOS::SyncFence(fd);
382 return syncFence->Wait(0) == -1 && errno == ETIME;
383 }
384
ReleaseSwapchainImage(VkDevice device,NativeWindow * window,int releaseFence,Swapchain::Image & image,bool deferIfPending)385 void ReleaseSwapchainImage(VkDevice device, NativeWindow* window, int releaseFence, Swapchain::Image &image,
386 bool deferIfPending)
387 {
388 if (releaseFence != -1 && !image.requested) {
389 SWLOGE("%{public}s, can't provide a release fence for non-requested images", __func__);
390 DebugMessageToUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
391 "can't provide a release fence for non-requested images");
392 return;
393 }
394
395 VkLayerDispatchTable* pDisp =
396 GetLayerDataPtr(GetDispatchKey(device))->deviceDispatchTable.get();
397 pDisp->DeviceWaitIdle(device);
398 if (image.requested) {
399 if (releaseFence >= 0) {
400 if (image.requestFence >= 0) {
401 sptr<OHOS::SyncFence> requestFence = new OHOS::SyncFence(image.requestFence);
402 requestFence->Wait(-1);
403 close(image.requestFence);
404 }
405 } else {
406 releaseFence = image.requestFence;
407 }
408 image.requestFence = -1;
409
410 if (window != nullptr) {
411 NativeWindowCancelBuffer(window, image.buffer);
412 } else {
413 if (releaseFence >= 0) {
414 close(releaseFence);
415 }
416 }
417 image.requested = false;
418 }
419
420 if (deferIfPending && IsFencePending(image.releaseFence)) {
421 return;
422 }
423
424 if (image.releaseFence >= 0) {
425 close(image.releaseFence);
426 image.releaseFence = -1;
427 }
428
429 if (image.image != VK_NULL_HANDLE) {
430 pDisp->DestroyImage(device, image.image, nullptr);
431 image.image = VK_NULL_HANDLE;
432 }
433 }
434
ReleaseSwapchain(VkDevice device,Swapchain * swapchain)435 void ReleaseSwapchain(VkDevice device, Swapchain* swapchain)
436 {
437 if (swapchain->surface.swapchainHandle != HandleFromSwapchain(swapchain)) {
438 return;
439 }
440
441 for (uint32_t i = 0; i < swapchain->numImages; i++) {
442 if (!swapchain->images[i].requested) {
443 ReleaseSwapchainImage(device, nullptr, -1, swapchain->images[i], true);
444 }
445 }
446 swapchain->surface.swapchainHandle = VK_NULL_HANDLE;
447 }
448
GetPixelFormat(VkFormat format)449 GraphicPixelFormat GetPixelFormat(VkFormat format)
450 {
451 GraphicPixelFormat nativeFormat = GRAPHIC_PIXEL_FMT_RGBA_8888;
452 switch (format) {
453 case VK_FORMAT_R8G8B8A8_UNORM:
454 case VK_FORMAT_R8G8B8A8_SRGB:
455 nativeFormat = GRAPHIC_PIXEL_FMT_RGBA_8888;
456 break;
457 case VK_FORMAT_R5G6B5_UNORM_PACK16:
458 nativeFormat = GRAPHIC_PIXEL_FMT_RGB_565;
459 break;
460 default:
461 SWLOGE("unsupported swapchain format %{public}d", format);
462 DebugMessageToUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
463 ("unsupported swapchain format " + std::to_string(format)).c_str());
464 break;
465 }
466 return nativeFormat;
467 }
468
SetWindowInfo(VkDevice device,const VkSwapchainCreateInfoKHR * createInfo,uint32_t * numImages)469 VKAPI_ATTR VkResult SetWindowInfo(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo, uint32_t* numImages)
470 {
471 GraphicPixelFormat pixelFormat = GetPixelFormat(createInfo->imageFormat);
472 Surface &surface = *SurfaceFromHandle(createInfo->surface);
473
474 NativeWindow* window = surface.window;
475 int err = NativeWindowHandleOpt(window, SET_FORMAT, pixelFormat);
476 if (err != OHOS::GSERROR_OK) {
477 SWLOGE("native_window_set_buffers_format(%{public}d) failed: (%{public}d)", pixelFormat, err);
478 return VK_ERROR_SURFACE_LOST_KHR;
479 }
480
481 err = NativeWindowHandleOpt(window, SET_BUFFER_GEOMETRY,
482 static_cast<int>(createInfo->imageExtent.width),
483 static_cast<int>(createInfo->imageExtent.height));
484 if (err != OHOS::GSERROR_OK) {
485 SWLOGE("NativeWindow SET_BUFFER_GEOMETRY width:%{public}d,height:%{public}d failed: %{public}d",
486 createInfo->imageExtent.width, createInfo->imageExtent.height, err);
487 return VK_ERROR_SURFACE_LOST_KHR;
488 }
489
490 if (createInfo->presentMode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR ||
491 createInfo->presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) {
492 *numImages = 1;
493 }
494
495 return VK_SUCCESS;
496 }
497
SetSwapchainCreateInfo(VkDevice device,const VkSwapchainCreateInfoKHR * createInfo,uint32_t * numImages)498 VkResult SetSwapchainCreateInfo(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo,
499 uint32_t* numImages)
500 {
501 GraphicColorDataSpace colorDataSpace = GetColorDataspace(createInfo->imageColorSpace);
502 if (colorDataSpace == GRAPHIC_COLOR_DATA_SPACE_UNKNOWN) {
503 return VK_ERROR_INITIALIZATION_FAILED;
504 }
505 if (createInfo->oldSwapchain != VK_NULL_HANDLE) {
506 ReleaseSwapchain(device, SwapchainFromHandle(createInfo->oldSwapchain));
507 }
508
509 return SetWindowInfo(device, createInfo, numImages);
510 }
511
TranslateVulkanToNativeTransform(VkSurfaceTransformFlagBitsKHR transform)512 int TranslateVulkanToNativeTransform(VkSurfaceTransformFlagBitsKHR transform)
513 {
514 switch (transform) {
515 case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
516 return GRAPHIC_ROTATE_90;
517 case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
518 return GRAPHIC_ROTATE_180;
519 case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
520 return GRAPHIC_ROTATE_270;
521 case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR:
522 return GRAPHIC_FLIP_H;
523 case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR:
524 return GRAPHIC_FLIP_H_ROT90;
525 case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR:
526 return GRAPHIC_FLIP_H_ROT180;
527 case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR:
528 return GRAPHIC_FLIP_H_ROT270;
529 case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
530 case VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR:
531 default:
532 return GRAPHIC_ROTATE_NONE;
533 }
534 }
535
InitImageCreateInfo(const VkSwapchainCreateInfoKHR * createInfo,VkImageCreateInfo * imageCreate)536 void InitImageCreateInfo(const VkSwapchainCreateInfoKHR* createInfo, VkImageCreateInfo* imageCreate)
537 {
538 imageCreate->sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
539 bool swapchainCreateProtected = createInfo->flags & VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR;
540 imageCreate->flags = swapchainCreateProtected ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u;
541 imageCreate->imageType = VK_IMAGE_TYPE_2D;
542 imageCreate->format = createInfo->imageFormat;
543 imageCreate->extent = {0, 0, 1};
544 imageCreate->mipLevels = 1;
545 imageCreate->arrayLayers = 1;
546 imageCreate->samples = VK_SAMPLE_COUNT_1_BIT;
547 imageCreate->tiling = VK_IMAGE_TILING_OPTIMAL;
548 imageCreate->usage = createInfo->imageUsage;
549 imageCreate->sharingMode = createInfo->imageSharingMode;
550 imageCreate->queueFamilyIndexCount = createInfo->queueFamilyIndexCount;
551 imageCreate->pQueueFamilyIndices = createInfo->pQueueFamilyIndices;
552 }
553
CreateImages(uint32_t & numImages,Swapchain * swapchain,const VkSwapchainCreateInfoKHR * createInfo,VkImageCreateInfo & imageCreate,VkDevice device)554 VKAPI_ATTR VkResult CreateImages(uint32_t &numImages, Swapchain* swapchain, const VkSwapchainCreateInfoKHR* createInfo,
555 VkImageCreateInfo &imageCreate, VkDevice device)
556 {
557 VkLayerDispatchTable* pDisp =
558 GetLayerDataPtr(GetDispatchKey(device))->deviceDispatchTable.get();
559 Surface &surface = *SurfaceFromHandle(createInfo->surface);
560 NativeWindow* window = surface.window;
561 if (createInfo->oldSwapchain != VK_NULL_HANDLE) {
562 SWLOGI("recreate swapchain ,clean buffer queue");
563 window->surface->CleanCache();
564 }
565 VkResult result = VK_SUCCESS;
566 for (uint32_t i = 0; i < numImages; i++) {
567 Swapchain::Image &img = swapchain->images[i];
568 NativeWindowBuffer* buffer = nullptr;
569 int err = NativeWindowRequestBuffer(window, &buffer, &img.requestFence);
570 if (err != OHOS::GSERROR_OK) {
571 SWLOGE("RequestBuffer[%{public}u] failed: (%{public}d)", i, err);
572 result = VK_ERROR_SURFACE_LOST_KHR;
573 break;
574 }
575 img.buffer = buffer;
576 img.requested = true;
577 imageCreate.extent = VkExtent3D {static_cast<uint32_t>(img.buffer->sfbuffer->GetWidth()),
578 static_cast<uint32_t>(img.buffer->sfbuffer->GetHeight()), 1};
579 ((VkNativeBufferOHOS*)(imageCreate.pNext))->handle =
580 reinterpret_cast<struct OHBufferHandle *>(img.buffer->sfbuffer->GetBufferHandle());
581 result = pDisp->CreateImage(device, &imageCreate, nullptr, &img.image);
582 if (result != VK_SUCCESS) {
583 SWLOGD("vkCreateImage native buffer failed: %{public}u", result);
584 break;
585 }
586 }
587
588 SWLOGD("swapchain init shared %{public}d", swapchain->shared);
589 for (uint32_t i = 0; i < numImages; i++) {
590 Swapchain::Image &img = swapchain->images[i];
591 if (img.requested) {
592 if (!swapchain->shared) {
593 NativeWindowCancelBuffer(window, img.buffer);
594 img.requestFence = -1;
595 img.requested = false;
596 }
597 }
598 }
599 return result;
600 }
601
DestroySwapchainInternal(VkDevice device,VkSwapchainKHR swapchainHandle,const VkAllocationCallbacks * allocator)602 static void DestroySwapchainInternal(VkDevice device, VkSwapchainKHR swapchainHandle,
603 const VkAllocationCallbacks* allocator)
604 {
605 Swapchain* swapchain = SwapchainFromHandle(swapchainHandle);
606 if (swapchain == nullptr) {
607 return;
608 }
609
610 bool active = swapchain->surface.swapchainHandle == swapchainHandle;
611 NativeWindow* window = active ? swapchain->surface.window : nullptr;
612
613 for (uint32_t i = 0; i < swapchain->numImages; i++) {
614 ReleaseSwapchainImage(device, window, -1, swapchain->images[i], false);
615 }
616
617 if (active) {
618 swapchain->surface.swapchainHandle = VK_NULL_HANDLE;
619 }
620 if (allocator == nullptr) {
621 allocator = &GetDefaultAllocator();
622 }
623 swapchain->~Swapchain();
624 allocator->pfnFree(allocator->pUserData, swapchain);
625 }
626
CreateSwapchainKHR(VkDevice device,const VkSwapchainCreateInfoKHR * createInfo,const VkAllocationCallbacks * allocator,VkSwapchainKHR * swapchainHandle)627 VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo,
628 const VkAllocationCallbacks* allocator, VkSwapchainKHR* swapchainHandle)
629 {
630 Surface &surface = *SurfaceFromHandle(createInfo->surface);
631 if (surface.swapchainHandle != createInfo->oldSwapchain) {
632 return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
633 }
634
635 uint32_t numImages = surface.window->surface->GetQueueSize();
636 VkResult result = SetSwapchainCreateInfo(device, createInfo, &numImages);
637 if (result != VK_SUCCESS) {
638 return result;
639 }
640
641 if (numImages < createInfo->minImageCount) {
642 SWLOGE("swapchain init minImageCount[%{public}u] can not be more than maxBufferCount[%{public}u]",
643 createInfo->minImageCount, numImages);
644 return VK_ERROR_INITIALIZATION_FAILED;
645 }
646
647 if (allocator == nullptr) {
648 allocator = &GetDefaultAllocator();
649 }
650 void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Swapchain), alignof(Swapchain),
651 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
652 if (mem == nullptr) {
653 return VK_ERROR_OUT_OF_HOST_MEMORY;
654 }
655
656 Swapchain* swapchain = new (mem) Swapchain(surface, numImages, createInfo->presentMode,
657 TranslateVulkanToNativeTransform(createInfo->preTransform));
658 VkSwapchainImageCreateInfoOHOS swapchainImageCreate = {
659 .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_OHOS,
660 .pNext = nullptr,
661 };
662 VkNativeBufferOHOS imageNativeBuffer = {
663 .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_OHOS,
664 .pNext = &swapchainImageCreate,
665 };
666
667 VkImageCreateInfo imageCreate = {
668 .pNext = &imageNativeBuffer,
669 };
670
671 InitImageCreateInfo(createInfo, &imageCreate);
672 result = CreateImages(numImages, swapchain, createInfo, imageCreate, device);
673 if (result != VK_SUCCESS) {
674 DestroySwapchainInternal(device, HandleFromSwapchain(swapchain), allocator);
675 return result;
676 }
677 surface.swapchainHandle = HandleFromSwapchain(swapchain);
678 *swapchainHandle = surface.swapchainHandle;
679 return VK_SUCCESS;
680 }
681
DestroySwapchainKHR(VkDevice device,VkSwapchainKHR vkSwapchain,const VkAllocationCallbacks * pAllocator)682 VKAPI_ATTR void VKAPI_CALL DestroySwapchainKHR(
683 VkDevice device, VkSwapchainKHR vkSwapchain, const VkAllocationCallbacks* pAllocator)
684 {
685 DestroySwapchainInternal(device, vkSwapchain, pAllocator);
686 }
687
GetSwapchainImagesKHR(VkDevice device,VkSwapchainKHR vkSwapchain,uint32_t * count,VkImage * images)688 VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(
689 VkDevice device, VkSwapchainKHR vkSwapchain, uint32_t* count, VkImage* images)
690 {
691 const Swapchain &swapchain = *SwapchainFromHandle(vkSwapchain);
692 if (images == nullptr) {
693 *count = swapchain.numImages;
694 return VK_SUCCESS;
695 }
696
697 VkResult result = VK_SUCCESS;
698 uint32_t numImages = swapchain.numImages;
699 if (*count < swapchain.numImages) {
700 numImages = *count;
701 result = VK_INCOMPLETE;
702 }
703 for (uint32_t i = 0; i < numImages; i++) {
704 images[i] = swapchain.images[i].image;
705 }
706 *count = numImages;
707 return result;
708 }
709
AcquireNextImageKHR(VkDevice device,VkSwapchainKHR swapchainHandle,uint64_t timeout,VkSemaphore semaphore,VkFence vkFence,uint32_t * imageIndex)710 VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchainHandle,
711 uint64_t timeout, VkSemaphore semaphore, VkFence vkFence, uint32_t* imageIndex)
712 {
713 Swapchain &swapchain = *SwapchainFromHandle(swapchainHandle);
714 NativeWindow* nativeWindow = swapchain.surface.window;
715 VkResult result = VK_SUCCESS;
716
717 if (swapchain.surface.swapchainHandle != swapchainHandle) {
718 return VK_ERROR_OUT_OF_DATE_KHR;
719 }
720
721 LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(device));
722 if (swapchain.shared) {
723 *imageIndex = 0;
724 return deviceLayerData->deviceDispatchTable->AcquireImageOHOS(device, swapchain.images[*imageIndex].image, -1,
725 semaphore, vkFence);
726 }
727
728 NativeWindowBuffer* nativeWindowBuffer = nullptr;
729 int fence = -1;
730 int32_t ret = NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fence);
731 if (ret != OHOS::GSERROR_OK) {
732 SWLOGE("RequestBuffer failed: (%{public}d)", ret);
733 DebugMessageToUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
734 ("RequestBuffer failed: " + std::to_string(ret)).c_str());
735 return VK_ERROR_SURFACE_LOST_KHR;
736 }
737
738 uint32_t index = 0;
739 for (; index < swapchain.numImages; index++) {
740 if (swapchain.images[index].buffer->sfbuffer == nativeWindowBuffer->sfbuffer) {
741 swapchain.images[index].requested = true;
742 swapchain.images[index].requestFence = fence;
743 break;
744 }
745 }
746
747 if (index == swapchain.numImages) {
748 SWLOGD("RequestBuffer returned unrecognized buffer");
749 if (NativeWindowCancelBuffer(nativeWindow, nativeWindowBuffer) != OHOS::GSERROR_OK) {
750 SWLOGE("NativeWindowCancelBuffer failed: (%{public}d)", ret);
751 }
752 return VK_ERROR_OUT_OF_DATE_KHR;
753 }
754 result = deviceLayerData->deviceDispatchTable->AcquireImageOHOS(device, swapchain.images[index].image, -1,
755 semaphore, vkFence);
756 if (result != VK_SUCCESS) {
757 if (NativeWindowCancelBuffer(nativeWindow, nativeWindowBuffer) != OHOS::GSERROR_OK) {
758 SWLOGE("NativeWindowCancelBuffer failed: (%{public}d)", ret);
759 }
760 swapchain.images[index].requested = false;
761 swapchain.images[index].requestFence = -1;
762 return result;
763 }
764
765 *imageIndex = index;
766 return VK_SUCCESS;
767 }
768
769 VKAPI_ATTR
GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pRectCount,VkRect2D * pRects)770 VkResult GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
771 VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects)
772 {
773 if (pRects == nullptr) {
774 *pRectCount = 1;
775 return VK_SUCCESS;
776 }
777 bool incomplete = *pRectCount < 1;
778 *pRectCount = std::min(*pRectCount, 1u);
779 if (incomplete) {
780 return VK_INCOMPLETE;
781 }
782
783 NativeWindow* window = SurfaceFromHandle(surface)->window;
784
785 int width = 0;
786 int height = 0;
787 int err = NativeWindowHandleOpt(window, GET_BUFFER_GEOMETRY, &height, &width);
788 if (err != OHOS::GSERROR_OK) {
789 SWLOGE("NATIVE_WINDOW_DEFAULT_WIDTH GET BUFFER GEOMETRY failed: (%{public}d)", err);
790 }
791 pRects[0].offset.x = 0;
792 pRects[0].offset.y = 0;
793 pRects[0].extent = VkExtent2D{static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
794 return VK_SUCCESS;
795 }
796
797 VKAPI_ATTR
AcquireNextImage2KHR(VkDevice device,const VkAcquireNextImageInfoKHR * pAcquireInfo,uint32_t * pImageIndex)798 VkResult AcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex)
799 {
800 return AcquireNextImageKHR(device, pAcquireInfo->swapchain, pAcquireInfo->timeout,
801 pAcquireInfo->semaphore, pAcquireInfo->fence, pImageIndex);
802 }
803
GetPresentRegion(const VkPresentRegionKHR * regions,const Swapchain & swapchain,uint32_t index)804 const VkPresentRegionKHR* GetPresentRegion(
805 const VkPresentRegionKHR* regions, const Swapchain &swapchain, uint32_t index)
806 {
807 return (regions && !swapchain.mailboxMode) ? ®ions[index] : nullptr;
808 }
809
GetPresentRegions(const VkPresentInfoKHR * presentInfo)810 const VkPresentRegionKHR* GetPresentRegions(const VkPresentInfoKHR* presentInfo)
811 {
812 const VkPresentRegionsKHR* presentRegions = nullptr;
813 const VkPresentRegionsKHR* nextRegions = reinterpret_cast<const VkPresentRegionsKHR*>(presentInfo->pNext);
814 while (nextRegions != nullptr) {
815 if (nextRegions->sType == VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR) {
816 presentRegions = nextRegions;
817 }
818 nextRegions = reinterpret_cast<const VkPresentRegionsKHR*>(nextRegions->pNext);
819 }
820
821 if (presentRegions == nullptr) {
822 return nullptr;
823 } else {
824 return presentRegions->pRegions;
825 }
826 }
827
ReleaseImage(VkQueue queue,const VkPresentInfoKHR * presentInfo,Swapchain::Image & img,int32_t & fence)828 VkResult ReleaseImage(VkQueue queue, const VkPresentInfoKHR* presentInfo,
829 Swapchain::Image &img, int32_t &fence)
830 {
831 LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(queue));
832 VkResult result = deviceLayerData->deviceDispatchTable->QueueSignalReleaseImageOHOS(
833 queue, presentInfo->waitSemaphoreCount, presentInfo->pWaitSemaphores, img.image, &fence);
834 if (img.releaseFence >= 0) {
835 close(img.releaseFence);
836 img.releaseFence = -1;
837 }
838 if (fence >= 0) {
839 img.releaseFence = dup(fence);
840 }
841 return result;
842 }
843
GetRegionRect(const VkAllocationCallbacks * defaultAllocator,struct Region::Rect ** rects,int32_t rectangleCount)844 struct Region::Rect* GetRegionRect(
845 const VkAllocationCallbacks* defaultAllocator, struct Region::Rect** rects, int32_t rectangleCount)
846 {
847 return static_cast<struct Region::Rect*>(
848 defaultAllocator->pfnReallocation(
849 defaultAllocator->pUserData, *rects,
850 sizeof(Region::Rect) *rectangleCount,
851 alignof(Region::Rect), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
852 }
853
InitRegionRect(const VkRectLayerKHR * layer,struct Region::Rect * rect)854 void InitRegionRect(const VkRectLayerKHR* layer, struct Region::Rect* rect)
855 {
856 rect->x = layer->offset.x;
857 rect->y = layer->offset.y;
858 rect->w = layer->extent.width;
859 rect->h = layer->extent.height;
860 }
861
FlushBuffer(const VkPresentRegionKHR * region,struct Region::Rect * rects,Swapchain & swapchain,Swapchain::Image & img,int32_t fence)862 VkResult FlushBuffer(const VkPresentRegionKHR* region, struct Region::Rect* rects,
863 Swapchain &swapchain, Swapchain::Image &img, int32_t fence)
864 {
865 const VkAllocationCallbacks* defaultAllocator = &GetDefaultAllocator();
866 Region localRegion = {};
867 if (memset_s(&localRegion, sizeof(localRegion), 0, sizeof(Region)) != EOK) {
868 return VK_ERROR_SURFACE_LOST_KHR;
869 }
870 if (region != nullptr) {
871 int32_t rectangleCount = region->rectangleCount;
872 if (rectangleCount > 0) {
873 struct Region::Rect* tmpRects = GetRegionRect(defaultAllocator, &rects, rectangleCount);
874 if (tmpRects != nullptr) {
875 rects = tmpRects;
876 } else {
877 rectangleCount = 0;
878 }
879 }
880 for (int32_t r = 0; r < rectangleCount; ++r) {
881 InitRegionRect(®ion->pRectangles[r], &rects[r]);
882 }
883
884 localRegion.rects = rects;
885 localRegion.rectNumber = rectangleCount;
886 }
887 NativeWindow* window = swapchain.surface.window;
888 // the acquire fence will be close by BufferQueue module
889 int err = NativeWindowFlushBuffer(window, img.buffer, fence, localRegion);
890 VkResult scResult = VK_SUCCESS;
891 if (err != OHOS::GSERROR_OK) {
892 SWLOGE("FlushBuffer failed: (%{public}d)", err);
893 scResult = VK_ERROR_SURFACE_LOST_KHR;
894 } else {
895 if (img.requestFence >= 0) {
896 close(img.requestFence);
897 img.requestFence = -1;
898 }
899 img.requested = false;
900 }
901
902 if (swapchain.shared && scResult == VK_SUCCESS) {
903 NativeWindowBuffer* buffer = nullptr;
904 int releaseFence = -1;
905 err = NativeWindowRequestBuffer(window, &buffer, &releaseFence);
906 if (err != OHOS::GSERROR_OK) {
907 scResult = VK_ERROR_SURFACE_LOST_KHR;
908 } else if (img.buffer != buffer) {
909 scResult = VK_ERROR_SURFACE_LOST_KHR;
910 } else {
911 img.requestFence = releaseFence;
912 img.requested = true;
913 }
914 }
915
916 return scResult;
917 }
918
QueuePresentKHR(VkQueue queue,const VkPresentInfoKHR * presentInfo)919 VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(
920 VkQueue queue, const VkPresentInfoKHR* presentInfo)
921 {
922 VkResult ret = VK_SUCCESS;
923
924 const VkPresentRegionKHR* regions = GetPresentRegions(presentInfo);
925 const VkAllocationCallbacks* defaultAllocator = &GetDefaultAllocator();
926 struct Region::Rect* rects = nullptr;
927 LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(queue));
928 VkDevice device = deviceLayerData->device;
929
930 for (uint32_t i = 0; i < presentInfo->swapchainCount; i++) {
931 Swapchain &swapchain = *(reinterpret_cast<Swapchain*>(presentInfo->pSwapchains[i]));
932 Swapchain::Image &img = swapchain.images[presentInfo->pImageIndices[i]];
933 const VkPresentRegionKHR* region = GetPresentRegion(regions, swapchain, i);
934 int32_t fence = -1;
935 ret = ReleaseImage(queue, presentInfo, img, fence);
936 if (swapchain.surface.swapchainHandle == presentInfo->pSwapchains[i]) {
937 if (ret == VK_SUCCESS) {
938 ret = FlushBuffer(region, rects, swapchain, img, fence);
939 } else {
940 ReleaseSwapchain(device, &swapchain);
941 }
942 } else {
943 SWLOGE("QueuePresentKHR swapchainHandle != pSwapchains[%{public}d]", i);
944 ReleaseSwapchainImage(device, nullptr, fence, img, true);
945 ret = VK_ERROR_OUT_OF_DATE_KHR;
946 }
947
948 if (presentInfo->pResults) {
949 presentInfo->pResults[i] = ret;
950 }
951 }
952 if (rects != nullptr) {
953 defaultAllocator->pfnFree(defaultAllocator->pUserData, rects);
954 }
955 return ret;
956 }
957
GetDeviceGroupPresentCapabilitiesKHR(VkDevice,VkDeviceGroupPresentCapabilitiesKHR * pDeviceGroupPresentCapabilities)958 VKAPI_ATTR VkResult GetDeviceGroupPresentCapabilitiesKHR(
959 VkDevice, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities)
960 {
961 if (pDeviceGroupPresentCapabilities == nullptr) {
962 return VK_ERROR_OUT_OF_HOST_MEMORY;
963 }
964
965 memset_s(pDeviceGroupPresentCapabilities->presentMask,
966 sizeof(pDeviceGroupPresentCapabilities->presentMask), 0, sizeof(pDeviceGroupPresentCapabilities->presentMask));
967 pDeviceGroupPresentCapabilities->presentMask[0] = 1u;
968 pDeviceGroupPresentCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
969
970 return VK_SUCCESS;
971 }
972
GetDeviceGroupSurfacePresentModesKHR(VkDevice,VkSurfaceKHR,VkDeviceGroupPresentModeFlagsKHR * pModes)973 VKAPI_ATTR VkResult GetDeviceGroupSurfacePresentModesKHR(
974 VkDevice, VkSurfaceKHR, VkDeviceGroupPresentModeFlagsKHR* pModes)
975 {
976 *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
977 return VK_SUCCESS;
978 }
979
GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,const VkSurfaceKHR surface,VkBool32 * pSupported)980 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(
981 VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, const VkSurfaceKHR surface, VkBool32* pSupported)
982 {
983 *pSupported = VK_TRUE;
984 return VK_SUCCESS;
985 }
986
CreateSurfaceOHOS(VkInstance instance,const VkSurfaceCreateInfoOHOS * pCreateInfo,const VkAllocationCallbacks * allocator,VkSurfaceKHR * outSurface)987 VKAPI_ATTR VkResult VKAPI_CALL CreateSurfaceOHOS(VkInstance instance,
988 const VkSurfaceCreateInfoOHOS* pCreateInfo,
989 const VkAllocationCallbacks* allocator, VkSurfaceKHR* outSurface)
990 {
991 if (allocator == nullptr) {
992 allocator = &GetDefaultAllocator();
993 }
994 void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Surface), alignof(Surface),
995 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
996 if (mem == nullptr) {
997 return VK_ERROR_OUT_OF_HOST_MEMORY;
998 }
999
1000 Surface* surface = new (mem) Surface;
1001 surface->window = pCreateInfo->window;
1002 surface->swapchainHandle = VK_NULL_HANDLE;
1003 NativeWindowHandleOpt(pCreateInfo->window, GET_USAGE, &(surface->consumerUsage));
1004
1005 if (surface->consumerUsage == 0) {
1006 SWLOGE("native window get usage failed, error num : %{public}d", VK_ERROR_SURFACE_LOST_KHR);
1007 surface->~Surface();
1008 allocator->pfnFree(allocator->pUserData, surface);
1009 return VK_ERROR_SURFACE_LOST_KHR;
1010 }
1011
1012 *outSurface = HandleFromSurface(surface);
1013 return VK_SUCCESS;
1014 }
1015
DestroySurfaceKHR(VkInstance instance,VkSurfaceKHR vkSurface,const VkAllocationCallbacks * pAllocator)1016 VKAPI_ATTR void VKAPI_CALL DestroySurfaceKHR(
1017 VkInstance instance, VkSurfaceKHR vkSurface, const VkAllocationCallbacks* pAllocator)
1018 {
1019 Surface* surface = SurfaceFromHandle(vkSurface);
1020 if (surface == nullptr) {
1021 return;
1022 }
1023 if (pAllocator == nullptr) {
1024 pAllocator = &GetDefaultAllocator();
1025 }
1026 surface->~Surface();
1027 pAllocator->pfnFree(pAllocator->pUserData, surface);
1028 }
1029
GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,VkSurfaceCapabilitiesKHR * capabilities)1030 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilitiesKHR(
1031 VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* capabilities)
1032 {
1033 int width = 0;
1034 int height = 0;
1035 uint32_t maxBufferCount = MAX_BUFFER_SIZE;
1036 if (surface != VK_NULL_HANDLE) {
1037 NativeWindow* window = SurfaceFromHandle(surface)->window;
1038 int err = NativeWindowHandleOpt(window, GET_BUFFER_GEOMETRY, &height, &width);
1039 if (err != OHOS::GSERROR_OK) {
1040 SWLOGE("NATIVE_WINDOW GET_BUFFER_GEOMETRY failed: (%{public}d)", err);
1041 return VK_ERROR_SURFACE_LOST_KHR;
1042 }
1043 maxBufferCount = window->surface->GetQueueSize();
1044 SWLOGD("queue size : (%{public}d)", maxBufferCount);
1045 }
1046
1047 capabilities->minImageCount = std::min(maxBufferCount, MIN_BUFFER_SIZE);
1048 capabilities->maxImageCount = maxBufferCount;
1049 capabilities->currentExtent = VkExtent2D {static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
1050 capabilities->minImageExtent = VkExtent2D {1, 1};
1051 capabilities->maxImageExtent = VkExtent2D {4096, 4096};
1052 capabilities->maxImageArrayLayers = 1;
1053 capabilities->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
1054 capabilities->supportedUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1055 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
1056 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1057 return VK_SUCCESS;
1058 }
1059
GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,const VkSurfaceKHR surface,uint32_t * count,VkSurfaceFormatKHR * formats)1060 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormatsKHR(
1061 VkPhysicalDevice physicalDevice, const VkSurfaceKHR surface, uint32_t* count, VkSurfaceFormatKHR* formats)
1062 {
1063 std::vector<VkSurfaceFormatKHR> allFormats = {
1064 {VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
1065 {VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}
1066 };
1067 VkResult result = VK_SUCCESS;
1068 if (formats != nullptr) {
1069 uint32_t transferCount = allFormats.size();
1070 if (transferCount > *count) {
1071 transferCount = *count;
1072 result = VK_INCOMPLETE;
1073 }
1074 std::copy(allFormats.begin(), allFormats.begin() + transferCount, formats);
1075 *count = transferCount;
1076 } else {
1077 *count = allFormats.size();
1078 }
1079
1080 return result;
1081 }
1082
QueryPresentationProperties(VkPhysicalDevice physicalDevice,VkPhysicalDevicePresentationPropertiesOHOS * presentationProperties)1083 void QueryPresentationProperties(
1084 VkPhysicalDevice physicalDevice,
1085 VkPhysicalDevicePresentationPropertiesOHOS* presentationProperties)
1086 {
1087 VkPhysicalDeviceProperties2 properties = {
1088 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
1089 presentationProperties,
1090 {},
1091 };
1092
1093 presentationProperties->sType =
1094 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_OHOS;
1095 presentationProperties->pNext = nullptr;
1096 presentationProperties->sharedImage = VK_FALSE;
1097
1098 DispatchKey key = GetDispatchKey(physicalDevice);
1099 LayerData* curLayerData = GetLayerDataPtr(key);
1100 if (curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2) {
1101 curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2(physicalDevice, &properties);
1102 } else if (curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2KHR) {
1103 curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2KHR(physicalDevice, &properties);
1104 } else {
1105 SWLOGE("Func vkGetPhysicalDeviceProperties2 and vkGetPhysicalDeviceProperties2KHR are both null.");
1106 }
1107 }
1108
GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,const VkSurfaceKHR surface,uint32_t * count,VkPresentModeKHR * pPresentModes)1109 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModesKHR(
1110 VkPhysicalDevice physicalDevice, const VkSurfaceKHR surface, uint32_t* count, VkPresentModeKHR* pPresentModes)
1111 {
1112 std::vector<VkPresentModeKHR> presentModes = {
1113 VK_PRESENT_MODE_MAILBOX_KHR,
1114 VK_PRESENT_MODE_FIFO_KHR
1115 };
1116
1117 VkPhysicalDevicePresentationPropertiesOHOS presentProperties = {};
1118 QueryPresentationProperties(physicalDevice, &presentProperties);
1119 if (presentProperties.sharedImage) {
1120 presentModes.push_back(VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR);
1121 presentModes.push_back(VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR);
1122 }
1123
1124 uint32_t numModes = static_cast<uint32_t>(presentModes.size());
1125 VkResult result = VK_SUCCESS;
1126 if (pPresentModes != nullptr) {
1127 if (*count < numModes) {
1128 result = VK_INCOMPLETE;
1129 }
1130 *count = std::min(*count, numModes);
1131 std::copy_n(presentModes.data(), *count, pPresentModes);
1132 } else {
1133 *count = numModes;
1134 }
1135 return result;
1136 }
1137
GetExtensionBitFromName(const char * name)1138 Extension GetExtensionBitFromName(const char* name)
1139 {
1140 if (name == nullptr) {
1141 return Extension::EXTENSION_UNKNOWN;
1142 }
1143 if (strcmp(name, VK_OHOS_SURFACE_EXTENSION_NAME) == 0) {
1144 return Extension::OHOS_SURFACE;
1145 }
1146 if (strcmp(name, VK_OHOS_NATIVE_BUFFER_EXTENSION_NAME) == 0) {
1147 return Extension::OHOS_NATIVE_BUFFER;
1148 }
1149 if (strcmp(name, VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
1150 return Extension::KHR_SURFACE;
1151 }
1152 if (strcmp(name, VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
1153 return Extension::KHR_SWAPCHAIN;
1154 }
1155 return Extension::EXTENSION_UNKNOWN;
1156 }
1157
CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)1158 VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(
1159 const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
1160 {
1161 VkLayerInstanceCreateInfo* chainInfo = GetChainInfo(pCreateInfo, VK_LAYER_LINK_INFO);
1162
1163 if (chainInfo == nullptr || chainInfo->u.pLayerInfo == nullptr) {
1164 return VK_ERROR_INITIALIZATION_FAILED;
1165 }
1166 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
1167 chainInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
1168 PFN_vkCreateInstance fpCreateInstance =
1169 (PFN_vkCreateInstance)fpGetInstanceProcAddr(nullptr, "vkCreateInstance");
1170 if (fpCreateInstance == nullptr) {
1171 return VK_ERROR_INITIALIZATION_FAILED;
1172 }
1173
1174 chainInfo->u.pLayerInfo = chainInfo->u.pLayerInfo->pNext;
1175
1176 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
1177 if (result != VK_SUCCESS) {
1178 return result;
1179 }
1180
1181 LayerData* instanceLayerData = GetLayerDataPtr(GetDispatchKey(*pInstance));
1182 instanceLayerData->instance = *pInstance;
1183 instanceLayerData->instanceDispatchTable = std::make_unique<VkLayerInstanceDispatchTable>();
1184 layer_init_instance_dispatch_table(*pInstance, instanceLayerData->instanceDispatchTable.get(),
1185 fpGetInstanceProcAddr);
1186 for (uint32_t index = 0; index < pCreateInfo->enabledExtensionCount; index++) {
1187 auto extBit = GetExtensionBitFromName(pCreateInfo->ppEnabledExtensionNames[index]);
1188 if (extBit != Extension::EXTENSION_UNKNOWN) {
1189 instanceLayerData->enabledExtensions.set(extBit);
1190 }
1191 }
1192 return result;
1193 }
1194
DestroyInstance(VkInstance instance,const VkAllocationCallbacks * pAllocator)1195 VKAPI_ATTR void VKAPI_CALL DestroyInstance(
1196 VkInstance instance, const VkAllocationCallbacks* pAllocator)
1197 {
1198 DispatchKey instanceKey = GetDispatchKey(instance);
1199 LayerData* curLayerData = GetLayerDataPtr(instanceKey);
1200 curLayerData->instanceDispatchTable->DestroyInstance(instance, pAllocator);
1201 FreeLayerDataPtr(instanceKey);
1202 }
1203
CheckExtensionAvailable(const std::string & extensionName,const std::vector<VkExtensionProperties> & deviceExtensions)1204 bool CheckExtensionAvailable(const std::string &extensionName,
1205 const std::vector<VkExtensionProperties> &deviceExtensions)
1206 {
1207 bool extensionAvailable = false;
1208 for (uint32_t i = 0; i < deviceExtensions.size(); i++) {
1209 if (strcmp(extensionName.data(), deviceExtensions[i].extensionName) == 0) {
1210 extensionAvailable = true;
1211 break;
1212 }
1213 }
1214 return extensionAvailable;
1215 }
1216
AddDeviceExtensions(VkPhysicalDevice gpu,const LayerData * gpuLayerData,std::vector<const char * > & enabledExtensions)1217 VkResult AddDeviceExtensions(VkPhysicalDevice gpu, const LayerData* gpuLayerData,
1218 std::vector<const char*> &enabledExtensions)
1219 {
1220 VkResult result = VK_SUCCESS;
1221 uint32_t deviceExtensionCount = 0;
1222 result = gpuLayerData->instanceDispatchTable->EnumerateDeviceExtensionProperties(
1223 gpu, nullptr, &deviceExtensionCount, nullptr);
1224 if (result == VK_SUCCESS && deviceExtensionCount > 0) {
1225 std::vector<VkExtensionProperties> deviceExtensions(deviceExtensionCount);
1226 result = gpuLayerData->instanceDispatchTable->EnumerateDeviceExtensionProperties(
1227 gpu, nullptr, &deviceExtensionCount, deviceExtensions.data());
1228 if (result == VK_SUCCESS) {
1229 if (!CheckExtensionAvailable(VK_OHOS_NATIVE_BUFFER_EXTENSION_NAME, deviceExtensions)) {
1230 return VK_ERROR_INITIALIZATION_FAILED;
1231 }
1232 enabledExtensions.push_back(VK_OHOS_NATIVE_BUFFER_EXTENSION_NAME);
1233 if (CheckExtensionAvailable(VK_OHOS_EXTERNAL_MEMORY_EXTENSION_NAME,
1234 deviceExtensions)) {
1235 enabledExtensions.push_back(VK_OHOS_EXTERNAL_MEMORY_EXTENSION_NAME);
1236 }
1237 }
1238 }
1239 return VK_SUCCESS;
1240 }
1241
CreateDevice(VkPhysicalDevice gpu,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)1242 VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu,
1243 const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
1244 {
1245 DispatchKey gpuKey = GetDispatchKey(gpu);
1246 LayerData* gpuLayerData = GetLayerDataPtr(gpuKey);
1247
1248 VkDeviceCreateInfo createInfo = *pCreateInfo;
1249 std::vector<const char*> enabledExtensions = {};
1250 for (uint32_t i = 0; i < createInfo.enabledExtensionCount; i++) {
1251 enabledExtensions.push_back(createInfo.ppEnabledExtensionNames[i]);
1252 }
1253
1254 VkResult result = AddDeviceExtensions(gpu, gpuLayerData, enabledExtensions);
1255 if (result != VK_SUCCESS) {
1256 return result;
1257 }
1258
1259 createInfo.enabledExtensionCount = ToUint32(enabledExtensions.size());
1260 createInfo.ppEnabledExtensionNames = enabledExtensions.data();
1261
1262 VkLayerDeviceCreateInfo* linkInfo = GetChainInfo(pCreateInfo, VK_LAYER_LINK_INFO);
1263
1264 if (linkInfo == nullptr || linkInfo->u.pLayerInfo == nullptr) {
1265 return VK_ERROR_INITIALIZATION_FAILED;
1266 }
1267 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = linkInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
1268 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = linkInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr;
1269 PFN_vkCreateDevice fpCreateDevice =
1270 (PFN_vkCreateDevice)fpGetInstanceProcAddr(gpuLayerData->instance, "vkCreateDevice");
1271 if (fpCreateDevice == nullptr) {
1272 return VK_ERROR_INITIALIZATION_FAILED;
1273 }
1274
1275 linkInfo->u.pLayerInfo = linkInfo->u.pLayerInfo->pNext;
1276
1277 result = fpCreateDevice(gpu, &createInfo, pAllocator, pDevice);
1278 if (result != VK_SUCCESS) {
1279 return result;
1280 }
1281
1282 LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(*pDevice));
1283 for (uint32_t i = 0; i < createInfo.enabledExtensionCount; i++) {
1284 auto extBit = GetExtensionBitFromName(createInfo.ppEnabledExtensionNames[i]);
1285 if (extBit != Extension::EXTENSION_UNKNOWN) {
1286 deviceLayerData->enabledExtensions.set(extBit);
1287 }
1288 }
1289
1290 deviceLayerData->deviceDispatchTable = std::make_unique<VkLayerDispatchTable>();
1291 deviceLayerData->instance = gpuLayerData->instance;
1292 deviceLayerData->device = *pDevice;
1293 layer_init_device_dispatch_table(*pDevice, deviceLayerData->deviceDispatchTable.get(), fpGetDeviceProcAddr);
1294
1295 VkLayerDeviceCreateInfo* callbackInfo = GetChainInfo(pCreateInfo, VK_LOADER_DATA_CALLBACK);
1296 if (callbackInfo == nullptr || callbackInfo->u.pfnSetDeviceLoaderData == nullptr) {
1297 return VK_ERROR_INITIALIZATION_FAILED;
1298 }
1299 deviceLayerData->fpSetDeviceLoaderData = callbackInfo->u.pfnSetDeviceLoaderData;
1300
1301 return VK_SUCCESS;
1302 }
1303
DestroyDevice(VkDevice device,const VkAllocationCallbacks * pAllocator)1304 VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
1305 {
1306 DispatchKey deviceKey = GetDispatchKey(device);
1307 LayerData* deviceData = GetLayerDataPtr(deviceKey);
1308 deviceData->deviceDispatchTable->DestroyDevice(device, pAllocator);
1309 FreeLayerDataPtr(deviceKey);
1310 }
1311
CreateDebugUtilsMessengerEXT(VkInstance instance,const VkDebugUtilsMessengerCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDebugUtilsMessengerEXT * pMessenger)1312 VKAPI_ATTR VkResult VKAPI_CALL CreateDebugUtilsMessengerEXT(
1313 VkInstance instance,
1314 const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
1315 const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger)
1316 {
1317 DispatchKey instanceKey = GetDispatchKey(instance);
1318 LayerData* curLayerData = GetLayerDataPtr(instanceKey);
1319 VkResult res = curLayerData->instanceDispatchTable->CreateDebugUtilsMessengerEXT(
1320 instance, pCreateInfo, pAllocator, pMessenger);
1321 if (res == VK_SUCCESS) {
1322 curLayerData->debugCallbacks[*pMessenger] = *pCreateInfo;
1323 }
1324 return res;
1325 }
1326
DestroyDebugUtilsMessengerEXT(VkInstance instance,VkDebugUtilsMessengerEXT messenger,const VkAllocationCallbacks * pAllocator)1327 VKAPI_ATTR void VKAPI_CALL DestroyDebugUtilsMessengerEXT(
1328 VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks* pAllocator)
1329 {
1330 DispatchKey instanceKey = GetDispatchKey(instance);
1331 LayerData* curLayerData = GetLayerDataPtr(instanceKey);
1332 curLayerData->debugCallbacks.erase(messenger);
1333 curLayerData->instanceDispatchTable->DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
1334 }
1335
EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)1336 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(
1337 const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
1338 {
1339 if ((pLayerName != nullptr) && (strcmp(pLayerName, swapchainLayer.layerName) == 0)) {
1340 return GetExtensionProperties(std::size(instanceExtensions), instanceExtensions, pCount, pProperties);
1341 }
1342 return VK_ERROR_LAYER_NOT_PRESENT;
1343 }
1344
EnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)1345 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties)
1346 {
1347 return GetLayerProperties(1, &swapchainLayer, pCount, pProperties);
1348 }
1349
EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkLayerProperties * pProperties)1350 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(
1351 VkPhysicalDevice physicalDevice, uint32_t* pCount, VkLayerProperties* pProperties)
1352 {
1353 return GetLayerProperties(1, &swapchainLayer, pCount, pProperties);
1354 }
1355
EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)1356 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(
1357 VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
1358 {
1359 if ((pLayerName != nullptr) && (strcmp(pLayerName, swapchainLayer.layerName) == 0)) {
1360 return GetExtensionProperties(
1361 std::size(deviceExtensions), deviceExtensions, pCount, pProperties);
1362 }
1363
1364 if (physicalDevice == nullptr) {
1365 SWLOGE("physicalDevice is null.");
1366 return VK_ERROR_LAYER_NOT_PRESENT;
1367 }
1368
1369 DispatchKey key = GetDispatchKey(physicalDevice);
1370 LayerData* curLayerData = GetLayerDataPtr(key);
1371 return curLayerData->instanceDispatchTable->EnumerateDeviceExtensionProperties(physicalDevice, nullptr,
1372 pCount, pProperties);
1373 }
1374
GetPhysicalDeviceProcAddr(VkInstance instance,const char * funcName)1375 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char* funcName)
1376 {
1377 if (instance == VK_NULL_HANDLE) {
1378 SWLOGE("instance is null.");
1379 return nullptr;
1380 }
1381
1382 LayerData* layerData = GetLayerDataPtr(GetDispatchKey(instance));
1383 VkLayerInstanceDispatchTable* pTable = layerData->instanceDispatchTable.get();
1384
1385 if (pTable->GetPhysicalDeviceProcAddr == nullptr) {
1386 return nullptr;
1387 }
1388 return pTable->GetPhysicalDeviceProcAddr(instance, funcName);
1389 }
1390
GetDebugUtilsProc(const char * name)1391 static inline PFN_vkVoidFunction GetDebugUtilsProc(const char* name)
1392 {
1393 if (name == nullptr) {
1394 return nullptr;
1395 }
1396 if (strcmp(name, "vkCreateDebugUtilsMessengerEXT") == 0) {
1397 return reinterpret_cast<PFN_vkVoidFunction>(CreateDebugUtilsMessengerEXT);
1398 }
1399 if (strcmp(name, "vkDestroyDebugUtilsMessengerEXT") == 0) {
1400 return reinterpret_cast<PFN_vkVoidFunction>(DestroyDebugUtilsMessengerEXT);
1401 }
1402 return nullptr;
1403 }
1404
GetGlobalProc(const char * name)1405 static inline PFN_vkVoidFunction GetGlobalProc(const char* name)
1406 {
1407 if (name == nullptr) {
1408 return nullptr;
1409 }
1410 if (strcmp("vkEnumerateDeviceLayerProperties", name) == 0) {
1411 return reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties);
1412 }
1413 return nullptr;
1414 }
1415
GetSwapchainProc(const char * name)1416 static inline PFN_vkVoidFunction GetSwapchainProc(const char* name)
1417 {
1418 if (name == nullptr) {
1419 return nullptr;
1420 }
1421 if (strcmp("vkCreateSwapchainKHR", name) == 0) {
1422 return reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR);
1423 }
1424 if (strcmp("vkDestroySwapchainKHR", name) == 0) {
1425 return reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR);
1426 }
1427 if (strcmp("vkAcquireNextImageKHR", name) == 0) {
1428 return reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR);
1429 }
1430 if (strcmp("vkAcquireNextImage2KHR", name) == 0) {
1431 return reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImage2KHR);
1432 }
1433 if (strcmp("vkQueuePresentKHR", name) == 0) {
1434 return reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR);
1435 }
1436 if (strcmp("vkGetSwapchainImagesKHR", name) == 0) {
1437 return reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR);
1438 }
1439 if (strcmp("vkGetDeviceGroupPresentCapabilitiesKHR", name) == 0) {
1440 return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceGroupPresentCapabilitiesKHR);
1441 }
1442 if (strcmp("vkGetDeviceGroupSurfacePresentModesKHR", name) == 0) {
1443 return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceGroupSurfacePresentModesKHR);
1444 }
1445 if (strcmp("vkGetPhysicalDevicePresentRectanglesKHR", name) == 0) {
1446 return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDevicePresentRectanglesKHR);
1447 }
1448 return nullptr;
1449 }
1450
LayerInterceptDeviceProc(std::bitset<Extension::EXTENSION_COUNT> & enabledExtensions,const char * name)1451 static inline PFN_vkVoidFunction LayerInterceptDeviceProc(
1452 std::bitset<Extension::EXTENSION_COUNT>& enabledExtensions, const char* name)
1453 {
1454 if (name == nullptr) {
1455 return nullptr;
1456 }
1457 if (strcmp("vkGetDeviceProcAddr", name) == 0) {
1458 return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr);
1459 }
1460 if (strcmp("vkDestroyDevice", name) == 0) {
1461 return reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice);
1462 }
1463 if (enabledExtensions.test(Extension::KHR_SWAPCHAIN)) {
1464 PFN_vkVoidFunction addr = GetSwapchainProc(name);
1465 if (addr != nullptr) {
1466 return addr;
1467 }
1468 }
1469 return nullptr;
1470 }
1471
GetSurfaceKHRProc(const char * name)1472 static inline PFN_vkVoidFunction GetSurfaceKHRProc(const char* name)
1473 {
1474 if (name == nullptr) {
1475 return nullptr;
1476 }
1477 if (strcmp("vkDestroySurfaceKHR", name) == 0) {
1478 return reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR);
1479 }
1480 if (strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name) == 0) {
1481 return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR);
1482 }
1483 if (strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name) == 0) {
1484 return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR);
1485 }
1486 if (strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name) == 0) {
1487 return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR);
1488 }
1489 if (strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name) == 0) {
1490 return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR);
1491 }
1492 return nullptr;
1493 }
1494
LayerInterceptInstanceProc(std::bitset<Extension::EXTENSION_COUNT> & enabledExtensions,const char * name)1495 static inline PFN_vkVoidFunction LayerInterceptInstanceProc(
1496 std::bitset<Extension::EXTENSION_COUNT>& enabledExtensions, const char* name)
1497 {
1498 if (name == nullptr) {
1499 return nullptr;
1500 }
1501 if (enabledExtensions.test(Extension::OHOS_SURFACE)) {
1502 if (strcmp("vkCreateSurfaceOHOS", name) == 0) {
1503 return reinterpret_cast<PFN_vkVoidFunction>(CreateSurfaceOHOS);
1504 }
1505 }
1506 if (enabledExtensions.test(Extension::KHR_SURFACE)) {
1507 PFN_vkVoidFunction addr = GetSurfaceKHRProc(name);
1508 if (addr != nullptr) {
1509 return addr;
1510 }
1511 }
1512
1513 if (enabledExtensions.test(Extension::KHR_SWAPCHAIN)) {
1514 PFN_vkVoidFunction addr = GetSwapchainProc(name);
1515 if (addr != nullptr) {
1516 return addr;
1517 }
1518 }
1519
1520 PFN_vkVoidFunction addr = GetDebugUtilsProc(name);
1521 if (addr != nullptr) {
1522 return addr;
1523 }
1524 return GetGlobalProc(name);
1525 }
1526
GetDeviceProcAddr(VkDevice device,const char * funcName)1527 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* funcName)
1528 {
1529 if (funcName == nullptr) {
1530 return nullptr;
1531 }
1532 if (device == VK_NULL_HANDLE) {
1533 SWLOGE("device is null.");
1534 return nullptr;
1535 }
1536 LayerData* layerData = GetLayerDataPtr(GetDispatchKey(device));
1537 if (layerData == nullptr) {
1538 SWLOGE("libvulkan_swapchain GetInstanceProcAddr layerData is null");
1539 return nullptr;
1540 }
1541
1542 PFN_vkVoidFunction addr = LayerInterceptDeviceProc(layerData->enabledExtensions, funcName);
1543 if (addr != nullptr) {
1544 return addr;
1545 }
1546 LayerData* devData = GetLayerDataPtr(GetDispatchKey(device));
1547 VkLayerDispatchTable* pTable = devData->deviceDispatchTable.get();
1548 if (pTable->GetDeviceProcAddr == nullptr) {
1549 return nullptr;
1550 }
1551 return pTable->GetDeviceProcAddr(device, funcName);
1552 }
1553
GetInstanceProcAddr(VkInstance instance,const char * funcName)1554 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char* funcName)
1555 {
1556 if (funcName == nullptr) {
1557 return nullptr;
1558 }
1559
1560 if (strcmp("vkGetInstanceProcAddr", funcName) == 0) {
1561 return reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr);
1562 }
1563 if (strcmp("vkCreateInstance", funcName) == 0) {
1564 return reinterpret_cast<PFN_vkVoidFunction>(CreateInstance);
1565 }
1566 if (strcmp("vkEnumerateInstanceExtensionProperties", funcName) == 0) {
1567 return reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties);
1568 }
1569 if (strcmp("vkEnumerateInstanceLayerProperties", funcName) == 0) {
1570 return reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceLayerProperties);
1571 }
1572 if (strcmp("vkDestroyInstance", funcName) == 0) {
1573 return reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance);
1574 }
1575 if (strcmp("vkCreateDevice", funcName) == 0) {
1576 return reinterpret_cast<PFN_vkVoidFunction>(CreateDevice);
1577 }
1578 if (strcmp("vkEnumerateDeviceExtensionProperties", funcName) == 0) {
1579 return reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties);
1580 }
1581
1582 if (instance == VK_NULL_HANDLE) {
1583 SWLOGE("libvulkan_swapchain GetInstanceProcAddr(func name %{public}s) instance is null", funcName);
1584 return nullptr;
1585 }
1586
1587 LayerData* layerData = GetLayerDataPtr(GetDispatchKey(instance));
1588 if (layerData == nullptr) {
1589 SWLOGE("libvulkan_swapchain GetInstanceProcAddr layerData is null");
1590 return nullptr;
1591 }
1592
1593 PFN_vkVoidFunction addr = LayerInterceptInstanceProc(layerData->enabledExtensions, funcName);
1594 if (addr != nullptr) {
1595 return addr;
1596 }
1597
1598 VkLayerInstanceDispatchTable* pTable = layerData->instanceDispatchTable.get();
1599 if (pTable == nullptr) {
1600 SWLOGE("libvulkan_swapchain GetInstanceProcAddr pTable = null");
1601 return nullptr;
1602 }
1603 if (pTable->GetInstanceProcAddr == nullptr) {
1604 SWLOGE("libvulkan_swapchain GetInstanceProcAddr pTable->GetInstanceProcAddr = null");
1605 return nullptr;
1606 }
1607 addr = pTable->GetInstanceProcAddr(instance, funcName);
1608
1609 return addr;
1610 }
1611 } // namespace SWAPCHAIN
1612
1613 #if defined(__GNUC__) && __GNUC__ >= 4
1614 #define SWAPCHAIN_EXPORT __attribute__((visibility("default")))
1615 #else
1616 #define SWAPCHAIN_EXPORT
1617 #endif
1618
1619 extern "C" {
vkEnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)1620 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
1621 const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
1622 {
1623 return SWAPCHAIN::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
1624 }
1625
1626 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkEnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)1627 vkEnumerateInstanceLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties)
1628 {
1629 return SWAPCHAIN::EnumerateInstanceLayerProperties(pCount, pProperties);
1630 }
1631
vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkLayerProperties * pProperties)1632 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(
1633 VkPhysicalDevice physicalDevice, uint32_t* pCount, VkLayerProperties* pProperties)
1634 {
1635 return SWAPCHAIN::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
1636 }
1637
vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)1638 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(
1639 VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
1640 {
1641 return SWAPCHAIN::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
1642 }
1643
vkGetDeviceProcAddr(VkDevice dev,const char * funcName)1644 SWAPCHAIN_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char* funcName)
1645 {
1646 return SWAPCHAIN::GetDeviceProcAddr(dev, funcName);
1647 }
1648
1649 SWAPCHAIN_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
vkGetInstanceProcAddr(VkInstance instance,const char * funcName)1650 vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
1651 {
1652 return SWAPCHAIN::GetInstanceProcAddr(instance, funcName);
1653 }
1654 }