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