blob: 72fd4fbc9c28d5f0c71df123d888a46985702d45 [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 Zhang7c0c07c2020-07-04 23:49:47 -0700101# Dict for mapping a promoted instance extension to the core Vulkan API version.
102promoted_inst_ext_dict = {}
103
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700104
105def indent(num):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700106 """Returns the requested indents.
107
108 Args:
109 num: Number of the 4-space indents.
110 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700111 return ' ' * num
112
113
114def copyright_and_warning(year):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700115 """Returns the standard copyright and warning codes.
116
117 Args:
118 year: An integer year for the copyright.
119 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700120 return """\
121/*
122 * Copyright """ + str(year) + """ The Android Open Source Project
123 *
124 * Licensed under the Apache License, Version 2.0 (the "License");
125 * you may not use this file except in compliance with the License.
126 * You may obtain a copy of the License at
127 *
128 * http://www.apache.org/licenses/LICENSE-2.0
129 *
130 * Unless required by applicable law or agreed to in writing, software
131 * distributed under the License is distributed on an "AS IS" BASIS,
132 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133 * See the License for the specific language governing permissions and
134 * limitations under the License.
135 */
136
137// WARNING: This file is generated. See ../README.md for instructions.
138
139"""
140
141
142def run_clang_format(args):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700143 """Run clang format on the file.
144
145 Args:
146 args: The file to be formatted.
147 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700148 clang_call = ['clang-format', '--style', 'file', '-i', args]
149 subprocess.check_call(clang_call)
150
151
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700152def is_extension_internal(ext):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700153 """Returns true if an extension is internal to the loader and drivers.
154
155 The loader should not enumerate this extension.
156
157 Args:
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700158 ext: Vulkan extension name.
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700159 """
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700160 return ext == 'VK_ANDROID_native_buffer'
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700161
162
163def base_name(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700164 """Returns a function name without the 'vk' prefix.
165
166 Args:
167 cmd: Vulkan function name.
168 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700169 return cmd[2:]
170
171
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700172def base_ext_name(ext):
173 """Returns an extension name without the 'VK_' prefix.
174
175 Args:
176 ext: Vulkan extension name.
177 """
178 return ext[3:]
179
180
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700181def version_code(version):
182 """Returns the version code from a version string.
183
184 Args:
185 version: Vulkan version string.
186 """
187 return version[11:]
188
189
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700190def version_2_api_version(version):
191 """Returns the api version from a version string.
192
193 Args:
194 version: Vulkan version string.
195 """
196 return 'VK_API' + version[2:]
197
198
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700199def is_function_supported(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700200 """Returns true if a function is core or from a supportable extension.
201
202 Args:
203 cmd: Vulkan function name.
204 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700205 if cmd not in extension_dict:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700206 return True
207 else:
Yiwei Zhang95924222020-06-15 09:39:03 -0700208 if extension_dict[cmd] not in _BLOCKED_EXTENSIONS:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700209 return True
210 return False
211
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700212
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700213def get_dispatch_table_type(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700214 """Returns the dispatch table type for a function.
215
216 Args:
217 cmd: Vulkan function name.
218 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700219 if cmd not in param_dict:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700220 return None
221
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700222 if param_dict[cmd]:
223 return _DISPATCH_TYPE_DICT.get(param_dict[cmd][0][0], 'Global')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700224 return 'Global'
225
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700226
227def is_globally_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700228 """Returns true if the function is global, which is not dispatched.
229
230 Only global functions and functions handled in the loader top without calling
231 into lower layers are not dispatched.
232
233 Args:
234 cmd: Vulkan function name.
235 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700236 return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Global'
237
238
239def is_instance_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700240 """Returns true for functions that can have instance-specific dispatch.
241
242 Args:
243 cmd: Vulkan function name.
244 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700245 return (is_function_supported(cmd) and
246 get_dispatch_table_type(cmd) == 'Instance')
247
248
249def is_device_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700250 """Returns true for functions that can have device-specific dispatch.
251
252 Args:
253 cmd: Vulkan function name.
254 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700255 return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Device'
256
257
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700258def is_extension_exported(ext):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700259 """Returns true if an extension has functions exported by the loader.
260
261 E.g. applications can directly link to an extension function.
262
263 Args:
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700264 ext: Vulkan extension name.
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700265 """
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700266 return ext in _EXPORTED_EXTENSIONS
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700267
268
269def is_function_exported(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700270 """Returns true if a function is exported from the Android Vulkan library.
271
272 Functions in the core API and in loader extensions are exported.
273
274 Args:
275 cmd: Vulkan function name.
276 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700277 if is_function_supported(cmd):
278 if cmd in extension_dict:
279 return is_extension_exported(extension_dict[cmd])
280 return True
281 return False
282
283
284def is_instance_dispatch_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700285 """Returns true if a function is exported and instance-dispatched.
286
287 Args:
288 cmd: Vulkan function name.
289 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700290 if cmd == 'vkEnumerateDeviceLayerProperties':
291 # deprecated, unused internally - @dbd33bc
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700292 return False
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700293 return is_function_exported(cmd) and is_instance_dispatched(cmd)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700294
295
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700296def is_device_dispatch_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700297 """Returns true if a function is exported and device-dispatched.
298
299 Args:
300 cmd: Vulkan function name.
301 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700302 return is_function_exported(cmd) and is_device_dispatched(cmd)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700303
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700304
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700305def init_proc(name, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700306 """Emits code to invoke INIT_PROC or INIT_PROC_EXT.
307
308 Args:
309 name: Vulkan function name.
310 f: Output file handle.
311 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700312 f.write(indent(1))
313 if name in extension_dict:
Yiwei Zhangaeaa8672019-10-16 18:59:41 -0700314 f.write('INIT_PROC_EXT(' + base_ext_name(extension_dict[name]) + ', ')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700315 else:
316 f.write('INIT_PROC(')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700317
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700318 if name in _OPTIONAL_COMMANDS:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700319 f.write('false, ')
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700320 elif version_dict[name] == 'VK_VERSION_1_0':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700321 f.write('true, ')
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700322 else:
323 f.write('false, ')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700324
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700325 if is_instance_dispatched(name):
326 f.write('instance, ')
327 else:
328 f.write('dev, ')
329
330 f.write(base_name(name) + ');\n')
331
332
333def parse_vulkan_registry():
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700334 """Parses Vulkan registry into the below global variables.
335
336 alias_dict
337 command_list
338 extension_dict
339 param_dict
340 return_type_dict
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700341 version_code_list
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700342 version_dict
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700343 promoted_inst_ext_dict
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700344 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700345 registry = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..',
346 'external', 'vulkan-headers', 'registry', 'vk.xml')
347 tree = element_tree.parse(registry)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700348 root = tree.getroot()
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700349 for commands in root.iter('commands'):
350 for command in commands:
351 if command.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700352 parameter_list = []
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700353 protoset = False
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700354 cmd_name = ''
355 cmd_type = ''
356 if command.get('alias') is not None:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700357 alias = command.get('alias')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700358 cmd_name = command.get('name')
359 alias_dict[cmd_name] = alias
360 command_list.append(cmd_name)
361 param_dict[cmd_name] = param_dict[alias].copy()
362 return_type_dict[cmd_name] = return_type_dict[alias]
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700363 for params in command:
Yiwei Zhang4bc489b2019-09-23 15:17:22 -0700364 if params.tag == 'param':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700365 param_type = ''
366 if params.text is not None and params.text.strip():
367 param_type = params.text.strip() + ' '
368 type_val = params.find('type')
369 param_type = param_type + type_val.text
370 if type_val.tail is not None:
371 param_type += type_val.tail.strip() + ' '
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700372 pname = params.find('name')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700373 param_name = pname.text
374 if pname.tail is not None and pname.tail.strip():
375 parameter_list.append(
376 (param_type, param_name, pname.tail.strip()))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700377 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700378 parameter_list.append((param_type, param_name))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700379 if params.tag == 'proto':
380 for c in params:
381 if c.tag == 'type':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700382 cmd_type = c.text
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700383 if c.tag == 'name':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700384 cmd_name = c.text
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700385 protoset = True
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700386 command_list.append(cmd_name)
387 return_type_dict[cmd_name] = cmd_type
388 if protoset:
389 param_dict[cmd_name] = parameter_list.copy()
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700390
391 for exts in root.iter('extensions'):
392 for extension in exts:
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700393 apiversion = 'VK_VERSION_1_0'
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700394 if extension.tag == 'extension':
395 extname = extension.get('name')
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700396 if (extension.get('type') == 'instance' and
397 extension.get('promotedto') is not None):
398 promoted_inst_ext_dict[extname] = \
399 version_2_api_version(extension.get('promotedto'))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700400 for req in extension:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700401 if req.get('feature') is not None:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700402 apiversion = req.get('feature')
403 for commands in req:
404 if commands.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700405 cmd_name = commands.get('name')
406 if cmd_name not in extension_dict:
407 extension_dict[cmd_name] = extname
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700408 version_dict[cmd_name] = apiversion
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700409
410 for feature in root.iter('feature'):
411 apiversion = feature.get('name')
412 for req in feature:
413 for command in req:
414 if command.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700415 cmd_name = command.get('name')
416 if cmd_name in command_list:
417 version_dict[cmd_name] = apiversion
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700418
419 version_code_set = set()
420 for version in version_dict.values():
421 version_code_set.add(version_code(version))
422 for code in sorted(version_code_set):
423 version_code_list.append(code)