blob: 7b1b0f704bf0d255e65045c580890fdb2273b170 [file] [log] [blame]
Chia-I Wufb2559d2014-08-01 11:19:52 +08001#!/usr/bin/env python3
Chia-I Wu44e42362014-09-02 08:32:09 +08002#
Courtney Goeltzenleuchter8a17da52015-10-29 13:50:34 -06003# Copyright (C) 2015 Valve Corporation
Michael Lentine92689442015-09-09 12:39:13 -07004# Copyright (C) 2015 Google Inc.
Chia-I Wu44e42362014-09-02 08:32:09 +08005#
6# Permission is hereby granted, free of charge, to any person obtaining a
7# copy of this software and associated documentation files (the "Software"),
8# to deal in the Software without restriction, including without limitation
9# the rights to use, copy, modify, merge, publish, distribute, sublicense,
10# and/or sell copies of the Software, and to permit persons to whom the
11# Software is furnished to do so, subject to the following conditions:
12#
13# The above copyright notice and this permission notice shall be included
14# in all copies or substantial portions of the Software.
15#
16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22# DEALINGS IN THE SOFTWARE.
23#
Courtney Goeltzenleuchter96cd7952015-10-30 11:14:30 -060024# Author: Chia-I Wu <olv@lunarg.com>
25# Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
26# Author: Jon Ashburn <jon@lunarg.com>
Chia-I Wufb2559d2014-08-01 11:19:52 +080027
28import sys
29
Courtney Goeltzenleuchtera8c06282015-04-14 14:55:44 -060030import vulkan
Chia-I Wufb2559d2014-08-01 11:19:52 +080031
Chia-I Wuf7d6d3c2015-01-05 12:55:13 +080032def generate_get_proc_addr_check(name):
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060033 return " if (!%s || %s[0] != 'v' || %s[1] != 'k')\n" \
34 " return NULL;" % ((name,) * 3)
Chia-I Wuf7d6d3c2015-01-05 12:55:13 +080035
Chia-I Wufb2559d2014-08-01 11:19:52 +080036class Subcommand(object):
37 def __init__(self, argv):
38 self.argv = argv
Courtney Goeltzenleuchtera8c06282015-04-14 14:55:44 -060039 self.headers = vulkan.headers
40 self.protos = vulkan.protos
Chia-I Wufb2559d2014-08-01 11:19:52 +080041
42 def run(self):
Chia-I Wufb2559d2014-08-01 11:19:52 +080043 print(self.generate())
44
45 def generate(self):
46 copyright = self.generate_copyright()
47 header = self.generate_header()
48 body = self.generate_body()
49 footer = self.generate_footer()
50
51 contents = []
52 if copyright:
53 contents.append(copyright)
54 if header:
55 contents.append(header)
56 if body:
57 contents.append(body)
58 if footer:
59 contents.append(footer)
60
61 return "\n\n".join(contents)
62
63 def generate_copyright(self):
64 return """/* THIS FILE IS GENERATED. DO NOT EDIT. */
65
66/*
Chia-I Wufb2559d2014-08-01 11:19:52 +080067 *
Courtney Goeltzenleuchter8a17da52015-10-29 13:50:34 -060068 * Copyright (C) 2015 Valve Corporation
Chia-I Wufb2559d2014-08-01 11:19:52 +080069 *
70 * Permission is hereby granted, free of charge, to any person obtaining a
71 * copy of this software and associated documentation files (the "Software"),
72 * to deal in the Software without restriction, including without limitation
73 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
74 * and/or sell copies of the Software, and to permit persons to whom the
75 * Software is furnished to do so, subject to the following conditions:
76 *
77 * The above copyright notice and this permission notice shall be included
78 * in all copies or substantial portions of the Software.
79 *
80 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
81 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
82 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
83 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
84 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
85 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
86 * DEALINGS IN THE SOFTWARE.
Courtney Goeltzenleuchter96cd7952015-10-30 11:14:30 -060087 *
88 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
Chia-I Wufb2559d2014-08-01 11:19:52 +080089 */"""
90
91 def generate_header(self):
Chia-I Wu6ae460f2014-09-13 13:36:06 +080092 return "\n".join(["#include <" + h + ">" for h in self.headers])
Chia-I Wufb2559d2014-08-01 11:19:52 +080093
94 def generate_body(self):
95 pass
96
97 def generate_footer(self):
98 pass
99
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800100class DispatchTableOpsSubcommand(Subcommand):
101 def run(self):
102 if len(self.argv) != 1:
103 print("DispatchTableOpsSubcommand: <prefix> unspecified")
104 return
105
106 self.prefix = self.argv[0]
Michael Lentine92689442015-09-09 12:39:13 -0700107 super(DispatchTableOpsSubcommand, self).run()
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800108
109 def generate_header(self):
David Pinedo329ca9e2015-11-06 12:54:48 -0700110 return "\n".join(["#include <vulkan/vulkan.h>",
111 "#include <vulkan/vk_layer.h>",
Jon Ashburnaef65882015-05-04 09:16:41 -0600112 "#include <string.h>"])
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800113
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600114 def _generate_init_dispatch(self, type):
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800115 stmts = []
Jon Ashburnd9564002015-05-07 10:27:37 -0600116 func = []
117 if type == "device":
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600118 # GPA has to be first one and uses wrapped object
Courtney Goeltzenleuchterf83cd4a2015-06-26 15:05:29 -0600119 stmts.append("memset(table, 0, sizeof(*table));")
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600120 stmts.append("table->GetDeviceProcAddr =(PFN_vkGetDeviceProcAddr) gpa(device,\"vkGetDeviceProcAddr\");")
Jon Ashburnd9564002015-05-07 10:27:37 -0600121 for proto in self.protos:
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700122 if proto.name == "CreateInstance" or proto.name == "EnumerateInstanceExtensionProperties" or proto.name == "EnumerateInstanceLayerProperties" or proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice":
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600123 continue
Jon Ashburn83334db2015-09-16 18:08:32 -0600124 if proto.name != "GetDeviceProcAddr" and 'KHR' not in proto.name:
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700125 stmts.append("table->%s = (PFN_vk%s) gpa(device, \"vk%s\");" %
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800126 (proto.name, proto.name, proto.name))
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700127 func.append("static inline void %s_init_device_dispatch_table(VkDevice device,"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800128 % self.prefix)
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700129 func.append("%s VkLayerDispatchTable *table,"
130 % (" " * len(self.prefix)))
131 func.append("%s PFN_vkGetDeviceProcAddr gpa)"
Jon Ashburnd9564002015-05-07 10:27:37 -0600132 % (" " * len(self.prefix)))
133 else:
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600134 stmts.append("table->GetInstanceProcAddr =(PFN_vkGetInstanceProcAddr) gpa(instance,\"vkGetInstanceProcAddr\");")
Jon Ashburnd9564002015-05-07 10:27:37 -0600135 for proto in self.protos:
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700136 if proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice":
Jon Ashburnd9564002015-05-07 10:27:37 -0600137 continue
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600138 if proto.name == "CreateDevice":
139 continue
Jon Ashburn83334db2015-09-16 18:08:32 -0600140 if proto.name != "GetInstanceProcAddr" and 'KHR' not in proto.name:
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700141 stmts.append("table->%s = (PFN_vk%s) gpa(instance, \"vk%s\");" %
Jon Ashburnd9564002015-05-07 10:27:37 -0600142 (proto.name, proto.name, proto.name))
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700143 func.append("static inline void %s_init_instance_dispatch_table(" % self.prefix)
144 func.append("%s VkInstance instance," % (" " * len(self.prefix)))
145 func.append("%s VkLayerInstanceDispatchTable *table," % (" " * len(self.prefix)))
146 func.append("%s PFN_vkGetInstanceProcAddr gpa)" % (" " * len(self.prefix)))
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800147 func.append("{")
148 func.append(" %s" % "\n ".join(stmts))
149 func.append("}")
150
151 return "\n".join(func)
152
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800153 def generate_body(self):
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600154 body = [self._generate_init_dispatch("device"),
155 self._generate_init_dispatch("instance")]
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800156
157 return "\n\n".join(body)
158
Chia-I Wu731517d2015-01-03 23:48:15 +0800159class IcdDummyEntrypointsSubcommand(Subcommand):
Chia-I Wu30c78292014-08-04 10:08:08 +0800160 def run(self):
Chia-I Wu731517d2015-01-03 23:48:15 +0800161 if len(self.argv) == 1:
162 self.prefix = self.argv[0]
163 self.qual = "static"
164 else:
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600165 self.prefix = "vk"
Jon Ashburn89a1c462016-01-07 09:46:26 -0700166 self.qual = ""
Chia-I Wu30c78292014-08-04 10:08:08 +0800167
168 super().run()
169
170 def generate_header(self):
171 return "#include \"icd.h\""
172
173 def _generate_stub_decl(self, proto):
Jon Ashburn89a1c462016-01-07 09:46:26 -0700174 if proto.name == "GetInstanceProcAddr":
175 return proto.c_pretty_decl(self.prefix + "_icd" + proto.name, attr="ICD_EXPORT VKAPI")
176 else:
177 return proto.c_pretty_decl(self.prefix + proto.name, attr="VKAPI")
Chia-I Wu30c78292014-08-04 10:08:08 +0800178
179 def _generate_stubs(self):
180 stubs = []
181 for proto in self.protos:
Chia-I Wu30c78292014-08-04 10:08:08 +0800182 decl = self._generate_stub_decl(proto)
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600183 if proto.ret != "void":
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600184 stmt = " return VK_ERROR_UNKNOWN;\n"
Chia-I Wu30c78292014-08-04 10:08:08 +0800185 else:
186 stmt = ""
187
Chia-I Wu731517d2015-01-03 23:48:15 +0800188 stubs.append("%s %s\n{\n%s}" % (self.qual, decl, stmt))
Chia-I Wu30c78292014-08-04 10:08:08 +0800189
190 return "\n\n".join(stubs)
191
Chia-I Wu30c78292014-08-04 10:08:08 +0800192 def generate_body(self):
Chia-I Wu731517d2015-01-03 23:48:15 +0800193 return self._generate_stubs()
Chia-I Wu30c78292014-08-04 10:08:08 +0800194
Chia-I Wu58f20852015-01-04 00:11:17 +0800195class IcdGetProcAddrSubcommand(IcdDummyEntrypointsSubcommand):
196 def generate_header(self):
197 return "\n".join(["#include <string.h>", "#include \"icd.h\""])
198
199 def generate_body(self):
200 for proto in self.protos:
Jon Ashburn1245cec2015-05-18 13:20:15 -0600201 if proto.name == "GetDeviceProcAddr":
Chia-I Wu58f20852015-01-04 00:11:17 +0800202 gpa_proto = proto
Jon Ashburn53c16772015-05-06 10:15:07 -0600203 if proto.name == "GetInstanceProcAddr":
204 gpa_instance_proto = proto
Chia-I Wu58f20852015-01-04 00:11:17 +0800205
Jon Ashburn53c16772015-05-06 10:15:07 -0600206 gpa_instance_decl = self._generate_stub_decl(gpa_instance_proto)
Chia-I Wu58f20852015-01-04 00:11:17 +0800207 gpa_decl = self._generate_stub_decl(gpa_proto)
208 gpa_pname = gpa_proto.params[-1].name
209
210 lookups = []
211 for proto in self.protos:
212 lookups.append("if (!strcmp(%s, \"%s\"))" %
213 (gpa_pname, proto.name))
Jon Ashburn89a1c462016-01-07 09:46:26 -0700214 if proto.name != "GetInstanceProcAddr":
215 lookups.append(" return (%s) %s%s;" %
Chia-I Wu58f20852015-01-04 00:11:17 +0800216 (gpa_proto.ret, self.prefix, proto.name))
Jon Ashburn89a1c462016-01-07 09:46:26 -0700217 else:
218 lookups.append(" return (%s) %s%s;" %
219 (gpa_proto.ret, self.prefix, "_icdGetInstanceProcAddr"))
Chia-I Wu58f20852015-01-04 00:11:17 +0800220
221 body = []
Jon Ashburn53c16772015-05-06 10:15:07 -0600222 body.append("%s %s" % (self.qual, gpa_instance_decl))
223 body.append("{")
Jon Ashburn4ca01502015-07-16 10:12:59 -0600224 body.append(generate_get_proc_addr_check(gpa_pname))
225 body.append("")
226 body.append(" %s += 2;" % gpa_pname)
227 body.append(" %s" % "\n ".join(lookups))
228 body.append("")
Jon Ashburn53c16772015-05-06 10:15:07 -0600229 body.append(" return NULL;")
230 body.append("}")
231 body.append("")
232
Chia-I Wu58f20852015-01-04 00:11:17 +0800233 body.append("%s %s" % (self.qual, gpa_decl))
234 body.append("{")
Chia-I Wuf7d6d3c2015-01-05 12:55:13 +0800235 body.append(generate_get_proc_addr_check(gpa_pname))
Chia-I Wu58f20852015-01-04 00:11:17 +0800236 body.append("")
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600237 body.append(" %s += 2;" % gpa_pname)
Chia-I Wu58f20852015-01-04 00:11:17 +0800238 body.append(" %s" % "\n ".join(lookups))
239 body.append("")
240 body.append(" return NULL;")
241 body.append("}")
242
243 return "\n".join(body)
244
Chia-I Wud98a23c2015-04-11 10:56:50 +0800245class WinDefFileSubcommand(Subcommand):
246 def run(self):
247 library_exports = {
248 "all": [],
249 "icd": [
Jon Ashburn89a1c462016-01-07 09:46:26 -0700250 "vk_icdGetInstanceProcAddr",
Chia-I Wud98a23c2015-04-11 10:56:50 +0800251 ],
252 "layer": [
Jon Ashburn88049b12015-08-13 14:15:07 -0700253 "vkGetInstanceProcAddr",
254 "vkGetDeviceProcAddr",
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600255 "vkEnumerateInstanceLayerProperties",
256 "vkEnumerateInstanceExtensionProperties"
Chia-I Wud98a23c2015-04-11 10:56:50 +0800257 ],
Mark Lobodzinski2e87e612015-12-30 08:16:12 -0700258 "layer_multi": [
Jon Ashburn88049b12015-08-13 14:15:07 -0700259 "multi2GetInstanceProcAddr",
260 "multi1GetDeviceProcAddr"
261 ]
Chia-I Wud98a23c2015-04-11 10:56:50 +0800262 }
263
264 if len(self.argv) != 2 or self.argv[1] not in library_exports:
265 print("WinDefFileSubcommand: <library-name> {%s}" %
266 "|".join(library_exports.keys()))
267 return
268
269 self.library = self.argv[0]
Mark Lobodzinski2e87e612015-12-30 08:16:12 -0700270 if self.library == "VkLayer_multi":
271 self.exports = library_exports["layer_multi"]
Jon Ashburn88049b12015-08-13 14:15:07 -0700272 else:
273 self.exports = library_exports[self.argv[1]]
Chia-I Wud98a23c2015-04-11 10:56:50 +0800274
275 super().run()
276
277 def generate_copyright(self):
278 return """; THIS FILE IS GENERATED. DO NOT EDIT.
279
280;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600281; Vulkan
Chia-I Wud98a23c2015-04-11 10:56:50 +0800282;
Courtney Goeltzenleuchter8a17da52015-10-29 13:50:34 -0600283; Copyright (C) 2015 Valve Corporation
Chia-I Wud98a23c2015-04-11 10:56:50 +0800284;
285; Permission is hereby granted, free of charge, to any person obtaining a
286; copy of this software and associated documentation files (the "Software"),
287; to deal in the Software without restriction, including without limitation
288; the rights to use, copy, modify, merge, publish, distribute, sublicense,
289; and/or sell copies of the Software, and to permit persons to whom the
290; Software is furnished to do so, subject to the following conditions:
291;
292; The above copyright notice and this permission notice shall be included
293; in all copies or substantial portions of the Software.
294;
295; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
296; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
297; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
298; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
299; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
300; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
301; DEALINGS IN THE SOFTWARE.
Courtney Goeltzenleuchtercf8ff4f2015-12-16 14:57:27 -0700302;
303; Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
Chia-I Wud98a23c2015-04-11 10:56:50 +0800304;;;; End Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"""
305
306 def generate_header(self):
307 return "; The following is required on Windows, for exporting symbols from the DLL"
308
309 def generate_body(self):
310 body = []
311
312 body.append("LIBRARY " + self.library)
313 body.append("EXPORTS")
314
Jon Ashburn88049b12015-08-13 14:15:07 -0700315 for proto in self.exports:
Mark Lobodzinski2e87e612015-12-30 08:16:12 -0700316 if self.library != "VkLayerSwapchain" or proto != "vkEnumerateInstanceExtensionProperties" and proto != "vkEnumerateInstanceLayerProperties":
Ian Elliott329da012015-09-22 10:51:24 -0600317 body.append( proto)
Chia-I Wud98a23c2015-04-11 10:56:50 +0800318
319 return "\n".join(body)
320
Chia-I Wufb2559d2014-08-01 11:19:52 +0800321def main():
322 subcommands = {
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800323 "dispatch-table-ops": DispatchTableOpsSubcommand,
Chia-I Wu731517d2015-01-03 23:48:15 +0800324 "icd-dummy-entrypoints": IcdDummyEntrypointsSubcommand,
Chia-I Wu58f20852015-01-04 00:11:17 +0800325 "icd-get-proc-addr": IcdGetProcAddrSubcommand,
Chia-I Wud98a23c2015-04-11 10:56:50 +0800326 "win-def-file": WinDefFileSubcommand,
Chia-I Wufb2559d2014-08-01 11:19:52 +0800327 }
328
329 if len(sys.argv) < 2 or sys.argv[1] not in subcommands:
330 print("Usage: %s <subcommand> [options]" % sys.argv[0])
331 print
332 print("Available sucommands are: %s" % " ".join(subcommands))
333 exit(1)
334
335 subcmd = subcommands[sys.argv[1]](sys.argv[2:])
336 subcmd.run()
337
338if __name__ == "__main__":
339 main()