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 28 29from mako.template import Template 30 31# Mesa-local imports must be declared in meson variable 32# '{file_without_suffix}_depend_files'. 33from vk_extensions import get_all_exts_from_xml, init_exts_from_xml 34 35_TEMPLATE_H = Template(COPYRIGHT + """ 36 37#ifndef ${driver.upper()}_EXTENSIONS_H 38#define ${driver.upper()}_EXTENSIONS_H 39 40#include <stdbool.h> 41 42%if driver == 'vk': 43 44<%def name="extension_table(type, extensions)"> 45#define VK_${type.upper()}_EXTENSION_COUNT ${len(extensions)} 46 47extern const VkExtensionProperties vk_${type}_extensions[]; 48 49struct vk_${type}_extension_table { 50 union { 51 bool extensions[VK_${type.upper()}_EXTENSION_COUNT]; 52 struct { 53%for ext in extensions: 54 bool ${ext.name[3:]}; 55%endfor 56 }; 57 58 /* Workaround for "error: too many initializers for vk_${type}_extension_table" */ 59 struct { 60%for ext in extensions: 61 bool ${ext.name[3:]}; 62%endfor 63 } table; 64 }; 65}; 66</%def> 67 68${extension_table('instance', instance_extensions)} 69${extension_table('device', device_extensions)} 70 71%else: 72#include "vk_extensions.h" 73%endif 74 75struct ${driver}_physical_device; 76 77%if driver == 'vk': 78#ifdef ANDROID 79extern const struct vk_instance_extension_table vk_android_allowed_instance_extensions; 80extern const struct vk_device_extension_table vk_android_allowed_device_extensions; 81#endif 82%else: 83extern const struct vk_instance_extension_table ${driver}_instance_extensions_supported; 84 85void 86${driver}_physical_device_get_supported_extensions(const struct ${driver}_physical_device *device, 87 struct vk_device_extension_table *extensions); 88%endif 89 90#endif /* ${driver.upper()}_EXTENSIONS_H */ 91""") 92 93_TEMPLATE_C = Template(COPYRIGHT + """ 94#include "vulkan/vulkan_core.h" 95%if driver != 'vk': 96#include "${driver}_private.h" 97%endif 98 99#include "${driver}_extensions.h" 100 101%if driver == 'vk': 102const VkExtensionProperties ${driver}_instance_extensions[${driver.upper()}_INSTANCE_EXTENSION_COUNT] = { 103%for ext in instance_extensions: 104 {"${ext.name}", ${ext.ext_version}}, 105%endfor 106}; 107 108const VkExtensionProperties ${driver}_device_extensions[${driver.upper()}_DEVICE_EXTENSION_COUNT] = { 109%for ext in device_extensions: 110 {"${ext.name}", ${ext.ext_version}}, 111%endfor 112}; 113 114#ifdef ANDROID 115const struct vk_instance_extension_table vk_android_allowed_instance_extensions = { 116%for ext in instance_extensions: 117 .${ext.name[3:]} = ${ext.c_android_condition()}, 118%endfor 119}; 120 121const struct vk_device_extension_table vk_android_allowed_device_extensions = { 122%for ext in device_extensions: 123 .${ext.name[3:]} = ${ext.c_android_condition()}, 124%endfor 125}; 126#endif 127%endif 128 129%if driver != 'vk': 130#include "vk_util.h" 131 132/* Convert the VK_USE_PLATFORM_* defines to booleans */ 133%for platform_define in platform_defines: 134#ifdef ${platform_define} 135# undef ${platform_define} 136# define ${platform_define} true 137#else 138# define ${platform_define} false 139#endif 140%endfor 141 142/* And ANDROID too */ 143#ifdef ANDROID 144# undef ANDROID 145# define ANDROID true 146#else 147# define ANDROID false 148# define ANDROID_API_LEVEL 0 149#endif 150 151#define ${driver.upper()}_HAS_SURFACE (VK_USE_PLATFORM_WIN32_KHR || \\ 152 VK_USE_PLATFORM_WAYLAND_KHR || \\ 153 VK_USE_PLATFORM_XCB_KHR || \\ 154 VK_USE_PLATFORM_XLIB_KHR || \\ 155 VK_USE_PLATFORM_DISPLAY_KHR) 156 157static const uint32_t MAX_API_VERSION = ${MAX_API_VERSION.c_vk_version()}; 158 159VKAPI_ATTR VkResult VKAPI_CALL ${driver}_EnumerateInstanceVersion( 160 uint32_t* pApiVersion) 161{ 162 *pApiVersion = MAX_API_VERSION; 163 return VK_SUCCESS; 164} 165 166const struct vk_instance_extension_table ${driver}_instance_extensions_supported = { 167%for ext in instance_extensions: 168 .${ext.name[3:]} = ${ext.enable}, 169%endfor 170}; 171 172uint32_t 173${driver}_physical_device_api_version(struct ${driver}_physical_device *device) 174{ 175 uint32_t version = 0; 176 177 uint32_t override = vk_get_version_override(); 178 if (override) 179 return MIN2(override, MAX_API_VERSION); 180 181%for version in API_VERSIONS: 182 if (!(${version.enable})) 183 return version; 184 version = ${version.version.c_vk_version()}; 185 186%endfor 187 return version; 188} 189 190void 191${driver}_physical_device_get_supported_extensions(const struct ${driver}_physical_device *device, 192 struct vk_device_extension_table *extensions) 193{ 194 *extensions = (struct vk_device_extension_table) { 195%for ext in device_extensions: 196 .${ext.name[3:]} = ${ext.enable}, 197%endfor 198 }; 199} 200%endif 201""") 202 203def gen_extensions(driver, xml_files, api_versions, max_api_version, 204 extensions, out_c, out_h): 205 platform_defines = [] 206 for filename in xml_files: 207 init_exts_from_xml(filename, extensions, platform_defines) 208 209 for ext in extensions: 210 assert ext.type in {'instance', 'device'} 211 212 template_env = { 213 'driver': driver, 214 'API_VERSIONS': api_versions, 215 'MAX_API_VERSION': max_api_version, 216 'instance_extensions': [e for e in extensions if e.type == 'instance'], 217 'device_extensions': [e for e in extensions if e.type == 'device'], 218 'platform_defines': platform_defines, 219 } 220 221 if out_h: 222 with open(out_h, 'w') as f: 223 f.write(_TEMPLATE_H.render(**template_env)) 224 225 if out_c: 226 with open(out_c, 'w') as f: 227 f.write(_TEMPLATE_C.render(**template_env)) 228 229 230def main(): 231 parser = argparse.ArgumentParser() 232 parser.add_argument('--out-c', help='Output C file.') 233 parser.add_argument('--out-h', help='Output H file.') 234 parser.add_argument('--xml', 235 help='Vulkan API XML file.', 236 required=True, 237 action='append', 238 dest='xml_files') 239 args = parser.parse_args() 240 241 extensions = [] 242 for filename in args.xml_files: 243 extensions += get_all_exts_from_xml(filename) 244 245 gen_extensions('vk', args.xml_files, None, None, 246 extensions, args.out_c, args.out_h) 247 248if __name__ == '__main__': 249 main() 250