blob: 5fff83efca47477f7f93edbd02cd166aebce19de [file] [log] [blame]
Adithya Srinivasan01364142019-07-02 15:52:49 -07001#!/usr/bin/env python3
2#
3# Copyright 2019 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17# This script provides the functions for generating the
18# vulkan driver framework directly from the vulkan registry (vk.xml).
19
Adithya Srinivasan01364142019-07-02 15:52:49 -070020import os
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070021import generator_common as gencom
Adithya Srinivasan01364142019-07-02 15:52:49 -070022
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070023_INTERCEPTED_EXTENSIONS = [
24 'VK_ANDROID_native_buffer',
25 'VK_EXT_debug_report',
26 'VK_EXT_hdr_metadata',
27 'VK_EXT_swapchain_colorspace',
28 'VK_GOOGLE_display_timing',
29 'VK_KHR_android_surface',
30 'VK_KHR_get_surface_capabilities2',
31 'VK_KHR_incremental_present',
32 'VK_KHR_shared_presentable_image',
33 'VK_KHR_surface',
34 'VK_KHR_swapchain',
Adithya Srinivasan01364142019-07-02 15:52:49 -070035]
36
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070037_KNOWN_EXTENSIONS = _INTERCEPTED_EXTENSIONS + [
38 'VK_ANDROID_external_memory_android_hardware_buffer',
39 'VK_KHR_bind_memory2',
40 'VK_KHR_get_physical_device_properties2',
Adithya Srinivasan01364142019-07-02 15:52:49 -070041]
42
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070043_NEEDED_COMMANDS = [
44 # Create functions of dispatchable objects
45 'vkCreateDevice',
46 'vkGetDeviceQueue',
47 'vkGetDeviceQueue2',
48 'vkAllocateCommandBuffers',
49
50 # Destroy functions of dispatchable objects
51 'vkDestroyInstance',
52 'vkDestroyDevice',
53
54 # Enumeration of extensions
55 'vkEnumerateDeviceExtensionProperties',
56
57 # We cache physical devices in loader.cpp
58 'vkEnumeratePhysicalDevices',
59 'vkEnumeratePhysicalDeviceGroups',
60
61 'vkGetInstanceProcAddr',
62 'vkGetDeviceProcAddr',
63
64 'vkQueueSubmit',
65
66 # VK_KHR_swapchain->VK_ANDROID_native_buffer translation
67 'vkCreateImage',
68 'vkDestroyImage',
69
70 'vkGetPhysicalDeviceProperties',
71 'vkGetPhysicalDeviceProperties2',
72 'vkGetPhysicalDeviceProperties2KHR',
73
74 # VK_KHR_swapchain v69 requirement
75 'vkBindImageMemory2',
76 'vkBindImageMemory2KHR',
77]
78
79_INTERCEPTED_COMMANDS = [
80 # Create functions of dispatchable objects
81 'vkCreateInstance',
82 'vkCreateDevice',
83 'vkEnumeratePhysicalDevices',
84 'vkEnumeratePhysicalDeviceGroups',
85 'vkGetDeviceQueue',
86 'vkGetDeviceQueue2',
87 'vkAllocateCommandBuffers',
88
89 # Destroy functions of dispatchable objects
90 'vkDestroyInstance',
91 'vkDestroyDevice',
92
93 # Enumeration of extensions
94 'vkEnumerateInstanceExtensionProperties',
95 'vkEnumerateDeviceExtensionProperties',
96
97 'vkGetInstanceProcAddr',
98 'vkGetDeviceProcAddr',
99
100 'vkQueueSubmit',
101
102 # VK_KHR_swapchain v69 requirement
103 'vkBindImageMemory2',
104 'vkBindImageMemory2KHR',
105]
106
107
108def _is_driver_table_entry(cmd):
109 if gencom.is_function_supported(cmd):
110 if cmd in _NEEDED_COMMANDS:
111 return True
112 if cmd in gencom.extension_dict:
113 if (gencom.extension_dict[cmd] == 'VK_ANDROID_native_buffer' or
114 gencom.extension_dict[cmd] == 'VK_EXT_debug_report'):
115 return True
116 return False
117
118
119def _is_instance_driver_table_entry(cmd):
120 return (_is_driver_table_entry(cmd) and
121 gencom.is_instance_dispatched(cmd))
122
123
124def _is_device_driver_table_entry(cmd):
125 return (_is_driver_table_entry(cmd) and
126 gencom.is_device_dispatched(cmd))
127
128
129def gen_h():
130 genfile = os.path.join(os.path.dirname(__file__),
131 '..', 'libvulkan', 'driver_gen.h')
132
133 with open(genfile, 'w') as f:
134 f.write(gencom.copyright_and_warning(2016))
135
136 f.write("""\
137#ifndef LIBVULKAN_DRIVER_GEN_H
138#define LIBVULKAN_DRIVER_GEN_H
139
140#include <vulkan/vk_android_native_buffer.h>
141#include <vulkan/vulkan.h>
142
143#include <bitset>
144
145namespace vulkan {
146namespace driver {
147
148struct ProcHook {
Adithya Srinivasan01364142019-07-02 15:52:49 -0700149 enum Type {
150 GLOBAL,
151 INSTANCE,
152 DEVICE,
153 };
154 enum Extension {\n""")
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700155
156 for exts in _KNOWN_EXTENSIONS:
157 f.write(gencom.indent(2) + exts[3:] + ',\n')
158
159 f.write("""
160 EXTENSION_CORE, // valid bit
Adithya Srinivasan01364142019-07-02 15:52:49 -0700161 EXTENSION_COUNT,
162 EXTENSION_UNKNOWN,
163 };
164
165 const char* name;
166 Type type;
167 Extension extension;
168
169 PFN_vkVoidFunction proc;
170 PFN_vkVoidFunction checked_proc; // always nullptr for non-device hooks
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700171};
Adithya Srinivasan01364142019-07-02 15:52:49 -0700172
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700173struct InstanceDriverTable {
174 // clang-format off\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700175
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700176 for cmd in gencom.command_list:
177 if _is_instance_driver_table_entry(cmd):
178 f.write(gencom.indent(1) + 'PFN_' + cmd + ' ' +
179 gencom.base_name(cmd) + ';\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700180
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700181 f.write("""\
182 // clang-format on
183};
Adithya Srinivasan01364142019-07-02 15:52:49 -0700184
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700185struct DeviceDriverTable {
186 // clang-format off\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700187
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700188 for cmd in gencom.command_list:
189 if _is_device_driver_table_entry(cmd):
190 f.write(gencom.indent(1) + 'PFN_' + cmd + ' ' +
191 gencom.base_name(cmd) + ';\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700192
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700193 f.write("""\
194 // clang-format on
195};
Adithya Srinivasan01364142019-07-02 15:52:49 -0700196
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700197const ProcHook* GetProcHook(const char* name);
Adithya Srinivasan01364142019-07-02 15:52:49 -0700198ProcHook::Extension GetProcHookExtension(const char* name);
199
200bool InitDriverTable(VkInstance instance,
201 PFN_vkGetInstanceProcAddr get_proc,
202 const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);
203bool InitDriverTable(VkDevice dev,
204 PFN_vkGetDeviceProcAddr get_proc,
205 const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);
206
207} // namespace driver
208} // namespace vulkan
209
210#endif // LIBVULKAN_DRIVER_TABLE_H\n""")
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700211
Adithya Srinivasan8dce9d72019-07-11 14:26:04 -0700212 f.close()
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700213 gencom.run_clang_format(genfile)
Adithya Srinivasan01364142019-07-02 15:52:49 -0700214
Adithya Srinivasan01364142019-07-02 15:52:49 -0700215
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700216def _is_intercepted(cmd):
217 if gencom.is_function_supported(cmd):
218 if cmd in _INTERCEPTED_COMMANDS:
219 return True
Adithya Srinivasan01364142019-07-02 15:52:49 -0700220
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700221 if cmd in gencom.extension_dict:
222 return gencom.extension_dict[cmd] in _INTERCEPTED_EXTENSIONS
Adithya Srinivasan01364142019-07-02 15:52:49 -0700223 return False
224
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700225
226def _need_proc_hook_stub(cmd):
227 if _is_intercepted(cmd) and gencom.is_device_dispatched(cmd):
228 if cmd in gencom.extension_dict:
229 if not gencom.is_extension_internal(gencom.extension_dict[cmd]):
Adithya Srinivasan01364142019-07-02 15:52:49 -0700230 return True
231 return False
232
Adithya Srinivasan01364142019-07-02 15:52:49 -0700233
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700234def _define_proc_hook_stub(cmd, f):
235 if _need_proc_hook_stub(cmd):
236 return_type = gencom.return_type_dict[cmd]
237 ext_name = gencom.extension_dict[cmd]
Adithya Srinivasan01364142019-07-02 15:52:49 -0700238 ext_hook = 'ProcHook::' + ext_name[3:]
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700239 handle = gencom.param_dict[cmd][0][1]
240 param_types = ', '.join([''.join(i) for i in gencom.param_dict[cmd]])
241 param_names = ', '.join([''.join(i[1]) for i in gencom.param_dict[cmd]])
Adithya Srinivasan01364142019-07-02 15:52:49 -0700242
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700243 f.write('VKAPI_ATTR ' + return_type + ' checked' + gencom.base_name(cmd) +
244 '(' + param_types + ') {\n')
245 f.write(gencom.indent(1) + 'if (GetData(' + handle + ').hook_extensions[' +
246 ext_hook + ']) {\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700247
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700248 f.write(gencom.indent(2))
249 if gencom.return_type_dict[cmd] != 'void':
250 f.write('return ')
251 f.write(gencom.base_name(cmd) + '(' + param_names + ');\n')
252
253 f.write(gencom.indent(1) + '} else {\n')
254 f.write(gencom.indent(2) + 'Logger(' + handle + ').Err(' + handle + ', \"' +
255 ext_name + ' not enabled. ' + cmd + ' not executed.\");\n')
256 if gencom.return_type_dict[cmd] != 'void':
257 f.write(gencom.indent(2) + 'return VK_SUCCESS;\n')
258 f.write(gencom.indent(1) + '}\n}\n\n')
259
260
261def _define_global_proc_hook(cmd, f):
262 assert cmd not in gencom.extension_dict
263
264 f.write(gencom.indent(1) + '{\n')
265 f.write(gencom.indent(2) + '\"' + cmd + '\",\n')
266 f.write("""\
267 ProcHook::GLOBAL,
Adithya Srinivasan01364142019-07-02 15:52:49 -0700268 ProcHook::EXTENSION_CORE,
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700269 reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """),
Adithya Srinivasan01364142019-07-02 15:52:49 -0700270 nullptr,
271 },\n""")
272
Adithya Srinivasan01364142019-07-02 15:52:49 -0700273
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700274def _define_instance_proc_hook(cmd, f):
275 f.write(gencom.indent(1) + '{\n')
276 f.write(gencom.indent(2) + '\"' + cmd + '\",\n')
277 f.write(gencom.indent(2) + 'ProcHook::INSTANCE,\n')
278
279 if cmd in gencom.extension_dict:
280 ext_name = gencom.extension_dict[cmd]
281 f.write(gencom.indent(2) + 'ProcHook::' + ext_name[3:] + ',\n')
282
283 if gencom.is_extension_internal(ext_name):
284 f.write("""\
285 nullptr,
286 nullptr,\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700287 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700288 f.write("""\
289 reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """),
290 nullptr,\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700291 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700292 f.write("""\
293 ProcHook::EXTENSION_CORE,
294 reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """),
Adithya Srinivasan01364142019-07-02 15:52:49 -0700295 nullptr,\n""")
296
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700297 f.write(gencom.indent(1) + '},\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700298
Adithya Srinivasan01364142019-07-02 15:52:49 -0700299
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700300def _define_device_proc_hook(cmd, f):
301 f.write(gencom.indent(1) + '{\n')
302 f.write(gencom.indent(2) + '\"' + cmd + '\",\n')
303 f.write(gencom.indent(2) + 'ProcHook::DEVICE,\n')
304
305 if cmd in gencom.extension_dict:
306 ext_name = gencom.extension_dict[cmd]
307 f.write(gencom.indent(2) + 'ProcHook::' + ext_name[3:] + ',\n')
308
309 if gencom.is_extension_internal(ext_name):
310 f.write("""\
311 nullptr,
312 nullptr,\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700313 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700314 f.write("""\
315 reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """),
316 reinterpret_cast<PFN_vkVoidFunction>(checked""" +
317 gencom.base_name(cmd) + '),\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700318
319 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700320 f.write("""\
321 ProcHook::EXTENSION_CORE,
322 reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """),
Adithya Srinivasan01364142019-07-02 15:52:49 -0700323 nullptr,\n""")
324
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700325 f.write(gencom.indent(1) + '},\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700326
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700327
328def gen_cpp():
329 genfile = os.path.join(os.path.dirname(__file__),
330 '..', 'libvulkan', 'driver_gen.cpp')
331
332 with open(genfile, 'w') as f:
333 f.write(gencom.copyright_and_warning(2016))
334 f.write("""\
335#include <log/log.h>
Adithya Srinivasan01364142019-07-02 15:52:49 -0700336#include <string.h>
337
338#include <algorithm>
339
340#include "driver.h"
341
342namespace vulkan {
343namespace driver {
344
345namespace {
346
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700347// clang-format off\n\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700348
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700349 for cmd in gencom.command_list:
350 _define_proc_hook_stub(cmd, f)
Adithya Srinivasan01364142019-07-02 15:52:49 -0700351
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700352 f.write("""\
353// clang-format on
Adithya Srinivasan01364142019-07-02 15:52:49 -0700354
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700355const ProcHook g_proc_hooks[] = {
356 // clang-format off\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700357
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700358 sorted_command_list = sorted(gencom.command_list)
359 for cmd in sorted_command_list:
360 if _is_intercepted(cmd):
361 if gencom.is_globally_dispatched(cmd):
362 _define_global_proc_hook(cmd, f)
363 elif gencom.is_instance_dispatched(cmd):
364 _define_instance_proc_hook(cmd, f)
365 elif gencom.is_device_dispatched(cmd):
366 _define_device_proc_hook(cmd, f)
Adithya Srinivasan01364142019-07-02 15:52:49 -0700367
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700368 f.write("""\
369 // clang-format on
370};
371
372} // namespace
373
374const ProcHook* GetProcHook(const char* name) {
Adithya Srinivasan01364142019-07-02 15:52:49 -0700375 const auto& begin = g_proc_hooks;
376 const auto& end =
377 g_proc_hooks + sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]);
378 const auto hook = std::lower_bound(
379 begin, end, name,
380 [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; });
381 return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr;
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700382}
Adithya Srinivasan01364142019-07-02 15:52:49 -0700383
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700384ProcHook::Extension GetProcHookExtension(const char* name) {
385 // clang-format off\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700386
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700387 for exts in _KNOWN_EXTENSIONS:
388 f.write(gencom.indent(1) + 'if (strcmp(name, \"' + exts +
389 '\") == 0) return ProcHook::' + exts[3:] + ';\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700390
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700391 f.write("""\
392 // clang-format on
393 return ProcHook::EXTENSION_UNKNOWN;
394}
395
396#define UNLIKELY(expr) __builtin_expect((expr), 0)
397
398#define INIT_PROC(required, obj, proc) \\
399 do { \\
400 data.driver.proc = \\
401 reinterpret_cast<PFN_vk##proc>(get_proc(obj, "vk" #proc)); \\
402 if (UNLIKELY(required && !data.driver.proc)) { \\
403 ALOGE("missing " #obj " proc: vk" #proc); \\
404 success = false; \\
405 } \\
406 } while (0)
407
408#define INIT_PROC_EXT(ext, required, obj, proc) \\
409 do { \\
410 if (extensions[ProcHook::ext]) \\
411 INIT_PROC(required, obj, proc); \\
412 } while (0)
413
414bool InitDriverTable(VkInstance instance,
Adithya Srinivasan01364142019-07-02 15:52:49 -0700415 PFN_vkGetInstanceProcAddr get_proc,
416 const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
417 auto& data = GetData(instance);
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700418 bool success = true;
Adithya Srinivasan01364142019-07-02 15:52:49 -0700419
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700420 // clang-format off\n""")
421
422 for cmd in gencom.command_list:
423 if _is_instance_driver_table_entry(cmd):
424 gencom.init_proc(cmd, f)
425
426 f.write("""\
427 // clang-format on
428
429 return success;
430}
431
432bool InitDriverTable(VkDevice dev,
Adithya Srinivasan01364142019-07-02 15:52:49 -0700433 PFN_vkGetDeviceProcAddr get_proc,
434 const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
435 auto& data = GetData(dev);
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700436 bool success = true;
437
438 // clang-format off\n""")
439
440 for cmd in gencom.command_list:
441 if _is_device_driver_table_entry(cmd):
442 gencom.init_proc(cmd, f)
443
444 f.write("""\
445 // clang-format on
446
447 return success;
448}
449
450} // namespace driver
451} // namespace vulkan\n""")
452
Adithya Srinivasan8dce9d72019-07-11 14:26:04 -0700453 f.close()
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700454 gencom.run_clang_format(genfile)