1bf215546Sopenharmony_ciCOPYRIGHT=u""" 2bf215546Sopenharmony_ci/* Copyright © 2015-2021 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci""" 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ciimport argparse 26bf215546Sopenharmony_ciimport os 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_cifrom mako.template import Template 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci# Mesa-local imports must be declared in meson variable 31bf215546Sopenharmony_ci# '{file_without_suffix}_depend_files'. 32bf215546Sopenharmony_cifrom vk_entrypoints import get_entrypoints_from_xml 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ciTEMPLATE_H = Template(COPYRIGHT + """\ 35bf215546Sopenharmony_ci/* This file generated from ${filename}, don't edit directly. */ 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "vk_dispatch_table.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci#ifndef ${guard} 40bf215546Sopenharmony_ci#define ${guard} 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci#ifdef __cplusplus 43bf215546Sopenharmony_ciextern "C" { 44bf215546Sopenharmony_ci#endif 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci% for p in instance_prefixes: 47bf215546Sopenharmony_ciextern const struct vk_instance_entrypoint_table ${p}_instance_entrypoints; 48bf215546Sopenharmony_ci% endfor 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci% for p in physical_device_prefixes: 51bf215546Sopenharmony_ciextern const struct vk_physical_device_entrypoint_table ${p}_physical_device_entrypoints; 52bf215546Sopenharmony_ci% endfor 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci% for p in device_prefixes: 55bf215546Sopenharmony_ciextern const struct vk_device_entrypoint_table ${p}_device_entrypoints; 56bf215546Sopenharmony_ci% endfor 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci% if gen_proto: 59bf215546Sopenharmony_ci% for e in instance_entrypoints: 60bf215546Sopenharmony_ci % if e.guard is not None: 61bf215546Sopenharmony_ci#ifdef ${e.guard} 62bf215546Sopenharmony_ci % endif 63bf215546Sopenharmony_ci % for p in physical_device_prefixes: 64bf215546Sopenharmony_ci VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}); 65bf215546Sopenharmony_ci % endfor 66bf215546Sopenharmony_ci % if e.guard is not None: 67bf215546Sopenharmony_ci#endif // ${e.guard} 68bf215546Sopenharmony_ci % endif 69bf215546Sopenharmony_ci% endfor 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci% for e in physical_device_entrypoints: 72bf215546Sopenharmony_ci % if e.guard is not None: 73bf215546Sopenharmony_ci#ifdef ${e.guard} 74bf215546Sopenharmony_ci % endif 75bf215546Sopenharmony_ci % for p in physical_device_prefixes: 76bf215546Sopenharmony_ci VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}); 77bf215546Sopenharmony_ci % endfor 78bf215546Sopenharmony_ci % if e.guard is not None: 79bf215546Sopenharmony_ci#endif // ${e.guard} 80bf215546Sopenharmony_ci % endif 81bf215546Sopenharmony_ci% endfor 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci% for e in device_entrypoints: 84bf215546Sopenharmony_ci % if e.guard is not None: 85bf215546Sopenharmony_ci#ifdef ${e.guard} 86bf215546Sopenharmony_ci % endif 87bf215546Sopenharmony_ci % for p in device_prefixes: 88bf215546Sopenharmony_ci VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}); 89bf215546Sopenharmony_ci % endfor 90bf215546Sopenharmony_ci % if e.guard is not None: 91bf215546Sopenharmony_ci#endif // ${e.guard} 92bf215546Sopenharmony_ci % endif 93bf215546Sopenharmony_ci% endfor 94bf215546Sopenharmony_ci% endif 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci#ifdef __cplusplus 97bf215546Sopenharmony_ci} 98bf215546Sopenharmony_ci#endif 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci#endif /* ${guard} */ 101bf215546Sopenharmony_ci""") 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ciTEMPLATE_C = Template(COPYRIGHT + """ 104bf215546Sopenharmony_ci/* This file generated from ${filename}, don't edit directly. */ 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci#include "${header}" 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci/* Weak aliases for all potential implementations. These will resolve to 109bf215546Sopenharmony_ci * NULL if they're not defined, which lets the resolve_entrypoint() function 110bf215546Sopenharmony_ci * either pick the correct entry point. 111bf215546Sopenharmony_ci * 112bf215546Sopenharmony_ci * MSVC uses different decorated names for 32-bit versus 64-bit. Declare 113bf215546Sopenharmony_ci * all argument sizes for 32-bit because computing the actual size would be 114bf215546Sopenharmony_ci * difficult. 115bf215546Sopenharmony_ci */ 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci<%def name="entrypoint_table(type, entrypoints, prefixes)"> 118bf215546Sopenharmony_ci% if gen_weak: 119bf215546Sopenharmony_ci % for e in entrypoints: 120bf215546Sopenharmony_ci % if e.guard is not None: 121bf215546Sopenharmony_ci#ifdef ${e.guard} 122bf215546Sopenharmony_ci % endif 123bf215546Sopenharmony_ci % for p in prefixes: 124bf215546Sopenharmony_ci#ifdef _MSC_VER 125bf215546Sopenharmony_ci#ifdef _M_IX86 126bf215546Sopenharmony_ci % for args_size in [4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 60, 104]: 127bf215546Sopenharmony_ci #pragma comment(linker, "/alternatename:_${p}_${e.name}@${args_size}=_vk_entrypoint_stub@0") 128bf215546Sopenharmony_ci % endfor 129bf215546Sopenharmony_ci#else 130bf215546Sopenharmony_ci #pragma comment(linker, "/alternatename:${p}_${e.name}=vk_entrypoint_stub") 131bf215546Sopenharmony_ci#if defined(_M_ARM64EC) 132bf215546Sopenharmony_ci #pragma comment(linker, "/alternatename:#${p}_${e.name}=#vk_entrypoint_stub") 133bf215546Sopenharmony_ci#endif 134bf215546Sopenharmony_ci#endif 135bf215546Sopenharmony_ci#else 136bf215546Sopenharmony_ci VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}) __attribute__ ((weak)); 137bf215546Sopenharmony_ci#endif 138bf215546Sopenharmony_ci % endfor 139bf215546Sopenharmony_ci % if e.guard is not None: 140bf215546Sopenharmony_ci#endif // ${e.guard} 141bf215546Sopenharmony_ci % endif 142bf215546Sopenharmony_ci % endfor 143bf215546Sopenharmony_ci% endif 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci% for p in prefixes: 146bf215546Sopenharmony_ciconst struct vk_${type}_entrypoint_table ${p}_${type}_entrypoints = { 147bf215546Sopenharmony_ci % for e in entrypoints: 148bf215546Sopenharmony_ci % if e.guard is not None: 149bf215546Sopenharmony_ci#ifdef ${e.guard} 150bf215546Sopenharmony_ci % endif 151bf215546Sopenharmony_ci .${e.name} = ${p}_${e.name}, 152bf215546Sopenharmony_ci % if e.guard is not None: 153bf215546Sopenharmony_ci#elif defined(_MSC_VER) 154bf215546Sopenharmony_ci .${e.name} = (PFN_vkVoidFunction)vk_entrypoint_stub, 155bf215546Sopenharmony_ci#endif // ${e.guard} 156bf215546Sopenharmony_ci % endif 157bf215546Sopenharmony_ci % endfor 158bf215546Sopenharmony_ci}; 159bf215546Sopenharmony_ci% endfor 160bf215546Sopenharmony_ci</%def> 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci${entrypoint_table('instance', instance_entrypoints, instance_prefixes)} 163bf215546Sopenharmony_ci${entrypoint_table('physical_device', physical_device_entrypoints, physical_device_prefixes)} 164bf215546Sopenharmony_ci${entrypoint_table('device', device_entrypoints, device_prefixes)} 165bf215546Sopenharmony_ci""") 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_cidef get_entrypoints_defines(doc): 168bf215546Sopenharmony_ci """Maps entry points to extension defines.""" 169bf215546Sopenharmony_ci entrypoints_to_defines = {} 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci platform_define = {} 172bf215546Sopenharmony_ci for platform in doc.findall('./platforms/platform'): 173bf215546Sopenharmony_ci name = platform.attrib['name'] 174bf215546Sopenharmony_ci define = platform.attrib['protect'] 175bf215546Sopenharmony_ci platform_define[name] = define 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci for extension in doc.findall('./extensions/extension[@platform]'): 178bf215546Sopenharmony_ci platform = extension.attrib['platform'] 179bf215546Sopenharmony_ci define = platform_define[platform] 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci for entrypoint in extension.findall('./require/command'): 182bf215546Sopenharmony_ci fullname = entrypoint.attrib['name'] 183bf215546Sopenharmony_ci entrypoints_to_defines[fullname] = define 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci return entrypoints_to_defines 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_cidef main(): 189bf215546Sopenharmony_ci parser = argparse.ArgumentParser() 190bf215546Sopenharmony_ci parser.add_argument('--out-c', required=True, help='Output C file.') 191bf215546Sopenharmony_ci parser.add_argument('--out-h', required=True, help='Output H file.') 192bf215546Sopenharmony_ci parser.add_argument('--xml', 193bf215546Sopenharmony_ci help='Vulkan API XML file.', 194bf215546Sopenharmony_ci required=True, action='append', dest='xml_files') 195bf215546Sopenharmony_ci parser.add_argument('--proto', help='Generate entrypoint prototypes', 196bf215546Sopenharmony_ci action='store_true', dest='gen_proto') 197bf215546Sopenharmony_ci parser.add_argument('--weak', help='Generate weak entrypoint declarations', 198bf215546Sopenharmony_ci action='store_true', dest='gen_weak') 199bf215546Sopenharmony_ci parser.add_argument('--prefix', 200bf215546Sopenharmony_ci help='Prefix to use for all dispatch tables.', 201bf215546Sopenharmony_ci action='append', default=[], dest='prefixes') 202bf215546Sopenharmony_ci parser.add_argument('--device-prefix', 203bf215546Sopenharmony_ci help='Prefix to use for device dispatch tables.', 204bf215546Sopenharmony_ci action='append', default=[], dest='device_prefixes') 205bf215546Sopenharmony_ci args = parser.parse_args() 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci instance_prefixes = args.prefixes 208bf215546Sopenharmony_ci physical_device_prefixes = args.prefixes 209bf215546Sopenharmony_ci device_prefixes = args.prefixes + args.device_prefixes 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci entrypoints = get_entrypoints_from_xml(args.xml_files) 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci device_entrypoints = [] 214bf215546Sopenharmony_ci physical_device_entrypoints = [] 215bf215546Sopenharmony_ci instance_entrypoints = [] 216bf215546Sopenharmony_ci for e in entrypoints: 217bf215546Sopenharmony_ci if e.is_device_entrypoint(): 218bf215546Sopenharmony_ci device_entrypoints.append(e) 219bf215546Sopenharmony_ci elif e.is_physical_device_entrypoint(): 220bf215546Sopenharmony_ci physical_device_entrypoints.append(e) 221bf215546Sopenharmony_ci else: 222bf215546Sopenharmony_ci instance_entrypoints.append(e) 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci assert os.path.dirname(args.out_c) == os.path.dirname(args.out_h) 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci environment = { 227bf215546Sopenharmony_ci 'gen_proto': args.gen_proto, 228bf215546Sopenharmony_ci 'gen_weak': args.gen_weak, 229bf215546Sopenharmony_ci 'header': os.path.basename(args.out_h), 230bf215546Sopenharmony_ci 'instance_entrypoints': instance_entrypoints, 231bf215546Sopenharmony_ci 'instance_prefixes': instance_prefixes, 232bf215546Sopenharmony_ci 'physical_device_entrypoints': physical_device_entrypoints, 233bf215546Sopenharmony_ci 'physical_device_prefixes': physical_device_prefixes, 234bf215546Sopenharmony_ci 'device_entrypoints': device_entrypoints, 235bf215546Sopenharmony_ci 'device_prefixes': device_prefixes, 236bf215546Sopenharmony_ci 'filename': os.path.basename(__file__), 237bf215546Sopenharmony_ci } 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci # For outputting entrypoints.h we generate a anv_EntryPoint() prototype 240bf215546Sopenharmony_ci # per entry point. 241bf215546Sopenharmony_ci try: 242bf215546Sopenharmony_ci with open(args.out_h, 'w', encoding='utf-8') as f: 243bf215546Sopenharmony_ci guard = os.path.basename(args.out_h).replace('.', '_').upper() 244bf215546Sopenharmony_ci f.write(TEMPLATE_H.render(guard=guard, **environment)) 245bf215546Sopenharmony_ci with open(args.out_c, 'w', encoding='utf-8') as f: 246bf215546Sopenharmony_ci f.write(TEMPLATE_C.render(**environment)) 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci except Exception: 249bf215546Sopenharmony_ci # In the event there's an error, this imports some helpers from mako 250bf215546Sopenharmony_ci # to print a useful stack trace and prints it, then exits with 251bf215546Sopenharmony_ci # status 1, if python is run with debug; otherwise it just raises 252bf215546Sopenharmony_ci # the exception 253bf215546Sopenharmony_ci import sys 254bf215546Sopenharmony_ci from mako import exceptions 255bf215546Sopenharmony_ci print(exceptions.text_error_template().render(), file=sys.stderr) 256bf215546Sopenharmony_ci sys.exit(1) 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ciif __name__ == '__main__': 259bf215546Sopenharmony_ci main() 260