blob: 48c0ae9304db121ed94d609ec85db096374914ec [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.
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070016
17"""Generates the driver_gen.h and driver_gen.cpp.
18"""
Adithya Srinivasan01364142019-07-02 15:52:49 -070019
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 Zhang6ca5d0c2019-10-11 17:15:02 -070023# Extensions intercepted at vulkan::driver level.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070024_INTERCEPTED_EXTENSIONS = [
25 'VK_ANDROID_native_buffer',
26 'VK_EXT_debug_report',
27 'VK_EXT_hdr_metadata',
28 'VK_EXT_swapchain_colorspace',
29 'VK_GOOGLE_display_timing',
Ian Elliott1ce053f2022-03-16 09:49:53 -060030 'VK_GOOGLE_surfaceless_query',
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070031 'VK_KHR_android_surface',
32 'VK_KHR_get_surface_capabilities2',
33 'VK_KHR_incremental_present',
34 'VK_KHR_shared_presentable_image',
35 'VK_KHR_surface',
Ian Elliottbb67b242022-03-16 09:52:28 -060036 'VK_KHR_surface_protected_capabilities',
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070037 'VK_KHR_swapchain',
Chris Forbes9d0d9ff2022-12-28 01:58:31 +000038 'VK_EXT_swapchain_maintenance1',
39 'VK_EXT_surface_maintenance1',
Adithya Srinivasan01364142019-07-02 15:52:49 -070040]
41
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070042# Extensions known to vulkan::driver level.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070043_KNOWN_EXTENSIONS = _INTERCEPTED_EXTENSIONS + [
44 'VK_ANDROID_external_memory_android_hardware_buffer',
45 'VK_KHR_bind_memory2',
46 'VK_KHR_get_physical_device_properties2',
Yiwei Zhange4f64172020-07-05 15:17:32 -070047 'VK_KHR_device_group_creation',
Yiwei Zhange1f35012020-07-05 22:52:04 -070048 'VK_KHR_external_memory_capabilities',
49 'VK_KHR_external_semaphore_capabilities',
50 'VK_KHR_external_fence_capabilities',
Chris Forbes9d0d9ff2022-12-28 01:58:31 +000051 'VK_KHR_external_fence_fd',
Adithya Srinivasan01364142019-07-02 15:52:49 -070052]
53
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070054# Functions needed at vulkan::driver level.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070055_NEEDED_COMMANDS = [
56 # Create functions of dispatchable objects
57 'vkCreateDevice',
58 'vkGetDeviceQueue',
59 'vkGetDeviceQueue2',
60 'vkAllocateCommandBuffers',
61
62 # Destroy functions of dispatchable objects
63 'vkDestroyInstance',
64 'vkDestroyDevice',
65
66 # Enumeration of extensions
67 'vkEnumerateDeviceExtensionProperties',
68
69 # We cache physical devices in loader.cpp
70 'vkEnumeratePhysicalDevices',
71 'vkEnumeratePhysicalDeviceGroups',
72
73 'vkGetInstanceProcAddr',
74 'vkGetDeviceProcAddr',
75
76 'vkQueueSubmit',
77
78 # VK_KHR_swapchain->VK_ANDROID_native_buffer translation
79 'vkCreateImage',
80 'vkDestroyImage',
81
82 'vkGetPhysicalDeviceProperties',
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070083
84 # VK_KHR_swapchain v69 requirement
85 'vkBindImageMemory2',
86 'vkBindImageMemory2KHR',
Yiwei Zhange4f64172020-07-05 15:17:32 -070087
88 # For promoted VK_KHR_device_group_creation
89 'vkEnumeratePhysicalDeviceGroupsKHR',
Yiwei Zhanga55624b2020-07-05 16:05:26 -070090
91 # For promoted VK_KHR_get_physical_device_properties2
92 'vkGetPhysicalDeviceFeatures2',
93 'vkGetPhysicalDeviceFeatures2KHR',
94 'vkGetPhysicalDeviceProperties2',
95 'vkGetPhysicalDeviceProperties2KHR',
96 'vkGetPhysicalDeviceFormatProperties2',
97 'vkGetPhysicalDeviceFormatProperties2KHR',
98 'vkGetPhysicalDeviceImageFormatProperties2',
99 'vkGetPhysicalDeviceImageFormatProperties2KHR',
100 'vkGetPhysicalDeviceQueueFamilyProperties2',
101 'vkGetPhysicalDeviceQueueFamilyProperties2KHR',
102 'vkGetPhysicalDeviceMemoryProperties2',
103 'vkGetPhysicalDeviceMemoryProperties2KHR',
104 'vkGetPhysicalDeviceSparseImageFormatProperties2',
105 'vkGetPhysicalDeviceSparseImageFormatProperties2KHR',
Yiwei Zhange1f35012020-07-05 22:52:04 -0700106
107 # For promoted VK_KHR_external_memory_capabilities
108 'vkGetPhysicalDeviceExternalBufferProperties',
109 'vkGetPhysicalDeviceExternalBufferPropertiesKHR',
110
111 # For promoted VK_KHR_external_semaphore_capabilities
112 'vkGetPhysicalDeviceExternalSemaphoreProperties',
113 'vkGetPhysicalDeviceExternalSemaphorePropertiesKHR',
114
115 # For promoted VK_KHR_external_fence_capabilities
116 'vkGetPhysicalDeviceExternalFenceProperties',
117 'vkGetPhysicalDeviceExternalFencePropertiesKHR',
Chris Forbes9d0d9ff2022-12-28 01:58:31 +0000118
119 # VK_KHR_swapchain_maintenance1 requirement
120 'vkImportFenceFdKHR',
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700121]
122
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700123# Functions intercepted at vulkan::driver level.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700124_INTERCEPTED_COMMANDS = [
125 # Create functions of dispatchable objects
126 'vkCreateInstance',
127 'vkCreateDevice',
128 'vkEnumeratePhysicalDevices',
129 'vkEnumeratePhysicalDeviceGroups',
130 'vkGetDeviceQueue',
131 'vkGetDeviceQueue2',
132 'vkAllocateCommandBuffers',
133
134 # Destroy functions of dispatchable objects
135 'vkDestroyInstance',
136 'vkDestroyDevice',
137
138 # Enumeration of extensions
139 'vkEnumerateInstanceExtensionProperties',
140 'vkEnumerateDeviceExtensionProperties',
141
142 'vkGetInstanceProcAddr',
143 'vkGetDeviceProcAddr',
144
145 'vkQueueSubmit',
146
147 # VK_KHR_swapchain v69 requirement
148 'vkBindImageMemory2',
149 'vkBindImageMemory2KHR',
Yiwei Zhanga55624b2020-07-05 16:05:26 -0700150
151 # For promoted VK_KHR_get_physical_device_properties2
152 'vkGetPhysicalDeviceFeatures2',
153 'vkGetPhysicalDeviceProperties2',
154 'vkGetPhysicalDeviceFormatProperties2',
155 'vkGetPhysicalDeviceImageFormatProperties2',
156 'vkGetPhysicalDeviceQueueFamilyProperties2',
157 'vkGetPhysicalDeviceMemoryProperties2',
158 'vkGetPhysicalDeviceSparseImageFormatProperties2',
Yiwei Zhange1f35012020-07-05 22:52:04 -0700159
160 # For promoted VK_KHR_external_memory_capabilities
161 'vkGetPhysicalDeviceExternalBufferProperties',
162
163 # For promoted VK_KHR_external_semaphore_capabilities
164 'vkGetPhysicalDeviceExternalSemaphoreProperties',
165
166 # For promoted VK_KHR_external_fence_capabilities
167 'vkGetPhysicalDeviceExternalFenceProperties',
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700168]
169
170
171def _is_driver_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700172 """Returns true if a function is needed by vulkan::driver.
173
174 Args:
175 cmd: Vulkan function name.
176 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700177 if gencom.is_function_supported(cmd):
178 if cmd in _NEEDED_COMMANDS:
179 return True
180 if cmd in gencom.extension_dict:
181 if (gencom.extension_dict[cmd] == 'VK_ANDROID_native_buffer' or
182 gencom.extension_dict[cmd] == 'VK_EXT_debug_report'):
183 return True
184 return False
185
186
187def _is_instance_driver_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700188 """Returns true if a instance-dispatched function is needed by vulkan::driver.
189
190 Args:
191 cmd: Vulkan function name.
192 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700193 return (_is_driver_table_entry(cmd) and
194 gencom.is_instance_dispatched(cmd))
195
196
197def _is_device_driver_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700198 """Returns true if a device-dispatched function is needed by vulkan::driver.
199
200 Args:
201 cmd: Vulkan function name.
202 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700203 return (_is_driver_table_entry(cmd) and
204 gencom.is_device_dispatched(cmd))
205
206
207def gen_h():
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700208 """Generates the driver_gen.h file.
209 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700210 genfile = os.path.join(os.path.dirname(__file__),
211 '..', 'libvulkan', 'driver_gen.h')
212
213 with open(genfile, 'w') as f:
214 f.write(gencom.copyright_and_warning(2016))
215
216 f.write("""\
217#ifndef LIBVULKAN_DRIVER_GEN_H
218#define LIBVULKAN_DRIVER_GEN_H
219
220#include <vulkan/vk_android_native_buffer.h>
221#include <vulkan/vulkan.h>
222
223#include <bitset>
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700224#include <optional>
225#include <vector>
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700226
227namespace vulkan {
228namespace driver {
229
230struct ProcHook {
Adithya Srinivasan01364142019-07-02 15:52:49 -0700231 enum Type {
232 GLOBAL,
233 INSTANCE,
234 DEVICE,
235 };
236 enum Extension {\n""")
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700237
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700238 for ext in _KNOWN_EXTENSIONS:
239 f.write(gencom.indent(2) + gencom.base_ext_name(ext) + ',\n')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700240
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700241 f.write('\n')
Jörg Wagner7b48c202024-05-13 19:44:08 +0000242 # EXTENSION_CORE_xxx API list must be the last set of enums after the extensions.
243 # This allows to easily identify "a" core function hook
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700244 for version in gencom.version_code_list:
245 f.write(gencom.indent(2) + 'EXTENSION_CORE_' + version + ',\n')
246
247 # EXTENSION_COUNT must be the next enum after the highest API version.
248 f.write("""\
Adithya Srinivasan01364142019-07-02 15:52:49 -0700249 EXTENSION_COUNT,
250 EXTENSION_UNKNOWN,
251 };
252
253 const char* name;
254 Type type;
255 Extension extension;
256
257 PFN_vkVoidFunction proc;
258 PFN_vkVoidFunction checked_proc; // always nullptr for non-device hooks
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700259};
Adithya Srinivasan01364142019-07-02 15:52:49 -0700260
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700261struct InstanceDriverTable {
262 // clang-format off\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700263
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700264 for cmd in gencom.command_list:
265 if _is_instance_driver_table_entry(cmd):
266 f.write(gencom.indent(1) + 'PFN_' + cmd + ' ' +
267 gencom.base_name(cmd) + ';\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700268
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700269 f.write("""\
270 // clang-format on
271};
Adithya Srinivasan01364142019-07-02 15:52:49 -0700272
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700273struct DeviceDriverTable {
274 // clang-format off\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700275
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700276 for cmd in gencom.command_list:
277 if _is_device_driver_table_entry(cmd):
278 f.write(gencom.indent(1) + 'PFN_' + cmd + ' ' +
279 gencom.base_name(cmd) + ';\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700280
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700281 f.write("""\
282 // clang-format on
283};
Adithya Srinivasan01364142019-07-02 15:52:49 -0700284
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700285const ProcHook* GetProcHook(const char* name);
Adithya Srinivasan01364142019-07-02 15:52:49 -0700286ProcHook::Extension GetProcHookExtension(const char* name);
287
288bool InitDriverTable(VkInstance instance,
289 PFN_vkGetInstanceProcAddr get_proc,
290 const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);
291bool InitDriverTable(VkDevice dev,
292 PFN_vkGetDeviceProcAddr get_proc,
293 const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);
294
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700295std::optional<uint32_t> GetInstanceExtensionPromotedVersion(const char* name);
296uint32_t CountPromotedInstanceExtensions(uint32_t begin_version,
297 uint32_t end_version);
298std::vector<const char*> GetPromotedInstanceExtensions(uint32_t begin_version,
299 uint32_t end_version);
300
Adithya Srinivasan01364142019-07-02 15:52:49 -0700301} // namespace driver
302} // namespace vulkan
303
304#endif // LIBVULKAN_DRIVER_TABLE_H\n""")
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700305
Adithya Srinivasan8dce9d72019-07-11 14:26:04 -0700306 f.close()
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700307 gencom.run_clang_format(genfile)
Adithya Srinivasan01364142019-07-02 15:52:49 -0700308
Adithya Srinivasan01364142019-07-02 15:52:49 -0700309
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700310def _is_intercepted(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700311 """Returns true if a function is intercepted by vulkan::driver.
312
313 Args:
314 cmd: Vulkan function name.
315 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700316 if gencom.is_function_supported(cmd):
317 if cmd in _INTERCEPTED_COMMANDS:
318 return True
Adithya Srinivasan01364142019-07-02 15:52:49 -0700319
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700320 if cmd in gencom.extension_dict:
321 return gencom.extension_dict[cmd] in _INTERCEPTED_EXTENSIONS
Adithya Srinivasan01364142019-07-02 15:52:49 -0700322 return False
323
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700324
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700325def _get_proc_hook_enum(cmd):
326 """Returns the ProcHook enumeration for the corresponding core function.
327
328 Args:
329 cmd: Vulkan function name.
330 """
331 assert cmd in gencom.version_dict
332 for version in gencom.version_code_list:
333 if gencom.version_dict[cmd] == 'VK_VERSION_' + version:
334 return 'ProcHook::EXTENSION_CORE_' + version
335
336
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700337def _need_proc_hook_stub(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700338 """Returns true if a function needs a ProcHook stub.
339
340 Args:
341 cmd: Vulkan function name.
342 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700343 if _is_intercepted(cmd) and gencom.is_device_dispatched(cmd):
344 if cmd in gencom.extension_dict:
345 if not gencom.is_extension_internal(gencom.extension_dict[cmd]):
Adithya Srinivasan01364142019-07-02 15:52:49 -0700346 return True
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700347 elif gencom.version_dict[cmd] != 'VK_VERSION_1_0':
348 return True
Adithya Srinivasan01364142019-07-02 15:52:49 -0700349 return False
350
Adithya Srinivasan01364142019-07-02 15:52:49 -0700351
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700352def _define_proc_hook_stub(cmd, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700353 """Emits a stub for ProcHook::checked_proc.
354
355 Args:
356 cmd: Vulkan function name.
357 f: Output file handle.
358 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700359 if _need_proc_hook_stub(cmd):
360 return_type = gencom.return_type_dict[cmd]
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700361
362 ext_name = ''
363 ext_hook = ''
364 if cmd in gencom.extension_dict:
365 ext_name = gencom.extension_dict[cmd]
366 ext_hook = 'ProcHook::' + gencom.base_ext_name(ext_name)
367 else:
368 ext_name = gencom.version_dict[cmd]
369 ext_hook = _get_proc_hook_enum(cmd)
370
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700371 handle = gencom.param_dict[cmd][0][1]
372 param_types = ', '.join([''.join(i) for i in gencom.param_dict[cmd]])
373 param_names = ', '.join([''.join(i[1]) for i in gencom.param_dict[cmd]])
Adithya Srinivasan01364142019-07-02 15:52:49 -0700374
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700375 f.write('VKAPI_ATTR ' + return_type + ' checked' + gencom.base_name(cmd) +
376 '(' + param_types + ') {\n')
377 f.write(gencom.indent(1) + 'if (GetData(' + handle + ').hook_extensions[' +
378 ext_hook + ']) {\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700379
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700380 f.write(gencom.indent(2))
381 if gencom.return_type_dict[cmd] != 'void':
382 f.write('return ')
383 f.write(gencom.base_name(cmd) + '(' + param_names + ');\n')
384
385 f.write(gencom.indent(1) + '} else {\n')
386 f.write(gencom.indent(2) + 'Logger(' + handle + ').Err(' + handle + ', \"' +
387 ext_name + ' not enabled. ' + cmd + ' not executed.\");\n')
388 if gencom.return_type_dict[cmd] != 'void':
389 f.write(gencom.indent(2) + 'return VK_SUCCESS;\n')
390 f.write(gencom.indent(1) + '}\n}\n\n')
391
392
393def _define_global_proc_hook(cmd, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700394 """Emits definition of a global ProcHook.
395
396 Args:
397 cmd: Vulkan function name.
398 f: Output file handle.
399 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700400 assert cmd not in gencom.extension_dict
401
402 f.write(gencom.indent(1) + '{\n')
403 f.write(gencom.indent(2) + '\"' + cmd + '\",\n')
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700404 f.write(gencom.indent(2) + 'ProcHook::GLOBAL,\n')
405 f.write(gencom.indent(2) + _get_proc_hook_enum(cmd) + ',\n')
406 f.write(gencom.indent(2) + 'reinterpret_cast<PFN_vkVoidFunction>(' +
407 gencom.base_name(cmd) + '),\n')
408 f.write(gencom.indent(2) + 'nullptr,\n')
409 f.write(gencom.indent(1) + '},\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700410
Adithya Srinivasan01364142019-07-02 15:52:49 -0700411
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700412def _define_instance_proc_hook(cmd, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700413 """Emits definition of a instance ProcHook.
414
415 Args:
416 cmd: Vulkan function name.
417 f: Output file handle.
418 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700419 f.write(gencom.indent(1) + '{\n')
420 f.write(gencom.indent(2) + '\"' + cmd + '\",\n')
421 f.write(gencom.indent(2) + 'ProcHook::INSTANCE,\n')
422
423 if cmd in gencom.extension_dict:
424 ext_name = gencom.extension_dict[cmd]
Yiwei Zhangaeaa8672019-10-16 18:59:41 -0700425 f.write(gencom.indent(2) + 'ProcHook::' +
426 gencom.base_ext_name(ext_name) + ',\n')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700427
428 if gencom.is_extension_internal(ext_name):
429 f.write("""\
430 nullptr,
431 nullptr,\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700432 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700433 f.write("""\
434 reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """),
435 nullptr,\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700436 else:
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700437 f.write(gencom.indent(2) + _get_proc_hook_enum(cmd) + ',\n')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700438 f.write("""\
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700439 reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """),
Adithya Srinivasan01364142019-07-02 15:52:49 -0700440 nullptr,\n""")
441
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700442 f.write(gencom.indent(1) + '},\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700443
Adithya Srinivasan01364142019-07-02 15:52:49 -0700444
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700445def _define_device_proc_hook(cmd, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700446 """Emits definition of a device ProcHook.
447
448 Args:
449 cmd: Vulkan function name.
450 f: Output file handle.
451 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700452 f.write(gencom.indent(1) + '{\n')
453 f.write(gencom.indent(2) + '\"' + cmd + '\",\n')
454 f.write(gencom.indent(2) + 'ProcHook::DEVICE,\n')
455
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700456 if (cmd in gencom.extension_dict or
457 gencom.version_dict[cmd] != 'VK_VERSION_1_0'):
458 ext_name = ''
459 ext_hook = ''
460 if cmd in gencom.extension_dict:
461 ext_name = gencom.extension_dict[cmd]
462 ext_hook = 'ProcHook::' + gencom.base_ext_name(ext_name)
463 else:
464 ext_name = gencom.version_dict[cmd]
465 ext_hook = _get_proc_hook_enum(cmd)
466 f.write(gencom.indent(2) + ext_hook + ',\n')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700467
468 if gencom.is_extension_internal(ext_name):
469 f.write("""\
470 nullptr,
471 nullptr,\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700472 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700473 f.write("""\
474 reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """),
475 reinterpret_cast<PFN_vkVoidFunction>(checked""" +
476 gencom.base_name(cmd) + '),\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700477
478 else:
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700479 f.write(gencom.indent(2) + _get_proc_hook_enum(cmd) + ',\n')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700480 f.write("""\
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700481 reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """),
Adithya Srinivasan01364142019-07-02 15:52:49 -0700482 nullptr,\n""")
483
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700484 f.write(gencom.indent(1) + '},\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700485
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700486
487def gen_cpp():
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700488 """Generates the driver_gen.cpp file.
489 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700490 genfile = os.path.join(os.path.dirname(__file__),
491 '..', 'libvulkan', 'driver_gen.cpp')
492
493 with open(genfile, 'w') as f:
494 f.write(gencom.copyright_and_warning(2016))
495 f.write("""\
496#include <log/log.h>
Adithya Srinivasan01364142019-07-02 15:52:49 -0700497#include <string.h>
498
499#include <algorithm>
500
501#include "driver.h"
502
503namespace vulkan {
504namespace driver {
505
506namespace {
507
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700508// clang-format off\n\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700509
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700510 for cmd in gencom.command_list:
511 _define_proc_hook_stub(cmd, f)
Adithya Srinivasan01364142019-07-02 15:52:49 -0700512
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700513 f.write("""\
514// clang-format on
Adithya Srinivasan01364142019-07-02 15:52:49 -0700515
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700516const ProcHook g_proc_hooks[] = {
517 // clang-format off\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700518
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700519 sorted_command_list = sorted(gencom.command_list)
520 for cmd in sorted_command_list:
521 if _is_intercepted(cmd):
522 if gencom.is_globally_dispatched(cmd):
523 _define_global_proc_hook(cmd, f)
524 elif gencom.is_instance_dispatched(cmd):
525 _define_instance_proc_hook(cmd, f)
526 elif gencom.is_device_dispatched(cmd):
527 _define_device_proc_hook(cmd, f)
Adithya Srinivasan01364142019-07-02 15:52:49 -0700528
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700529 f.write("""\
530 // clang-format on
531};
532
533} // namespace
534
535const ProcHook* GetProcHook(const char* name) {
Yiwei Zhang93b521c2020-07-11 16:32:09 -0700536 auto begin = std::cbegin(g_proc_hooks);
537 auto end = std::cend(g_proc_hooks);
538 auto hook = std::lower_bound(
Adithya Srinivasan01364142019-07-02 15:52:49 -0700539 begin, end, name,
540 [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; });
541 return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr;
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700542}
Adithya Srinivasan01364142019-07-02 15:52:49 -0700543
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700544ProcHook::Extension GetProcHookExtension(const char* name) {
545 // clang-format off\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700546
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700547 for ext in _KNOWN_EXTENSIONS:
548 f.write(gencom.indent(1) + 'if (strcmp(name, \"' + ext +
549 '\") == 0) return ProcHook::' + gencom.base_ext_name(ext) + ';\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700550
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700551 f.write("""\
552 // clang-format on
553 return ProcHook::EXTENSION_UNKNOWN;
554}
555
556#define UNLIKELY(expr) __builtin_expect((expr), 0)
557
558#define INIT_PROC(required, obj, proc) \\
559 do { \\
560 data.driver.proc = \\
561 reinterpret_cast<PFN_vk##proc>(get_proc(obj, "vk" #proc)); \\
562 if (UNLIKELY(required && !data.driver.proc)) { \\
563 ALOGE("missing " #obj " proc: vk" #proc); \\
564 success = false; \\
565 } \\
566 } while (0)
567
568#define INIT_PROC_EXT(ext, required, obj, proc) \\
569 do { \\
570 if (extensions[ProcHook::ext]) \\
571 INIT_PROC(required, obj, proc); \\
572 } while (0)
573
574bool InitDriverTable(VkInstance instance,
Adithya Srinivasan01364142019-07-02 15:52:49 -0700575 PFN_vkGetInstanceProcAddr get_proc,
576 const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
577 auto& data = GetData(instance);
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700578 bool success = true;
Adithya Srinivasan01364142019-07-02 15:52:49 -0700579
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700580 // clang-format off\n""")
581
582 for cmd in gencom.command_list:
583 if _is_instance_driver_table_entry(cmd):
584 gencom.init_proc(cmd, f)
585
586 f.write("""\
587 // clang-format on
588
589 return success;
590}
591
592bool InitDriverTable(VkDevice dev,
Adithya Srinivasan01364142019-07-02 15:52:49 -0700593 PFN_vkGetDeviceProcAddr get_proc,
594 const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
595 auto& data = GetData(dev);
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700596 bool success = true;
597
598 // clang-format off\n""")
599
600 for cmd in gencom.command_list:
601 if _is_device_driver_table_entry(cmd):
602 gencom.init_proc(cmd, f)
603
604 f.write("""\
605 // clang-format on
606
607 return success;
608}
609
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700610const std::pair<const char*, uint32_t> g_promoted_instance_extensions[] = {
611 // clang-format off\n""")
612
613 for key, value in sorted(gencom.promoted_inst_ext_dict.items()):
614 f.write(gencom.indent(1) + 'std::make_pair("' + key + '", ' + value + '),\n')
615
616 f.write("""\
617 // clang-format on
618};
619
620std::optional<uint32_t> GetInstanceExtensionPromotedVersion(const char* name) {
621 auto begin = std::cbegin(g_promoted_instance_extensions);
622 auto end = std::cend(g_promoted_instance_extensions);
623 auto iter =
624 std::lower_bound(begin, end, name,
625 [](const std::pair<const char*, uint32_t>& e,
626 const char* n) { return strcmp(e.first, n) < 0; });
627 return (iter < end && strcmp(iter->first, name) == 0)
628 ? std::optional<uint32_t>(iter->second)
629 : std::nullopt;
630}
631
632uint32_t CountPromotedInstanceExtensions(uint32_t begin_version,
633 uint32_t end_version) {
634 auto begin = std::cbegin(g_promoted_instance_extensions);
635 auto end = std::cend(g_promoted_instance_extensions);
636 uint32_t count = 0;
637
638 for (auto iter = begin; iter != end; iter++)
639 if (iter->second > begin_version && iter->second <= end_version)
640 count++;
641
642 return count;
643}
644
645std::vector<const char*> GetPromotedInstanceExtensions(uint32_t begin_version,
646 uint32_t end_version) {
647 auto begin = std::cbegin(g_promoted_instance_extensions);
648 auto end = std::cend(g_promoted_instance_extensions);
649 std::vector<const char*> extensions;
650
651 for (auto iter = begin; iter != end; iter++)
652 if (iter->second > begin_version && iter->second <= end_version)
653 extensions.emplace_back(iter->first);
654
655 return extensions;
656}
657
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700658} // namespace driver
659} // namespace vulkan\n""")
660
Adithya Srinivasan8dce9d72019-07-11 14:26:04 -0700661 f.close()
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700662 gencom.run_clang_format(genfile)