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#include <algorithm>
21#include <log/log.h>
22
23#include "driver.h"
24
25namespace vulkan {
26namespace driver {
27
28namespace {
29
30// clang-format off
31
32VKAPI_ATTR VkResult checkedCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) {
33    if (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) {
34        return CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
35    } else {
36        Logger(device).Err(device, "VK_KHR_swapchain not enabled. vkCreateSwapchainKHR not executed.");
37        return VK_SUCCESS;
38    }
39}
40
41VKAPI_ATTR void checkedDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator) {
42    if (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) {
43        DestroySwapchainKHR(device, swapchain, pAllocator);
44    } else {
45        Logger(device).Err(device, "VK_KHR_swapchain not enabled. vkDestroySwapchainKHR not executed.");
46    }
47}
48
49VKAPI_ATTR VkResult checkedGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages) {
50    if (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) {
51        return GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
52    } else {
53        Logger(device).Err(device, "VK_KHR_swapchain not enabled. vkGetSwapchainImagesKHR not executed.");
54        return VK_SUCCESS;
55    }
56}
57
58VKAPI_ATTR VkResult checkedAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex) {
59    if (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) {
60        return AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
61    } else {
62        Logger(device).Err(device, "VK_KHR_swapchain not enabled. vkAcquireNextImageKHR not executed.");
63        return VK_SUCCESS;
64    }
65}
66
67VKAPI_ATTR VkResult checkedQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPresentInfo) {
68    if (GetData(queue).hook_extensions[ProcHook::KHR_swapchain]) {
69        return QueuePresentKHR(queue, pPresentInfo);
70    } else {
71        Logger(queue).Err(queue, "VK_KHR_swapchain not enabled. vkQueuePresentKHR not executed.");
72        return VK_SUCCESS;
73    }
74}
75
76// clang-format on
77
78const ProcHook g_proc_hooks[] = {
79    // clang-format off
80    {
81        "vkAcquireImageANDROID",
82        ProcHook::DEVICE,
83        ProcHook::ANDROID_native_buffer,
84        nullptr,
85        nullptr,
86    },
87    {
88        "vkAcquireNextImageKHR",
89        ProcHook::DEVICE,
90        ProcHook::KHR_swapchain,
91        reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR),
92        reinterpret_cast<PFN_vkVoidFunction>(checkedAcquireNextImageKHR),
93    },
94    {
95        "vkAllocateCommandBuffers",
96        ProcHook::DEVICE,
97        ProcHook::EXTENSION_CORE,
98        reinterpret_cast<PFN_vkVoidFunction>(AllocateCommandBuffers),
99        nullptr,
100    },
101    {
102        "vkCreateAndroidSurfaceKHR",
103        ProcHook::INSTANCE,
104        ProcHook::KHR_android_surface,
105        reinterpret_cast<PFN_vkVoidFunction>(CreateAndroidSurfaceKHR),
106        nullptr,
107    },
108    {
109        "vkCreateDebugReportCallbackEXT",
110        ProcHook::INSTANCE,
111        ProcHook::EXT_debug_report,
112        reinterpret_cast<PFN_vkVoidFunction>(CreateDebugReportCallbackEXT),
113        nullptr,
114    },
115    {
116        "vkCreateDevice",
117        ProcHook::INSTANCE,
118        ProcHook::EXTENSION_CORE,
119        reinterpret_cast<PFN_vkVoidFunction>(CreateDevice),
120        nullptr,
121    },
122    {
123        "vkCreateInstance",
124        ProcHook::GLOBAL,
125        ProcHook::EXTENSION_CORE,
126        reinterpret_cast<PFN_vkVoidFunction>(CreateInstance),
127        nullptr,
128    },
129    {
130        "vkCreateSwapchainKHR",
131        ProcHook::DEVICE,
132        ProcHook::KHR_swapchain,
133        reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR),
134        reinterpret_cast<PFN_vkVoidFunction>(checkedCreateSwapchainKHR),
135    },
136    {
137        "vkDebugReportMessageEXT",
138        ProcHook::INSTANCE,
139        ProcHook::EXT_debug_report,
140        reinterpret_cast<PFN_vkVoidFunction>(DebugReportMessageEXT),
141        nullptr,
142    },
143    {
144        "vkDestroyDebugReportCallbackEXT",
145        ProcHook::INSTANCE,
146        ProcHook::EXT_debug_report,
147        reinterpret_cast<PFN_vkVoidFunction>(DestroyDebugReportCallbackEXT),
148        nullptr,
149    },
150    {
151        "vkDestroyDevice",
152        ProcHook::DEVICE,
153        ProcHook::EXTENSION_CORE,
154        reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice),
155        nullptr,
156    },
157    {
158        "vkDestroyInstance",
159        ProcHook::INSTANCE,
160        ProcHook::EXTENSION_CORE,
161        reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance),
162        nullptr,
163    },
164    {
165        "vkDestroySurfaceKHR",
166        ProcHook::INSTANCE,
167        ProcHook::KHR_surface,
168        reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR),
169        nullptr,
170    },
171    {
172        "vkDestroySwapchainKHR",
173        ProcHook::DEVICE,
174        ProcHook::KHR_swapchain,
175        reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR),
176        reinterpret_cast<PFN_vkVoidFunction>(checkedDestroySwapchainKHR),
177    },
178    {
179        "vkEnumerateDeviceExtensionProperties",
180        ProcHook::INSTANCE,
181        ProcHook::EXTENSION_CORE,
182        reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties),
183        nullptr,
184    },
185    {
186        "vkEnumerateInstanceExtensionProperties",
187        ProcHook::GLOBAL,
188        ProcHook::EXTENSION_CORE,
189        reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties),
190        nullptr,
191    },
192    {
193        "vkEnumeratePhysicalDevices",
194        ProcHook::INSTANCE,
195        ProcHook::EXTENSION_CORE,
196        reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices),
197        nullptr,
198    },
199    {
200        "vkGetDeviceProcAddr",
201        ProcHook::DEVICE,
202        ProcHook::EXTENSION_CORE,
203        reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr),
204        nullptr,
205    },
206    {
207        "vkGetDeviceQueue",
208        ProcHook::DEVICE,
209        ProcHook::EXTENSION_CORE,
210        reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue),
211        nullptr,
212    },
213    {
214        "vkGetInstanceProcAddr",
215        ProcHook::INSTANCE,
216        ProcHook::EXTENSION_CORE,
217        reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr),
218        nullptr,
219    },
220    {
221        "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
222        ProcHook::INSTANCE,
223        ProcHook::KHR_surface,
224        reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR),
225        nullptr,
226    },
227    {
228        "vkGetPhysicalDeviceSurfaceFormatsKHR",
229        ProcHook::INSTANCE,
230        ProcHook::KHR_surface,
231        reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR),
232        nullptr,
233    },
234    {
235        "vkGetPhysicalDeviceSurfacePresentModesKHR",
236        ProcHook::INSTANCE,
237        ProcHook::KHR_surface,
238        reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR),
239        nullptr,
240    },
241    {
242        "vkGetPhysicalDeviceSurfaceSupportKHR",
243        ProcHook::INSTANCE,
244        ProcHook::KHR_surface,
245        reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR),
246        nullptr,
247    },
248    {
249        "vkGetSwapchainGrallocUsageANDROID",
250        ProcHook::DEVICE,
251        ProcHook::ANDROID_native_buffer,
252        nullptr,
253        nullptr,
254    },
255    {
256        "vkGetSwapchainImagesKHR",
257        ProcHook::DEVICE,
258        ProcHook::KHR_swapchain,
259        reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR),
260        reinterpret_cast<PFN_vkVoidFunction>(checkedGetSwapchainImagesKHR),
261    },
262    {
263        "vkQueuePresentKHR",
264        ProcHook::DEVICE,
265        ProcHook::KHR_swapchain,
266        reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR),
267        reinterpret_cast<PFN_vkVoidFunction>(checkedQueuePresentKHR),
268    },
269    {
270        "vkQueueSignalReleaseImageANDROID",
271        ProcHook::DEVICE,
272        ProcHook::ANDROID_native_buffer,
273        nullptr,
274        nullptr,
275    },
276    // clang-format on
277};
278
279}  // anonymous
280
281const ProcHook* GetProcHook(const char* name) {
282    const auto& begin = g_proc_hooks;
283    const auto& end =
284        g_proc_hooks + sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]);
285    const auto hook = std::lower_bound(
286        begin, end, name,
287        [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; });
288    return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr;
289}
290
291ProcHook::Extension GetProcHookExtension(const char* name) {
292    // clang-format off
293    if (strcmp(name, "VK_ANDROID_native_buffer") == 0) return ProcHook::ANDROID_native_buffer;
294    if (strcmp(name, "VK_EXT_debug_report") == 0) return ProcHook::EXT_debug_report;
295    if (strcmp(name, "VK_KHR_android_surface") == 0) return ProcHook::KHR_android_surface;
296    if (strcmp(name, "VK_KHR_surface") == 0) return ProcHook::KHR_surface;
297    if (strcmp(name, "VK_KHR_swapchain") == 0) return ProcHook::KHR_swapchain;
298    // clang-format on
299    return ProcHook::EXTENSION_UNKNOWN;
300}
301
302#define UNLIKELY(expr) __builtin_expect((expr), 0)
303
304#define INIT_PROC(obj, proc)                                           \
305    do {                                                               \
306        data.driver.proc =                                             \
307            reinterpret_cast<PFN_vk##proc>(get_proc(obj, "vk" #proc)); \
308        if (UNLIKELY(!data.driver.proc)) {                             \
309            ALOGE("missing " #obj " proc: vk" #proc);                  \
310            success = false;                                           \
311        }                                                              \
312    } while (0)
313
314#define INIT_PROC_EXT(ext, obj, proc)  \
315    do {                               \
316        if (extensions[ProcHook::ext]) \
317            INIT_PROC(obj, proc);      \
318    } while (0)
319
320bool InitDriverTable(VkInstance instance,
321                     PFN_vkGetInstanceProcAddr get_proc,
322                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
323    auto& data = GetData(instance);
324    bool success = true;
325
326    // clang-format off
327    INIT_PROC(instance, DestroyInstance);
328    INIT_PROC(instance, EnumeratePhysicalDevices);
329    INIT_PROC(instance, GetInstanceProcAddr);
330    INIT_PROC(instance, CreateDevice);
331    INIT_PROC(instance, EnumerateDeviceExtensionProperties);
332    INIT_PROC_EXT(EXT_debug_report, instance, CreateDebugReportCallbackEXT);
333    INIT_PROC_EXT(EXT_debug_report, instance, DestroyDebugReportCallbackEXT);
334    INIT_PROC_EXT(EXT_debug_report, instance, DebugReportMessageEXT);
335    // clang-format on
336
337    return success;
338}
339
340bool InitDriverTable(VkDevice dev,
341                     PFN_vkGetDeviceProcAddr get_proc,
342                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
343    auto& data = GetData(dev);
344    bool success = true;
345
346    // clang-format off
347    INIT_PROC(dev, GetDeviceProcAddr);
348    INIT_PROC(dev, DestroyDevice);
349    INIT_PROC(dev, GetDeviceQueue);
350    INIT_PROC(dev, CreateImage);
351    INIT_PROC(dev, DestroyImage);
352    INIT_PROC(dev, AllocateCommandBuffers);
353    INIT_PROC_EXT(ANDROID_native_buffer, dev, GetSwapchainGrallocUsageANDROID);
354    INIT_PROC_EXT(ANDROID_native_buffer, dev, AcquireImageANDROID);
355    INIT_PROC_EXT(ANDROID_native_buffer, dev, QueueSignalReleaseImageANDROID);
356    // clang-format on
357
358    return success;
359}
360
361}  // namespace driver
362}  // namespace vulkan
363
364// clang-format on
365