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