blob: e9a96f3959da6ff9c80ec5644b7eb9ea97718ebb [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',
36 'VK_KHR_display',
37 'VK_KHR_display_swapchain',
38 'VK_KHR_external_fence_win32',
39 'VK_KHR_external_memory_win32',
40 'VK_KHR_external_semaphore_win32',
41 'VK_KHR_mir_surface',
42 'VK_KHR_wayland_surface',
43 'VK_KHR_win32_keyed_mutex',
44 'VK_KHR_win32_surface',
45 'VK_KHR_xcb_surface',
46 'VK_KHR_xlib_surface',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070047 'VK_MVK_ios_surface',
48 'VK_MVK_macos_surface',
49 'VK_NN_vi_surface',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070050 'VK_NV_cooperative_matrix',
51 'VK_NV_coverage_reduction_mode',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070052 'VK_NV_external_memory_win32',
53 'VK_NV_win32_keyed_mutex',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070054 'VK_NVX_image_view_handle',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070055]
56
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070057# Extensions having functions exported by the loader.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070058_EXPORTED_EXTENSIONS = [
Yiwei Zhangdc792f52019-10-10 16:29:42 -070059 'VK_ANDROID_external_memory_android_hardware_buffer',
60 'VK_KHR_android_surface',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070061 'VK_KHR_surface',
62 'VK_KHR_swapchain',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070063]
64
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070065# Functions optional on Android even if extension is advertised.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070066_OPTIONAL_COMMANDS = [
Yiwei Zhangdc792f52019-10-10 16:29:42 -070067 'vkGetSwapchainGrallocUsageANDROID',
68 'vkGetSwapchainGrallocUsage2ANDROID',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070069]
70
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070071# Dict for mapping dispatch table to a type.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070072_DISPATCH_TYPE_DICT = {
73 'VkInstance ': 'Instance',
74 'VkPhysicalDevice ': 'Instance',
75 'VkDevice ': 'Device',
76 'VkQueue ': 'Device',
77 'VkCommandBuffer ': 'Device'
78}
Adithya Srinivasan8dce9d72019-07-11 14:26:04 -070079
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070080# Dict for mapping a function to its alias.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070081alias_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070082
83# List of all the Vulkan functions.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070084command_list = []
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070085
86# Dict for mapping a function to an extension.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070087extension_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070088
89# Dict for mapping a function to all its parameters.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070090param_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070091
92# Dict for mapping a function to its return type.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070093return_type_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070094
Yiwei Zhang7cc36a52019-10-11 19:02:09 -070095# List of the sorted Vulkan version codes. e.g. '1_0', '1_1'.
96version_code_list = []
97
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070098# Dict for mapping a function to the core Vulkan API version.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070099version_dict = {}
Adithya Srinivasan01364142019-07-02 15:52:49 -0700100
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700101
102def indent(num):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700103 """Returns the requested indents.
104
105 Args:
106 num: Number of the 4-space indents.
107 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700108 return ' ' * num
109
110
111def copyright_and_warning(year):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700112 """Returns the standard copyright and warning codes.
113
114 Args:
115 year: An integer year for the copyright.
116 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700117 return """\
118/*
119 * Copyright """ + str(year) + """ The Android Open Source Project
120 *
121 * Licensed under the Apache License, Version 2.0 (the "License");
122 * you may not use this file except in compliance with the License.
123 * You may obtain a copy of the License at
124 *
125 * http://www.apache.org/licenses/LICENSE-2.0
126 *
127 * Unless required by applicable law or agreed to in writing, software
128 * distributed under the License is distributed on an "AS IS" BASIS,
129 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130 * See the License for the specific language governing permissions and
131 * limitations under the License.
132 */
133
134// WARNING: This file is generated. See ../README.md for instructions.
135
136"""
137
138
139def run_clang_format(args):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700140 """Run clang format on the file.
141
142 Args:
143 args: The file to be formatted.
144 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700145 clang_call = ['clang-format', '--style', 'file', '-i', args]
146 subprocess.check_call(clang_call)
147
148
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700149def is_extension_internal(ext):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700150 """Returns true if an extension is internal to the loader and drivers.
151
152 The loader should not enumerate this extension.
153
154 Args:
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700155 ext: Vulkan extension name.
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700156 """
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700157 return ext == 'VK_ANDROID_native_buffer'
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700158
159
160def base_name(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700161 """Returns a function name without the 'vk' prefix.
162
163 Args:
164 cmd: Vulkan function name.
165 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700166 return cmd[2:]
167
168
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700169def base_ext_name(ext):
170 """Returns an extension name without the 'VK_' prefix.
171
172 Args:
173 ext: Vulkan extension name.
174 """
175 return ext[3:]
176
177
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700178def version_code(version):
179 """Returns the version code from a version string.
180
181 Args:
182 version: Vulkan version string.
183 """
184 return version[11:]
185
186
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700187def is_function_supported(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700188 """Returns true if a function is core or from a supportable extension.
189
190 Args:
191 cmd: Vulkan function name.
192 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700193 if cmd not in extension_dict:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700194 return True
195 else:
Yiwei Zhang95924222020-06-15 09:39:03 -0700196 if extension_dict[cmd] not in _BLOCKED_EXTENSIONS:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700197 return True
198 return False
199
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700200
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700201def get_dispatch_table_type(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700202 """Returns the dispatch table type for a function.
203
204 Args:
205 cmd: Vulkan function name.
206 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700207 if cmd not in param_dict:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700208 return None
209
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700210 if param_dict[cmd]:
211 return _DISPATCH_TYPE_DICT.get(param_dict[cmd][0][0], 'Global')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700212 return 'Global'
213
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700214
215def is_globally_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700216 """Returns true if the function is global, which is not dispatched.
217
218 Only global functions and functions handled in the loader top without calling
219 into lower layers are not dispatched.
220
221 Args:
222 cmd: Vulkan function name.
223 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700224 return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Global'
225
226
227def is_instance_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700228 """Returns true for functions that can have instance-specific dispatch.
229
230 Args:
231 cmd: Vulkan function name.
232 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700233 return (is_function_supported(cmd) and
234 get_dispatch_table_type(cmd) == 'Instance')
235
236
237def is_device_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700238 """Returns true for functions that can have device-specific dispatch.
239
240 Args:
241 cmd: Vulkan function name.
242 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700243 return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Device'
244
245
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700246def is_extension_exported(ext):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700247 """Returns true if an extension has functions exported by the loader.
248
249 E.g. applications can directly link to an extension function.
250
251 Args:
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700252 ext: Vulkan extension name.
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700253 """
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700254 return ext in _EXPORTED_EXTENSIONS
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700255
256
257def is_function_exported(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700258 """Returns true if a function is exported from the Android Vulkan library.
259
260 Functions in the core API and in loader extensions are exported.
261
262 Args:
263 cmd: Vulkan function name.
264 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700265 if is_function_supported(cmd):
266 if cmd in extension_dict:
267 return is_extension_exported(extension_dict[cmd])
268 return True
269 return False
270
271
272def is_instance_dispatch_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700273 """Returns true if a function is exported and instance-dispatched.
274
275 Args:
276 cmd: Vulkan function name.
277 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700278 if cmd == 'vkEnumerateDeviceLayerProperties':
279 # deprecated, unused internally - @dbd33bc
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700280 return False
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700281 return is_function_exported(cmd) and is_instance_dispatched(cmd)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700282
283
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700284def is_device_dispatch_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700285 """Returns true if a function is exported and device-dispatched.
286
287 Args:
288 cmd: Vulkan function name.
289 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700290 return is_function_exported(cmd) and is_device_dispatched(cmd)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700291
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700292
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700293def init_proc(name, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700294 """Emits code to invoke INIT_PROC or INIT_PROC_EXT.
295
296 Args:
297 name: Vulkan function name.
298 f: Output file handle.
299 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700300 f.write(indent(1))
301 if name in extension_dict:
Yiwei Zhangaeaa8672019-10-16 18:59:41 -0700302 f.write('INIT_PROC_EXT(' + base_ext_name(extension_dict[name]) + ', ')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700303 else:
304 f.write('INIT_PROC(')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700305
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700306 if name in _OPTIONAL_COMMANDS:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700307 f.write('false, ')
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700308 elif version_dict[name] == 'VK_VERSION_1_0':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700309 f.write('true, ')
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700310 else:
311 f.write('false, ')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700312
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700313 if is_instance_dispatched(name):
314 f.write('instance, ')
315 else:
316 f.write('dev, ')
317
318 f.write(base_name(name) + ');\n')
319
320
321def parse_vulkan_registry():
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700322 """Parses Vulkan registry into the below global variables.
323
324 alias_dict
325 command_list
326 extension_dict
327 param_dict
328 return_type_dict
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700329 version_code_list
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700330 version_dict
331 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700332 registry = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..',
333 'external', 'vulkan-headers', 'registry', 'vk.xml')
334 tree = element_tree.parse(registry)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700335 root = tree.getroot()
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700336 for commands in root.iter('commands'):
337 for command in commands:
338 if command.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700339 parameter_list = []
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700340 protoset = False
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700341 cmd_name = ''
342 cmd_type = ''
343 if command.get('alias') is not None:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700344 alias = command.get('alias')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700345 cmd_name = command.get('name')
346 alias_dict[cmd_name] = alias
347 command_list.append(cmd_name)
348 param_dict[cmd_name] = param_dict[alias].copy()
349 return_type_dict[cmd_name] = return_type_dict[alias]
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700350 for params in command:
Yiwei Zhang4bc489b2019-09-23 15:17:22 -0700351 if params.tag == 'param':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700352 param_type = ''
353 if params.text is not None and params.text.strip():
354 param_type = params.text.strip() + ' '
355 type_val = params.find('type')
356 param_type = param_type + type_val.text
357 if type_val.tail is not None:
358 param_type += type_val.tail.strip() + ' '
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700359 pname = params.find('name')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700360 param_name = pname.text
361 if pname.tail is not None and pname.tail.strip():
362 parameter_list.append(
363 (param_type, param_name, pname.tail.strip()))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700364 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700365 parameter_list.append((param_type, param_name))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700366 if params.tag == 'proto':
367 for c in params:
368 if c.tag == 'type':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700369 cmd_type = c.text
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700370 if c.tag == 'name':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700371 cmd_name = c.text
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700372 protoset = True
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700373 command_list.append(cmd_name)
374 return_type_dict[cmd_name] = cmd_type
375 if protoset:
376 param_dict[cmd_name] = parameter_list.copy()
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700377
378 for exts in root.iter('extensions'):
379 for extension in exts:
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700380 apiversion = 'VK_VERSION_1_0'
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700381 if extension.tag == 'extension':
382 extname = extension.get('name')
383 for req in extension:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700384 if req.get('feature') is not None:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700385 apiversion = req.get('feature')
386 for commands in req:
387 if commands.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700388 cmd_name = commands.get('name')
389 if cmd_name not in extension_dict:
390 extension_dict[cmd_name] = extname
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700391 version_dict[cmd_name] = apiversion
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700392
393 for feature in root.iter('feature'):
394 apiversion = feature.get('name')
395 for req in feature:
396 for command in req:
397 if command.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700398 cmd_name = command.get('name')
399 if cmd_name in command_list:
400 version_dict[cmd_name] = apiversion
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700401
402 version_code_set = set()
403 for version in version_dict.values():
404 version_code_set.add(version_code(version))
405 for code in sorted(version_code_set):
406 version_code_list.append(code)