blob: 866c1b7b757c507247e9f1345148b5af7d15932e [file] [log] [blame]
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -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"""Provide the utilities for framework generation.
18"""
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070019
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070020import os
21import subprocess
22import xml.etree.ElementTree as element_tree
Adithya Srinivasan8dce9d72019-07-11 14:26:04 -070023
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070024# Extensions unsupported on Android.
Yiwei Zhang95924222020-06-15 09:39:03 -070025_BLOCKED_EXTENSIONS = [
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070026 'VK_EXT_acquire_xlib_display',
27 'VK_EXT_direct_mode_display',
Yiwei Zhang6be097b2020-10-19 20:22:05 -070028 'VK_EXT_directfb_surface',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070029 'VK_EXT_display_control',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070030 'VK_EXT_display_surface_counter',
31 'VK_EXT_full_screen_exclusive',
32 'VK_EXT_headless_surface',
33 'VK_EXT_metal_surface',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070034 'VK_FUCHSIA_imagepipe_surface',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070035 'VK_GGP_stream_descriptor_surface',
Trevor David Black4c622a02021-06-28 22:46:14 +000036 'VK_HUAWEI_subpass_shading',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070037 'VK_KHR_display',
38 'VK_KHR_display_swapchain',
39 'VK_KHR_external_fence_win32',
40 'VK_KHR_external_memory_win32',
41 'VK_KHR_external_semaphore_win32',
42 'VK_KHR_mir_surface',
43 'VK_KHR_wayland_surface',
44 'VK_KHR_win32_keyed_mutex',
45 'VK_KHR_win32_surface',
46 'VK_KHR_xcb_surface',
47 'VK_KHR_xlib_surface',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070048 'VK_MVK_ios_surface',
49 'VK_MVK_macos_surface',
50 'VK_NN_vi_surface',
Trevor David Black4c622a02021-06-28 22:46:14 +000051 'VK_NV_acquire_winrt_display',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070052 'VK_NV_cooperative_matrix',
53 'VK_NV_coverage_reduction_mode',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070054 'VK_NV_external_memory_win32',
55 'VK_NV_win32_keyed_mutex',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070056 'VK_NVX_image_view_handle',
Trevor David Black4c622a02021-06-28 22:46:14 +000057 'VK_QNX_screen_surface',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070058]
59
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070060# Extensions having functions exported by the loader.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070061_EXPORTED_EXTENSIONS = [
Yiwei Zhangdc792f52019-10-10 16:29:42 -070062 'VK_ANDROID_external_memory_android_hardware_buffer',
63 'VK_KHR_android_surface',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070064 'VK_KHR_surface',
65 'VK_KHR_swapchain',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070066]
67
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070068# Functions optional on Android even if extension is advertised.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070069_OPTIONAL_COMMANDS = [
Yiwei Zhangdc792f52019-10-10 16:29:42 -070070 'vkGetSwapchainGrallocUsageANDROID',
71 'vkGetSwapchainGrallocUsage2ANDROID',
Trevor David Black2cc44682022-03-09 00:31:38 +000072 'vkGetSwapchainGrallocUsage3ANDROID',
Trevor David Blackb6ca8422023-07-26 20:00:04 +000073 'vkGetSwapchainGrallocUsage4ANDROID',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070074]
75
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070076# Dict for mapping dispatch table to a type.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070077_DISPATCH_TYPE_DICT = {
78 'VkInstance ': 'Instance',
79 'VkPhysicalDevice ': 'Instance',
80 'VkDevice ': 'Device',
81 'VkQueue ': 'Device',
82 'VkCommandBuffer ': 'Device'
83}
Adithya Srinivasan8dce9d72019-07-11 14:26:04 -070084
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070085# Dict for mapping a function to its alias.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070086alias_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070087
88# List of all the Vulkan functions.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070089command_list = []
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070090
91# Dict for mapping a function to an extension.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070092extension_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070093
94# Dict for mapping a function to all its parameters.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070095param_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070096
97# Dict for mapping a function to its return type.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070098return_type_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070099
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700100# List of the sorted Vulkan version codes. e.g. '1_0', '1_1'.
101version_code_list = []
102
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700103# Dict for mapping a function to the core Vulkan API version.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700104version_dict = {}
Adithya Srinivasan01364142019-07-02 15:52:49 -0700105
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700106# Dict for mapping a promoted instance extension to the core Vulkan API version.
107promoted_inst_ext_dict = {}
108
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700109
110def indent(num):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700111 """Returns the requested indents.
112
113 Args:
114 num: Number of the 4-space indents.
115 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700116 return ' ' * num
117
118
119def copyright_and_warning(year):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700120 """Returns the standard copyright and warning codes.
121
122 Args:
123 year: An integer year for the copyright.
124 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700125 return """\
126/*
127 * Copyright """ + str(year) + """ The Android Open Source Project
128 *
129 * Licensed under the Apache License, Version 2.0 (the "License");
130 * you may not use this file except in compliance with the License.
131 * You may obtain a copy of the License at
132 *
133 * http://www.apache.org/licenses/LICENSE-2.0
134 *
135 * Unless required by applicable law or agreed to in writing, software
136 * distributed under the License is distributed on an "AS IS" BASIS,
137 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138 * See the License for the specific language governing permissions and
139 * limitations under the License.
140 */
141
142// WARNING: This file is generated. See ../README.md for instructions.
143
144"""
145
146
147def run_clang_format(args):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700148 """Run clang format on the file.
149
150 Args:
151 args: The file to be formatted.
152 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700153 clang_call = ['clang-format', '--style', 'file', '-i', args]
154 subprocess.check_call(clang_call)
155
156
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700157def is_extension_internal(ext):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700158 """Returns true if an extension is internal to the loader and drivers.
159
160 The loader should not enumerate this extension.
161
162 Args:
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700163 ext: Vulkan extension name.
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700164 """
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700165 return ext == 'VK_ANDROID_native_buffer'
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700166
167
168def base_name(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700169 """Returns a function name without the 'vk' prefix.
170
171 Args:
172 cmd: Vulkan function name.
173 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700174 return cmd[2:]
175
176
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700177def base_ext_name(ext):
178 """Returns an extension name without the 'VK_' prefix.
179
180 Args:
181 ext: Vulkan extension name.
182 """
183 return ext[3:]
184
185
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700186def version_code(version):
187 """Returns the version code from a version string.
188
189 Args:
190 version: Vulkan version string.
191 """
192 return version[11:]
193
194
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700195def version_2_api_version(version):
196 """Returns the api version from a version string.
197
198 Args:
199 version: Vulkan version string.
200 """
201 return 'VK_API' + version[2:]
202
203
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700204def is_function_supported(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700205 """Returns true if a function is core or from a supportable extension.
206
207 Args:
208 cmd: Vulkan function name.
209 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700210 if cmd not in extension_dict:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700211 return True
212 else:
Yiwei Zhang95924222020-06-15 09:39:03 -0700213 if extension_dict[cmd] not in _BLOCKED_EXTENSIONS:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700214 return True
215 return False
216
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700217
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700218def get_dispatch_table_type(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700219 """Returns the dispatch table type for a function.
220
221 Args:
222 cmd: Vulkan function name.
223 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700224 if cmd not in param_dict:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700225 return None
226
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700227 if param_dict[cmd]:
228 return _DISPATCH_TYPE_DICT.get(param_dict[cmd][0][0], 'Global')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700229 return 'Global'
230
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700231
232def is_globally_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700233 """Returns true if the function is global, which is not dispatched.
234
235 Only global functions and functions handled in the loader top without calling
236 into lower layers are not dispatched.
237
238 Args:
239 cmd: Vulkan function name.
240 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700241 return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Global'
242
243
244def is_instance_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700245 """Returns true for functions that can have instance-specific dispatch.
246
247 Args:
248 cmd: Vulkan function name.
249 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700250 return (is_function_supported(cmd) and
251 get_dispatch_table_type(cmd) == 'Instance')
252
253
254def is_device_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700255 """Returns true for functions that can have device-specific dispatch.
256
257 Args:
258 cmd: Vulkan function name.
259 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700260 return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Device'
261
262
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700263def is_extension_exported(ext):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700264 """Returns true if an extension has functions exported by the loader.
265
266 E.g. applications can directly link to an extension function.
267
268 Args:
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700269 ext: Vulkan extension name.
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700270 """
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700271 return ext in _EXPORTED_EXTENSIONS
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700272
273
274def is_function_exported(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700275 """Returns true if a function is exported from the Android Vulkan library.
276
277 Functions in the core API and in loader extensions are exported.
278
279 Args:
280 cmd: Vulkan function name.
281 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700282 if is_function_supported(cmd):
283 if cmd in extension_dict:
284 return is_extension_exported(extension_dict[cmd])
285 return True
286 return False
287
288
289def is_instance_dispatch_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700290 """Returns true if a function is exported and instance-dispatched.
291
292 Args:
293 cmd: Vulkan function name.
294 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700295 if cmd == 'vkEnumerateDeviceLayerProperties':
296 # deprecated, unused internally - @dbd33bc
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700297 return False
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700298 return is_function_exported(cmd) and is_instance_dispatched(cmd)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700299
300
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700301def is_device_dispatch_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700302 """Returns true if a function is exported and device-dispatched.
303
304 Args:
305 cmd: Vulkan function name.
306 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700307 return is_function_exported(cmd) and is_device_dispatched(cmd)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700308
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700309
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700310def init_proc(name, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700311 """Emits code to invoke INIT_PROC or INIT_PROC_EXT.
312
313 Args:
314 name: Vulkan function name.
315 f: Output file handle.
316 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700317 f.write(indent(1))
318 if name in extension_dict:
Yiwei Zhangaeaa8672019-10-16 18:59:41 -0700319 f.write('INIT_PROC_EXT(' + base_ext_name(extension_dict[name]) + ', ')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700320 else:
321 f.write('INIT_PROC(')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700322
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700323 if name in _OPTIONAL_COMMANDS:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700324 f.write('false, ')
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700325 elif version_dict[name] == 'VK_VERSION_1_0':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700326 f.write('true, ')
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700327 else:
328 f.write('false, ')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700329
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700330 if is_instance_dispatched(name):
331 f.write('instance, ')
332 else:
333 f.write('dev, ')
334
335 f.write(base_name(name) + ');\n')
336
337
338def parse_vulkan_registry():
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700339 """Parses Vulkan registry into the below global variables.
340
341 alias_dict
342 command_list
343 extension_dict
344 param_dict
345 return_type_dict
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700346 version_code_list
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700347 version_dict
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700348 promoted_inst_ext_dict
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700349 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700350 registry = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..',
351 'external', 'vulkan-headers', 'registry', 'vk.xml')
352 tree = element_tree.parse(registry)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700353 root = tree.getroot()
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700354 for commands in root.iter('commands'):
355 for command in commands:
356 if command.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700357 parameter_list = []
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700358 protoset = False
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700359 cmd_name = ''
360 cmd_type = ''
361 if command.get('alias') is not None:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700362 alias = command.get('alias')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700363 cmd_name = command.get('name')
364 alias_dict[cmd_name] = alias
365 command_list.append(cmd_name)
366 param_dict[cmd_name] = param_dict[alias].copy()
367 return_type_dict[cmd_name] = return_type_dict[alias]
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700368 for params in command:
Yiwei Zhang4bc489b2019-09-23 15:17:22 -0700369 if params.tag == 'param':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700370 param_type = ''
371 if params.text is not None and params.text.strip():
372 param_type = params.text.strip() + ' '
373 type_val = params.find('type')
374 param_type = param_type + type_val.text
375 if type_val.tail is not None:
376 param_type += type_val.tail.strip() + ' '
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700377 pname = params.find('name')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700378 param_name = pname.text
379 if pname.tail is not None and pname.tail.strip():
380 parameter_list.append(
381 (param_type, param_name, pname.tail.strip()))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700382 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700383 parameter_list.append((param_type, param_name))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700384 if params.tag == 'proto':
385 for c in params:
386 if c.tag == 'type':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700387 cmd_type = c.text
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700388 if c.tag == 'name':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700389 cmd_name = c.text
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700390 protoset = True
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700391 command_list.append(cmd_name)
392 return_type_dict[cmd_name] = cmd_type
393 if protoset:
394 param_dict[cmd_name] = parameter_list.copy()
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700395
396 for exts in root.iter('extensions'):
397 for extension in exts:
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700398 apiversion = 'VK_VERSION_1_0'
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700399 if extension.tag == 'extension':
400 extname = extension.get('name')
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700401 if (extension.get('type') == 'instance' and
402 extension.get('promotedto') is not None):
403 promoted_inst_ext_dict[extname] = \
404 version_2_api_version(extension.get('promotedto'))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700405 for req in extension:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700406 if req.get('feature') is not None:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700407 apiversion = req.get('feature')
408 for commands in req:
409 if commands.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700410 cmd_name = commands.get('name')
411 if cmd_name not in extension_dict:
412 extension_dict[cmd_name] = extname
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700413 version_dict[cmd_name] = apiversion
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700414
415 for feature in root.iter('feature'):
416 apiversion = feature.get('name')
417 for req in feature:
418 for command in req:
419 if command.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700420 cmd_name = command.get('name')
421 if cmd_name in command_list:
422 version_dict[cmd_name] = apiversion
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700423
424 version_code_set = set()
425 for version in version_dict.values():
426 version_code_set.add(version_code(version))
427 for code in sorted(version_code_set):
428 version_code_list.append(code)