17ec681f3Smrg# coding=utf-8 27ec681f3SmrgCOPYRIGHT=u""" 37ec681f3Smrg/* Copyright © 2015-2021 Intel Corporation 47ec681f3Smrg * 57ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 67ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 77ec681f3Smrg * to deal in the Software without restriction, including without limitation 87ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 97ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 107ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 117ec681f3Smrg * 127ec681f3Smrg * The above copyright notice and this permission notice (including the next 137ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 147ec681f3Smrg * Software. 157ec681f3Smrg * 167ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 177ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 187ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 197ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 207ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 217ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 227ec681f3Smrg * IN THE SOFTWARE. 237ec681f3Smrg */ 247ec681f3Smrg""" 257ec681f3Smrg 267ec681f3Smrgimport argparse 277ec681f3Smrgimport os 287ec681f3Smrg 297ec681f3Smrgfrom mako.template import Template 307ec681f3Smrg 317ec681f3Smrg# Mesa-local imports must be declared in meson variable 327ec681f3Smrg# '{file_without_suffix}_depend_files'. 337ec681f3Smrgfrom vk_dispatch_table_gen import get_entrypoints_from_xml 347ec681f3Smrg 357ec681f3SmrgTEMPLATE_H = Template(COPYRIGHT + """\ 367ec681f3Smrg/* This file generated from ${filename}, don't edit directly. */ 377ec681f3Smrg 387ec681f3Smrg#include "vk_dispatch_table.h" 397ec681f3Smrg 407ec681f3Smrg#ifndef ${guard} 417ec681f3Smrg#define ${guard} 427ec681f3Smrg 437ec681f3Smrg#ifdef __cplusplus 447ec681f3Smrgextern "C" { 457ec681f3Smrg#endif 467ec681f3Smrg 477ec681f3Smrg% for p in instance_prefixes: 487ec681f3Smrgextern const struct vk_instance_entrypoint_table ${p}_instance_entrypoints; 497ec681f3Smrg% endfor 507ec681f3Smrg 517ec681f3Smrg% for p in physical_device_prefixes: 527ec681f3Smrgextern const struct vk_physical_device_entrypoint_table ${p}_physical_device_entrypoints; 537ec681f3Smrg% endfor 547ec681f3Smrg 557ec681f3Smrg% for p in device_prefixes: 567ec681f3Smrgextern const struct vk_device_entrypoint_table ${p}_device_entrypoints; 577ec681f3Smrg% endfor 587ec681f3Smrg 597ec681f3Smrg% if gen_proto: 607ec681f3Smrg% for e in instance_entrypoints: 617ec681f3Smrg % if e.guard is not None: 627ec681f3Smrg#ifdef ${e.guard} 637ec681f3Smrg % endif 647ec681f3Smrg % for p in physical_device_prefixes: 657ec681f3Smrg VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}); 667ec681f3Smrg % endfor 677ec681f3Smrg % if e.guard is not None: 687ec681f3Smrg#endif // ${e.guard} 697ec681f3Smrg % endif 707ec681f3Smrg% endfor 717ec681f3Smrg 727ec681f3Smrg% for e in physical_device_entrypoints: 737ec681f3Smrg % if e.guard is not None: 747ec681f3Smrg#ifdef ${e.guard} 757ec681f3Smrg % endif 767ec681f3Smrg % for p in physical_device_prefixes: 777ec681f3Smrg VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}); 787ec681f3Smrg % endfor 797ec681f3Smrg % if e.guard is not None: 807ec681f3Smrg#endif // ${e.guard} 817ec681f3Smrg % endif 827ec681f3Smrg% endfor 837ec681f3Smrg 847ec681f3Smrg% for e in device_entrypoints: 857ec681f3Smrg % if e.guard is not None: 867ec681f3Smrg#ifdef ${e.guard} 877ec681f3Smrg % endif 887ec681f3Smrg % for p in device_prefixes: 897ec681f3Smrg VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}); 907ec681f3Smrg % endfor 917ec681f3Smrg % if e.guard is not None: 927ec681f3Smrg#endif // ${e.guard} 937ec681f3Smrg % endif 947ec681f3Smrg% endfor 957ec681f3Smrg% endif 967ec681f3Smrg 977ec681f3Smrg#ifdef __cplusplus 987ec681f3Smrg} 997ec681f3Smrg#endif 1007ec681f3Smrg 1017ec681f3Smrg#endif /* ${guard} */ 1027ec681f3Smrg""") 1037ec681f3Smrg 1047ec681f3SmrgTEMPLATE_C = Template(COPYRIGHT + """ 1057ec681f3Smrg/* This file generated from ${filename}, don't edit directly. */ 1067ec681f3Smrg 1077ec681f3Smrg#include "${header}" 1087ec681f3Smrg 1097ec681f3Smrg/* Weak aliases for all potential implementations. These will resolve to 1107ec681f3Smrg * NULL if they're not defined, which lets the resolve_entrypoint() function 1117ec681f3Smrg * either pick the correct entry point. 1127ec681f3Smrg * 1137ec681f3Smrg * MSVC uses different decorated names for 32-bit versus 64-bit. Declare 1147ec681f3Smrg * all argument sizes for 32-bit because computing the actual size would be 1157ec681f3Smrg * difficult. 1167ec681f3Smrg */ 1177ec681f3Smrg 1187ec681f3Smrg<%def name="entrypoint_table(type, entrypoints, prefixes)"> 1197ec681f3Smrg% if gen_weak: 1207ec681f3Smrg % for e in entrypoints: 1217ec681f3Smrg % if e.guard is not None: 1227ec681f3Smrg#ifdef ${e.guard} 1237ec681f3Smrg % endif 1247ec681f3Smrg % for p in prefixes: 1257ec681f3Smrg#ifdef _MSC_VER 1267ec681f3Smrg#ifdef _M_IX86 1277ec681f3Smrg % for args_size in [4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 60, 104]: 1287ec681f3Smrg #pragma comment(linker, "/alternatename:_${p}_${e.name}@${args_size}=_vk_entrypoint_stub@0") 1297ec681f3Smrg % endfor 1307ec681f3Smrg#else 1317ec681f3Smrg #pragma comment(linker, "/alternatename:${p}_${e.name}=vk_entrypoint_stub") 1327ec681f3Smrg#endif 1337ec681f3Smrg#else 1347ec681f3Smrg VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}) __attribute__ ((weak)); 1357ec681f3Smrg#endif 1367ec681f3Smrg % endfor 1377ec681f3Smrg % if e.guard is not None: 1387ec681f3Smrg#endif // ${e.guard} 1397ec681f3Smrg % endif 1407ec681f3Smrg % endfor 1417ec681f3Smrg% endif 1427ec681f3Smrg 1437ec681f3Smrg% for p in prefixes: 1447ec681f3Smrgconst struct vk_${type}_entrypoint_table ${p}_${type}_entrypoints = { 1457ec681f3Smrg % for e in entrypoints: 1467ec681f3Smrg % if e.guard is not None: 1477ec681f3Smrg#ifdef ${e.guard} 1487ec681f3Smrg % endif 1497ec681f3Smrg .${e.name} = ${p}_${e.name}, 1507ec681f3Smrg % if e.guard is not None: 1517ec681f3Smrg#elif defined(_MSC_VER) 1527ec681f3Smrg .${e.name} = (PFN_vkVoidFunction)vk_entrypoint_stub, 1537ec681f3Smrg#endif // ${e.guard} 1547ec681f3Smrg % endif 1557ec681f3Smrg % endfor 1567ec681f3Smrg}; 1577ec681f3Smrg% endfor 1587ec681f3Smrg</%def> 1597ec681f3Smrg 1607ec681f3Smrg${entrypoint_table('instance', instance_entrypoints, instance_prefixes)} 1617ec681f3Smrg${entrypoint_table('physical_device', physical_device_entrypoints, physical_device_prefixes)} 1627ec681f3Smrg${entrypoint_table('device', device_entrypoints, device_prefixes)} 1637ec681f3Smrg""") 1647ec681f3Smrg 1657ec681f3Smrgdef get_entrypoints_defines(doc): 1667ec681f3Smrg """Maps entry points to extension defines.""" 1677ec681f3Smrg entrypoints_to_defines = {} 1687ec681f3Smrg 1697ec681f3Smrg platform_define = {} 1707ec681f3Smrg for platform in doc.findall('./platforms/platform'): 1717ec681f3Smrg name = platform.attrib['name'] 1727ec681f3Smrg define = platform.attrib['protect'] 1737ec681f3Smrg platform_define[name] = define 1747ec681f3Smrg 1757ec681f3Smrg for extension in doc.findall('./extensions/extension[@platform]'): 1767ec681f3Smrg platform = extension.attrib['platform'] 1777ec681f3Smrg define = platform_define[platform] 1787ec681f3Smrg 1797ec681f3Smrg for entrypoint in extension.findall('./require/command'): 1807ec681f3Smrg fullname = entrypoint.attrib['name'] 1817ec681f3Smrg entrypoints_to_defines[fullname] = define 1827ec681f3Smrg 1837ec681f3Smrg return entrypoints_to_defines 1847ec681f3Smrg 1857ec681f3Smrg 1867ec681f3Smrgdef main(): 1877ec681f3Smrg parser = argparse.ArgumentParser() 1887ec681f3Smrg parser.add_argument('--out-c', required=True, help='Output C file.') 1897ec681f3Smrg parser.add_argument('--out-h', required=True, help='Output H file.') 1907ec681f3Smrg parser.add_argument('--xml', 1917ec681f3Smrg help='Vulkan API XML file.', 1927ec681f3Smrg required=True, action='append', dest='xml_files') 1937ec681f3Smrg parser.add_argument('--proto', help='Generate entrypoint prototypes', 1947ec681f3Smrg action='store_true', dest='gen_proto') 1957ec681f3Smrg parser.add_argument('--weak', help='Generate weak entrypoint declarations', 1967ec681f3Smrg action='store_true', dest='gen_weak') 1977ec681f3Smrg parser.add_argument('--prefix', 1987ec681f3Smrg help='Prefix to use for all dispatch tables.', 1997ec681f3Smrg action='append', default=[], dest='prefixes') 2007ec681f3Smrg parser.add_argument('--device-prefix', 2017ec681f3Smrg help='Prefix to use for device dispatch tables.', 2027ec681f3Smrg action='append', default=[], dest='device_prefixes') 2037ec681f3Smrg args = parser.parse_args() 2047ec681f3Smrg 2057ec681f3Smrg instance_prefixes = args.prefixes 2067ec681f3Smrg physical_device_prefixes = args.prefixes 2077ec681f3Smrg device_prefixes = args.prefixes + args.device_prefixes 2087ec681f3Smrg 2097ec681f3Smrg entrypoints = get_entrypoints_from_xml(args.xml_files) 2107ec681f3Smrg 2117ec681f3Smrg device_entrypoints = [] 2127ec681f3Smrg physical_device_entrypoints = [] 2137ec681f3Smrg instance_entrypoints = [] 2147ec681f3Smrg for e in entrypoints: 2157ec681f3Smrg if e.is_device_entrypoint(): 2167ec681f3Smrg device_entrypoints.append(e) 2177ec681f3Smrg elif e.is_physical_device_entrypoint(): 2187ec681f3Smrg physical_device_entrypoints.append(e) 2197ec681f3Smrg else: 2207ec681f3Smrg instance_entrypoints.append(e) 2217ec681f3Smrg 2227ec681f3Smrg assert os.path.dirname(args.out_c) == os.path.dirname(args.out_h) 2237ec681f3Smrg 2247ec681f3Smrg environment = { 2257ec681f3Smrg 'gen_proto': args.gen_proto, 2267ec681f3Smrg 'gen_weak': args.gen_weak, 2277ec681f3Smrg 'header': os.path.basename(args.out_h), 2287ec681f3Smrg 'instance_entrypoints': instance_entrypoints, 2297ec681f3Smrg 'instance_prefixes': instance_prefixes, 2307ec681f3Smrg 'physical_device_entrypoints': physical_device_entrypoints, 2317ec681f3Smrg 'physical_device_prefixes': physical_device_prefixes, 2327ec681f3Smrg 'device_entrypoints': device_entrypoints, 2337ec681f3Smrg 'device_prefixes': device_prefixes, 2347ec681f3Smrg 'filename': os.path.basename(__file__), 2357ec681f3Smrg } 2367ec681f3Smrg 2377ec681f3Smrg # For outputting entrypoints.h we generate a anv_EntryPoint() prototype 2387ec681f3Smrg # per entry point. 2397ec681f3Smrg try: 2407ec681f3Smrg with open(args.out_h, 'w') as f: 2417ec681f3Smrg guard = os.path.basename(args.out_h).replace('.', '_').upper() 2427ec681f3Smrg f.write(TEMPLATE_H.render(guard=guard, **environment)) 2437ec681f3Smrg with open(args.out_c, 'w') as f: 2447ec681f3Smrg f.write(TEMPLATE_C.render(**environment)) 2457ec681f3Smrg 2467ec681f3Smrg except Exception: 2477ec681f3Smrg # In the event there's an error, this imports some helpers from mako 2487ec681f3Smrg # to print a useful stack trace and prints it, then exits with 2497ec681f3Smrg # status 1, if python is run with debug; otherwise it just raises 2507ec681f3Smrg # the exception 2517ec681f3Smrg if __debug__: 2527ec681f3Smrg import sys 2537ec681f3Smrg from mako import exceptions 2547ec681f3Smrg sys.stderr.write(exceptions.text_error_template().render() + '\n') 2557ec681f3Smrg sys.exit(1) 2567ec681f3Smrg raise 2577ec681f3Smrg 2587ec681f3Smrgif __name__ == '__main__': 2597ec681f3Smrg main() 260