1# coding=utf-8 2COPYRIGHT = """\ 3/* 4 * Copyright 2020 Intel Corporation 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26""" 27 28import argparse 29import os 30 31from mako.template import Template 32 33# Mesa-local imports must be declared in meson variable 34# '{file_without_suffix}_depend_files'. 35from vk_entrypoints import get_entrypoints_from_xml 36 37TEMPLATE_H = Template(COPYRIGHT + """\ 38/* This file generated from ${filename}, don't edit directly. */ 39 40#ifndef VK_DISPATCH_TRAMPOLINES_H 41#define VK_DISPATCH_TRAMPOLINES_H 42 43#include "vulkan/util/vk_dispatch_table.h" 44 45#ifdef __cplusplus 46extern "C" { 47#endif 48 49extern struct vk_physical_device_dispatch_table vk_physical_device_trampolines; 50extern struct vk_device_dispatch_table vk_device_trampolines; 51 52#ifdef __cplusplus 53} 54#endif 55 56#endif /* VK_DISPATCH_TRAMPOLINES_H */ 57""") 58 59TEMPLATE_C = Template(COPYRIGHT + """\ 60/* This file generated from ${filename}, don't edit directly. */ 61 62#include "vk_device.h" 63#include "vk_dispatch_trampolines.h" 64#include "vk_object.h" 65#include "vk_physical_device.h" 66 67% for e in entrypoints: 68 % if not e.is_physical_device_entrypoint() or e.alias: 69 <% continue %> 70 % endif 71 % if e.guard is not None: 72#ifdef ${e.guard} 73 % endif 74static VKAPI_ATTR ${e.return_type} VKAPI_CALL 75${e.prefixed_name('vk_tramp')}(${e.decl_params()}) 76{ 77 <% assert e.params[0].type == 'VkPhysicalDevice' %> 78 VK_FROM_HANDLE(vk_physical_device, vk_physical_device, ${e.params[0].name}); 79 % if e.return_type == 'void': 80 vk_physical_device->dispatch_table.${e.name}(${e.call_params()}); 81 % else: 82 return vk_physical_device->dispatch_table.${e.name}(${e.call_params()}); 83 % endif 84} 85 % if e.guard is not None: 86#endif 87 % endif 88% endfor 89 90struct vk_physical_device_dispatch_table vk_physical_device_trampolines = { 91% for e in entrypoints: 92 % if not e.is_physical_device_entrypoint() or e.alias: 93 <% continue %> 94 % endif 95 % if e.guard is not None: 96#ifdef ${e.guard} 97 % endif 98 .${e.name} = ${e.prefixed_name('vk_tramp')}, 99 % if e.guard is not None: 100#endif 101 % endif 102% endfor 103}; 104 105% for e in entrypoints: 106 % if not e.is_device_entrypoint() or e.alias: 107 <% continue %> 108 % endif 109 % if e.guard is not None: 110#ifdef ${e.guard} 111 % endif 112static VKAPI_ATTR ${e.return_type} VKAPI_CALL 113${e.prefixed_name('vk_tramp')}(${e.decl_params()}) 114{ 115 % if e.params[0].type == 'VkDevice': 116 VK_FROM_HANDLE(vk_device, vk_device, ${e.params[0].name}); 117 % if e.return_type == 'void': 118 vk_device->dispatch_table.${e.name}(${e.call_params()}); 119 % else: 120 return vk_device->dispatch_table.${e.name}(${e.call_params()}); 121 % endif 122 % elif e.params[0].type in ('VkCommandBuffer', 'VkQueue'): 123 struct vk_object_base *vk_object = (struct vk_object_base *)${e.params[0].name}; 124 % if e.return_type == 'void': 125 vk_object->device->dispatch_table.${e.name}(${e.call_params()}); 126 % else: 127 return vk_object->device->dispatch_table.${e.name}(${e.call_params()}); 128 % endif 129 % else: 130 assert(!"Unhandled device child trampoline case: ${e.params[0].type}"); 131 % endif 132} 133 % if e.guard is not None: 134#endif 135 % endif 136% endfor 137 138struct vk_device_dispatch_table vk_device_trampolines = { 139% for e in entrypoints: 140 % if not e.is_device_entrypoint() or e.alias: 141 <% continue %> 142 % endif 143 % if e.guard is not None: 144#ifdef ${e.guard} 145 % endif 146 .${e.name} = ${e.prefixed_name('vk_tramp')}, 147 % if e.guard is not None: 148#endif 149 % endif 150% endfor 151}; 152""") 153 154def main(): 155 parser = argparse.ArgumentParser() 156 parser.add_argument('--out-c', help='Output C file.') 157 parser.add_argument('--out-h', help='Output H file.') 158 parser.add_argument('--xml', 159 help='Vulkan API XML file.', 160 required=True, 161 action='append', 162 dest='xml_files') 163 args = parser.parse_args() 164 165 entrypoints = get_entrypoints_from_xml(args.xml_files) 166 167 # For outputting entrypoints.h we generate a anv_EntryPoint() prototype 168 # per entry point. 169 try: 170 if args.out_h: 171 with open(args.out_h, 'w') as f: 172 f.write(TEMPLATE_H.render(entrypoints=entrypoints, 173 filename=os.path.basename(__file__))) 174 if args.out_c: 175 with open(args.out_c, 'w') as f: 176 f.write(TEMPLATE_C.render(entrypoints=entrypoints, 177 filename=os.path.basename(__file__))) 178 except Exception: 179 # In the event there's an error, this imports some helpers from mako 180 # to print a useful stack trace and prints it, then exits with 181 # status 1, if python is run with debug; otherwise it just raises 182 # the exception 183 if __debug__: 184 import sys 185 from mako import exceptions 186 sys.stderr.write(exceptions.text_error_template().render() + '\n') 187 sys.exit(1) 188 raise 189 190 191if __name__ == '__main__': 192 main() 193