blob: 5bfa9ecb52939fe86a23be1192dd809609069628 [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
94# Dict for mapping a function to the core Vulkan API version.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070095version_dict = {}
Adithya Srinivasan01364142019-07-02 15:52:49 -070096
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070097
98def indent(num):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070099 """Returns the requested indents.
100
101 Args:
102 num: Number of the 4-space indents.
103 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700104 return ' ' * num
105
106
107def copyright_and_warning(year):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700108 """Returns the standard copyright and warning codes.
109
110 Args:
111 year: An integer year for the copyright.
112 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700113 return """\
114/*
115 * Copyright """ + str(year) + """ The Android Open Source Project
116 *
117 * Licensed under the Apache License, Version 2.0 (the "License");
118 * you may not use this file except in compliance with the License.
119 * You may obtain a copy of the License at
120 *
121 * http://www.apache.org/licenses/LICENSE-2.0
122 *
123 * Unless required by applicable law or agreed to in writing, software
124 * distributed under the License is distributed on an "AS IS" BASIS,
125 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126 * See the License for the specific language governing permissions and
127 * limitations under the License.
128 */
129
130// WARNING: This file is generated. See ../README.md for instructions.
131
132"""
133
134
135def run_clang_format(args):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700136 """Run clang format on the file.
137
138 Args:
139 args: The file to be formatted.
140 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700141 clang_call = ['clang-format', '--style', 'file', '-i', args]
142 subprocess.check_call(clang_call)
143
144
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700145def is_extension_internal(ext):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700146 """Returns true if an extension is internal to the loader and drivers.
147
148 The loader should not enumerate this extension.
149
150 Args:
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700151 ext: Vulkan extension name.
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700152 """
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700153 return ext == 'VK_ANDROID_native_buffer'
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700154
155
156def base_name(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700157 """Returns a function name without the 'vk' prefix.
158
159 Args:
160 cmd: Vulkan function name.
161 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700162 return cmd[2:]
163
164
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700165def base_ext_name(ext):
166 """Returns an extension name without the 'VK_' prefix.
167
168 Args:
169 ext: Vulkan extension name.
170 """
171 return ext[3:]
172
173
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700174def is_function_supported(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700175 """Returns true if a function is core or from a supportable extension.
176
177 Args:
178 cmd: Vulkan function name.
179 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700180 if cmd not in extension_dict:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700181 return True
182 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700183 if extension_dict[cmd] not in _BLACKLISTED_EXTENSIONS:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700184 return True
185 return False
186
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700187
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700188def get_dispatch_table_type(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700189 """Returns the dispatch table type for a function.
190
191 Args:
192 cmd: Vulkan function name.
193 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700194 if cmd not in param_dict:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700195 return None
196
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700197 if param_dict[cmd]:
198 return _DISPATCH_TYPE_DICT.get(param_dict[cmd][0][0], 'Global')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700199 return 'Global'
200
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700201
202def is_globally_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700203 """Returns true if the function is global, which is not dispatched.
204
205 Only global functions and functions handled in the loader top without calling
206 into lower layers are not dispatched.
207
208 Args:
209 cmd: Vulkan function name.
210 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700211 return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Global'
212
213
214def is_instance_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700215 """Returns true for functions that can have instance-specific dispatch.
216
217 Args:
218 cmd: Vulkan function name.
219 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700220 return (is_function_supported(cmd) and
221 get_dispatch_table_type(cmd) == 'Instance')
222
223
224def is_device_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700225 """Returns true for functions that can have device-specific dispatch.
226
227 Args:
228 cmd: Vulkan function name.
229 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700230 return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Device'
231
232
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700233def is_extension_exported(ext):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700234 """Returns true if an extension has functions exported by the loader.
235
236 E.g. applications can directly link to an extension function.
237
238 Args:
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700239 ext: Vulkan extension name.
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700240 """
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700241 return ext in _EXPORTED_EXTENSIONS
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700242
243
244def is_function_exported(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700245 """Returns true if a function is exported from the Android Vulkan library.
246
247 Functions in the core API and in loader extensions are exported.
248
249 Args:
250 cmd: Vulkan function name.
251 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700252 if is_function_supported(cmd):
253 if cmd in extension_dict:
254 return is_extension_exported(extension_dict[cmd])
255 return True
256 return False
257
258
259def is_instance_dispatch_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700260 """Returns true if a function is exported and instance-dispatched.
261
262 Args:
263 cmd: Vulkan function name.
264 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700265 if cmd == 'vkEnumerateDeviceLayerProperties':
266 # deprecated, unused internally - @dbd33bc
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700267 return False
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700268 return is_function_exported(cmd) and is_instance_dispatched(cmd)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700269
270
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700271def is_device_dispatch_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700272 """Returns true if a function is exported and device-dispatched.
273
274 Args:
275 cmd: Vulkan function name.
276 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700277 return is_function_exported(cmd) and is_device_dispatched(cmd)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700278
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700279
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700280def init_proc(name, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700281 """Emits code to invoke INIT_PROC or INIT_PROC_EXT.
282
283 Args:
284 name: Vulkan function name.
285 f: Output file handle.
286 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700287 f.write(indent(1))
288 if name in extension_dict:
289 f.write('INIT_PROC_EXT(' + extension_dict[name][3:] + ', ')
290 else:
291 f.write('INIT_PROC(')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700292
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700293 if name in version_dict and version_dict[name] == 'VK_VERSION_1_1':
294 f.write('false, ')
295 elif name in _OPTIONAL_COMMANDS:
296 f.write('false, ')
297 else:
298 f.write('true, ')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700299
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700300 if is_instance_dispatched(name):
301 f.write('instance, ')
302 else:
303 f.write('dev, ')
304
305 f.write(base_name(name) + ');\n')
306
307
308def parse_vulkan_registry():
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700309 """Parses Vulkan registry into the below global variables.
310
311 alias_dict
312 command_list
313 extension_dict
314 param_dict
315 return_type_dict
316 version_dict
317 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700318 registry = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..',
319 'external', 'vulkan-headers', 'registry', 'vk.xml')
320 tree = element_tree.parse(registry)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700321 root = tree.getroot()
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700322 for commands in root.iter('commands'):
323 for command in commands:
324 if command.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700325 parameter_list = []
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700326 protoset = False
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700327 cmd_name = ''
328 cmd_type = ''
329 if command.get('alias') is not None:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700330 alias = command.get('alias')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700331 cmd_name = command.get('name')
332 alias_dict[cmd_name] = alias
333 command_list.append(cmd_name)
334 param_dict[cmd_name] = param_dict[alias].copy()
335 return_type_dict[cmd_name] = return_type_dict[alias]
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700336 for params in command:
Yiwei Zhang4bc489b2019-09-23 15:17:22 -0700337 if params.tag == 'param':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700338 param_type = ''
339 if params.text is not None and params.text.strip():
340 param_type = params.text.strip() + ' '
341 type_val = params.find('type')
342 param_type = param_type + type_val.text
343 if type_val.tail is not None:
344 param_type += type_val.tail.strip() + ' '
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700345 pname = params.find('name')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700346 param_name = pname.text
347 if pname.tail is not None and pname.tail.strip():
348 parameter_list.append(
349 (param_type, param_name, pname.tail.strip()))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700350 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700351 parameter_list.append((param_type, param_name))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700352 if params.tag == 'proto':
353 for c in params:
354 if c.tag == 'type':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700355 cmd_type = c.text
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700356 if c.tag == 'name':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700357 cmd_name = c.text
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700358 protoset = True
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700359 command_list.append(cmd_name)
360 return_type_dict[cmd_name] = cmd_type
361 if protoset:
362 param_dict[cmd_name] = parameter_list.copy()
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700363
364 for exts in root.iter('extensions'):
365 for extension in exts:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700366 apiversion = ''
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700367 if extension.tag == 'extension':
368 extname = extension.get('name')
369 for req in extension:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700370 if req.get('feature') is not None:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700371 apiversion = req.get('feature')
372 for commands in req:
373 if commands.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700374 cmd_name = commands.get('name')
375 if cmd_name not in extension_dict:
376 extension_dict[cmd_name] = extname
377 if apiversion:
378 version_dict[cmd_name] = apiversion
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700379
380 for feature in root.iter('feature'):
381 apiversion = feature.get('name')
382 for req in feature:
383 for command in req:
384 if command.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700385 cmd_name = command.get('name')
386 if cmd_name in command_list:
387 version_dict[cmd_name] = apiversion