1#!/usr/bin/env python3 2# 3# Copyright (c) 2015-2016 The Khronos Group Inc. 4# Copyright (c) 2015-2016 Valve Corporation 5# Copyright (c) 2015-2016 LunarG, Inc. 6# Copyright (c) 2015-2016 Google Inc. 7# 8# Permission is hereby granted, free of charge, to any person obtaining a copy 9# of this software and/or associated documentation files (the "Materials"), to 10# deal in the Materials without restriction, including without limitation the 11# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 12# sell copies of the Materials, and to permit persons to whom the Materials 13# are furnished to do so, subject to the following conditions: 14# 15# The above copyright notice(s) and this permission notice shall be included 16# in all copies or substantial portions of the Materials. 17# 18# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21# 22# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 23# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 24# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 25# USE OR OTHER DEALINGS IN THE MATERIALS 26# 27# Author: Chia-I Wu <olv@lunarg.com> 28# Author: Courtney Goeltzenleuchter <courtney@LunarG.com> 29# Author: Jon Ashburn <jon@lunarg.com> 30# Author: Gwan-gyeong Mun <kk.moon@samsung.com> 31 32import sys 33 34import vulkan 35 36def generate_get_proc_addr_check(name): 37 return " if (!%s || %s[0] != 'v' || %s[1] != 'k')\n" \ 38 " return NULL;" % ((name,) * 3) 39 40class Subcommand(object): 41 def __init__(self, argv): 42 self.argv = argv 43 self.headers = vulkan.headers 44 self.protos = vulkan.protos 45 46 def run(self): 47 print(self.generate()) 48 49 def generate(self): 50 copyright = self.generate_copyright() 51 header = self.generate_header() 52 body = self.generate_body() 53 footer = self.generate_footer() 54 55 contents = [] 56 if copyright: 57 contents.append(copyright) 58 if header: 59 contents.append(header) 60 if body: 61 contents.append(body) 62 if footer: 63 contents.append(footer) 64 65 return "\n\n".join(contents) 66 67 def generate_copyright(self): 68 return """/* THIS FILE IS GENERATED. DO NOT EDIT. */ 69 70/* 71 * Copyright (c) 2015-2016 The Khronos Group Inc. 72 * Copyright (c) 2015-2016 Valve Corporation 73 * Copyright (c) 2015-2016 LunarG, Inc. 74 * 75 * Permission is hereby granted, free of charge, to any person obtaining a copy 76 * of this software and/or associated documentation files (the "Materials"), to 77 * deal in the Materials without restriction, including without limitation the 78 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 79 * sell copies of the Materials, and to permit persons to whom the Materials are 80 * furnished to do so, subject to the following conditions: 81 * 82 * The above copyright notice(s) and this permission notice shall be included in 83 * all copies or substantial portions of the Materials. 84 * 85 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 86 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 87 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 88 * 89 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 90 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 91 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 92 * USE OR OTHER DEALINGS IN THE MATERIALS. 93 * 94 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com> 95 */""" 96 97 def generate_header(self): 98 return "\n".join(["#include <" + h + ">" for h in self.headers]) 99 100 def generate_body(self): 101 pass 102 103 def generate_footer(self): 104 pass 105 106class DispatchTableOpsSubcommand(Subcommand): 107 def run(self): 108 if len(self.argv) != 1: 109 print("DispatchTableOpsSubcommand: <prefix> unspecified") 110 return 111 112 self.prefix = self.argv[0] 113 super(DispatchTableOpsSubcommand, self).run() 114 115 def generate_header(self): 116 return "\n".join(["#include <vulkan/vulkan.h>", 117 "#include <vulkan/vk_layer.h>", 118 "#include <string.h>"]) 119 120 def _generate_init_dispatch(self, type): 121 stmts = [] 122 func = [] 123 if type == "device": 124 # GPA has to be first one and uses wrapped object 125 stmts.append("memset(table, 0, sizeof(*table));") 126 stmts.append("table->GetDeviceProcAddr =(PFN_vkGetDeviceProcAddr) gpa(device,\"vkGetDeviceProcAddr\");") 127 for proto in self.protos: 128 if proto.name == "CreateInstance" or proto.name == "EnumerateInstanceExtensionProperties" or proto.name == "EnumerateInstanceLayerProperties" or proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice": 129 continue 130 if proto.name != "GetDeviceProcAddr" and 'KHR' not in proto.name: 131 stmts.append("table->%s = (PFN_vk%s) gpa(device, \"vk%s\");" % 132 (proto.name, proto.name, proto.name)) 133 func.append("static inline void %s_init_device_dispatch_table(VkDevice device," 134 % self.prefix) 135 func.append("%s VkLayerDispatchTable *table," 136 % (" " * len(self.prefix))) 137 func.append("%s PFN_vkGetDeviceProcAddr gpa)" 138 % (" " * len(self.prefix))) 139 else: 140 stmts.append("table->GetInstanceProcAddr =(PFN_vkGetInstanceProcAddr) gpa(instance,\"vkGetInstanceProcAddr\");") 141 for proto in self.protos: 142 if proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice": 143 continue 144 if proto.name == "CreateDevice": 145 continue 146 if proto.name != "GetInstanceProcAddr" and 'KHR' not in proto.name: 147 stmts.append("table->%s = (PFN_vk%s) gpa(instance, \"vk%s\");" % 148 (proto.name, proto.name, proto.name)) 149 func.append("static inline void %s_init_instance_dispatch_table(" % self.prefix) 150 func.append("%s VkInstance instance," % (" " * len(self.prefix))) 151 func.append("%s VkLayerInstanceDispatchTable *table," % (" " * len(self.prefix))) 152 func.append("%s PFN_vkGetInstanceProcAddr gpa)" % (" " * len(self.prefix))) 153 func.append("{") 154 func.append(" %s" % "\n ".join(stmts)) 155 func.append("}") 156 157 return "\n".join(func) 158 159 def generate_body(self): 160 body = [self._generate_init_dispatch("device"), 161 self._generate_init_dispatch("instance")] 162 163 return "\n\n".join(body) 164 165class WinDefFileSubcommand(Subcommand): 166 def run(self): 167 library_exports = { 168 "all": [], 169 "icd": [ 170 "vk_icdGetInstanceProcAddr", 171 ], 172 "layer": [ 173 "vkGetInstanceProcAddr", 174 "vkGetDeviceProcAddr", 175 "vkEnumerateInstanceLayerProperties", 176 "vkEnumerateInstanceExtensionProperties" 177 ], 178 "layer_multi": [ 179 "multi2GetInstanceProcAddr", 180 "multi1GetDeviceProcAddr" 181 ] 182 } 183 184 if len(self.argv) != 2 or self.argv[1] not in library_exports: 185 print("WinDefFileSubcommand: <library-name> {%s}" % 186 "|".join(library_exports.keys())) 187 return 188 189 self.library = self.argv[0] 190 if self.library == "VkLayer_multi": 191 self.exports = library_exports["layer_multi"] 192 else: 193 self.exports = library_exports[self.argv[1]] 194 195 super().run() 196 197 def generate_copyright(self): 198 return """; THIS FILE IS GENERATED. DO NOT EDIT. 199 200;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 201; Vulkan 202; 203; Copyright (c) 2015-2016 The Khronos Group Inc. 204; Copyright (c) 2015-2016 Valve Corporation 205; Copyright (c) 2015-2016 LunarG, Inc. 206; 207; Permission is hereby granted, free of charge, to any person obtaining a copy 208; of this software and/or associated documentation files (the "Materials"), to 209; deal in the Materials without restriction, including without limitation the 210; rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 211; sell copies of the Materials, and to permit persons to whom the Materials are 212; furnished to do so, subject to the following conditions: 213; 214; The above copyright notice(s) and this permission notice shall be included in 215; all copies or substantial portions of the Materials. 216; 217; THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 218; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 219; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 220; 221; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 222; DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 223; OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 224; USE OR OTHER DEALINGS IN THE MATERIALS. 225; 226; Author: Courtney Goeltzenleuchter <courtney@LunarG.com> 227;;;; End Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;""" 228 229 def generate_header(self): 230 return "; The following is required on Windows, for exporting symbols from the DLL" 231 232 def generate_body(self): 233 body = [] 234 235 body.append("LIBRARY " + self.library) 236 body.append("EXPORTS") 237 238 for proto in self.exports: 239 if self.library != "VkLayerSwapchain" or proto != "vkEnumerateInstanceExtensionProperties" and proto != "vkEnumerateInstanceLayerProperties": 240 body.append( proto) 241 242 return "\n".join(body) 243 244def main(): 245 wsi = { 246 "Win32", 247 "Android", 248 "Xcb", 249 "Xlib", 250 "Wayland", 251 "Mir" 252 } 253 subcommands = { 254 "dispatch-table-ops": DispatchTableOpsSubcommand, 255 "win-def-file": WinDefFileSubcommand, 256 } 257 258 if len(sys.argv) < 3 or sys.argv[1] not in wsi or sys.argv[2] not in subcommands: 259 print("Usage: %s <wsi> <subcommand> [options]" % sys.argv[0]) 260 print 261 print("Available sucommands are: %s" % " ".join(subcommands)) 262 exit(1) 263 264 subcmd = subcommands[sys.argv[2]](sys.argv[3:]) 265 subcmd.run() 266 267if __name__ == "__main__": 268 main() 269