1/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// WARNING: This file is generated. See ../README.md for instructions.
18
19#include <string.h>
20
21#include <algorithm>
22
23#include <log/log.h>
24
25#include "driver.h"
26
27namespace vulkan {
28namespace driver {
29
30namespace {
31
32// clang-format off
33
34VKAPI_ATTR VkResult checkedCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) {
35    if (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) {
36        return CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
37    } else {
38        Logger(device).Err(device, "VK_KHR_swapchain not enabled. vkCreateSwapchainKHR not executed.");
39        return VK_SUCCESS;
40    }
41}
42
43VKAPI_ATTR void checkedDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator) {
44    if (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) {
45        DestroySwapchainKHR(device, swapchain, pAllocator);
46    } else {
47        Logger(device).Err(device, "VK_KHR_swapchain not enabled. vkDestroySwapchainKHR not executed.");
48    }
49}
50
51VKAPI_ATTR VkResult checkedGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages) {
52    if (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) {
53        return GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
54    } else {
55        Logger(device).Err(device, "VK_KHR_swapchain not enabled. vkGetSwapchainImagesKHR not executed.");
56        return VK_SUCCESS;
57    }
58}
59
60VKAPI_ATTR VkResult checkedAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex) {
61    if (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) {
62        return AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
63    } else {
64        Logger(device).Err(device, "VK_KHR_swapchain not enabled. vkAcquireNextImageKHR not executed.");
65        return VK_SUCCESS;
66    }
67}
68
69VKAPI_ATTR VkResult checkedQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPresentInfo) {
70    if (GetData(queue).hook_extensions[ProcHook::KHR_swapchain]) {
71        return QueuePresentKHR(queue, pPresentInfo);
72    } else {
73        Logger(queue).Err(queue, "VK_KHR_swapchain not enabled. vkQueuePresentKHR not executed.");
74        return VK_SUCCESS;
75    }
76}
77
78VKAPI_ATTR VkResult checkedGetRefreshCycleDurationGOOGLE(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) {
79    if (GetData(device).hook_extensions[ProcHook::GOOGLE_display_timing]) {
80        return GetRefreshCycleDurationGOOGLE(device, swapchain, pDisplayTimingProperties);
81    } else {
82        Logger(device).Err(device, "VK_GOOGLE_display_timing not enabled. vkGetRefreshCycleDurationGOOGLE not executed.");
83        return VK_SUCCESS;
84    }
85}
86
87VKAPI_ATTR VkResult checkedGetPastPresentationTimingGOOGLE(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings) {
88    if (GetData(device).hook_extensions[ProcHook::GOOGLE_display_timing]) {
89        return GetPastPresentationTimingGOOGLE(device, swapchain, pPresentationTimingCount, pPresentationTimings);
90    } else {
91        Logger(device).Err(device, "VK_GOOGLE_display_timing not enabled. vkGetPastPresentationTimingGOOGLE not executed.");
92        return VK_SUCCESS;
93    }
94}
95
96VKAPI_ATTR void checkedSetHdrMetadataEXT(VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pMetadata) {
97    if (GetData(device).hook_extensions[ProcHook::EXT_hdr_metadata]) {
98        SetHdrMetadataEXT(device, swapchainCount, pSwapchains, pMetadata);
99    } else {
100        Logger(device).Err(device, "VK_EXT_hdr_metadata not enabled. vkSetHdrMetadataEXT not executed.");
101    }
102}
103
104VKAPI_ATTR VkResult checkedGetSwapchainStatusKHR(VkDevice device, VkSwapchainKHR swapchain) {
105    if (GetData(device).hook_extensions[ProcHook::KHR_shared_presentable_image]) {
106        return GetSwapchainStatusKHR(device, swapchain);
107    } else {
108        Logger(device).Err(device, "VK_KHR_shared_presentable_image not enabled. vkGetSwapchainStatusKHR not executed.");
109        return VK_SUCCESS;
110    }
111}
112
113// clang-format on
114
115const ProcHook g_proc_hooks[] = {
116    // clang-format off
117    {
118        "vkAcquireImageANDROID",
119        ProcHook::DEVICE,
120        ProcHook::ANDROID_native_buffer,
121        nullptr,
122        nullptr,
123    },
124    {
125        "vkAcquireNextImageKHR",
126        ProcHook::DEVICE,
127        ProcHook::KHR_swapchain,
128        reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR),
129        reinterpret_cast<PFN_vkVoidFunction>(checkedAcquireNextImageKHR),
130    },
131    {
132        "vkAllocateCommandBuffers",
133        ProcHook::DEVICE,
134        ProcHook::EXTENSION_CORE,
135        reinterpret_cast<PFN_vkVoidFunction>(AllocateCommandBuffers),
136        nullptr,
137    },
138    {
139        "vkCreateAndroidSurfaceKHR",
140        ProcHook::INSTANCE,
141        ProcHook::KHR_android_surface,
142        reinterpret_cast<PFN_vkVoidFunction>(CreateAndroidSurfaceKHR),
143        nullptr,
144    },
145    {
146        "vkCreateDebugReportCallbackEXT",
147        ProcHook::INSTANCE,
148        ProcHook::EXT_debug_report,
149        reinterpret_cast<PFN_vkVoidFunction>(CreateDebugReportCallbackEXT),
150        nullptr,
151    },
152    {
153        "vkCreateDevice",
154        ProcHook::INSTANCE,
155        ProcHook::EXTENSION_CORE,
156        reinterpret_cast<PFN_vkVoidFunction>(CreateDevice),
157        nullptr,
158    },
159    {
160        "vkCreateInstance",
161        ProcHook::GLOBAL,
162        ProcHook::EXTENSION_CORE,
163        reinterpret_cast<PFN_vkVoidFunction>(CreateInstance),
164        nullptr,
165    },
166    {
167        "vkCreateSwapchainKHR",
168        ProcHook::DEVICE,
169        ProcHook::KHR_swapchain,
170        reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR),
171        reinterpret_cast<PFN_vkVoidFunction>(checkedCreateSwapchainKHR),
172    },
173    {
174        "vkDebugReportMessageEXT",
175        ProcHook::INSTANCE,
176        ProcHook::EXT_debug_report,
177        reinterpret_cast<PFN_vkVoidFunction>(DebugReportMessageEXT),
178        nullptr,
179    },
180    {
181        "vkDestroyDebugReportCallbackEXT",
182        ProcHook::INSTANCE,
183        ProcHook::EXT_debug_report,
184        reinterpret_cast<PFN_vkVoidFunction>(DestroyDebugReportCallbackEXT),
185        nullptr,
186    },
187    {
188        "vkDestroyDevice",
189        ProcHook::DEVICE,
190        ProcHook::EXTENSION_CORE,
191        reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice),
192        nullptr,
193    },
194    {
195        "vkDestroyInstance",
196        ProcHook::INSTANCE,
197        ProcHook::EXTENSION_CORE,
198        reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance),
199        nullptr,
200    },
201    {
202        "vkDestroySurfaceKHR",
203        ProcHook::INSTANCE,
204        ProcHook::KHR_surface,
205        reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR),
206        nullptr,
207    },
208    {
209        "vkDestroySwapchainKHR",
210        ProcHook::DEVICE,
211        ProcHook::KHR_swapchain,
212        reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR),
213        reinterpret_cast<PFN_vkVoidFunction>(checkedDestroySwapchainKHR),
214    },
215    {
216        "vkEnumerateDeviceExtensionProperties",
217        ProcHook::INSTANCE,
218        ProcHook::EXTENSION_CORE,
219        reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties),
220        nullptr,
221    },
222    {
223        "vkEnumerateInstanceExtensionProperties",
224        ProcHook::GLOBAL,
225        ProcHook::EXTENSION_CORE,
226        reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties),
227        nullptr,
228    },
229    {
230        "vkEnumeratePhysicalDevices",
231        ProcHook::INSTANCE,
232        ProcHook::EXTENSION_CORE,
233        reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices),
234        nullptr,
235    },
236    {
237        "vkGetDeviceProcAddr",
238        ProcHook::DEVICE,
239        ProcHook::EXTENSION_CORE,
240        reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr),
241        nullptr,
242    },
243    {
244        "vkGetDeviceQueue",
245        ProcHook::DEVICE,
246        ProcHook::EXTENSION_CORE,
247        reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue),
248        nullptr,
249    },
250    {
251        "vkGetInstanceProcAddr",
252        ProcHook::INSTANCE,
253        ProcHook::EXTENSION_CORE,
254        reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr),
255        nullptr,
256    },
257    {
258        "vkGetPastPresentationTimingGOOGLE",
259        ProcHook::DEVICE,
260        ProcHook::GOOGLE_display_timing,
261        reinterpret_cast<PFN_vkVoidFunction>(GetPastPresentationTimingGOOGLE),
262        reinterpret_cast<PFN_vkVoidFunction>(checkedGetPastPresentationTimingGOOGLE),
263    },
264    {
265        "vkGetPhysicalDeviceSurfaceCapabilities2KHR",
266        ProcHook::INSTANCE,
267        ProcHook::KHR_get_surface_capabilities2,
268        reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilities2KHR),
269        nullptr,
270    },
271    {
272        "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
273        ProcHook::INSTANCE,
274        ProcHook::KHR_surface,
275        reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR),
276        nullptr,
277    },
278    {
279        "vkGetPhysicalDeviceSurfaceFormats2KHR",
280        ProcHook::INSTANCE,
281        ProcHook::KHR_get_surface_capabilities2,
282        reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormats2KHR),
283        nullptr,
284    },
285    {
286        "vkGetPhysicalDeviceSurfaceFormatsKHR",
287        ProcHook::INSTANCE,
288        ProcHook::KHR_surface,
289        reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR),
290        nullptr,
291    },
292    {
293        "vkGetPhysicalDeviceSurfacePresentModesKHR",
294        ProcHook::INSTANCE,
295        ProcHook::KHR_surface,
296        reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR),
297        nullptr,
298    },
299    {
300        "vkGetPhysicalDeviceSurfaceSupportKHR",
301        ProcHook::INSTANCE,
302        ProcHook::KHR_surface,
303        reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR),
304        nullptr,
305    },
306    {
307        "vkGetRefreshCycleDurationGOOGLE",
308        ProcHook::DEVICE,
309        ProcHook::GOOGLE_display_timing,
310        reinterpret_cast<PFN_vkVoidFunction>(GetRefreshCycleDurationGOOGLE),
311        reinterpret_cast<PFN_vkVoidFunction>(checkedGetRefreshCycleDurationGOOGLE),
312    },
313    {
314        "vkGetSwapchainGrallocUsage2ANDROID",
315        ProcHook::DEVICE,
316        ProcHook::ANDROID_native_buffer,
317        nullptr,
318        nullptr,
319    },
320    {
321        "vkGetSwapchainGrallocUsageANDROID",
322        ProcHook::DEVICE,
323        ProcHook::ANDROID_native_buffer,
324        nullptr,
325        nullptr,
326    },
327    {
328        "vkGetSwapchainImagesKHR",
329        ProcHook::DEVICE,
330        ProcHook::KHR_swapchain,
331        reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR),
332        reinterpret_cast<PFN_vkVoidFunction>(checkedGetSwapchainImagesKHR),
333    },
334    {
335        "vkGetSwapchainStatusKHR",
336        ProcHook::DEVICE,
337        ProcHook::KHR_shared_presentable_image,
338        reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainStatusKHR),
339        reinterpret_cast<PFN_vkVoidFunction>(checkedGetSwapchainStatusKHR),
340    },
341    {
342        "vkQueuePresentKHR",
343        ProcHook::DEVICE,
344        ProcHook::KHR_swapchain,
345        reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR),
346        reinterpret_cast<PFN_vkVoidFunction>(checkedQueuePresentKHR),
347    },
348    {
349        "vkQueueSignalReleaseImageANDROID",
350        ProcHook::DEVICE,
351        ProcHook::ANDROID_native_buffer,
352        nullptr,
353        nullptr,
354    },
355    {
356        "vkSetHdrMetadataEXT",
357        ProcHook::DEVICE,
358        ProcHook::EXT_hdr_metadata,
359        reinterpret_cast<PFN_vkVoidFunction>(SetHdrMetadataEXT),
360        reinterpret_cast<PFN_vkVoidFunction>(checkedSetHdrMetadataEXT),
361    },
362    // clang-format on
363};
364
365}  // namespace
366
367const ProcHook* GetProcHook(const char* name) {
368    const auto& begin = g_proc_hooks;
369    const auto& end =
370        g_proc_hooks + sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]);
371    const auto hook = std::lower_bound(
372        begin, end, name,
373        [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; });
374    return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr;
375}
376
377ProcHook::Extension GetProcHookExtension(const char* name) {
378    // clang-format off
379    if (strcmp(name, "VK_ANDROID_native_buffer") == 0) return ProcHook::ANDROID_native_buffer;
380    if (strcmp(name, "VK_EXT_debug_report") == 0) return ProcHook::EXT_debug_report;
381    if (strcmp(name, "VK_EXT_hdr_metadata") == 0) return ProcHook::EXT_hdr_metadata;
382    if (strcmp(name, "VK_EXT_swapchain_colorspace") == 0) return ProcHook::EXT_swapchain_colorspace;
383    if (strcmp(name, "VK_GOOGLE_display_timing") == 0) return ProcHook::GOOGLE_display_timing;
384    if (strcmp(name, "VK_KHR_android_surface") == 0) return ProcHook::KHR_android_surface;
385    if (strcmp(name, "VK_KHR_incremental_present") == 0) return ProcHook::KHR_incremental_present;
386    if (strcmp(name, "VK_KHR_shared_presentable_image") == 0) return ProcHook::KHR_shared_presentable_image;
387    if (strcmp(name, "VK_KHR_surface") == 0) return ProcHook::KHR_surface;
388    if (strcmp(name, "VK_KHR_swapchain") == 0) return ProcHook::KHR_swapchain;
389    if (strcmp(name, "VK_KHR_get_surface_capabilities2") == 0) return ProcHook::KHR_get_surface_capabilities2;
390    if (strcmp(name, "VK_KHR_get_physical_device_properties2") == 0) return ProcHook::KHR_get_physical_device_properties2;
391    // clang-format on
392    return ProcHook::EXTENSION_UNKNOWN;
393}
394
395#define UNLIKELY(expr) __builtin_expect((expr), 0)
396
397#define INIT_PROC(required, obj, proc)                                 \
398    do {                                                               \
399        data.driver.proc =                                             \
400            reinterpret_cast<PFN_vk##proc>(get_proc(obj, "vk" #proc)); \
401        if (UNLIKELY(required && !data.driver.proc)) {                 \
402            ALOGE("missing " #obj " proc: vk" #proc);                  \
403            success = false;                                           \
404        }                                                              \
405    } while (0)
406
407#define INIT_PROC_EXT(ext, required, obj, proc) \
408    do {                                        \
409        if (extensions[ProcHook::ext])          \
410            INIT_PROC(required, obj, proc);     \
411    } while (0)
412
413bool InitDriverTable(VkInstance instance,
414                     PFN_vkGetInstanceProcAddr get_proc,
415                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
416    auto& data = GetData(instance);
417    bool success = true;
418
419    // clang-format off
420    INIT_PROC(true, instance, DestroyInstance);
421    INIT_PROC(true, instance, EnumeratePhysicalDevices);
422    INIT_PROC(true, instance, GetInstanceProcAddr);
423    INIT_PROC(true, instance, GetPhysicalDeviceProperties);
424    INIT_PROC(true, instance, CreateDevice);
425    INIT_PROC(true, instance, EnumerateDeviceExtensionProperties);
426    INIT_PROC_EXT(EXT_debug_report, true, instance, CreateDebugReportCallbackEXT);
427    INIT_PROC_EXT(EXT_debug_report, true, instance, DestroyDebugReportCallbackEXT);
428    INIT_PROC_EXT(EXT_debug_report, true, instance, DebugReportMessageEXT);
429    INIT_PROC_EXT(KHR_get_physical_device_properties2, true, instance, GetPhysicalDeviceProperties2KHR);
430    // clang-format on
431
432    return success;
433}
434
435bool InitDriverTable(VkDevice dev,
436                     PFN_vkGetDeviceProcAddr get_proc,
437                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
438    auto& data = GetData(dev);
439    bool success = true;
440
441    // clang-format off
442    INIT_PROC(true, dev, GetDeviceProcAddr);
443    INIT_PROC(true, dev, DestroyDevice);
444    INIT_PROC(true, dev, GetDeviceQueue);
445    INIT_PROC(true, dev, CreateImage);
446    INIT_PROC(true, dev, DestroyImage);
447    INIT_PROC(true, dev, AllocateCommandBuffers);
448    INIT_PROC_EXT(ANDROID_native_buffer, false, dev, GetSwapchainGrallocUsageANDROID);
449    INIT_PROC_EXT(ANDROID_native_buffer, false, dev, GetSwapchainGrallocUsage2ANDROID);
450    INIT_PROC_EXT(ANDROID_native_buffer, true, dev, AcquireImageANDROID);
451    INIT_PROC_EXT(ANDROID_native_buffer, true, dev, QueueSignalReleaseImageANDROID);
452    // clang-format on
453
454    return success;
455}
456
457}  // namespace driver
458}  // namespace vulkan
459
460// clang-format on
461