Path: blob/21.2-virgl/src/vulkan/util/vk_entrypoints_gen.py
7196 views
# coding=utf-81COPYRIGHT=u"""2/* Copyright © 2015-2021 Intel Corporation3*4* Permission is hereby granted, free of charge, to any person obtaining a5* copy of this software and associated documentation files (the "Software"),6* to deal in the Software without restriction, including without limitation7* the rights to use, copy, modify, merge, publish, distribute, sublicense,8* and/or sell copies of the Software, and to permit persons to whom the9* Software is furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice (including the next12* paragraph) shall be included in all copies or substantial portions of the13* Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING20* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS21* IN THE SOFTWARE.22*/23"""2425import argparse26import os2728from mako.template import Template2930# Mesa-local imports must be declared in meson variable31# '{file_without_suffix}_depend_files'.32from vk_dispatch_table_gen import get_entrypoints_from_xml3334TEMPLATE_H = Template(COPYRIGHT + """\35/* This file generated from ${filename}, don't edit directly. */3637#include "vk_dispatch_table.h"3839#ifndef ${guard}40#define ${guard}4142#ifdef __cplusplus43extern "C" {44#endif4546% for p in instance_prefixes:47extern const struct vk_instance_entrypoint_table ${p}_instance_entrypoints;48% endfor4950% for p in physical_device_prefixes:51extern const struct vk_physical_device_entrypoint_table ${p}_physical_device_entrypoints;52% endfor5354% for p in device_prefixes:55extern const struct vk_device_entrypoint_table ${p}_device_entrypoints;56% endfor5758% if gen_proto:59% for e in instance_entrypoints:60% if e.guard is not None:61#ifdef ${e.guard}62% endif63% for p in physical_device_prefixes:64VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()});65% endfor66% if e.guard is not None:67#endif // ${e.guard}68% endif69% endfor7071% for e in physical_device_entrypoints:72% if e.guard is not None:73#ifdef ${e.guard}74% endif75% for p in physical_device_prefixes:76VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()});77% endfor78% if e.guard is not None:79#endif // ${e.guard}80% endif81% endfor8283% for e in device_entrypoints:84% if e.guard is not None:85#ifdef ${e.guard}86% endif87% for p in device_prefixes:88VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()});89% endfor90% if e.guard is not None:91#endif // ${e.guard}92% endif93% endfor94% endif9596#ifdef __cplusplus97}98#endif99100#endif /* ${guard} */101""", output_encoding='utf-8')102103TEMPLATE_C = Template(COPYRIGHT + """104/* This file generated from ${filename}, don't edit directly. */105106#include "${header}"107108/* Weak aliases for all potential implementations. These will resolve to109* NULL if they're not defined, which lets the resolve_entrypoint() function110* either pick the correct entry point.111*112* MSVC uses different decorated names for 32-bit versus 64-bit. Declare113* all argument sizes for 32-bit because computing the actual size would be114* difficult.115*/116117<%def name="entrypoint_table(type, entrypoints, prefixes)">118% if gen_weak:119% for e in entrypoints:120% if e.guard is not None:121#ifdef ${e.guard}122% endif123% for p in prefixes:124#ifdef _MSC_VER125${e.return_type} (*${p}_${e.name}_Null)(${e.decl_params()}) = 0;126#ifdef _M_IX86127% for args_size in [4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 60, 104]:128#pragma comment(linker, "/alternatename:_${p}_${e.name}@${args_size}=_${p}_${e.name}_Null")129% endfor130#else131#pragma comment(linker, "/alternatename:${p}_${e.name}=${p}_${e.name}_Null")132#endif133#else134VKAPI_ATTR ${e.return_type} VKAPI_CALL ${p}_${e.name}(${e.decl_params()}) __attribute__ ((weak));135#endif136% endfor137% if e.guard is not None:138#endif // ${e.guard}139% endif140% endfor141% endif142143% for p in prefixes:144const struct vk_${type}_entrypoint_table ${p}_${type}_entrypoints = {145% for e in entrypoints:146% if e.guard is not None:147#ifdef ${e.guard}148% endif149.${e.name} = ${p}_${e.name},150% if e.guard is not None:151#endif // ${e.guard}152% endif153% endfor154};155% endfor156</%def>157158${entrypoint_table('instance', instance_entrypoints, instance_prefixes)}159${entrypoint_table('physical_device', physical_device_entrypoints, physical_device_prefixes)}160${entrypoint_table('device', device_entrypoints, device_prefixes)}161""", output_encoding='utf-8')162163def get_entrypoints_defines(doc):164"""Maps entry points to extension defines."""165entrypoints_to_defines = {}166167platform_define = {}168for platform in doc.findall('./platforms/platform'):169name = platform.attrib['name']170define = platform.attrib['protect']171platform_define[name] = define172173for extension in doc.findall('./extensions/extension[@platform]'):174platform = extension.attrib['platform']175define = platform_define[platform]176177for entrypoint in extension.findall('./require/command'):178fullname = entrypoint.attrib['name']179entrypoints_to_defines[fullname] = define180181return entrypoints_to_defines182183184def main():185parser = argparse.ArgumentParser()186parser.add_argument('--out-c', required=True, help='Output C file.')187parser.add_argument('--out-h', required=True, help='Output H file.')188parser.add_argument('--xml',189help='Vulkan API XML file.',190required=True, action='append', dest='xml_files')191parser.add_argument('--proto', help='Generate entrypoint prototypes',192action='store_true', dest='gen_proto')193parser.add_argument('--weak', help='Generate weak entrypoint declarations',194action='store_true', dest='gen_weak')195parser.add_argument('--prefix',196help='Prefix to use for all dispatch tables.',197action='append', default=[], dest='prefixes')198parser.add_argument('--device-prefix',199help='Prefix to use for device dispatch tables.',200action='append', default=[], dest='device_prefixes')201args = parser.parse_args()202203instance_prefixes = args.prefixes204physical_device_prefixes = args.prefixes205device_prefixes = args.prefixes + args.device_prefixes206207entrypoints = get_entrypoints_from_xml(args.xml_files)208209device_entrypoints = []210physical_device_entrypoints = []211instance_entrypoints = []212for e in entrypoints:213if e.is_device_entrypoint():214device_entrypoints.append(e)215elif e.is_physical_device_entrypoint():216physical_device_entrypoints.append(e)217else:218instance_entrypoints.append(e)219220assert os.path.dirname(args.out_c) == os.path.dirname(args.out_h)221222environment = {223'gen_proto': args.gen_proto,224'gen_weak': args.gen_weak,225'header': os.path.basename(args.out_h),226'instance_entrypoints': instance_entrypoints,227'instance_prefixes': instance_prefixes,228'physical_device_entrypoints': physical_device_entrypoints,229'physical_device_prefixes': physical_device_prefixes,230'device_entrypoints': device_entrypoints,231'device_prefixes': device_prefixes,232'filename': os.path.basename(__file__),233}234235# For outputting entrypoints.h we generate a anv_EntryPoint() prototype236# per entry point.237try:238with open(args.out_h, 'wb') as f:239guard = os.path.basename(args.out_h).replace('.', '_').upper()240f.write(TEMPLATE_H.render(guard=guard, **environment))241with open(args.out_c, 'wb') as f:242f.write(TEMPLATE_C.render(**environment))243244except Exception:245# In the event there's an error, this imports some helpers from mako246# to print a useful stack trace and prints it, then exits with247# status 1, if python is run with debug; otherwise it just raises248# the exception249if __debug__:250import sys251from mako import exceptions252sys.stderr.write(exceptions.text_error_template().render() + '\n')253sys.exit(1)254raise255256if __name__ == '__main__':257main()258259260