blob: c25c6cbda08ae90647c419ad2bd68561c0e764c7 [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',
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -070073]
74
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070075# Dict for mapping dispatch table to a type.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070076_DISPATCH_TYPE_DICT = {
77 'VkInstance ': 'Instance',
78 'VkPhysicalDevice ': 'Instance',
79 'VkDevice ': 'Device',
80 'VkQueue ': 'Device',
81 'VkCommandBuffer ': 'Device'
82}
Adithya Srinivasan8dce9d72019-07-11 14:26:04 -070083
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070084# Dict for mapping a function to its alias.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070085alias_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070086
87# List of all the Vulkan functions.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070088command_list = []
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070089
90# Dict for mapping a function to an extension.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070091extension_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070092
93# Dict for mapping a function to all its parameters.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070094param_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070095
96# Dict for mapping a function to its return type.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -070097return_type_dict = {}
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -070098
Yiwei Zhang7cc36a52019-10-11 19:02:09 -070099# List of the sorted Vulkan version codes. e.g. '1_0', '1_1'.
100version_code_list = []
101
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700102# Dict for mapping a function to the core Vulkan API version.
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700103version_dict = {}
Adithya Srinivasan01364142019-07-02 15:52:49 -0700104
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700105# Dict for mapping a promoted instance extension to the core Vulkan API version.
106promoted_inst_ext_dict = {}
107
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700108
109def indent(num):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700110 """Returns the requested indents.
111
112 Args:
113 num: Number of the 4-space indents.
114 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700115 return ' ' * num
116
117
118def copyright_and_warning(year):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700119 """Returns the standard copyright and warning codes.
120
121 Args:
122 year: An integer year for the copyright.
123 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700124 return """\
125/*
126 * Copyright """ + str(year) + """ The Android Open Source Project
127 *
128 * Licensed under the Apache License, Version 2.0 (the "License");
129 * you may not use this file except in compliance with the License.
130 * You may obtain a copy of the License at
131 *
132 * http://www.apache.org/licenses/LICENSE-2.0
133 *
134 * Unless required by applicable law or agreed to in writing, software
135 * distributed under the License is distributed on an "AS IS" BASIS,
136 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137 * See the License for the specific language governing permissions and
138 * limitations under the License.
139 */
140
141// WARNING: This file is generated. See ../README.md for instructions.
142
143"""
144
145
146def run_clang_format(args):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700147 """Run clang format on the file.
148
149 Args:
150 args: The file to be formatted.
151 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700152 clang_call = ['clang-format', '--style', 'file', '-i', args]
153 subprocess.check_call(clang_call)
154
155
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700156def is_extension_internal(ext):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700157 """Returns true if an extension is internal to the loader and drivers.
158
159 The loader should not enumerate this extension.
160
161 Args:
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700162 ext: Vulkan extension name.
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700163 """
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700164 return ext == 'VK_ANDROID_native_buffer'
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700165
166
167def base_name(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700168 """Returns a function name without the 'vk' prefix.
169
170 Args:
171 cmd: Vulkan function name.
172 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700173 return cmd[2:]
174
175
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700176def base_ext_name(ext):
177 """Returns an extension name without the 'VK_' prefix.
178
179 Args:
180 ext: Vulkan extension name.
181 """
182 return ext[3:]
183
184
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700185def version_code(version):
186 """Returns the version code from a version string.
187
188 Args:
189 version: Vulkan version string.
190 """
191 return version[11:]
192
193
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700194def version_2_api_version(version):
195 """Returns the api version from a version string.
196
197 Args:
198 version: Vulkan version string.
199 """
200 return 'VK_API' + version[2:]
201
202
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700203def is_function_supported(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700204 """Returns true if a function is core or from a supportable extension.
205
206 Args:
207 cmd: Vulkan function name.
208 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700209 if cmd not in extension_dict:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700210 return True
211 else:
Yiwei Zhang95924222020-06-15 09:39:03 -0700212 if extension_dict[cmd] not in _BLOCKED_EXTENSIONS:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700213 return True
214 return False
215
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700216
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700217def get_dispatch_table_type(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700218 """Returns the dispatch table type for a function.
219
220 Args:
221 cmd: Vulkan function name.
222 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700223 if cmd not in param_dict:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700224 return None
225
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700226 if param_dict[cmd]:
227 return _DISPATCH_TYPE_DICT.get(param_dict[cmd][0][0], 'Global')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700228 return 'Global'
229
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700230
231def is_globally_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700232 """Returns true if the function is global, which is not dispatched.
233
234 Only global functions and functions handled in the loader top without calling
235 into lower layers are not dispatched.
236
237 Args:
238 cmd: Vulkan function name.
239 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700240 return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Global'
241
242
243def is_instance_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700244 """Returns true for functions that can have instance-specific dispatch.
245
246 Args:
247 cmd: Vulkan function name.
248 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700249 return (is_function_supported(cmd) and
250 get_dispatch_table_type(cmd) == 'Instance')
251
252
253def is_device_dispatched(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700254 """Returns true for functions that can have device-specific dispatch.
255
256 Args:
257 cmd: Vulkan function name.
258 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700259 return is_function_supported(cmd) and get_dispatch_table_type(cmd) == 'Device'
260
261
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700262def is_extension_exported(ext):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700263 """Returns true if an extension has functions exported by the loader.
264
265 E.g. applications can directly link to an extension function.
266
267 Args:
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700268 ext: Vulkan extension name.
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700269 """
Yiwei Zhang5365a7b2019-10-11 17:26:44 -0700270 return ext in _EXPORTED_EXTENSIONS
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700271
272
273def is_function_exported(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700274 """Returns true if a function is exported from the Android Vulkan library.
275
276 Functions in the core API and in loader extensions are exported.
277
278 Args:
279 cmd: Vulkan function name.
280 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700281 if is_function_supported(cmd):
282 if cmd in extension_dict:
283 return is_extension_exported(extension_dict[cmd])
284 return True
285 return False
286
287
288def is_instance_dispatch_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700289 """Returns true if a function is exported and instance-dispatched.
290
291 Args:
292 cmd: Vulkan function name.
293 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700294 if cmd == 'vkEnumerateDeviceLayerProperties':
295 # deprecated, unused internally - @dbd33bc
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700296 return False
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700297 return is_function_exported(cmd) and is_instance_dispatched(cmd)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700298
299
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700300def is_device_dispatch_table_entry(cmd):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700301 """Returns true if a function is exported and device-dispatched.
302
303 Args:
304 cmd: Vulkan function name.
305 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700306 return is_function_exported(cmd) and is_device_dispatched(cmd)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700307
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700308
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700309def init_proc(name, f):
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700310 """Emits code to invoke INIT_PROC or INIT_PROC_EXT.
311
312 Args:
313 name: Vulkan function name.
314 f: Output file handle.
315 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700316 f.write(indent(1))
317 if name in extension_dict:
Yiwei Zhangaeaa8672019-10-16 18:59:41 -0700318 f.write('INIT_PROC_EXT(' + base_ext_name(extension_dict[name]) + ', ')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700319 else:
320 f.write('INIT_PROC(')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700321
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700322 if name in _OPTIONAL_COMMANDS:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700323 f.write('false, ')
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700324 elif version_dict[name] == 'VK_VERSION_1_0':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700325 f.write('true, ')
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700326 else:
327 f.write('false, ')
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700328
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700329 if is_instance_dispatched(name):
330 f.write('instance, ')
331 else:
332 f.write('dev, ')
333
334 f.write(base_name(name) + ');\n')
335
336
337def parse_vulkan_registry():
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700338 """Parses Vulkan registry into the below global variables.
339
340 alias_dict
341 command_list
342 extension_dict
343 param_dict
344 return_type_dict
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700345 version_code_list
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700346 version_dict
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700347 promoted_inst_ext_dict
Yiwei Zhang6ca5d0c2019-10-11 17:15:02 -0700348 """
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700349 registry = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..',
350 'external', 'vulkan-headers', 'registry', 'vk.xml')
351 tree = element_tree.parse(registry)
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700352 root = tree.getroot()
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700353 for commands in root.iter('commands'):
354 for command in commands:
355 if command.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700356 parameter_list = []
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700357 protoset = False
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700358 cmd_name = ''
359 cmd_type = ''
360 if command.get('alias') is not None:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700361 alias = command.get('alias')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700362 cmd_name = command.get('name')
363 alias_dict[cmd_name] = alias
364 command_list.append(cmd_name)
365 param_dict[cmd_name] = param_dict[alias].copy()
366 return_type_dict[cmd_name] = return_type_dict[alias]
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700367 for params in command:
Yiwei Zhang4bc489b2019-09-23 15:17:22 -0700368 if params.tag == 'param':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700369 param_type = ''
370 if params.text is not None and params.text.strip():
371 param_type = params.text.strip() + ' '
372 type_val = params.find('type')
373 param_type = param_type + type_val.text
374 if type_val.tail is not None:
375 param_type += type_val.tail.strip() + ' '
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700376 pname = params.find('name')
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700377 param_name = pname.text
378 if pname.tail is not None and pname.tail.strip():
379 parameter_list.append(
380 (param_type, param_name, pname.tail.strip()))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700381 else:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700382 parameter_list.append((param_type, param_name))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700383 if params.tag == 'proto':
384 for c in params:
385 if c.tag == 'type':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700386 cmd_type = c.text
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700387 if c.tag == 'name':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700388 cmd_name = c.text
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700389 protoset = True
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700390 command_list.append(cmd_name)
391 return_type_dict[cmd_name] = cmd_type
392 if protoset:
393 param_dict[cmd_name] = parameter_list.copy()
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700394
395 for exts in root.iter('extensions'):
396 for extension in exts:
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700397 apiversion = 'VK_VERSION_1_0'
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700398 if extension.tag == 'extension':
399 extname = extension.get('name')
Yiwei Zhang7c0c07c2020-07-04 23:49:47 -0700400 if (extension.get('type') == 'instance' and
401 extension.get('promotedto') is not None):
402 promoted_inst_ext_dict[extname] = \
403 version_2_api_version(extension.get('promotedto'))
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700404 for req in extension:
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700405 if req.get('feature') is not None:
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700406 apiversion = req.get('feature')
407 for commands in req:
408 if commands.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700409 cmd_name = commands.get('name')
410 if cmd_name not in extension_dict:
411 extension_dict[cmd_name] = extname
Yiwei Zhang6be097b2020-10-19 20:22:05 -0700412 version_dict[cmd_name] = apiversion
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -0700413
414 for feature in root.iter('feature'):
415 apiversion = feature.get('name')
416 for req in feature:
417 for command in req:
418 if command.tag == 'command':
Yiwei Zhang1ca59c12019-10-10 12:54:42 -0700419 cmd_name = command.get('name')
420 if cmd_name in command_list:
421 version_dict[cmd_name] = apiversion
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700422
423 version_code_set = set()
424 for version in version_dict.values():
425 version_code_set.add(version_code(version))
426 for code in sorted(version_code_set):
427 version_code_list.append(code)