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 <scoped_bytrace.h>
38 #include "vk_dispatch_table_helper.h"
39 #include "vk_layer_dispatch_table.h"
40 #include "swapchain_layer_log.h"
41 #include "sync_fence.h"
42 #if USE_APS_IGAMESERVICE_FUNC
43 #include "vulkan_slice_report.h"
44 #endif
45
46 #define SWAPCHAIN_SURFACE_NAME "VK_LAYER_OHOS_surface"
47 using namespace OHOS;
48
49 enum Extension {
50 OHOS_SURFACE,
51 OHOS_NATIVE_BUFFER,
52 KHR_SURFACE,
53 KHR_SWAPCHAIN,
54 EXT_SWAPCHAIN_COLOR_SPACE,
55 KHR_GET_SURFACE_CAPABILITIES_2,
56 EXT_HDR_METADATA,
57 EXTENSION_COUNT,
58 EXTENSION_UNKNOWN,
59 };
60
61 struct LayerData {
62 VkInstance instance = VK_NULL_HANDLE;
63 VkDevice device = VK_NULL_HANDLE;
64 uint32_t instanceVersion = VK_API_VERSION_1_0;
65 std::unique_ptr<VkLayerDispatchTable> deviceDispatchTable;
66 std::unique_ptr<VkLayerInstanceDispatchTable> instanceDispatchTable;
67 std::unordered_map<VkDebugUtilsMessengerEXT, VkDebugUtilsMessengerCreateInfoEXT> debugCallbacks;
68 PFN_vkSetDeviceLoaderData fpSetDeviceLoaderData = nullptr;
69 std::bitset<Extension::EXTENSION_COUNT> enabledExtensions;
70 };
71
72 namespace {
73 constexpr uint32_t MIN_BUFFER_SIZE = SURFACE_DEFAULT_QUEUE_SIZE;
74 constexpr uint32_t MAX_BUFFER_SIZE = SURFACE_MAX_QUEUE_SIZE;
75 struct LoaderVkLayerDispatchTable;
76 typedef uintptr_t DispatchKey;
77
78 template <typename T>
GetDispatchKey(const T object)79 inline DispatchKey GetDispatchKey(const T object)
80 {
81 return reinterpret_cast<DispatchKey>(*reinterpret_cast<LoaderVkLayerDispatchTable* const*>(object));
82 }
83
GetChainInfo(const VkInstanceCreateInfo* pCreateInfo, VkLayerFunction func)84 VkLayerInstanceCreateInfo* GetChainInfo(const VkInstanceCreateInfo* pCreateInfo, VkLayerFunction func)
85 {
86 auto chainInfo = static_cast<const VkLayerInstanceCreateInfo*>(pCreateInfo->pNext);
87 while (chainInfo != nullptr) {
88 if (chainInfo->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chainInfo->function == func) {
89 return const_cast<VkLayerInstanceCreateInfo*>(chainInfo);
90 }
91 chainInfo = static_cast<const VkLayerInstanceCreateInfo*>(chainInfo->pNext);
92 }
93 SWLOGE("SwapchainLayer Find VkLayerInstanceCreateInfo Failed");
94 return nullptr;
95 }
96
GetChainInfo(const VkDeviceCreateInfo* pCreateInfo, VkLayerFunction func)97 VkLayerDeviceCreateInfo* GetChainInfo(const VkDeviceCreateInfo* pCreateInfo, VkLayerFunction func)
98 {
99 auto chainInfo = static_cast<const VkLayerDeviceCreateInfo*>(pCreateInfo->pNext);
100 while (chainInfo != nullptr) {
101 if (chainInfo->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chainInfo->function == func) {
102 return const_cast<VkLayerDeviceCreateInfo*>(chainInfo);
103 }
104 chainInfo = static_cast<const VkLayerDeviceCreateInfo*>(chainInfo->pNext);
105 }
106 SWLOGE("SwapchainLayer Find VkLayerDeviceCreateInfo Failed");
107 return nullptr;
108 }
109 } // namespace
110
111 #define VK_LAYER_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION)
112
ToUint32(uint64_t val)113 static inline uint32_t ToUint32(uint64_t val)
114 {
115 if (val > UINT32_MAX) {
116 SWLOGE("%{public}" PRIu64 " is too large to convert to uint32", val);
117 }
118 return static_cast<uint32_t>(val);
119 }
120
121 namespace SWAPCHAIN {
122 std::unordered_map<DispatchKey, LayerData*> g_layerDataMap;
123 const VkSurfaceTransformFlagsKHR g_supportedTransforms =
124 VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR |
125 VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR |
126 VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR |
127 VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR |
128 VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR |
129 VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR |
130 VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR |
131 VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR |
132 VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR;
133
GetLayerDataPtr(DispatchKey dataKey)134 LayerData* GetLayerDataPtr(DispatchKey dataKey)
135 {
136 LayerData* layerData = nullptr;
137 auto it = g_layerDataMap.find(dataKey);
138 if (it == g_layerDataMap.end()) {
139 layerData = new LayerData;
140 g_layerDataMap[dataKey] = layerData;
141 } else {
142 layerData = it->second;
143 }
144 return layerData;
145 }
146
FreeLayerDataPtr(DispatchKey dataKey)147 void FreeLayerDataPtr(DispatchKey dataKey)
148 {
149 auto it = g_layerDataMap.find(dataKey);
150 if (it == g_layerDataMap.end()) {
151 return;
152 }
153 delete it->second;
154 g_layerDataMap.erase(it);
155 }
156
DebugMessageToUserCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, const char* message)157 void DebugMessageToUserCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, const char* message)
158 {
159 VkDebugUtilsMessengerCallbackDataEXT callbackData = {};
160 callbackData.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
161 callbackData.pMessageIdName = "SwapchainLayer";
162 callbackData.pMessage = message;
163
164 for (auto [key, layerData] : g_layerDataMap) {
165 if (layerData->debugCallbacks.empty()) {
166 continue;
167 }
168 for (auto& callback : layerData->debugCallbacks) {
169 if (!(severity & callback.second.messageSeverity)) {
170 continue;
171 }
172 if (!(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT & callback.second.messageType)) {
173 continue;
174 }
175 callback.second.pfnUserCallback(severity, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
176 &callbackData, callback.second.pUserData);
177 }
178 }
179 }
180
GetExtensionProperties(const uint32_t count, const VkExtensionProperties* layerExtensions, uint32_t* pCount, VkExtensionProperties* pProperties)181 VkResult GetExtensionProperties(const uint32_t count, const VkExtensionProperties* layerExtensions,
182 uint32_t* pCount, VkExtensionProperties* pProperties)
183 {
184 if (pProperties == nullptr || layerExtensions == nullptr) {
185 *pCount = count;
186 return VK_SUCCESS;
187 }
188
189 uint32_t copySize = *pCount < count ? *pCount : count;
190 errno_t ret = memcpy_s(pProperties, copySize * sizeof(VkExtensionProperties),
191 layerExtensions, copySize * sizeof(VkExtensionProperties));
192 if (ret != EOK) {
193 return VK_INCOMPLETE;
194 }
195 *pCount = copySize;
196 if (copySize < count) {
197 return VK_INCOMPLETE;
198 }
199
200 return VK_SUCCESS;
201 }
202
203 VkResult GetLayerProperties(const uint32_t count, const VkLayerProperties* layerProperties,
204 uint32_t* pCount, VkLayerProperties* pProperties)
205 {
206 if (pProperties == nullptr || layerProperties == nullptr) {
207 *pCount = count;
208 return VK_SUCCESS;
209 }
210
211 uint32_t copySize = *pCount < count ? *pCount : count;
212 errno_t ret = memcpy_s(pProperties, copySize * sizeof(VkLayerProperties),
213 layerProperties, copySize * sizeof(VkLayerProperties));
214 if (ret != EOK) {
215 return VK_INCOMPLETE;
216 }
217 *pCount = copySize;
218 if (copySize < count) {
219 return VK_INCOMPLETE;
220 }
221
222 return VK_SUCCESS;
223 }
224
225 static const VkExtensionProperties g_instanceExtensions[] = {
226 {
227 .extensionName = VK_KHR_SURFACE_EXTENSION_NAME,
228 .specVersion = 25,
229 },
230 {
231 .extensionName = VK_OHOS_SURFACE_EXTENSION_NAME,
232 .specVersion = 1,
233 },
234 {
235 .extensionName = VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
236 .specVersion = 4,
237 },
238 {
239 .extensionName = VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
240 .specVersion = 1,
241 }
242 };
243
244 static const VkExtensionProperties g_deviceExtensions[] = {
245 {
246 .extensionName = VK_KHR_SWAPCHAIN_EXTENSION_NAME,
247 .specVersion = 70,
248 },
249 {
250 .extensionName = VK_EXT_HDR_METADATA_EXTENSION_NAME,
251 .specVersion = 2,
252 }
253 };
254
255 constexpr VkLayerProperties swapchainLayer = {
256 SWAPCHAIN_SURFACE_NAME,
257 VK_LAYER_API_VERSION,
258 1,
259 "Vulkan Swapchain",
260 };
261
262 struct Surface {
263 NativeWindow* window;
264 VkSwapchainKHR swapchainHandle;
265 uint64_t usage;
266 };
267
268 struct Swapchain {
269 Swapchain(Surface &surface, uint32_t numImages, VkPresentModeKHR presentMode,
270 OH_NativeBuffer_TransformType preTransform)
271 : surface(surface), numImages(numImages), mailboxMode(presentMode == VK_PRESENT_MODE_MAILBOX_KHR),
272 preTransform(preTransform),
273 shared(presentMode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR ||
274 presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) {}
275
276 Surface &surface;
277 uint32_t numImages;
278 bool mailboxMode;
279 OH_NativeBuffer_TransformType preTransform;
280 bool shared;
281
282 struct Image {
283 Image() : image(VK_NULL_HANDLE), buffer(nullptr), requestFence(-1), releaseFence(-1), requested(false) {}
284 VkImage image;
285 NativeWindowBuffer* buffer;
286 int requestFence;
287 int releaseFence;
288 bool requested;
289 } images[MAX_BUFFER_SIZE];
290 };
291
292 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* funcName);
293 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance,
294 const char* funcName);
295
296 VkSurfaceKHR HandleFromSurface(Surface* surface)
297 {
298 return VkSurfaceKHR(reinterpret_cast<uint64_t>(surface));
299 }
300
301 Surface* SurfaceFromHandle(VkSurfaceKHR handle)
302 {
303 return reinterpret_cast<Surface*>(handle);
304 }
305
306 Swapchain* SwapchainFromHandle(VkSwapchainKHR handle)
307 {
308 return reinterpret_cast<Swapchain*>(handle);
309 }
310
311 VkSwapchainKHR HandleFromSwapchain(Swapchain* swapchain)
312 {
313 return VkSwapchainKHR(reinterpret_cast<uint64_t>(swapchain));
314 }
315
316 VKAPI_ATTR void* DefaultAllocate(void*, size_t size, size_t alignment, VkSystemAllocationScope)
317 {
318 void* ptr = nullptr;
319 int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
320 return ret == 0 ? ptr : nullptr;
321 }
322
323 VKAPI_ATTR void* DefaultReallocate(void*, void* ptr, size_t size, size_t alignment, VkSystemAllocationScope)
324 {
325 if (size == 0) {
326 free(ptr);
327 return nullptr;
328 }
329
330 size_t oldSize = ptr ? malloc_usable_size(ptr) : 0;
331 if (size <= oldSize) {
332 return ptr;
333 }
334
335 void* newPtr = nullptr;
336 if (posix_memalign(&newPtr, std::max(alignment, sizeof(void*)), size) != 0) {
337 return nullptr;
338 }
339
340 if (ptr != nullptr) {
341 auto ret = memcpy_s(newPtr, size, ptr, oldSize);
342 if (ret != EOK) {
343 free(newPtr);
344 return nullptr;
345 }
346 free(ptr);
347 }
348 return newPtr;
349 }
350
351 VKAPI_ATTR void DefaultFree(void*, void* ptr)
352 {
353 free(ptr);
354 }
355
356 const VkAllocationCallbacks &GetDefaultAllocator()
357 {
358 static const VkAllocationCallbacks defaultAllocCallbacks = {
359 .pUserData = nullptr,
360 .pfnAllocation = DefaultAllocate,
361 .pfnReallocation = DefaultReallocate,
362 .pfnFree = DefaultFree,
363 };
364
365 return defaultAllocCallbacks;
366 }
367
368 GraphicColorDataSpace GetColorDataspace(VkColorSpaceKHR colorspace)
369 {
370 switch (colorspace) {
371 case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR:
372 return GRAPHIC_BT709_SRGB_FULL;
373 case VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT:
374 return GRAPHIC_DCI_P3_GAMMA26_FULL;
375 case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT:
376 return GRAPHIC_BT709_LINEAR_EXTENDED;
377 case VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT:
378 return GRAPHIC_BT709_SRGB_EXTENDED;
379 case VK_COLOR_SPACE_DCI_P3_LINEAR_EXT:
380 return GRAPHIC_DCI_P3_LINEAR_FULL;
381 case VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT:
382 return GRAPHIC_DCI_P3_GAMMA26_FULL;
383 case VK_COLOR_SPACE_BT709_LINEAR_EXT:
384 return GRAPHIC_BT709_LINEAR_FULL;
385 case VK_COLOR_SPACE_BT709_NONLINEAR_EXT:
386 return GRAPHIC_BT709_SRGB_FULL;
387 case VK_COLOR_SPACE_BT2020_LINEAR_EXT:
388 return GRAPHIC_BT2020_LINEAR_FULL;
389 case VK_COLOR_SPACE_HDR10_ST2084_EXT:
390 return GRAPHIC_BT2020_ST2084_FULL;
391 case VK_COLOR_SPACE_DOLBYVISION_EXT:
392 return GRAPHIC_BT2020_ST2084_FULL;
393 case VK_COLOR_SPACE_HDR10_HLG_EXT:
394 return GRAPHIC_BT2020_HLG_FULL;
395 case VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT:
396 return static_cast<GraphicColorDataSpace>(GRAPHIC_GAMUT_ADOBE_RGB |
397 GRAPHIC_TRANSFORM_FUNC_LINEAR | GRAPHIC_PRECISION_FULL);
398 case VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT:
399 return GRAPHIC_ADOBE_RGB_GAMMA22_FULL;
400 default:
401 return GRAPHIC_COLOR_DATA_SPACE_UNKNOWN;
402 }
403 }
404
405 void SwapchainCloseFd(int &fd)
406 {
407 if (fd < 0) {
408 return;
409 }
410 close(fd);
411 fd = -1;
412 }
413
414 static bool IsFencePending(int fd)
415 {
416 if (fd < 0) {
417 return false;
418 }
419 errno = 0;
420 sptr<OHOS::SyncFence> syncFence = new OHOS::SyncFence(fd);
421 return syncFence->Wait(0) == -1 && errno == ETIME;
422 }
423
424 void ReleaseSwapchainImage(VkDevice device, NativeWindow* window, int releaseFence, Swapchain::Image &image,
425 bool deferIfPending)
426 {
427 ScopedBytrace trace(__func__);
428 if (releaseFence != -1 && !image.requested) {
429 SWLOGE("%{public}s, can't provide a release fence for non-requested images", __func__);
430 DebugMessageToUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
431 "can't provide a release fence for non-requested images");
432 return;
433 }
434
435 VkLayerDispatchTable* pDisp =
436 GetLayerDataPtr(GetDispatchKey(device))->deviceDispatchTable.get();
437 if (image.requested) {
438 if (releaseFence >= 0) {
439 SwapchainCloseFd(image.requestFence);
440 } else {
441 releaseFence = image.requestFence;
442 }
443 image.requestFence = -1;
444
445 if (window != nullptr) {
446 NativeWindowCancelBuffer(window, image.buffer);
447 SwapchainCloseFd(releaseFence);
448 } else {
449 if (releaseFence >= 0) {
450 sptr<OHOS::SyncFence> releaseSyncFence = new OHOS::SyncFence(releaseFence);
451 releaseSyncFence->Wait(-1);
452 }
453 }
454 releaseFence = -1;
455 image.requested = false;
456 }
457
458 if (deferIfPending && IsFencePending(image.releaseFence)) {
459 return;
460 }
461
462 SwapchainCloseFd(image.releaseFence);
463
464 if (image.image != VK_NULL_HANDLE) {
465 NativeObjectUnreference(image.buffer);
466 image.buffer = nullptr;
467 pDisp->DestroyImage(device, image.image, nullptr);
468 image.image = VK_NULL_HANDLE;
469 }
470 }
471
472 void ReleaseSwapchain(VkDevice device, Swapchain* swapchain)
473 {
474 ScopedBytrace trace(__func__);
475 if (swapchain->surface.swapchainHandle != HandleFromSwapchain(swapchain)) {
476 return;
477 }
478
479 for (uint32_t i = 0; i < swapchain->numImages; i++) {
480 if (!swapchain->images[i].requested) {
481 ReleaseSwapchainImage(device, nullptr, -1, swapchain->images[i], true);
482 }
483 }
484 swapchain->surface.swapchainHandle = VK_NULL_HANDLE;
485 }
486
GetPixelFormat(VkFormat format)487 GraphicPixelFormat GetPixelFormat(VkFormat format)
488 {
489 switch (format) {
490 case VK_FORMAT_R8G8B8A8_UNORM:
491 case VK_FORMAT_R8G8B8A8_SRGB:
492 return GRAPHIC_PIXEL_FMT_RGBA_8888;
493 case VK_FORMAT_R5G6B5_UNORM_PACK16:
494 return GRAPHIC_PIXEL_FMT_RGB_565;
495 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
496 return GRAPHIC_PIXEL_FMT_RGBA_1010102;
497 default:
498 SWLOGE("Swapchain format %{public}d unsupported return GRAPHIC_PIXEL_FMT_RGBA_8888;", format);
499 DebugMessageToUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
500 ("unsupported swapchain format " + std::to_string(format)).c_str());
501 return GRAPHIC_PIXEL_FMT_RGBA_8888;
502 }
503 }
504
505 /*
506 On OpenHarmony, the direction of rotation is counterclockwise
507 */
508
TranslateNativeToVulkanTransformHint(OH_NativeBuffer_TransformType nativeTransformType)509 VkSurfaceTransformFlagBitsKHR TranslateNativeToVulkanTransformHint(OH_NativeBuffer_TransformType nativeTransformType)
510 {
511 switch (nativeTransformType) {
512 case NATIVEBUFFER_ROTATE_NONE:
513 return VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
514 case NATIVEBUFFER_ROTATE_90:
515 return VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR;
516 case NATIVEBUFFER_ROTATE_180:
517 return VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR;
518 case NATIVEBUFFER_ROTATE_270:
519 return VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR;
520 case NATIVEBUFFER_FLIP_H:
521 case NATIVEBUFFER_FLIP_V_ROT180:
522 return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR;
523 case NATIVEBUFFER_FLIP_V:
524 case NATIVEBUFFER_FLIP_H_ROT180:
525 return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR;
526 case NATIVEBUFFER_FLIP_H_ROT90:
527 case NATIVEBUFFER_FLIP_V_ROT270:
528 return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR;
529 case NATIVEBUFFER_FLIP_V_ROT90:
530 case NATIVEBUFFER_FLIP_H_ROT270:
531 return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR;
532 default:
533 return VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
534 }
535 }
536
537 //Use to compare preTransform to transformHint
TranslateVulkanToNativeTransform(VkSurfaceTransformFlagBitsKHR transform)538 OH_NativeBuffer_TransformType TranslateVulkanToNativeTransform(VkSurfaceTransformFlagBitsKHR transform)
539 {
540 switch (transform) {
541 case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
542 return NATIVEBUFFER_ROTATE_NONE;
543 case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
544 return NATIVEBUFFER_ROTATE_270;
545 case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
546 return NATIVEBUFFER_ROTATE_180;
547 case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
548 return NATIVEBUFFER_ROTATE_90;
549 case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR:
550 return NATIVEBUFFER_FLIP_H;
551 case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR:
552 return NATIVEBUFFER_FLIP_V_ROT90;
553 case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR:
554 return NATIVEBUFFER_FLIP_V;
555 case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR:
556 return NATIVEBUFFER_FLIP_H_ROT90;
557 default:
558 return NATIVEBUFFER_ROTATE_NONE;
559 }
560 }
561
562 //After pre-rotation, the window needs to be rotated counterclockwise to the corresponding angle
InvertTransformToNative(VkSurfaceTransformFlagBitsKHR transform)563 OH_NativeBuffer_TransformType InvertTransformToNative(VkSurfaceTransformFlagBitsKHR transform)
564 {
565 switch (transform) {
566 case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
567 return NATIVEBUFFER_ROTATE_NONE;
568 case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
569 return NATIVEBUFFER_ROTATE_90;
570 case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
571 return NATIVEBUFFER_ROTATE_180;
572 case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
573 return NATIVEBUFFER_ROTATE_270;
574 case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR:
575 return NATIVEBUFFER_FLIP_H;
576 case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR:
577 return NATIVEBUFFER_FLIP_H_ROT270;
578 case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR:
579 return NATIVEBUFFER_FLIP_V;
580 case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR:
581 return NATIVEBUFFER_FLIP_H_ROT90;
582 default:
583 return NATIVEBUFFER_ROTATE_NONE;
584 }
585 }
586
SetWindowPixelFormat(NativeWindow* window, GraphicPixelFormat pixelFormat)587 VKAPI_ATTR VkResult SetWindowPixelFormat(NativeWindow* window, GraphicPixelFormat pixelFormat)
588 {
589 if (window == nullptr) {
590 return VK_ERROR_SURFACE_LOST_KHR;
591 }
592 int err = NativeWindowHandleOpt(window, SET_FORMAT, pixelFormat);
593 if (err != OHOS::GSERROR_OK) {
594 SWLOGE("NativeWindow Set Buffers Format(%{public}d) failed: (%{public}d)", pixelFormat, err);
595 return VK_ERROR_SURFACE_LOST_KHR;
596 }
597 return VK_SUCCESS;
598 }
599
SetWindowColorDataSpace(NativeWindow* window, GraphicColorDataSpace colorDataSpace)600 VKAPI_ATTR VkResult SetWindowColorDataSpace(NativeWindow* window, GraphicColorDataSpace colorDataSpace)
601 {
602 if (window == nullptr) {
603 return VK_ERROR_SURFACE_LOST_KHR;
604 }
605 SWLOGE("NativeWindow Not Support Set Color dataspace, now. Set GraphicColorDataSpace is [%{public}d]",
606 static_cast<int>(colorDataSpace));
607
608 return VK_SUCCESS;
609 }
610
SetWindowBufferGeometry(NativeWindow* window, int width, int height)611 VKAPI_ATTR VkResult SetWindowBufferGeometry(NativeWindow* window, int width, int height)
612 {
613 if (window == nullptr) {
614 return VK_ERROR_SURFACE_LOST_KHR;
615 }
616 int err = NativeWindowHandleOpt(window, SET_BUFFER_GEOMETRY, width, height);
617 if (err != OHOS::GSERROR_OK) {
618 SWLOGE("NativeWindow Set Buffer Geometry width:%{public}d,height:%{public}d failed: %{public}d",
619 width, height, err);
620 return VK_ERROR_SURFACE_LOST_KHR;
621 }
622
623 return VK_SUCCESS;
624 }
625
SetWindowTransform(NativeWindow* window, const VkSwapchainCreateInfoKHR* createInfo)626 VKAPI_ATTR VkResult SetWindowTransform(NativeWindow* window, const VkSwapchainCreateInfoKHR* createInfo)
627 {
628 OH_NativeBuffer_TransformType transformType = InvertTransformToNative(createInfo->preTransform);
629 SWLOGD("Swapchain translate VkSurfaceTransformFlagBitsKHR:%{public}d to OH_NativeBuffer_TransformType:%{public}d",
630 static_cast<int>(createInfo->preTransform), static_cast<int>(transformType));
631 if (window == nullptr) {
632 return VK_ERROR_SURFACE_LOST_KHR;
633 }
634 int err = NativeWindowHandleOpt(window, SET_TRANSFORM, transformType);
635 if (err != OHOS::GSERROR_OK) {
636 SWLOGE("NativeWindow Set Transform failed: %{public}d", err);
637 return VK_ERROR_SURFACE_LOST_KHR;
638 }
639
640 OH_NativeBuffer_TransformType transformHint = NATIVEBUFFER_ROTATE_NONE;
641 err = NativeWindowGetTransformHint(window, &transformHint);
642 if (err != OHOS::GSERROR_OK) {
643 SWLOGE("NativeWindow get TransformHint failed, error num : %{public}d", err);
644 return VK_ERROR_SURFACE_LOST_KHR;
645 }
646 if (transformHint != TranslateVulkanToNativeTransform(createInfo->preTransform)) {
647 SWLOGE("The App Is Not Doing Pre-rotation, transformHint: %{public}d, preTransform(to native): %{public}d",
648 transformHint, TranslateVulkanToNativeTransform(createInfo->preTransform));
649 }
650
651 return VK_SUCCESS;
652 }
653
SetWindowBufferUsage(VkDevice device, NativeWindow* window, const VkSwapchainCreateInfoKHR* createInfo)654 VKAPI_ATTR VkResult SetWindowBufferUsage(VkDevice device, NativeWindow* window,
655 const VkSwapchainCreateInfoKHR* createInfo)
656 {
657 uint64_t grallocUsage = 0;
658 VkLayerDispatchTable* pDisp =
659 GetLayerDataPtr(GetDispatchKey(device))->deviceDispatchTable.get();
660 if (pDisp->GetSwapchainGrallocUsageOHOS != nullptr) {
661 VkResult res =
662 pDisp->GetSwapchainGrallocUsageOHOS(device, createInfo->imageFormat, createInfo->imageUsage, &grallocUsage);
663 if (res != VK_SUCCESS) {
664 SWLOGE("GetSwapchainGrallocUsageOHOS failed: %{public}d", res);
665 return VK_ERROR_SURFACE_LOST_KHR;
666 }
667 SWLOGD("GetSwapchainGrallocUsageOHOS Get grallocUsage %{public}" PRIu64"", grallocUsage);
668 }
669
670 bool userSetVkTransform = createInfo->preTransform != VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
671 SWLOGD("User %{public}d Set VkTransform, preTransform is %{public}d",
672 userSetVkTransform, static_cast<int32_t>(createInfo->preTransform));
673 bool needSetFlgForDSS = false;
674 if (!userSetVkTransform) {
675 OH_NativeBuffer_TransformType curWindowTransformType = NATIVEBUFFER_ROTATE_NONE;
676 int err = NativeWindowGetTransformHint(window, &curWindowTransformType);
677 if (err != OHOS::GSERROR_OK) {
678 SWLOGE("NativeWindow Get TransformHint failed: %{public}d", err);
679 return VK_ERROR_SURFACE_LOST_KHR;
680 }
681 SWLOGD("NativeWindow Get NativeTransformHint %{public}d", static_cast<int>(curWindowTransformType));
682 if (curWindowTransformType == NATIVEBUFFER_ROTATE_270 || curWindowTransformType == NATIVEBUFFER_ROTATE_90) {
683 needSetFlgForDSS = true;
684 }
685 }
686
687 if (needSetFlgForDSS) {
688 grallocUsage |= BUFFER_USAGE_VENDOR_PRI19;
689 } else {
690 grallocUsage &= ~BUFFER_USAGE_VENDOR_PRI19;
691 }
692 SWLOGD("[%{public}d] Set Rotated Flag in Usage: %{public}" PRIu64"", needSetFlgForDSS, grallocUsage);
693
694 if (createInfo->flags & VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR) {
695 grallocUsage |= BUFFER_USAGE_PROTECTED;
696 }
697 int err = NativeWindowHandleOpt(window, SET_USAGE, grallocUsage);
698 if (err != OHOS::GSERROR_OK) {
699 SWLOGE("NativeWindow Set Usage %{public}" PRIu64" failed: %{public}d", grallocUsage, err);
700 return VK_ERROR_SURFACE_LOST_KHR;
701 }
702 return VK_SUCCESS;
703 }
704
SetWindowScalingMode(NativeWindow* window, OHScalingModeV2 scalingMode)705 VKAPI_ATTR VkResult SetWindowScalingMode(NativeWindow* window, OHScalingModeV2 scalingMode)
706 {
707 if (window == nullptr) {
708 return VK_ERROR_SURFACE_LOST_KHR;
709 }
710 SWLOGD("NativeWindow Set OHScalingMode is [%{public}d]", static_cast<int>(scalingMode));
711 int err = OH_NativeWindow_NativeWindowSetScalingModeV2(window, scalingMode);
712 if (err != OHOS::GSERROR_OK) {
713 SWLOGE("NativeWindow Set ScalingMode[%{public}d] failed, error: %{public}d",
714 static_cast<int>(scalingMode), err);
715 return VK_ERROR_SURFACE_LOST_KHR;
716 }
717
718 return VK_SUCCESS;
719 }
720
SetWindowQueueSize(NativeWindow* window, const VkSwapchainCreateInfoKHR* createInfo)721 VKAPI_ATTR VkResult SetWindowQueueSize(NativeWindow* window, const VkSwapchainCreateInfoKHR* createInfo)
722 {
723 if (window == nullptr) {
724 return VK_ERROR_SURFACE_LOST_KHR;
725 }
726 uint32_t numImages = createInfo->minImageCount;
727 if (numImages > MAX_BUFFER_SIZE) {
728 SWLOGE("Swapchain init minImageCount[%{public}u] can not be more than maxBufferCount[%{public}u]",
729 numImages, MAX_BUFFER_SIZE);
730 return VK_ERROR_INITIALIZATION_FAILED;
731 }
732 if (createInfo->presentMode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR ||
733 createInfo->presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) {
734 numImages = 1;
735 }
736 SWLOGD("NativeWindow Set Queue Size [%{public}u], Swapchain has the same number of iamge", numImages);
737 window->surface->SetQueueSize(numImages);
738
739 return VK_SUCCESS;
740 }
741
SetWindowInfo(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo)742 VKAPI_ATTR VkResult SetWindowInfo(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo)
743 {
744 GraphicColorDataSpace colorDataSpace = GetColorDataspace(createInfo->imageColorSpace);
745 SWLOGD("Swapchain translate VkColorSpaceKHR:%{public}d to GraphicColorDataSpace:%{public}d",
746 static_cast<int>(createInfo->imageColorSpace), static_cast<int>(colorDataSpace));
747 if (colorDataSpace == GRAPHIC_COLOR_DATA_SPACE_UNKNOWN) {
748 return VK_ERROR_INITIALIZATION_FAILED;
749 }
750 GraphicPixelFormat pixelFormat = GetPixelFormat(createInfo->imageFormat);
751 SWLOGD("Swapchain translate VkFormat:%{public}d to GraphicPixelFormat:%{public}d",
752 static_cast<int>(createInfo->imageFormat), static_cast<int>(pixelFormat));
753 Surface &surface = *SurfaceFromHandle(createInfo->surface);
754
755 NativeWindow* window = surface.window;
756 // Set PixelFormat
757 if (SetWindowPixelFormat(window, pixelFormat) != VK_SUCCESS) {
758 return VK_ERROR_SURFACE_LOST_KHR;
759 }
760 // Set DataSpace
761 if (SetWindowColorDataSpace(window, colorDataSpace) != VK_SUCCESS) {
762 return VK_ERROR_SURFACE_LOST_KHR;
763 }
764 // Set BufferGeometry
765 if (SetWindowBufferGeometry(window, static_cast<int>(createInfo->imageExtent.width),
766 static_cast<int>(createInfo->imageExtent.height)) != VK_SUCCESS) {
767 return VK_ERROR_SURFACE_LOST_KHR;
768 }
769
770 // Set Buffer Usage
771 if (SetWindowBufferUsage(device, window, createInfo) != VK_SUCCESS) {
772 return VK_ERROR_SURFACE_LOST_KHR;
773 }
774
775 // Set Transform
776 if (SetWindowTransform(window, createInfo) != VK_SUCCESS) {
777 return VK_ERROR_SURFACE_LOST_KHR;
778 }
779
780 // Set Scaling mode
781 if (SetWindowScalingMode(window, OHScalingModeV2::OH_SCALING_MODE_SCALE_TO_WINDOW_V2) != VK_SUCCESS) {
782 return VK_ERROR_SURFACE_LOST_KHR;
783 }
784
785 // Set Bufferqueue Size
786 if (SetWindowQueueSize(window, createInfo) != VK_SUCCESS) {
787 return VK_ERROR_SURFACE_LOST_KHR;
788 }
789
790 return VK_SUCCESS;
791 }
792
SetSwapchainCreateInfo(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo)793 VkResult SetSwapchainCreateInfo(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo)
794 {
795 if (createInfo->oldSwapchain != VK_NULL_HANDLE) {
796 ReleaseSwapchain(device, SwapchainFromHandle(createInfo->oldSwapchain));
797 }
798
799 return SetWindowInfo(device, createInfo);
800 }
801
InitImageCreateInfo(const VkSwapchainCreateInfoKHR* createInfo, VkImageCreateInfo* imageCreate)802 void InitImageCreateInfo(const VkSwapchainCreateInfoKHR* createInfo, VkImageCreateInfo* imageCreate)
803 {
804 imageCreate->sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
805 bool swapchainCreateProtected = createInfo->flags & VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR;
806 imageCreate->flags = swapchainCreateProtected ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u;
807 imageCreate->imageType = VK_IMAGE_TYPE_2D;
808 imageCreate->format = createInfo->imageFormat;
809 imageCreate->extent = {0, 0, 1};
810 imageCreate->mipLevels = 1;
811 imageCreate->arrayLayers = 1;
812 imageCreate->samples = VK_SAMPLE_COUNT_1_BIT;
813 imageCreate->tiling = VK_IMAGE_TILING_OPTIMAL;
814 imageCreate->usage = createInfo->imageUsage;
815 imageCreate->sharingMode = createInfo->imageSharingMode;
816 imageCreate->queueFamilyIndexCount = createInfo->queueFamilyIndexCount;
817 imageCreate->pQueueFamilyIndices = createInfo->pQueueFamilyIndices;
818 }
819
CreateImages(uint32_t &numImages, Swapchain* swapchain, const VkSwapchainCreateInfoKHR* createInfo, VkImageCreateInfo &imageCreate, VkDevice device)820 VKAPI_ATTR VkResult CreateImages(uint32_t &numImages, Swapchain* swapchain, const VkSwapchainCreateInfoKHR* createInfo,
821 VkImageCreateInfo &imageCreate, VkDevice device)
822 {
823 ScopedBytrace trace(__func__);
824 VkLayerDispatchTable* pDisp =
825 GetLayerDataPtr(GetDispatchKey(device))->deviceDispatchTable.get();
826 Surface &surface = *SurfaceFromHandle(createInfo->surface);
827 NativeWindow* window = surface.window;
828 if (createInfo->oldSwapchain != VK_NULL_HANDLE) {
829 SWLOGD("Swapchain Recreate ,clean buffer queue");
830 window->surface->CleanCache();
831 }
832 VkResult result = VK_SUCCESS;
833 for (uint32_t i = 0; i < numImages; i++) {
834 Swapchain::Image &img = swapchain->images[i];
835 NativeWindowBuffer* buffer = nullptr;
836 int fencefd = -1;
837 // if NativeWindowRequestBuffer success, should close fencefd
838 int err = NativeWindowRequestBuffer(window, &buffer, &fencefd);
839 if (err != OHOS::GSERROR_OK) {
840 SWLOGE("NativeWindow RequestBuffer[%{public}u] failed: (%{public}d)", i, err);
841 result = VK_ERROR_SURFACE_LOST_KHR;
842 break;
843 }
844 img.buffer = buffer;
845 img.requested = true;
846 img.requestFence = fencefd;
847 imageCreate.extent = VkExtent3D {static_cast<uint32_t>(img.buffer->sfbuffer->GetWidth()),
848 static_cast<uint32_t>(img.buffer->sfbuffer->GetHeight()), 1};
849 ((VkNativeBufferOHOS*)(imageCreate.pNext))->handle =
850 reinterpret_cast<struct OHBufferHandle *>(img.buffer->sfbuffer->GetBufferHandle());
851 result = pDisp->CreateImage(device, &imageCreate, nullptr, &img.image);
852 if (result != VK_SUCCESS) {
853 SWLOGD("vkCreateImage failed error: %{public}u", result);
854 break;
855 }
856 NativeObjectReference(buffer);
857 }
858
859 SWLOGD("swapchain init shared %{public}d", swapchain->shared);
860 for (uint32_t i = 0; i < numImages; i++) {
861 Swapchain::Image &img = swapchain->images[i];
862 if (img.requested) {
863 if (!swapchain->shared) {
864 NativeWindowCancelBuffer(window, img.buffer);
865 SwapchainCloseFd(img.requestFence);
866 img.requested = false;
867 }
868 }
869 }
870 return result;
871 }
872
DestroySwapchainInternal(VkDevice device, VkSwapchainKHR swapchainHandle, const VkAllocationCallbacks* allocator)873 static void DestroySwapchainInternal(VkDevice device, VkSwapchainKHR swapchainHandle,
874 const VkAllocationCallbacks* allocator)
875 {
876 ScopedBytrace trace(__func__);
877 Swapchain* swapchain = SwapchainFromHandle(swapchainHandle);
878 if (swapchain == nullptr) {
879 return;
880 }
881
882 bool active = swapchain->surface.swapchainHandle == swapchainHandle;
883 NativeWindow* window = active ? swapchain->surface.window : nullptr;
884
885 for (uint32_t i = 0; i < swapchain->numImages; i++) {
886 ReleaseSwapchainImage(device, window, -1, swapchain->images[i], false);
887 }
888
889 if (active) {
890 swapchain->surface.swapchainHandle = VK_NULL_HANDLE;
891 window->surface->CleanCache();
892 }
893 if (allocator == nullptr) {
894 allocator = &GetDefaultAllocator();
895 }
896 swapchain->~Swapchain();
897 allocator->pfnFree(allocator->pUserData, swapchain);
898 }
899
CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo, const VkAllocationCallbacks* allocator, VkSwapchainKHR* swapchainHandle)900 VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo,
901 const VkAllocationCallbacks* allocator, VkSwapchainKHR* swapchainHandle)
902 {
903 ScopedBytrace trace(__func__);
904 Surface &surface = *SurfaceFromHandle(createInfo->surface);
905 if (surface.swapchainHandle != createInfo->oldSwapchain) {
906 return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
907 }
908
909 VkResult result = SetSwapchainCreateInfo(device, createInfo);
910 if (result != VK_SUCCESS) {
911 return result;
912 }
913 uint32_t numImages = surface.window->surface->GetQueueSize();
914
915 if (allocator == nullptr) {
916 allocator = &GetDefaultAllocator();
917 }
918 void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Swapchain), alignof(Swapchain),
919 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
920 if (mem == nullptr) {
921 return VK_ERROR_OUT_OF_HOST_MEMORY;
922 }
923
924 OH_NativeBuffer_TransformType transformType = TranslateVulkanToNativeTransform(createInfo->preTransform);
925 SWLOGD("Swapchain translate VkSurfaceTransformFlagBitsKHR:%{public}d to OH_NativeBuffer_TransformType:%{public}d",
926 static_cast<int>(createInfo->preTransform), static_cast<int>(transformType));
927 Swapchain* swapchain = new (mem) Swapchain(surface, numImages, createInfo->presentMode, transformType);
928
929 VkSwapchainImageCreateInfoOHOS swapchainImageCreate = {
930 .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_OHOS,
931 .pNext = nullptr,
932 };
933 VkNativeBufferOHOS imageNativeBuffer = {
934 .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_OHOS,
935 .pNext = &swapchainImageCreate,
936 };
937
938 VkImageCreateInfo imageCreate = {
939 .pNext = &imageNativeBuffer,
940 };
941
942 InitImageCreateInfo(createInfo, &imageCreate);
943 result = CreateImages(numImages, swapchain, createInfo, imageCreate, device);
944 if (result != VK_SUCCESS) {
945 DestroySwapchainInternal(device, HandleFromSwapchain(swapchain), allocator);
946 return result;
947 }
948
949 surface.swapchainHandle = HandleFromSwapchain(swapchain);
950 *swapchainHandle = surface.swapchainHandle;
951 return VK_SUCCESS;
952 }
953
DestroySwapchainKHR( VkDevice device, VkSwapchainKHR vkSwapchain, const VkAllocationCallbacks* pAllocator)954 VKAPI_ATTR void VKAPI_CALL DestroySwapchainKHR(
955 VkDevice device, VkSwapchainKHR vkSwapchain, const VkAllocationCallbacks* pAllocator)
956 {
957 ScopedBytrace trace(__func__);
958 DestroySwapchainInternal(device, vkSwapchain, pAllocator);
959 }
960
GetSwapchainImagesKHR( VkDevice device, VkSwapchainKHR vkSwapchain, uint32_t* count, VkImage* images)961 VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(
962 VkDevice device, VkSwapchainKHR vkSwapchain, uint32_t* count, VkImage* images)
963 {
964 const Swapchain &swapchain = *SwapchainFromHandle(vkSwapchain);
965 if (images == nullptr) {
966 *count = swapchain.numImages;
967 return VK_SUCCESS;
968 }
969
970 VkResult result = VK_SUCCESS;
971 uint32_t numImages = swapchain.numImages;
972 if (*count < swapchain.numImages) {
973 numImages = *count;
974 result = VK_INCOMPLETE;
975 }
976 for (uint32_t i = 0; i < numImages; i++) {
977 images[i] = swapchain.images[i].image;
978 }
979 *count = numImages;
980 return result;
981 }
982
AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchainHandle, uint64_t timeout, VkSemaphore semaphore, VkFence vkFence, uint32_t* imageIndex)983 VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchainHandle,
984 uint64_t timeout, VkSemaphore semaphore, VkFence vkFence, uint32_t* imageIndex)
985 {
986 ScopedBytrace trace(__func__);
987 Swapchain &swapchain = *SwapchainFromHandle(swapchainHandle);
988 NativeWindow* nativeWindow = swapchain.surface.window;
989 VkResult result = VK_SUCCESS;
990
991 if (swapchain.surface.swapchainHandle != swapchainHandle) {
992 return VK_ERROR_OUT_OF_DATE_KHR;
993 }
994
995 LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(device));
996 if (swapchain.shared) {
997 *imageIndex = 0;
998 return deviceLayerData->deviceDispatchTable->AcquireImageOHOS(device, swapchain.images[*imageIndex].image, -1,
999 semaphore, vkFence);
1000 }
1001
1002 NativeWindowBuffer* nativeWindowBuffer = nullptr;
1003 int fence = -1;
1004 int32_t ret = NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fence);
1005 if (ret != OHOS::GSERROR_OK) {
1006 SWLOGE("NativeWindow RequestBuffer failed: (%{public}d)", ret);
1007 DebugMessageToUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
1008 ("RequestBuffer failed: " + std::to_string(ret)).c_str());
1009 return VK_ERROR_SURFACE_LOST_KHR;
1010 }
1011
1012 uint32_t index = 0;
1013 for (; index < swapchain.numImages; index++) {
1014 if (swapchain.images[index].buffer->sfbuffer == nativeWindowBuffer->sfbuffer) {
1015 swapchain.images[index].requested = true;
1016 swapchain.images[index].requestFence = fence;
1017 break;
1018 }
1019 }
1020
1021 if (index == swapchain.numImages) {
1022 SWLOGD("NativeWindow RequestBuffer returned unrecognized buffer");
1023 if (NativeWindowCancelBuffer(nativeWindow, nativeWindowBuffer) != OHOS::GSERROR_OK) {
1024 SWLOGE("NativeWindowCancelBuffer failed: (%{public}d)", ret);
1025 }
1026 SwapchainCloseFd(fence);
1027 return VK_ERROR_OUT_OF_DATE_KHR;
1028 }
1029 int fenceDup = -1;
1030 if (fence != -1) {
1031 fenceDup = ::dup(fence);
1032 if (fenceDup == -1) {
1033 SWLOGE("dup NativeWindow requested fencefd failed, wait for signalled");
1034 sptr<OHOS::SyncFence> syncFence = new OHOS::SyncFence(fence);
1035 syncFence->Wait(-1);
1036 }
1037 }
1038 // in vkAcquireImageOHOS should close fenceDup fd
1039 result = deviceLayerData->deviceDispatchTable->AcquireImageOHOS(device, swapchain.images[index].image, fenceDup,
1040 semaphore, vkFence);
1041 if (result != VK_SUCCESS) {
1042 if (NativeWindowCancelBuffer(nativeWindow, nativeWindowBuffer) != OHOS::GSERROR_OK) {
1043 SWLOGE("NativeWindowCancelBuffer failed: (%{public}d)", ret);
1044 }
1045 swapchain.images[index].requested = false;
1046 swapchain.images[index].requestFence = -1;
1047 SwapchainCloseFd(fence);
1048 return result;
1049 }
1050
1051 *imageIndex = index;
1052 return VK_SUCCESS;
1053 }
1054
1055 VKAPI_ATTR
GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects)1056 VkResult GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
1057 VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects)
1058 {
1059 if (pRects == nullptr) {
1060 *pRectCount = 1;
1061 return VK_SUCCESS;
1062 }
1063 bool incomplete = *pRectCount < 1;
1064 *pRectCount = std::min(*pRectCount, 1u);
1065 if (incomplete) {
1066 return VK_INCOMPLETE;
1067 }
1068
1069 NativeWindow* window = SurfaceFromHandle(surface)->window;
1070
1071 int32_t width = 0;
1072 int32_t height = 0;
1073 int err = NativeWindowHandleOpt(window, GET_BUFFER_GEOMETRY, &height, &width);
1074 if (err != OHOS::GSERROR_OK) {
1075 SWLOGE("NativeWindow get buffer geometry failed: (%{public}d)", err);
1076 }
1077 pRects[0].offset.x = 0;
1078 pRects[0].offset.y = 0;
1079 pRects[0].extent = VkExtent2D{static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
1080 return VK_SUCCESS;
1081 }
1082
1083 VKAPI_ATTR
AcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex)1084 VkResult AcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex)
1085 {
1086 return AcquireNextImageKHR(device, pAcquireInfo->swapchain, pAcquireInfo->timeout,
1087 pAcquireInfo->semaphore, pAcquireInfo->fence, pImageIndex);
1088 }
1089
GetPresentRegions(const VkPresentInfoKHR* presentInfo)1090 const VkPresentRegionKHR* GetPresentRegions(const VkPresentInfoKHR* presentInfo)
1091 {
1092 const VkPresentRegionsKHR* presentRegions = nullptr;
1093 const VkPresentRegionsKHR* nextRegions = reinterpret_cast<const VkPresentRegionsKHR*>(presentInfo->pNext);
1094 while (nextRegions != nullptr) {
1095 if (nextRegions->sType == VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR) {
1096 presentRegions = nextRegions;
1097 }
1098 nextRegions = reinterpret_cast<const VkPresentRegionsKHR*>(nextRegions->pNext);
1099 }
1100
1101 if (presentRegions == nullptr) {
1102 return nullptr;
1103 } else {
1104 if (presentRegions->swapchainCount != presentInfo->swapchainCount) {
1105 SWLOGE("vkQueuePresentKHR VkPresentRegions::swapchainCount != VkPresentInfo::swapchainCount");
1106 }
1107 return presentRegions->pRegions;
1108 }
1109 }
1110
ReleaseImage(VkQueue queue, const VkPresentInfoKHR* presentInfo, Swapchain::Image &img, int32_t &fence)1111 VkResult ReleaseImage(VkQueue queue, const VkPresentInfoKHR* presentInfo,
1112 Swapchain::Image &img, int32_t &fence)
1113 {
1114 ScopedBytrace trace(__func__);
1115 LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(queue));
1116 VkResult result = deviceLayerData->deviceDispatchTable->QueueSignalReleaseImageOHOS(
1117 queue, presentInfo->waitSemaphoreCount, presentInfo->pWaitSemaphores, img.image, &fence);
1118 SwapchainCloseFd(img.releaseFence);
1119 if (fence >= 0) {
1120 img.releaseFence = dup(fence);
1121 }
1122 return result;
1123 }
1124
GetRegionRect( const VkAllocationCallbacks* defaultAllocator, struct Region::Rect** rects, int32_t rectangleCount)1125 struct Region::Rect* GetRegionRect(
1126 const VkAllocationCallbacks* defaultAllocator, struct Region::Rect** rects, int32_t rectangleCount)
1127 {
1128 return static_cast<struct Region::Rect*>(
1129 defaultAllocator->pfnReallocation(
1130 defaultAllocator->pUserData, *rects,
1131 sizeof(Region::Rect) *rectangleCount,
1132 alignof(Region::Rect), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
1133 }
1134
InitRegionRect(const VkRectLayerKHR* layer, struct Region::Rect* rect, int32_t bufferHeight)1135 void InitRegionRect(const VkRectLayerKHR* layer, struct Region::Rect* rect, int32_t bufferHeight)
1136 {
1137 rect->x = layer->offset.x;
1138 // flip rect to adapt to bottom-left coordinate
1139 rect->y = bufferHeight - layer->extent.height - layer->offset.y;
1140 rect->w = layer->extent.width;
1141 rect->h = layer->extent.height;
1142 }
1143
FlushBuffer(const VkPresentRegionKHR* region, struct Region::Rect* rects, Swapchain &swapchain, Swapchain::Image &img, int32_t fence)1144 VkResult FlushBuffer(const VkPresentRegionKHR* region, struct Region::Rect* rects,
1145 Swapchain &swapchain, Swapchain::Image &img, int32_t fence)
1146 {
1147 ScopedBytrace trace(__func__);
1148 const VkAllocationCallbacks* defaultAllocator = &GetDefaultAllocator();
1149 Region localRegion = {};
1150 if (memset_s(&localRegion, sizeof(localRegion), 0, sizeof(Region)) != EOK) {
1151 return VK_ERROR_SURFACE_LOST_KHR;
1152 }
1153 NativeWindow* window = swapchain.surface.window;
1154 // Get buffer width and height for flip damage rect
1155 int32_t bufferWidth = 0;
1156 int32_t bufferHeight = 0;
1157 int err = NativeWindowHandleOpt(window, GET_BUFFER_GEOMETRY, &bufferHeight, &bufferWidth);
1158 if (err != OHOS::GSERROR_OK) {
1159 SWLOGE("NativeWindow get buffer geometry failed, error num: %{public}d", err);
1160 return VK_ERROR_SURFACE_LOST_KHR;
1161 }
1162 if (region != nullptr) {
1163 int32_t rectangleCount = region->rectangleCount;
1164 if (rectangleCount > 0) {
1165 struct Region::Rect* tmpRects = GetRegionRect(defaultAllocator, &rects, rectangleCount);
1166 if (tmpRects != nullptr) {
1167 rects = tmpRects;
1168 } else {
1169 rectangleCount = 0;
1170 }
1171 }
1172 for (int32_t r = 0; r < rectangleCount; ++r) {
1173 InitRegionRect(®ion->pRectangles[r], &rects[r], bufferHeight);
1174 }
1175
1176 localRegion.rects = rects;
1177 localRegion.rectNumber = rectangleCount;
1178 }
1179 // the acquire fence will be close by BufferQueue module
1180 err = NativeWindowFlushBuffer(window, img.buffer, fence, localRegion);
1181 VkResult scResult = VK_SUCCESS;
1182 if (err != OHOS::GSERROR_OK) {
1183 SWLOGE("NativeWindow FlushBuffer failed: (%{public}d)", err);
1184 scResult = VK_ERROR_SURFACE_LOST_KHR;
1185 } else {
1186 SwapchainCloseFd(img.requestFence);
1187 img.requested = false;
1188 }
1189
1190 if (swapchain.shared && scResult == VK_SUCCESS) {
1191 NativeWindowBuffer* buffer = nullptr;
1192 int fenceFd = -1;
1193 err = NativeWindowRequestBuffer(window, &buffer, &fenceFd);
1194 if (err != OHOS::GSERROR_OK) {
1195 scResult = VK_ERROR_SURFACE_LOST_KHR;
1196 } else if (img.buffer != buffer) {
1197 scResult = VK_ERROR_SURFACE_LOST_KHR;
1198 SwapchainCloseFd(fenceFd);
1199 } else {
1200 img.requestFence = fenceFd;
1201 img.requested = true;
1202 }
1203 }
1204
1205 return scResult;
1206 }
1207
QueuePresentKHR( VkQueue queue, const VkPresentInfoKHR* presentInfo)1208 VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(
1209 VkQueue queue, const VkPresentInfoKHR* presentInfo)
1210 {
1211 ScopedBytrace trace(__func__);
1212 VkResult ret = VK_SUCCESS;
1213
1214 const VkPresentRegionKHR* regions = GetPresentRegions(presentInfo);
1215 const VkAllocationCallbacks* defaultAllocator = &GetDefaultAllocator();
1216 struct Region::Rect* rects = nullptr;
1217 LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(queue));
1218 VkDevice device = deviceLayerData->device;
1219
1220 for (uint32_t i = 0; i < presentInfo->swapchainCount; i++) {
1221 Swapchain &swapchain = *(reinterpret_cast<Swapchain*>(presentInfo->pSwapchains[i]));
1222 Swapchain::Image &img = swapchain.images[presentInfo->pImageIndices[i]];
1223 const VkPresentRegionKHR* region = (regions != nullptr) ? ®ions[i] : nullptr;
1224 int32_t fence = -1;
1225 ret = ReleaseImage(queue, presentInfo, img, fence);
1226 if (swapchain.surface.swapchainHandle == presentInfo->pSwapchains[i]) {
1227 if (ret == VK_SUCCESS) {
1228 ret = FlushBuffer(region, rects, swapchain, img, fence);
1229 } else {
1230 ReleaseSwapchain(device, &swapchain);
1231 }
1232 } else {
1233 SWLOGE("vkQueuePresentKHR swapchainHandle != pSwapchains[%{public}d]", i);
1234 ReleaseSwapchainImage(device, nullptr, fence, img, true);
1235 ret = VK_ERROR_OUT_OF_DATE_KHR;
1236 }
1237
1238 if (presentInfo->pResults) {
1239 presentInfo->pResults[i] = ret;
1240 }
1241 }
1242 if (rects != nullptr) {
1243 defaultAllocator->pfnFree(defaultAllocator->pUserData, rects);
1244 }
1245 #if USE_APS_IGAMESERVICE_FUNC
1246 OHOS::GameService::VulkanSliceReport::GetInstance().ReportVulkanRender();
1247 #endif
1248 return ret;
1249 }
1250
GetDeviceGroupPresentCapabilitiesKHR( VkDevice, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities)1251 VKAPI_ATTR VkResult GetDeviceGroupPresentCapabilitiesKHR(
1252 VkDevice, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities)
1253 {
1254 if (pDeviceGroupPresentCapabilities == nullptr) {
1255 return VK_ERROR_OUT_OF_HOST_MEMORY;
1256 }
1257
1258 memset_s(pDeviceGroupPresentCapabilities->presentMask,
1259 sizeof(pDeviceGroupPresentCapabilities->presentMask), 0, sizeof(pDeviceGroupPresentCapabilities->presentMask));
1260 pDeviceGroupPresentCapabilities->presentMask[0] = 1u;
1261 pDeviceGroupPresentCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
1262
1263 return VK_SUCCESS;
1264 }
1265
GetDeviceGroupSurfacePresentModesKHR( VkDevice, VkSurfaceKHR, VkDeviceGroupPresentModeFlagsKHR* pModes)1266 VKAPI_ATTR VkResult GetDeviceGroupSurfacePresentModesKHR(
1267 VkDevice, VkSurfaceKHR, VkDeviceGroupPresentModeFlagsKHR* pModes)
1268 {
1269 *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
1270 return VK_SUCCESS;
1271 }
1272
GetPhysicalDeviceSurfaceSupportKHR( VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, const VkSurfaceKHR surface, VkBool32* pSupported)1273 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(
1274 VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, const VkSurfaceKHR surface, VkBool32* pSupported)
1275 {
1276 *pSupported = VK_TRUE;
1277 return VK_SUCCESS;
1278 }
1279
CreateSurfaceOHOS(VkInstance instance, const VkSurfaceCreateInfoOHOS* pCreateInfo, const VkAllocationCallbacks* allocator, VkSurfaceKHR* outSurface)1280 VKAPI_ATTR VkResult VKAPI_CALL CreateSurfaceOHOS(VkInstance instance,
1281 const VkSurfaceCreateInfoOHOS* pCreateInfo,
1282 const VkAllocationCallbacks* allocator, VkSurfaceKHR* outSurface)
1283 {
1284 ScopedBytrace trace(__func__);
1285 if (allocator == nullptr) {
1286 allocator = &GetDefaultAllocator();
1287 }
1288 void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Surface), alignof(Surface),
1289 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1290 if (mem == nullptr) {
1291 return VK_ERROR_OUT_OF_HOST_MEMORY;
1292 }
1293
1294 Surface* surface = new (mem) Surface;
1295 surface->window = pCreateInfo->window;
1296 NativeObjectReference(surface->window);
1297 surface->swapchainHandle = VK_NULL_HANDLE;
1298 int err = NativeWindowHandleOpt(pCreateInfo->window, GET_USAGE, &(surface->usage));
1299 if (err != OHOS::GSERROR_OK) {
1300 NativeObjectUnreference(surface->window);
1301 surface->~Surface();
1302 allocator->pfnFree(allocator->pUserData, surface);
1303 SWLOGE("NativeWindow get usage failed, error num : %{public}d", err);
1304 return VK_ERROR_SURFACE_LOST_KHR;
1305 }
1306
1307 *outSurface = HandleFromSurface(surface);
1308 return VK_SUCCESS;
1309 }
1310
DestroySurfaceKHR( VkInstance instance, VkSurfaceKHR vkSurface, const VkAllocationCallbacks* pAllocator)1311 VKAPI_ATTR void VKAPI_CALL DestroySurfaceKHR(
1312 VkInstance instance, VkSurfaceKHR vkSurface, const VkAllocationCallbacks* pAllocator)
1313 {
1314 ScopedBytrace trace(__func__);
1315 Surface* surface = SurfaceFromHandle(vkSurface);
1316 if (surface == nullptr) {
1317 return;
1318 }
1319 if (pAllocator == nullptr) {
1320 pAllocator = &GetDefaultAllocator();
1321 }
1322 NativeObjectUnreference(surface->window);
1323 surface->~Surface();
1324 pAllocator->pfnFree(pAllocator->pUserData, surface);
1325 }
1326
GetPhysicalDeviceSurfaceCapabilitiesKHR( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* capabilities)1327 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilitiesKHR(
1328 VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* capabilities)
1329 {
1330 int32_t width = 0;
1331 int32_t height = 0;
1332 OH_NativeBuffer_TransformType transformHint = NATIVEBUFFER_ROTATE_NONE;
1333 uint32_t defaultQueueSize = MAX_BUFFER_SIZE;
1334 if (surface != VK_NULL_HANDLE) {
1335 NativeWindow* window = SurfaceFromHandle(surface)->window;
1336 int err = NativeWindowHandleOpt(window, GET_BUFFER_GEOMETRY, &height, &width);
1337 if (err != OHOS::GSERROR_OK) {
1338 SWLOGE("NativeWindow get buffer geometry failed, error num : %{public}d", err);
1339 return VK_ERROR_SURFACE_LOST_KHR;
1340 }
1341 err = NativeWindowGetTransformHint(window, &transformHint);
1342 if (err != OHOS::GSERROR_OK) {
1343 SWLOGE("NativeWindow get TransformHint failed, error num : %{public}d", err);
1344 return VK_ERROR_SURFACE_LOST_KHR;
1345 }
1346 defaultQueueSize = window->surface->GetQueueSize();
1347 SWLOGD("NativeWindow default Queue Size : (%{public}d)", defaultQueueSize);
1348 }
1349
1350 capabilities->minImageCount = std::min(defaultQueueSize, MIN_BUFFER_SIZE);
1351 capabilities->maxImageCount = std::max(defaultQueueSize, MAX_BUFFER_SIZE);
1352 capabilities->currentExtent = VkExtent2D {static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
1353 capabilities->minImageExtent = VkExtent2D {1, 1};
1354 capabilities->maxImageExtent = VkExtent2D {4096, 4096};
1355 capabilities->maxImageArrayLayers = 1;
1356 capabilities->supportedTransforms = g_supportedTransforms;
1357 capabilities->currentTransform = TranslateNativeToVulkanTransformHint(transformHint);
1358 capabilities->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
1359 capabilities->supportedUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1360 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
1361 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1362 return VK_SUCCESS;
1363 }
1364
1365
1366 /*
1367 VK_EXT_hdr_metadata
1368 */
SetHdrMetadataEXT( VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pMetadata)1369 VKAPI_ATTR void VKAPI_CALL SetHdrMetadataEXT(
1370 VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pMetadata)
1371 {
1372 SWLOGE("NativeWindow Not Support Set HdrMetaData[TODO]");
1373 }
1374
GetPhysicalDeviceSurfaceCapabilities2KHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities)1375 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(
1376 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
1377 VkSurfaceCapabilities2KHR* pSurfaceCapabilities)
1378 {
1379 VkResult result = GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, pSurfaceInfo->surface,
1380 &pSurfaceCapabilities->surfaceCapabilities);
1381
1382 VkSurfaceCapabilities2KHR* caps = pSurfaceCapabilities;
1383 while (caps->pNext != nullptr) {
1384 caps = reinterpret_cast<VkSurfaceCapabilities2KHR*>(caps->pNext);
1385 if (caps->sType == VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR) {
1386 reinterpret_cast<VkSharedPresentSurfaceCapabilitiesKHR*>(caps)->sharedPresentSupportedUsageFlags =
1387 pSurfaceCapabilities->surfaceCapabilities.supportedUsageFlags;
1388 } else if (caps->sType == VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR) {
1389 reinterpret_cast<VkSurfaceProtectedCapabilitiesKHR*>(caps)->supportsProtected= VK_TRUE;
1390 }
1391 }
1392 return result;
1393 }
1394
1395
GetPhysicalDeviceSurfaceFormatsKHR( VkPhysicalDevice physicalDevice, const VkSurfaceKHR surface, uint32_t* count, VkSurfaceFormatKHR* formats)1396 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormatsKHR(
1397 VkPhysicalDevice physicalDevice, const VkSurfaceKHR surface, uint32_t* count, VkSurfaceFormatKHR* formats)
1398 {
1399 if (surface == VK_NULL_HANDLE) {
1400 return VK_ERROR_SURFACE_LOST_KHR;
1401 }
1402
1403 LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(physicalDevice));
1404 bool enableSwapchainColorSpace = deviceLayerData->enabledExtensions.test(Extension::EXT_SWAPCHAIN_COLOR_SPACE);
1405
1406 std::vector<VkSurfaceFormatKHR> allFormats = {
1407 // RGBA_8888
1408 {VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
1409 {VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
1410 // RGB_565
1411 {VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
1412 // RGBA_1010102
1413 {VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
1414 {VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT}
1415 };
1416
1417 if (enableSwapchainColorSpace) {
1418 allFormats.emplace_back(VkSurfaceFormatKHR{
1419 VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_BT709_LINEAR_EXT});
1420 allFormats.emplace_back(VkSurfaceFormatKHR{
1421 VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT});
1422 allFormats.emplace_back(VkSurfaceFormatKHR{
1423 VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT});
1424 }
1425 VkResult result = VK_SUCCESS;
1426 if (formats != nullptr) {
1427 uint32_t transferCount = allFormats.size();
1428 if (transferCount > *count) {
1429 transferCount = *count;
1430 result = VK_INCOMPLETE;
1431 }
1432 std::copy(allFormats.begin(), allFormats.begin() + transferCount, formats);
1433 *count = transferCount;
1434 } else {
1435 *count = allFormats.size();
1436 }
1437
1438 return result;
1439 }
1440
GetPhysicalDeviceSurfaceFormats2KHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats)1441 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(
1442 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
1443 uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats)
1444 {
1445 // Get pSurfaceFormatCount
1446 if (pSurfaceFormats == nullptr) {
1447 return GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount, nullptr);
1448 }
1449 // Get pSurfaceFormats
1450 uint32_t formatCount = *pSurfaceFormatCount;
1451
1452 std::vector<VkSurfaceFormatKHR> surfaceFormats(formatCount);
1453 VkResult res = GetPhysicalDeviceSurfaceFormatsKHR(
1454 physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount, surfaceFormats.data());
1455 if (res == VK_SUCCESS || res == VK_INCOMPLETE) {
1456 for (uint32_t i = 0; i < formatCount; i++) {
1457 pSurfaceFormats[i].surfaceFormat = surfaceFormats[i];
1458 }
1459 }
1460
1461 return res;
1462 }
1463
QueryPresentationProperties( VkPhysicalDevice physicalDevice, VkPhysicalDevicePresentationPropertiesOHOS* presentationProperties)1464 void QueryPresentationProperties(
1465 VkPhysicalDevice physicalDevice,
1466 VkPhysicalDevicePresentationPropertiesOHOS* presentationProperties)
1467 {
1468 VkPhysicalDeviceProperties2 properties = {
1469 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
1470 presentationProperties,
1471 {},
1472 };
1473
1474 presentationProperties->sType =
1475 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_OHOS;
1476 presentationProperties->pNext = nullptr;
1477 presentationProperties->sharedImage = VK_FALSE;
1478
1479 DispatchKey key = GetDispatchKey(physicalDevice);
1480 LayerData* curLayerData = GetLayerDataPtr(key);
1481 if (curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2) {
1482 curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2(physicalDevice, &properties);
1483 } else if (curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2KHR) {
1484 curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2KHR(physicalDevice, &properties);
1485 } else {
1486 SWLOGE("Func vkGetPhysicalDeviceProperties2 and vkGetPhysicalDeviceProperties2KHR are both null.");
1487 }
1488 }
1489
GetPhysicalDeviceSurfacePresentModesKHR( VkPhysicalDevice physicalDevice, const VkSurfaceKHR surface, uint32_t* count, VkPresentModeKHR* pPresentModes)1490 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModesKHR(
1491 VkPhysicalDevice physicalDevice, const VkSurfaceKHR surface, uint32_t* count, VkPresentModeKHR* pPresentModes)
1492 {
1493 std::vector<VkPresentModeKHR> presentModes = {
1494 VK_PRESENT_MODE_MAILBOX_KHR,
1495 VK_PRESENT_MODE_FIFO_KHR
1496 };
1497
1498 VkPhysicalDevicePresentationPropertiesOHOS presentProperties = {};
1499 QueryPresentationProperties(physicalDevice, &presentProperties);
1500 if (presentProperties.sharedImage) {
1501 SWLOGE("NativeWindow Not Support Shared Mode, now. Not Report Shared Mode.");
1502 }
1503
1504 uint32_t numModes = static_cast<uint32_t>(presentModes.size());
1505 VkResult result = VK_SUCCESS;
1506 if (pPresentModes != nullptr) {
1507 if (*count < numModes) {
1508 result = VK_INCOMPLETE;
1509 }
1510 *count = std::min(*count, numModes);
1511 std::copy_n(presentModes.data(), *count, pPresentModes);
1512 } else {
1513 *count = numModes;
1514 }
1515 return result;
1516 }
1517
GetExtensionBitFromName(const char* name)1518 Extension GetExtensionBitFromName(const char* name)
1519 {
1520 if (name == nullptr) {
1521 return Extension::EXTENSION_UNKNOWN;
1522 }
1523 if (strcmp(name, VK_OHOS_SURFACE_EXTENSION_NAME) == 0) {
1524 return Extension::OHOS_SURFACE;
1525 }
1526 if (strcmp(name, VK_OHOS_NATIVE_BUFFER_EXTENSION_NAME) == 0) {
1527 return Extension::OHOS_NATIVE_BUFFER;
1528 }
1529 if (strcmp(name, VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
1530 return Extension::KHR_SURFACE;
1531 }
1532 if (strcmp(name, VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
1533 return Extension::KHR_SWAPCHAIN;
1534 }
1535 if (strcmp(name, VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME) == 0) {
1536 return Extension::EXT_SWAPCHAIN_COLOR_SPACE;
1537 }
1538 if (strcmp(name, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME) == 0) {
1539 return Extension::KHR_GET_SURFACE_CAPABILITIES_2;
1540 }
1541 if (strcmp(name, VK_EXT_HDR_METADATA_EXTENSION_NAME) == 0) {
1542 return Extension::EXT_HDR_METADATA;
1543 }
1544 return Extension::EXTENSION_UNKNOWN;
1545 }
1546
CreateInstance( const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)1547 VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(
1548 const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
1549 {
1550 ScopedBytrace trace(__func__);
1551 VkLayerInstanceCreateInfo* chainInfo = GetChainInfo(pCreateInfo, VK_LAYER_LINK_INFO);
1552
1553 if (chainInfo == nullptr || chainInfo->u.pLayerInfo == nullptr) {
1554 return VK_ERROR_INITIALIZATION_FAILED;
1555 }
1556 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
1557 chainInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
1558 PFN_vkCreateInstance fpCreateInstance =
1559 (PFN_vkCreateInstance)fpGetInstanceProcAddr(nullptr, "vkCreateInstance");
1560 if (fpCreateInstance == nullptr) {
1561 return VK_ERROR_INITIALIZATION_FAILED;
1562 }
1563
1564 chainInfo->u.pLayerInfo = chainInfo->u.pLayerInfo->pNext;
1565
1566 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
1567 if (result != VK_SUCCESS) {
1568 return result;
1569 }
1570 #if USE_APS_IGAMESERVICE_FUNC
1571 OHOS::GameService::VulkanSliceReport::GetInstance().InitVulkanReport();
1572 #endif
1573
1574 LayerData* instanceLayerData = GetLayerDataPtr(GetDispatchKey(*pInstance));
1575 instanceLayerData->instance = *pInstance;
1576 instanceLayerData->instanceDispatchTable = std::make_unique<VkLayerInstanceDispatchTable>();
1577 layer_init_instance_dispatch_table(*pInstance, instanceLayerData->instanceDispatchTable.get(),
1578 fpGetInstanceProcAddr);
1579 for (uint32_t index = 0; index < pCreateInfo->enabledExtensionCount; index++) {
1580 auto extBit = GetExtensionBitFromName(pCreateInfo->ppEnabledExtensionNames[index]);
1581 if (extBit != Extension::EXTENSION_UNKNOWN) {
1582 instanceLayerData->enabledExtensions.set(extBit);
1583 }
1584 }
1585 return result;
1586 }
1587
DestroyInstance( VkInstance instance, const VkAllocationCallbacks* pAllocator)1588 VKAPI_ATTR void VKAPI_CALL DestroyInstance(
1589 VkInstance instance, const VkAllocationCallbacks* pAllocator)
1590 {
1591 ScopedBytrace trace(__func__);
1592 DispatchKey instanceKey = GetDispatchKey(instance);
1593 LayerData* curLayerData = GetLayerDataPtr(instanceKey);
1594 curLayerData->instanceDispatchTable->DestroyInstance(instance, pAllocator);
1595 FreeLayerDataPtr(instanceKey);
1596 }
1597
CheckExtensionAvailable(const std::string &extensionName, const std::vector<VkExtensionProperties> &deviceExtensions)1598 bool CheckExtensionAvailable(const std::string &extensionName,
1599 const std::vector<VkExtensionProperties> &deviceExtensions)
1600 {
1601 bool extensionAvailable = false;
1602 for (uint32_t i = 0; i < deviceExtensions.size(); i++) {
1603 if (strcmp(extensionName.data(), deviceExtensions[i].extensionName) == 0) {
1604 extensionAvailable = true;
1605 break;
1606 }
1607 }
1608 return extensionAvailable;
1609 }
1610
AddDeviceExtensions(VkPhysicalDevice gpu, const LayerData* gpuLayerData, std::vector<const char*> &enabledExtensions)1611 VkResult AddDeviceExtensions(VkPhysicalDevice gpu, const LayerData* gpuLayerData,
1612 std::vector<const char*> &enabledExtensions)
1613 {
1614 VkResult result = VK_SUCCESS;
1615 uint32_t deviceExtensionCount = 0;
1616 result = gpuLayerData->instanceDispatchTable->EnumerateDeviceExtensionProperties(
1617 gpu, nullptr, &deviceExtensionCount, nullptr);
1618 if (result == VK_SUCCESS && deviceExtensionCount > 0) {
1619 std::vector<VkExtensionProperties> deviceExtensions(deviceExtensionCount);
1620 result = gpuLayerData->instanceDispatchTable->EnumerateDeviceExtensionProperties(
1621 gpu, nullptr, &deviceExtensionCount, deviceExtensions.data());
1622 if (result == VK_SUCCESS) {
1623 if (!CheckExtensionAvailable(VK_OHOS_NATIVE_BUFFER_EXTENSION_NAME, deviceExtensions)) {
1624 return VK_ERROR_INITIALIZATION_FAILED;
1625 }
1626 enabledExtensions.push_back(VK_OHOS_NATIVE_BUFFER_EXTENSION_NAME);
1627 if (CheckExtensionAvailable(VK_OHOS_EXTERNAL_MEMORY_EXTENSION_NAME,
1628 deviceExtensions)) {
1629 enabledExtensions.push_back(VK_OHOS_EXTERNAL_MEMORY_EXTENSION_NAME);
1630 }
1631 }
1632 }
1633 return VK_SUCCESS;
1634 }
1635
CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)1636 VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu,
1637 const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
1638 {
1639 ScopedBytrace trace(__func__);
1640 DispatchKey gpuKey = GetDispatchKey(gpu);
1641 LayerData* gpuLayerData = GetLayerDataPtr(gpuKey);
1642
1643 VkDeviceCreateInfo createInfo = *pCreateInfo;
1644 std::vector<const char*> enabledExtensions = {};
1645 for (uint32_t i = 0; i < createInfo.enabledExtensionCount; i++) {
1646 enabledExtensions.push_back(createInfo.ppEnabledExtensionNames[i]);
1647 }
1648
1649 VkResult result = AddDeviceExtensions(gpu, gpuLayerData, enabledExtensions);
1650 if (result != VK_SUCCESS) {
1651 return result;
1652 }
1653
1654 createInfo.enabledExtensionCount = ToUint32(enabledExtensions.size());
1655 createInfo.ppEnabledExtensionNames = enabledExtensions.data();
1656
1657 VkLayerDeviceCreateInfo* linkInfo = GetChainInfo(pCreateInfo, VK_LAYER_LINK_INFO);
1658
1659 if (linkInfo == nullptr || linkInfo->u.pLayerInfo == nullptr) {
1660 return VK_ERROR_INITIALIZATION_FAILED;
1661 }
1662 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = linkInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
1663 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = linkInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr;
1664 PFN_vkCreateDevice fpCreateDevice =
1665 (PFN_vkCreateDevice)fpGetInstanceProcAddr(gpuLayerData->instance, "vkCreateDevice");
1666 if (fpCreateDevice == nullptr) {
1667 return VK_ERROR_INITIALIZATION_FAILED;
1668 }
1669
1670 linkInfo->u.pLayerInfo = linkInfo->u.pLayerInfo->pNext;
1671
1672 result = fpCreateDevice(gpu, &createInfo, pAllocator, pDevice);
1673 if (result != VK_SUCCESS) {
1674 return result;
1675 }
1676
1677 LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(*pDevice));
1678 for (uint32_t i = 0; i < createInfo.enabledExtensionCount; i++) {
1679 auto extBit = GetExtensionBitFromName(createInfo.ppEnabledExtensionNames[i]);
1680 if (extBit != Extension::EXTENSION_UNKNOWN) {
1681 deviceLayerData->enabledExtensions.set(extBit);
1682 }
1683 }
1684
1685 deviceLayerData->deviceDispatchTable = std::make_unique<VkLayerDispatchTable>();
1686 deviceLayerData->instance = gpuLayerData->instance;
1687 deviceLayerData->device = *pDevice;
1688 layer_init_device_dispatch_table(*pDevice, deviceLayerData->deviceDispatchTable.get(), fpGetDeviceProcAddr);
1689
1690 VkLayerDeviceCreateInfo* callbackInfo = GetChainInfo(pCreateInfo, VK_LOADER_DATA_CALLBACK);
1691 if (callbackInfo == nullptr || callbackInfo->u.pfnSetDeviceLoaderData == nullptr) {
1692 return VK_ERROR_INITIALIZATION_FAILED;
1693 }
1694 deviceLayerData->fpSetDeviceLoaderData = callbackInfo->u.pfnSetDeviceLoaderData;
1695
1696 return VK_SUCCESS;
1697 }
1698
DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)1699 VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
1700 {
1701 ScopedBytrace trace(__func__);
1702 DispatchKey deviceKey = GetDispatchKey(device);
1703 LayerData* deviceData = GetLayerDataPtr(deviceKey);
1704 deviceData->deviceDispatchTable->DestroyDevice(device, pAllocator);
1705 FreeLayerDataPtr(deviceKey);
1706 }
1707
CreateDebugUtilsMessengerEXT( VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger)1708 VKAPI_ATTR VkResult VKAPI_CALL CreateDebugUtilsMessengerEXT(
1709 VkInstance instance,
1710 const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
1711 const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger)
1712 {
1713 DispatchKey instanceKey = GetDispatchKey(instance);
1714 LayerData* curLayerData = GetLayerDataPtr(instanceKey);
1715 VkResult res = curLayerData->instanceDispatchTable->CreateDebugUtilsMessengerEXT(
1716 instance, pCreateInfo, pAllocator, pMessenger);
1717 if (res == VK_SUCCESS) {
1718 curLayerData->debugCallbacks[*pMessenger] = *pCreateInfo;
1719 }
1720 return res;
1721 }
1722
DestroyDebugUtilsMessengerEXT( VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks* pAllocator)1723 VKAPI_ATTR void VKAPI_CALL DestroyDebugUtilsMessengerEXT(
1724 VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks* pAllocator)
1725 {
1726 DispatchKey instanceKey = GetDispatchKey(instance);
1727 LayerData* curLayerData = GetLayerDataPtr(instanceKey);
1728 curLayerData->debugCallbacks.erase(messenger);
1729 curLayerData->instanceDispatchTable->DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
1730 }
1731
EnumerateInstanceExtensionProperties( const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)1732 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(
1733 const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
1734 {
1735 if ((pLayerName != nullptr) && (strcmp(pLayerName, swapchainLayer.layerName) == 0)) {
1736 return GetExtensionProperties(std::size(g_instanceExtensions), g_instanceExtensions, pCount, pProperties);
1737 }
1738 return VK_ERROR_LAYER_NOT_PRESENT;
1739 }
1740
1741 // Vulkan Loader will read json and call this func
EnumerateInstanceLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties)1742 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties)
1743 {
1744 return GetLayerProperties(1, &swapchainLayer, pCount, pProperties);
1745 }
1746
EnumerateDeviceLayerProperties( VkPhysicalDevice physicalDevice, uint32_t* pCount, VkLayerProperties* pProperties)1747 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(
1748 VkPhysicalDevice physicalDevice, uint32_t* pCount, VkLayerProperties* pProperties)
1749 {
1750 return GetLayerProperties(1, &swapchainLayer, pCount, pProperties);
1751 }
1752
EnumerateDeviceExtensionProperties( VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)1753 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(
1754 VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
1755 {
1756 if ((pLayerName != nullptr) && (strcmp(pLayerName, swapchainLayer.layerName) == 0)) {
1757 return GetExtensionProperties(
1758 std::size(g_deviceExtensions), g_deviceExtensions, pCount, pProperties);
1759 }
1760
1761 if (physicalDevice == nullptr) {
1762 SWLOGE("vkEnumerateDeviceExtensionProperties physicalDevice is null.");
1763 return VK_ERROR_LAYER_NOT_PRESENT;
1764 }
1765
1766 DispatchKey key = GetDispatchKey(physicalDevice);
1767 LayerData* curLayerData = GetLayerDataPtr(key);
1768 return curLayerData->instanceDispatchTable->EnumerateDeviceExtensionProperties(physicalDevice, nullptr,
1769 pCount, pProperties);
1770 }
1771
GetPhysicalDeviceProcAddr(VkInstance instance, const char* funcName)1772 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char* funcName)
1773 {
1774 if (instance == VK_NULL_HANDLE) {
1775 SWLOGE("vkGetPhysicalDeviceProcAddr instance is null.");
1776 return nullptr;
1777 }
1778
1779 LayerData* layerData = GetLayerDataPtr(GetDispatchKey(instance));
1780 VkLayerInstanceDispatchTable* pTable = layerData->instanceDispatchTable.get();
1781
1782 if (pTable->GetPhysicalDeviceProcAddr == nullptr) {
1783 return nullptr;
1784 }
1785 return pTable->GetPhysicalDeviceProcAddr(instance, funcName);
1786 }
1787
GetDebugUtilsProc(const char* name)1788 static inline PFN_vkVoidFunction GetDebugUtilsProc(const char* name)
1789 {
1790 if (name == nullptr) {
1791 return nullptr;
1792 }
1793 if (strcmp(name, "vkCreateDebugUtilsMessengerEXT") == 0) {
1794 return reinterpret_cast<PFN_vkVoidFunction>(CreateDebugUtilsMessengerEXT);
1795 }
1796 if (strcmp(name, "vkDestroyDebugUtilsMessengerEXT") == 0) {
1797 return reinterpret_cast<PFN_vkVoidFunction>(DestroyDebugUtilsMessengerEXT);
1798 }
1799 return nullptr;
1800 }
1801
GetGlobalProc(const char* name)1802 static inline PFN_vkVoidFunction GetGlobalProc(const char* name)
1803 {
1804 if (name == nullptr) {
1805 return nullptr;
1806 }
1807 if (strcmp("vkEnumerateDeviceLayerProperties", name) == 0) {
1808 return reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties);
1809 }
1810 return nullptr;
1811 }
1812
GetSwapchainProc(const char* name)1813 static inline PFN_vkVoidFunction GetSwapchainProc(const char* name)
1814 {
1815 if (name == nullptr) {
1816 return nullptr;
1817 }
1818 if (strcmp("vkCreateSwapchainKHR", name) == 0) {
1819 return reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR);
1820 }
1821 if (strcmp("vkDestroySwapchainKHR", name) == 0) {
1822 return reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR);
1823 }
1824 if (strcmp("vkAcquireNextImageKHR", name) == 0) {
1825 return reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR);
1826 }
1827 if (strcmp("vkAcquireNextImage2KHR", name) == 0) {
1828 return reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImage2KHR);
1829 }
1830 if (strcmp("vkQueuePresentKHR", name) == 0) {
1831 return reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR);
1832 }
1833 if (strcmp("vkGetSwapchainImagesKHR", name) == 0) {
1834 return reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR);
1835 }
1836 if (strcmp("vkGetDeviceGroupPresentCapabilitiesKHR", name) == 0) {
1837 return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceGroupPresentCapabilitiesKHR);
1838 }
1839 if (strcmp("vkGetDeviceGroupSurfacePresentModesKHR", name) == 0) {
1840 return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceGroupSurfacePresentModesKHR);
1841 }
1842 if (strcmp("vkGetPhysicalDevicePresentRectanglesKHR", name) == 0) {
1843 return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDevicePresentRectanglesKHR);
1844 }
1845 return nullptr;
1846 }
1847
LayerInterceptDeviceProc( std::bitset<Extension::EXTENSION_COUNT>& enabledExtensions, const char* name)1848 static inline PFN_vkVoidFunction LayerInterceptDeviceProc(
1849 std::bitset<Extension::EXTENSION_COUNT>& enabledExtensions, const char* name)
1850 {
1851 if (name == nullptr) {
1852 return nullptr;
1853 }
1854 if (strcmp("vkGetDeviceProcAddr", name) == 0) {
1855 return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr);
1856 }
1857 if (strcmp("vkDestroyDevice", name) == 0) {
1858 return reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice);
1859 }
1860 if (enabledExtensions.test(Extension::KHR_SWAPCHAIN)) {
1861 PFN_vkVoidFunction addr = GetSwapchainProc(name);
1862 if (addr != nullptr) {
1863 return addr;
1864 }
1865 }
1866 if (enabledExtensions.test(Extension::EXT_HDR_METADATA)) {
1867 if (strcmp("vkSetHdrMetadataEXT", name) == 0) {
1868 return reinterpret_cast<PFN_vkVoidFunction>(SetHdrMetadataEXT);
1869 }
1870 }
1871 return nullptr;
1872 }
1873
GetSurfaceKHRProc(const char* name)1874 static inline PFN_vkVoidFunction GetSurfaceKHRProc(const char* name)
1875 {
1876 if (name == nullptr) {
1877 return nullptr;
1878 }
1879 if (strcmp("vkDestroySurfaceKHR", name) == 0) {
1880 return reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR);
1881 }
1882 if (strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name) == 0) {
1883 return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR);
1884 }
1885 if (strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name) == 0) {
1886 return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR);
1887 }
1888 if (strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name) == 0) {
1889 return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR);
1890 }
1891 if (strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name) == 0) {
1892 return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR);
1893 }
1894 return nullptr;
1895 }
1896
GetSurfaceCapabilities2Proc(const char* name)1897 static inline PFN_vkVoidFunction GetSurfaceCapabilities2Proc(const char* name)
1898 {
1899 if (name == nullptr) {
1900 return nullptr;
1901 }
1902 if (strcmp("vkGetPhysicalDeviceSurfaceCapabilities2KHR", name) == 0) {
1903 return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilities2KHR);
1904 }
1905 if (strcmp("vkGetPhysicalDeviceSurfaceFormats2KHR", name) == 0) {
1906 return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormats2KHR);
1907 }
1908 return nullptr;
1909 }
1910
LayerInterceptInstanceProc( std::bitset<Extension::EXTENSION_COUNT>& enabledExtensions, const char* name)1911 static inline PFN_vkVoidFunction LayerInterceptInstanceProc(
1912 std::bitset<Extension::EXTENSION_COUNT>& enabledExtensions, const char* name)
1913 {
1914 if (name == nullptr) {
1915 return nullptr;
1916 }
1917 if (enabledExtensions.test(Extension::OHOS_SURFACE)) {
1918 if (strcmp("vkCreateSurfaceOHOS", name) == 0) {
1919 return reinterpret_cast<PFN_vkVoidFunction>(CreateSurfaceOHOS);
1920 }
1921 }
1922 if (enabledExtensions.test(Extension::KHR_SURFACE)) {
1923 PFN_vkVoidFunction addr = GetSurfaceKHRProc(name);
1924 if (addr != nullptr) {
1925 return addr;
1926 }
1927 if (enabledExtensions.test(Extension::KHR_GET_SURFACE_CAPABILITIES_2)) {
1928 PFN_vkVoidFunction addr = GetSurfaceCapabilities2Proc(name);
1929 if (addr != nullptr) {
1930 return addr;
1931 }
1932 }
1933 }
1934
1935 if (enabledExtensions.test(Extension::KHR_SWAPCHAIN)) {
1936 PFN_vkVoidFunction addr = GetSwapchainProc(name);
1937 if (addr != nullptr) {
1938 return addr;
1939 }
1940 }
1941
1942 PFN_vkVoidFunction addr = GetDebugUtilsProc(name);
1943 if (addr != nullptr) {
1944 return addr;
1945 }
1946 return GetGlobalProc(name);
1947 }
1948
GetDeviceProcAddr(VkDevice device, const char* funcName)1949 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* funcName)
1950 {
1951 if (funcName == nullptr) {
1952 return nullptr;
1953 }
1954 if (device == VK_NULL_HANDLE) {
1955 SWLOGE("vkGetDeviceProcAddr device is null.");
1956 return nullptr;
1957 }
1958 LayerData* layerData = GetLayerDataPtr(GetDispatchKey(device));
1959 if (layerData == nullptr) {
1960 SWLOGE("libvulkan_swapchain GetInstanceProcAddr layerData is null");
1961 return nullptr;
1962 }
1963
1964 PFN_vkVoidFunction addr = LayerInterceptDeviceProc(layerData->enabledExtensions, funcName);
1965 if (addr != nullptr) {
1966 return addr;
1967 }
1968 LayerData* devData = GetLayerDataPtr(GetDispatchKey(device));
1969 VkLayerDispatchTable* pTable = devData->deviceDispatchTable.get();
1970 if (pTable->GetDeviceProcAddr == nullptr) {
1971 return nullptr;
1972 }
1973 return pTable->GetDeviceProcAddr(device, funcName);
1974 }
1975
GetInstanceProcAddr(VkInstance instance, const char* funcName)1976 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char* funcName)
1977 {
1978 if (funcName == nullptr) {
1979 return nullptr;
1980 }
1981
1982 if (strcmp("vkGetInstanceProcAddr", funcName) == 0) {
1983 return reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr);
1984 }
1985 if (strcmp("vkCreateInstance", funcName) == 0) {
1986 return reinterpret_cast<PFN_vkVoidFunction>(CreateInstance);
1987 }
1988 if (strcmp("vkEnumerateInstanceExtensionProperties", funcName) == 0) {
1989 return reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties);
1990 }
1991 if (strcmp("vkEnumerateInstanceLayerProperties", funcName) == 0) {
1992 return reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceLayerProperties);
1993 }
1994 if (strcmp("vkDestroyInstance", funcName) == 0) {
1995 return reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance);
1996 }
1997 if (strcmp("vkCreateDevice", funcName) == 0) {
1998 return reinterpret_cast<PFN_vkVoidFunction>(CreateDevice);
1999 }
2000 if (strcmp("vkEnumerateDeviceExtensionProperties", funcName) == 0) {
2001 return reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties);
2002 }
2003
2004 if (instance == VK_NULL_HANDLE) {
2005 SWLOGE("SwapchainLayer GetInstanceProcAddr(func name %{public}s) instance is null", funcName);
2006 return nullptr;
2007 }
2008
2009 LayerData* layerData = GetLayerDataPtr(GetDispatchKey(instance));
2010 if (layerData == nullptr) {
2011 SWLOGE("SwapchainLayer GetInstanceProcAddr layerData is null");
2012 return nullptr;
2013 }
2014
2015 PFN_vkVoidFunction addr = LayerInterceptInstanceProc(layerData->enabledExtensions, funcName);
2016 if (addr != nullptr) {
2017 return addr;
2018 }
2019
2020 VkLayerInstanceDispatchTable* pTable = layerData->instanceDispatchTable.get();
2021 if (pTable == nullptr) {
2022 SWLOGE("SwapchainLayer GetInstanceProcAddr pTable = null");
2023 return nullptr;
2024 }
2025 if (pTable->GetInstanceProcAddr == nullptr) {
2026 SWLOGE("SwapchainLayer GetInstanceProcAddr pTable->GetInstanceProcAddr = null");
2027 return nullptr;
2028 }
2029 addr = pTable->GetInstanceProcAddr(instance, funcName);
2030
2031 return addr;
2032 }
2033 } // namespace SWAPCHAIN
2034
2035 #if defined(__GNUC__) && __GNUC__ >= 4
2036 #define SWAPCHAIN_EXPORT __attribute__((visibility("default")))
2037 #else
2038 #define SWAPCHAIN_EXPORT
2039 #endif
2040
2041 extern "C" {
vkEnumerateInstanceExtensionProperties( const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)2042 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
2043 const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
2044 {
2045 return SWAPCHAIN::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
2046 }
2047
2048 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkEnumerateInstanceLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties)2049 vkEnumerateInstanceLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties)
2050 {
2051 return SWAPCHAIN::EnumerateInstanceLayerProperties(pCount, pProperties);
2052 }
2053
vkEnumerateDeviceLayerProperties( VkPhysicalDevice physicalDevice, uint32_t* pCount, VkLayerProperties* pProperties)2054 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(
2055 VkPhysicalDevice physicalDevice, uint32_t* pCount, VkLayerProperties* pProperties)
2056 {
2057 return SWAPCHAIN::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
2058 }
2059
vkEnumerateDeviceExtensionProperties( VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)2060 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(
2061 VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
2062 {
2063 return SWAPCHAIN::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
2064 }
2065
vkGetDeviceProcAddr(VkDevice dev, const char* funcName)2066 SWAPCHAIN_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char* funcName)
2067 {
2068 return SWAPCHAIN::GetDeviceProcAddr(dev, funcName);
2069 }
2070
2071 SWAPCHAIN_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
vkGetInstanceProcAddr(VkInstance instance, const char* funcName)2072 vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
2073 {
2074 return SWAPCHAIN::GetInstanceProcAddr(instance, funcName);
2075 }
2076 }