blob: cf370fafe5cf1f8f9bdea9751250ac95ae1b524a [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 Zhang1ca59c12019-10-10 12:54:42 -070025_BLACKLISTED_EXTENSIONS = [
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070026 'VK_EXT_acquire_xlib_display',
27 'VK_EXT_direct_mode_display',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070028 'VK_EXT_display_control',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070029 'VK_EXT_display_surface_counter',
30 'VK_EXT_full_screen_exclusive',
31 'VK_EXT_headless_surface',
32 'VK_EXT_metal_surface',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070033 'VK_FUCHSIA_imagepipe_surface',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070034 'VK_GGP_stream_descriptor_surface',
35 'VK_KHR_display',
36 'VK_KHR_display_swapchain',
37 'VK_KHR_external_fence_win32',
38 'VK_KHR_external_memory_win32',
39 'VK_KHR_external_semaphore_win32',
40 'VK_KHR_mir_surface',
41 'VK_KHR_wayland_surface',
42 'VK_KHR_win32_keyed_mutex',
43 'VK_KHR_win32_surface',
44 'VK_KHR_xcb_surface',
45 'VK_KHR_xlib_surface',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070046 'VK_MVK_ios_surface',
47 'VK_MVK_macos_surface',
48 'VK_NN_vi_surface',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070049 'VK_NV_cooperative_matrix',
50 'VK_NV_coverage_reduction_mode',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070051 'VK_NV_external_memory_win32',
52 'VK_NV_win32_keyed_mutex',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070053 'VK_NVX_image_view_handle',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070054]
55
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070056# Extensions having functions exported by the loader.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070057_EXPORTED_EXTENSIONS = [
Yiwei Zhangdc792f52019-10-10 16:29:42 -070058 'VK_ANDROID_external_memory_android_hardware_buffer',
59 'VK_KHR_android_surface',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070060 'VK_KHR_surface',
61 'VK_KHR_swapchain',
Yiwei Zhangdc792f52019-10-10 16:29:42 -070062]
63
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070064# Functions optional on Android even if extension is advertised.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070065_OPTIONAL_COMMANDS = [
Yiwei Zhangdc792f52019-10-10 16:29:42 -070066 'vkGetSwapchainGrallocUsageANDROID',
67 'vkGetSwapchainGrallocUsage2ANDROID',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070068]
69
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070070# Dict for mapping dispatch table to a type.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070071_DISPATCH_TYPE_DICT = {
72 'VkInstance ': 'Instance',
73 'VkPhysicalDevice ': 'Instance',
74 'VkDevice ': 'Device',
75 'VkQueue ': 'Device',
76 'VkCommandBuffer ': 'Device'
77}
Adithya Srinivasan8dce9d72019-07-11 14:26:04 -070078
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070079# Dict for mapping a function to its alias.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070080alias_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070081
82# List of all the Vulkan functions.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070083command_list = []
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070084
85# Dict for mapping a function to an extension.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070086extension_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070087
88# Dict for mapping a function to all its parameters.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070089param_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070090
91# Dict for mapping a function to its return type.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070092return_type_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070093
Yiwei Zhang7cc36a52019-10-11 19:02:09 -070094# List of the sorted Vulkan version codes. e.g. '1_0', '1_1'.
95version_code_list = []
96
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070097# Dict for mapping a function to the core Vulkan API version.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070098version_dict = {}
Adithya Srinivasan01364142019-07-02 15:52:49 -070099
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700100
101def indent(num):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700102 """Returns the requested indents.
103
104 Args:
105 num: Number of the 4-space indents.
106 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700107 return ' ' * num
108
109
110def copyright_and_warning(year):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700111 """Returns the standard copyright and warning codes.
112
113 Args:
114 year: An integer year for the copyright.
115 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700116 return """\
117/*
118 * Copyright """ + str(year) + """ The Android Open Source Project
119 *
120 * Licensed under the Apache License, Version 2.0 (the "License");
121 * you may not use this file except in compliance with the License.
122 * You may obtain a copy of the License at
123 *
124 * http://www.apache.org/licenses/LICENSE-2.0
125 *
126 * Unless required by applicable law or agreed to in writing, software
127 * distributed under the License is distributed on an "AS IS" BASIS,
128 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129 * See the License for the specific language governing permissions and
130 * limitations under the License.
131 */
132
133// WARNING: This file is generated. See ../README.md for instructions.
134
135"""
136
137
138def run_clang_format(args):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700139 """Run clang format on the file.
140
141 Args:
142 args: The file to be formatted.
143 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700144 clang_call = ['clang-format', '--style', 'file', '-i', args]
145 subprocess.check_call(clang_call)
146
147
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700148def is_extension_internal(ext):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700149 """Returns true if an extension is internal to the loader and drivers.
150
151 The loader should not enumerate this extension.
152
153 Args:
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700154 ext: Vulkan extension name.
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700155 """
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700156 return ext == 'VK_ANDROID_native_buffer'
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700157
158
159def base_name(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700160 """Returns a function name without the 'vk' prefix.
161
162 Args:
163 cmd: Vulkan function name.
164 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700165 return cmd[2:]
166
167
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700168def base_ext_name(ext):
169 """Returns an extension name without the 'VK_' prefix.
170
171 Args:
172 ext: Vulkan extension name.
173 """
174 return ext[3:]
175
176
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700177def version_code(version):
178 """Returns the version code from a version string.
179
180 Args:
181 version: Vulkan version string.
182 """
183 return version[11:]
184
185
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700186def is_function_supported(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700187 """Returns true if a function is core or from a supportable extension.
188
189 Args:
190 cmd: Vulkan function name.
191 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700192 if cmd not in extension_dict:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700193 return True
194 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700195 if extension_dict[cmd] not in _BLACKLISTED_EXTENSIONS:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700196 return True
197 return False
198
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700199
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700200def get_dispatch_table_type(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700201 """Returns the dispatch table type for a function.
202
203 Args:
204 cmd: Vulkan function name.
205 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700206 if cmd not in param_dict:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700207 return None
208
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700209 if param_dict[cmd]:
210 return _DISPATCH_TYPE_DICT.get(param_dict[cmd][0][0], 'Global')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700211 return 'Global'
212
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700213
214def is_globally_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700215 """Returns true if the function is global, which is not dispatched.
216
217 Only global functions and functions handled in the loader top without calling
218 into lower layers are not dispatched.
219
220 Args:
221 cmd: Vulkan function name.
222 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700223 return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Global'
224
225
226def is_instance_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700227 """Returns true for functions that can have instance-specific dispatch.
228
229 Args:
230 cmd: Vulkan function name.
231 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700232 return (is_function_supported(cmd) and
233 get_dispatch_table_type(cmd) == 'Instance')
234
235
236def is_device_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700237 """Returns true for functions that can have device-specific dispatch.
238
239 Args:
240 cmd: Vulkan function name.
241 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700242 return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Device'
243
244
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700245def is_extension_exported(ext):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700246 """Returns true if an extension has functions exported by the loader.
247
248 E.g. applications can directly link to an extension function.
249
250 Args:
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700251 ext: Vulkan extension name.
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700252 """
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700253 return ext in _EXPORTED_EXTENSIONS
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700254
255
256def is_function_exported(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700257 """Returns true if a function is exported from the Android Vulkan library.
258
259 Functions in the core API and in loader extensions are exported.
260
261 Args:
262 cmd: Vulkan function name.
263 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700264 if is_function_supported(cmd):
265 if cmd in extension_dict:
266 return is_extension_exported(extension_dict[cmd])
267 return True
268 return False
269
270
271def is_instance_dispatch_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700272 """Returns true if a function is exported and instance-dispatched.
273
274 Args:
275 cmd: Vulkan function name.
276 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700277 if cmd == 'vkEnumerateDeviceLayerProperties':
278 # deprecated, unused internally - @dbd33bc
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700279 return False
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700280 return is_function_exported(cmd) and is_instance_dispatched(cmd)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700281
282
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700283def is_device_dispatch_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700284 """Returns true if a function is exported and device-dispatched.
285
286 Args:
287 cmd: Vulkan function name.
288 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700289 return is_function_exported(cmd) and is_device_dispatched(cmd)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700290
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700291
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700292def init_proc(name, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700293 """Emits code to invoke INIT_PROC or INIT_PROC_EXT.
294
295 Args:
296 name: Vulkan function name.
297 f: Output file handle.
298 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700299 f.write(indent(1))
300 if name in extension_dict:
Yiwei Zhangaeaa8672019-10-16 18:59:41 -0700301 f.write('INIT_PROC_EXT(' + base_ext_name(extension_dict[name]) + ', ')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700302 else:
303 f.write('INIT_PROC(')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700304
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700305 if name in version_dict and version_dict[name] == 'VK_VERSION_1_1':
306 f.write('false, ')
307 elif name in _OPTIONAL_COMMANDS:
308 f.write('false, ')
309 else:
310 f.write('true, ')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700311
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700312 if is_instance_dispatched(name):
313 f.write('instance, ')
314 else:
315 f.write('dev, ')
316
317 f.write(base_name(name) + ');\n')
318
319
320def parse_vulkan_registry():
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700321 """Parses Vulkan registry into the below global variables.
322
323 alias_dict
324 command_list
325 extension_dict
326 param_dict
327 return_type_dict
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700328 version_code_list
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700329 version_dict
330 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700331 registry = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..',
332 'external', 'vulkan-headers', 'registry', 'vk.xml')
333 tree = element_tree.parse(registry)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700334 root = tree.getroot()
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700335 for commands in root.iter('commands'):
336 for command in commands:
337 if command.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700338 parameter_list = []
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700339 protoset = False
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700340 cmd_name = ''
341 cmd_type = ''
342 if command.get('alias') is not None:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700343 alias = command.get('alias')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700344 cmd_name = command.get('name')
345 alias_dict[cmd_name] = alias
346 command_list.append(cmd_name)
347 param_dict[cmd_name] = param_dict[alias].copy()
348 return_type_dict[cmd_name] = return_type_dict[alias]
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700349 for params in command:
Yiwei Zhang4bc489b2019-09-23 15:17:22 -0700350 if params.tag == 'param':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700351 param_type = ''
352 if params.text is not None and params.text.strip():
353 param_type = params.text.strip() + ' '
354 type_val = params.find('type')
355 param_type = param_type + type_val.text
356 if type_val.tail is not None:
357 param_type += type_val.tail.strip() + ' '
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700358 pname = params.find('name')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700359 param_name = pname.text
360 if pname.tail is not None and pname.tail.strip():
361 parameter_list.append(
362 (param_type, param_name, pname.tail.strip()))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700363 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700364 parameter_list.append((param_type, param_name))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700365 if params.tag == 'proto':
366 for c in params:
367 if c.tag == 'type':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700368 cmd_type = c.text
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700369 if c.tag == 'name':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700370 cmd_name = c.text
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700371 protoset = True
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700372 command_list.append(cmd_name)
373 return_type_dict[cmd_name] = cmd_type
374 if protoset:
375 param_dict[cmd_name] = parameter_list.copy()
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700376
377 for exts in root.iter('extensions'):
378 for extension in exts:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700379 apiversion = ''
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700380 if extension.tag == 'extension':
381 extname = extension.get('name')
382 for req in extension:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700383 if req.get('feature') is not None:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700384 apiversion = req.get('feature')
385 for commands in req:
386 if commands.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700387 cmd_name = commands.get('name')
388 if cmd_name not in extension_dict:
389 extension_dict[cmd_name] = extname
390 if apiversion:
391 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)