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