blob: 78b550c202f1324bc84abcaba670b3db12d51b5f [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')
242 for version in gencom.version_code_list:
243 f.write(gencom.indent(2) + 'EXTENSION_CORE_' + version + ',\n')
244
245 # EXTENSION_COUNT must be the next enum after the highest API version.
246 f.write("""\
Adithya Srinivasan01364142019-07-02 15:52:49 -0700247 EXTENSION_COUNT,
248 EXTENSION_UNKNOWN,
249 };
250
251 const char* name;
252 Type type;
253 Extension extension;
254
255 PFN_vkVoidFunction proc;
256 PFN_vkVoidFunction checked_proc; // always nullptr for non-device hooks
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700257};
Adithya Srinivasan01364142019-07-02 15:52:49 -0700258
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700259struct InstanceDriverTable {
260 // clang-format off\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700261
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700262 for cmd in gencom.command_list:
263 if _is_instance_driver_table_entry(cmd):
264 f.write(gencom.indent(1) + 'PFN_' + cmd + ' ' +
265 gencom.base_name(cmd) + ';\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700266
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700267 f.write("""\
268 // clang-format on
269};
Adithya Srinivasan01364142019-07-02 15:52:49 -0700270
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700271struct DeviceDriverTable {
272 // clang-format off\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700273
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700274 for cmd in gencom.command_list:
275 if _is_device_driver_table_entry(cmd):
276 f.write(gencom.indent(1) + 'PFN_' + cmd + ' ' +
277 gencom.base_name(cmd) + ';\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700278
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700279 f.write("""\
280 // clang-format on
281};
Adithya Srinivasan01364142019-07-02 15:52:49 -0700282
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700283const ProcHook* GetProcHook(const char* name);
Adithya Srinivasan01364142019-07-02 15:52:49 -0700284ProcHook::Extension GetProcHookExtension(const char* name);
285
286bool InitDriverTable(VkInstance instance,
287 PFN_vkGetInstanceProcAddr get_proc,
288 const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);
289bool InitDriverTable(VkDevice dev,
290 PFN_vkGetDeviceProcAddr get_proc,
291 const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);
292
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700293std::optional<uint32_t> GetInstanceExtensionPromotedVersion(const char* name);
294uint32_t CountPromotedInstanceExtensions(uint32_t begin_version,
295 uint32_t end_version);
296std::vector<const char*> GetPromotedInstanceExtensions(uint32_t begin_version,
297 uint32_t end_version);
298
Adithya Srinivasan01364142019-07-02 15:52:49 -0700299} // namespace driver
300} // namespace vulkan
301
302#endif // LIBVULKAN_DRIVER_TABLE_H\n""")
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700303
Adithya Srinivasan8dce9d72019-07-11 14:26:04 -0700304 f.close()
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700305 gencom.run_clang_format(genfile)
Adithya Srinivasan01364142019-07-02 15:52:49 -0700306
Adithya Srinivasan01364142019-07-02 15:52:49 -0700307
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700308def _is_intercepted(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700309 """Returns true if a function is intercepted by vulkan::driver.
310
311 Args:
312 cmd: Vulkan function name.
313 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700314 if gencom.is_function_supported(cmd):
315 if cmd in _INTERCEPTED_COMMANDS:
316 return True
Adithya Srinivasan01364142019-07-02 15:52:49 -0700317
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700318 if cmd in gencom.extension_dict:
319 return gencom.extension_dict[cmd] in _INTERCEPTED_EXTENSIONS
Adithya Srinivasan01364142019-07-02 15:52:49 -0700320 return False
321
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700322
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700323def _get_proc_hook_enum(cmd):
324 """Returns the ProcHook enumeration for the corresponding core function.
325
326 Args:
327 cmd: Vulkan function name.
328 """
329 assert cmd in gencom.version_dict
330 for version in gencom.version_code_list:
331 if gencom.version_dict[cmd] == 'VK_VERSION_' + version:
332 return 'ProcHook::EXTENSION_CORE_' + version
333
334
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700335def _need_proc_hook_stub(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700336 """Returns true if a function needs a ProcHook stub.
337
338 Args:
339 cmd: Vulkan function name.
340 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700341 if _is_intercepted(cmd) and gencom.is_device_dispatched(cmd):
342 if cmd in gencom.extension_dict:
343 if not gencom.is_extension_internal(gencom.extension_dict[cmd]):
Adithya Srinivasan01364142019-07-02 15:52:49 -0700344 return True
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700345 elif gencom.version_dict[cmd] != 'VK_VERSION_1_0':
346 return True
Adithya Srinivasan01364142019-07-02 15:52:49 -0700347 return False
348
Adithya Srinivasan01364142019-07-02 15:52:49 -0700349
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700350def _define_proc_hook_stub(cmd, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700351 """Emits a stub for ProcHook::checked_proc.
352
353 Args:
354 cmd: Vulkan function name.
355 f: Output file handle.
356 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700357 if _need_proc_hook_stub(cmd):
358 return_type = gencom.return_type_dict[cmd]
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700359
360 ext_name = ''
361 ext_hook = ''
362 if cmd in gencom.extension_dict:
363 ext_name = gencom.extension_dict[cmd]
364 ext_hook = 'ProcHook::' + gencom.base_ext_name(ext_name)
365 else:
366 ext_name = gencom.version_dict[cmd]
367 ext_hook = _get_proc_hook_enum(cmd)
368
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700369 handle = gencom.param_dict[cmd][0][1]
370 param_types = ', '.join([''.join(i) for i in gencom.param_dict[cmd]])
371 param_names = ', '.join([''.join(i[1]) for i in gencom.param_dict[cmd]])
Adithya Srinivasan01364142019-07-02 15:52:49 -0700372
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700373 f.write('VKAPI_ATTR ' + return_type + ' checked' + gencom.base_name(cmd) +
374 '(' + param_types + ') {\n')
375 f.write(gencom.indent(1) + 'if (GetData(' + handle + ').hook_extensions[' +
376 ext_hook + ']) {\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700377
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700378 f.write(gencom.indent(2))
379 if gencom.return_type_dict[cmd] != 'void':
380 f.write('return ')
381 f.write(gencom.base_name(cmd) + '(' + param_names + ');\n')
382
383 f.write(gencom.indent(1) + '} else {\n')
384 f.write(gencom.indent(2) + 'Logger(' + handle + ').Err(' + handle + ', \"' +
385 ext_name + ' not enabled. ' + cmd + ' not executed.\");\n')
386 if gencom.return_type_dict[cmd] != 'void':
387 f.write(gencom.indent(2) + 'return VK_SUCCESS;\n')
388 f.write(gencom.indent(1) + '}\n}\n\n')
389
390
391def _define_global_proc_hook(cmd, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700392 """Emits definition of a global ProcHook.
393
394 Args:
395 cmd: Vulkan function name.
396 f: Output file handle.
397 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700398 assert cmd not in gencom.extension_dict
399
400 f.write(gencom.indent(1) + '{\n')
401 f.write(gencom.indent(2) + '\"' + cmd + '\",\n')
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700402 f.write(gencom.indent(2) + 'ProcHook::GLOBAL,\n')
403 f.write(gencom.indent(2) + _get_proc_hook_enum(cmd) + ',\n')
404 f.write(gencom.indent(2) + 'reinterpret_cast<PFN_vkVoidFunction>(' +
405 gencom.base_name(cmd) + '),\n')
406 f.write(gencom.indent(2) + 'nullptr,\n')
407 f.write(gencom.indent(1) + '},\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700408
Adithya Srinivasan01364142019-07-02 15:52:49 -0700409
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700410def _define_instance_proc_hook(cmd, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700411 """Emits definition of a instance ProcHook.
412
413 Args:
414 cmd: Vulkan function name.
415 f: Output file handle.
416 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700417 f.write(gencom.indent(1) + '{\n')
418 f.write(gencom.indent(2) + '\"' + cmd + '\",\n')
419 f.write(gencom.indent(2) + 'ProcHook::INSTANCE,\n')
420
421 if cmd in gencom.extension_dict:
422 ext_name = gencom.extension_dict[cmd]
Yiwei Zhangaeaa8672019-10-16 18:59:41 -0700423 f.write(gencom.indent(2) + 'ProcHook::' +
424 gencom.base_ext_name(ext_name) + ',\n')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700425
426 if gencom.is_extension_internal(ext_name):
427 f.write("""\
428 nullptr,
429 nullptr,\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700430 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700431 f.write("""\
432 reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """),
433 nullptr,\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700434 else:
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700435 f.write(gencom.indent(2) + _get_proc_hook_enum(cmd) + ',\n')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700436 f.write("""\
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700437 reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """),
Adithya Srinivasan01364142019-07-02 15:52:49 -0700438 nullptr,\n""")
439
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700440 f.write(gencom.indent(1) + '},\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700441
Adithya Srinivasan01364142019-07-02 15:52:49 -0700442
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700443def _define_device_proc_hook(cmd, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700444 """Emits definition of a device ProcHook.
445
446 Args:
447 cmd: Vulkan function name.
448 f: Output file handle.
449 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700450 f.write(gencom.indent(1) + '{\n')
451 f.write(gencom.indent(2) + '\"' + cmd + '\",\n')
452 f.write(gencom.indent(2) + 'ProcHook::DEVICE,\n')
453
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700454 if (cmd in gencom.extension_dict or
455 gencom.version_dict[cmd] != 'VK_VERSION_1_0'):
456 ext_name = ''
457 ext_hook = ''
458 if cmd in gencom.extension_dict:
459 ext_name = gencom.extension_dict[cmd]
460 ext_hook = 'ProcHook::' + gencom.base_ext_name(ext_name)
461 else:
462 ext_name = gencom.version_dict[cmd]
463 ext_hook = _get_proc_hook_enum(cmd)
464 f.write(gencom.indent(2) + ext_hook + ',\n')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700465
466 if gencom.is_extension_internal(ext_name):
467 f.write("""\
468 nullptr,
469 nullptr,\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700470 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700471 f.write("""\
472 reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """),
473 reinterpret_cast<PFN_vkVoidFunction>(checked""" +
474 gencom.base_name(cmd) + '),\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700475
476 else:
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700477 f.write(gencom.indent(2) + _get_proc_hook_enum(cmd) + ',\n')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700478 f.write("""\
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700479 reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """),
Adithya Srinivasan01364142019-07-02 15:52:49 -0700480 nullptr,\n""")
481
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700482 f.write(gencom.indent(1) + '},\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700483
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700484
485def gen_cpp():
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700486 """Generates the driver_gen.cpp file.
487 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700488 genfile = os.path.join(os.path.dirname(__file__),
489 '..', 'libvulkan', 'driver_gen.cpp')
490
491 with open(genfile, 'w') as f:
492 f.write(gencom.copyright_and_warning(2016))
493 f.write("""\
494#include <log/log.h>
Adithya Srinivasan01364142019-07-02 15:52:49 -0700495#include <string.h>
496
497#include <algorithm>
498
499#include "driver.h"
500
501namespace vulkan {
502namespace driver {
503
504namespace {
505
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700506// clang-format off\n\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700507
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700508 for cmd in gencom.command_list:
509 _define_proc_hook_stub(cmd, f)
Adithya Srinivasan01364142019-07-02 15:52:49 -0700510
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700511 f.write("""\
512// clang-format on
Adithya Srinivasan01364142019-07-02 15:52:49 -0700513
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700514const ProcHook g_proc_hooks[] = {
515 // clang-format off\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700516
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700517 sorted_command_list = sorted(gencom.command_list)
518 for cmd in sorted_command_list:
519 if _is_intercepted(cmd):
520 if gencom.is_globally_dispatched(cmd):
521 _define_global_proc_hook(cmd, f)
522 elif gencom.is_instance_dispatched(cmd):
523 _define_instance_proc_hook(cmd, f)
524 elif gencom.is_device_dispatched(cmd):
525 _define_device_proc_hook(cmd, f)
Adithya Srinivasan01364142019-07-02 15:52:49 -0700526
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700527 f.write("""\
528 // clang-format on
529};
530
531} // namespace
532
533const ProcHook* GetProcHook(const char* name) {
Yiwei Zhang93b521c2020-07-11 16:32:09 -0700534 auto begin = std::cbegin(g_proc_hooks);
535 auto end = std::cend(g_proc_hooks);
536 auto hook = std::lower_bound(
Adithya Srinivasan01364142019-07-02 15:52:49 -0700537 begin, end, name,
538 [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; });
539 return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr;
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700540}
Adithya Srinivasan01364142019-07-02 15:52:49 -0700541
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700542ProcHook::Extension GetProcHookExtension(const char* name) {
543 // clang-format off\n""")
Adithya Srinivasan01364142019-07-02 15:52:49 -0700544
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700545 for ext in _KNOWN_EXTENSIONS:
546 f.write(gencom.indent(1) + 'if (strcmp(name, \"' + ext +
547 '\") == 0) return ProcHook::' + gencom.base_ext_name(ext) + ';\n')
Adithya Srinivasan01364142019-07-02 15:52:49 -0700548
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700549 f.write("""\
550 // clang-format on
551 return ProcHook::EXTENSION_UNKNOWN;
552}
553
554#define UNLIKELY(expr) __builtin_expect((expr), 0)
555
556#define INIT_PROC(required, obj, proc) \\
557 do { \\
558 data.driver.proc = \\
559 reinterpret_cast<PFN_vk##proc>(get_proc(obj, "vk" #proc)); \\
560 if (UNLIKELY(required && !data.driver.proc)) { \\
561 ALOGE("missing " #obj " proc: vk" #proc); \\
562 success = false; \\
563 } \\
564 } while (0)
565
566#define INIT_PROC_EXT(ext, required, obj, proc) \\
567 do { \\
568 if (extensions[ProcHook::ext]) \\
569 INIT_PROC(required, obj, proc); \\
570 } while (0)
571
572bool InitDriverTable(VkInstance instance,
Adithya Srinivasan01364142019-07-02 15:52:49 -0700573 PFN_vkGetInstanceProcAddr get_proc,
574 const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
575 auto& data = GetData(instance);
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700576 bool success = true;
Adithya Srinivasan01364142019-07-02 15:52:49 -0700577
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700578 // clang-format off\n""")
579
580 for cmd in gencom.command_list:
581 if _is_instance_driver_table_entry(cmd):
582 gencom.init_proc(cmd, f)
583
584 f.write("""\
585 // clang-format on
586
587 return success;
588}
589
590bool InitDriverTable(VkDevice dev,
Adithya Srinivasan01364142019-07-02 15:52:49 -0700591 PFN_vkGetDeviceProcAddr get_proc,
592 const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
593 auto& data = GetData(dev);
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700594 bool success = true;
595
596 // clang-format off\n""")
597
598 for cmd in gencom.command_list:
599 if _is_device_driver_table_entry(cmd):
600 gencom.init_proc(cmd, f)
601
602 f.write("""\
603 // clang-format on
604
605 return success;
606}
607
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700608const std::pair<const char*, uint32_t> g_promoted_instance_extensions[] = {
609 // clang-format off\n""")
610
611 for key, value in sorted(gencom.promoted_inst_ext_dict.items()):
612 f.write(gencom.indent(1) + 'std::make_pair("' + key + '", ' + value + '),\n')
613
614 f.write("""\
615 // clang-format on
616};
617
618std::optional<uint32_t> GetInstanceExtensionPromotedVersion(const char* name) {
619 auto begin = std::cbegin(g_promoted_instance_extensions);
620 auto end = std::cend(g_promoted_instance_extensions);
621 auto iter =
622 std::lower_bound(begin, end, name,
623 [](const std::pair<const char*, uint32_t>& e,
624 const char* n) { return strcmp(e.first, n) < 0; });
625 return (iter < end && strcmp(iter->first, name) == 0)
626 ? std::optional<uint32_t>(iter->second)
627 : std::nullopt;
628}
629
630uint32_t CountPromotedInstanceExtensions(uint32_t begin_version,
631 uint32_t end_version) {
632 auto begin = std::cbegin(g_promoted_instance_extensions);
633 auto end = std::cend(g_promoted_instance_extensions);
634 uint32_t count = 0;
635
636 for (auto iter = begin; iter != end; iter++)
637 if (iter->second > begin_version && iter->second <= end_version)
638 count++;
639
640 return count;
641}
642
643std::vector<const char*> GetPromotedInstanceExtensions(uint32_t begin_version,
644 uint32_t end_version) {
645 auto begin = std::cbegin(g_promoted_instance_extensions);
646 auto end = std::cend(g_promoted_instance_extensions);
647 std::vector<const char*> extensions;
648
649 for (auto iter = begin; iter != end; iter++)
650 if (iter->second > begin_version && iter->second <= end_version)
651 extensions.emplace_back(iter->first);
652
653 return extensions;
654}
655
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700656} // namespace driver
657} // namespace vulkan\n""")
658
Adithya Srinivasan8dce9d72019-07-11 14:26:04 -0700659 f.close()
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700660 gencom.run_clang_format(genfile)