1COPYRIGHT = """\ 2/* 3 * Copyright 2017 Intel Corporation 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25""" 26 27import argparse 28import copy 29import re 30import xml.etree.cElementTree as et 31 32from mako.template import Template 33 34MAX_API_VERSION = '1.1.82' 35 36class Extension: 37 def __init__(self, name, ext_version, enable): 38 self.name = name 39 self.ext_version = int(ext_version) 40 if enable is True: 41 self.enable = 'true'; 42 elif enable is False: 43 self.enable = 'false'; 44 else: 45 self.enable = enable; 46 47# On Android, we disable all surface and swapchain extensions. Android's Vulkan 48# loader implements VK_KHR_surface and VK_KHR_swapchain, and applications 49# cannot access the driver's implementation. Moreoever, if the driver exposes 50# the those extension strings, then tests dEQP-VK.api.info.instance.extensions 51# and dEQP-VK.api.info.device fail due to the duplicated strings. 52EXTENSIONS = [ 53 Extension('VK_KHR_bind_memory2', 1, True), 54 Extension('VK_KHR_create_renderpass2', 1, True), 55 Extension('VK_KHR_dedicated_allocation', 1, True), 56 Extension('VK_KHR_get_display_properties2', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'), 57 Extension('VK_KHR_get_memory_requirements2', 1, True), 58 Extension('VK_KHR_get_physical_device_properties2', 1, True), 59 Extension('VK_KHR_get_surface_capabilities2', 1, 'TU_HAS_SURFACE'), 60 Extension('VK_KHR_maintenance1', 1, True), 61 Extension('VK_KHR_maintenance2', 1, True), 62 Extension('VK_KHR_maintenance3', 1, True), 63 Extension('VK_KHR_surface', 25, 'TU_HAS_SURFACE'), 64 Extension('VK_KHR_swapchain', 68, 'TU_HAS_SURFACE'), 65 Extension('VK_KHR_wayland_surface', 6, 'VK_USE_PLATFORM_WAYLAND_KHR'), 66 Extension('VK_KHR_xcb_surface', 6, 'VK_USE_PLATFORM_XCB_KHR'), 67 Extension('VK_KHR_xlib_surface', 6, 'VK_USE_PLATFORM_XLIB_KHR'), 68 Extension('VK_KHR_display', 23, 'VK_USE_PLATFORM_DISPLAY_KHR'), 69 Extension('VK_EXT_direct_mode_display', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'), 70 Extension('VK_EXT_acquire_xlib_display', 1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'), 71 Extension('VK_EXT_display_surface_counter', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'), 72 Extension('VK_EXT_display_control', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'), 73 Extension('VK_EXT_debug_report', 9, True), 74 Extension('VK_KHR_external_memory_capabilities', 1, True), 75 Extension('VK_KHR_external_memory', 1, True), 76 Extension('VK_KHR_external_memory_fd', 1, True), 77 Extension('VK_EXT_external_memory_dma_buf', 1, True), 78] 79 80class VkVersion: 81 def __init__(self, string): 82 split = string.split('.') 83 self.major = int(split[0]) 84 self.minor = int(split[1]) 85 if len(split) > 2: 86 assert len(split) == 3 87 self.patch = int(split[2]) 88 else: 89 self.patch = None 90 91 # Sanity check. The range bits are required by the definition of the 92 # VK_MAKE_VERSION macro 93 assert self.major < 1024 and self.minor < 1024 94 assert self.patch is None or self.patch < 4096 95 assert(str(self) == string) 96 97 def __str__(self): 98 ver_list = [str(self.major), str(self.minor)] 99 if self.patch is not None: 100 ver_list.append(str(self.patch)) 101 return '.'.join(ver_list) 102 103 def c_vk_version(self): 104 patch = self.patch if self.patch is not None else 0 105 ver_list = [str(self.major), str(self.minor), str(patch)] 106 return 'VK_MAKE_VERSION(' + ', '.join(ver_list) + ')' 107 108 def __int_ver(self): 109 # This is just an expansion of VK_VERSION 110 patch = self.patch if self.patch is not None else 0 111 return (self.major << 22) | (self.minor << 12) | patch 112 113 def __gt__(self, other): 114 # If only one of them has a patch version, "ignore" it by making 115 # other's patch version match self. 116 if (self.patch is None) != (other.patch is None): 117 other = copy.copy(other) 118 other.patch = self.patch 119 120 return self.__int_ver() > other.__int_ver() 121 122MAX_API_VERSION = VkVersion(MAX_API_VERSION) 123 124def _init_exts_from_xml(xml): 125 """ Walk the Vulkan XML and fill out extra extension information. """ 126 127 xml = et.parse(xml) 128 129 ext_name_map = {} 130 for ext in EXTENSIONS: 131 ext_name_map[ext.name] = ext 132 133 for ext_elem in xml.findall('.extensions/extension'): 134 ext_name = ext_elem.attrib['name'] 135 if ext_name not in ext_name_map: 136 continue 137 138 ext = ext_name_map[ext_name] 139 ext.type = ext_elem.attrib['type'] 140 141_TEMPLATE_H = Template(COPYRIGHT + """ 142#ifndef TU_EXTENSIONS_H 143#define TU_EXTENSIONS_H 144 145enum { 146 TU_INSTANCE_EXTENSION_COUNT = ${len(instance_extensions)}, 147 TU_DEVICE_EXTENSION_COUNT = ${len(device_extensions)}, 148}; 149 150struct tu_instance_extension_table { 151 union { 152 bool extensions[TU_INSTANCE_EXTENSION_COUNT]; 153 struct { 154%for ext in instance_extensions: 155 bool ${ext.name[3:]}; 156%endfor 157 }; 158 }; 159}; 160 161struct tu_device_extension_table { 162 union { 163 bool extensions[TU_DEVICE_EXTENSION_COUNT]; 164 struct { 165%for ext in device_extensions: 166 bool ${ext.name[3:]}; 167%endfor 168 }; 169 }; 170}; 171 172extern const VkExtensionProperties tu_instance_extensions[TU_INSTANCE_EXTENSION_COUNT]; 173extern const VkExtensionProperties tu_device_extensions[TU_DEVICE_EXTENSION_COUNT]; 174extern const struct tu_instance_extension_table tu_supported_instance_extensions; 175 176 177struct tu_physical_device; 178 179void tu_fill_device_extension_table(const struct tu_physical_device *device, 180 struct tu_device_extension_table* table); 181#endif 182""") 183 184_TEMPLATE_C = Template(COPYRIGHT + """ 185#include "tu_private.h" 186 187#include "vk_util.h" 188 189/* Convert the VK_USE_PLATFORM_* defines to booleans */ 190%for platform in ['ANDROID_KHR', 'WAYLAND_KHR', 'XCB_KHR', 'XLIB_KHR', 'DISPLAY_KHR', 'XLIB_XRANDR_EXT']: 191#ifdef VK_USE_PLATFORM_${platform} 192# undef VK_USE_PLATFORM_${platform} 193# define VK_USE_PLATFORM_${platform} true 194#else 195# define VK_USE_PLATFORM_${platform} false 196#endif 197%endfor 198 199/* And ANDROID too */ 200#ifdef ANDROID 201# undef ANDROID 202# define ANDROID true 203#else 204# define ANDROID false 205#endif 206 207#define TU_HAS_SURFACE (VK_USE_PLATFORM_WAYLAND_KHR || \\ 208 VK_USE_PLATFORM_XCB_KHR || \\ 209 VK_USE_PLATFORM_XLIB_KHR || \\ 210 VK_USE_PLATFORM_DISPLAY_KHR) 211 212 213const VkExtensionProperties tu_instance_extensions[TU_INSTANCE_EXTENSION_COUNT] = { 214%for ext in instance_extensions: 215 {"${ext.name}", ${ext.ext_version}}, 216%endfor 217}; 218 219const VkExtensionProperties tu_device_extensions[TU_DEVICE_EXTENSION_COUNT] = { 220%for ext in device_extensions: 221 {"${ext.name}", ${ext.ext_version}}, 222%endfor 223}; 224 225const struct tu_instance_extension_table tu_supported_instance_extensions = { 226%for ext in instance_extensions: 227 .${ext.name[3:]} = ${ext.enable}, 228%endfor 229}; 230 231void tu_fill_device_extension_table(const struct tu_physical_device *device, 232 struct tu_device_extension_table* table) 233{ 234%for ext in device_extensions: 235 table->${ext.name[3:]} = ${ext.enable}; 236%endfor 237} 238 239VkResult tu_EnumerateInstanceVersion( 240 uint32_t* pApiVersion) 241{ 242 *pApiVersion = ${MAX_API_VERSION.c_vk_version()}; 243 return VK_SUCCESS; 244} 245 246uint32_t 247tu_physical_device_api_version(struct tu_physical_device *dev) 248{ 249 return VK_MAKE_VERSION(1, 1, 82); 250} 251""") 252 253if __name__ == '__main__': 254 parser = argparse.ArgumentParser() 255 parser.add_argument('--out-c', help='Output C file.', required=True) 256 parser.add_argument('--out-h', help='Output H file.', required=True) 257 parser.add_argument('--xml', 258 help='Vulkan API XML file.', 259 required=True, 260 action='append', 261 dest='xml_files') 262 args = parser.parse_args() 263 264 for filename in args.xml_files: 265 _init_exts_from_xml(filename) 266 267 for ext in EXTENSIONS: 268 assert ext.type == 'instance' or ext.type == 'device' 269 270 template_env = { 271 'MAX_API_VERSION': MAX_API_VERSION, 272 'instance_extensions': [e for e in EXTENSIONS if e.type == 'instance'], 273 'device_extensions': [e for e in EXTENSIONS if e.type == 'device'], 274 } 275 276 with open(args.out_c, 'w') as f: 277 f.write(_TEMPLATE_C.render(**template_env)) 278 with open(args.out_h, 'w') as f: 279 f.write(_TEMPLATE_H.render(**template_env)) 280