blob: 00327b75bfe9f4727f56abd04c2bf0c8a659368d [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 Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003# VK
Chia-I Wu44e42362014-09-02 08:32:09 +08004#
5# Copyright (C) 2014 LunarG, Inc.
6#
7# Permission is hereby granted, free of charge, to any person obtaining a
8# copy of this software and associated documentation files (the "Software"),
9# to deal in the Software without restriction, including without limitation
10# the rights to use, copy, modify, merge, publish, distribute, sublicense,
11# and/or sell copies of the Software, and to permit persons to whom the
12# Software is furnished to do so, subject to the following conditions:
13#
14# The above copyright notice and this permission notice shall be included
15# in all copies or substantial portions of the Software.
16#
17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23# DEALINGS IN THE SOFTWARE.
24#
25# Authors:
26# Chia-I Wu <olv@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/*
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060067 * Vulkan
Chia-I Wufb2559d2014-08-01 11:19:52 +080068 *
69 * Copyright (C) 2014 LunarG, Inc.
70 *
71 * Permission is hereby granted, free of charge, to any person obtaining a
72 * copy of this software and associated documentation files (the "Software"),
73 * to deal in the Software without restriction, including without limitation
74 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
75 * and/or sell copies of the Software, and to permit persons to whom the
76 * Software is furnished to do so, subject to the following conditions:
77 *
78 * The above copyright notice and this permission notice shall be included
79 * in all copies or substantial portions of the Software.
80 *
81 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
82 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
83 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
84 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
85 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
86 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
87 * DEALINGS IN THE SOFTWARE.
88 */"""
89
90 def generate_header(self):
Chia-I Wu6ae460f2014-09-13 13:36:06 +080091 return "\n".join(["#include <" + h + ">" for h in self.headers])
Chia-I Wufb2559d2014-08-01 11:19:52 +080092
93 def generate_body(self):
94 pass
95
96 def generate_footer(self):
97 pass
98
Chia-I Wu28b8d8c2015-01-04 10:19:50 +080099class DispatchTableOpsSubcommand(Subcommand):
100 def run(self):
101 if len(self.argv) != 1:
102 print("DispatchTableOpsSubcommand: <prefix> unspecified")
103 return
104
105 self.prefix = self.argv[0]
106 super().run()
107
108 def generate_header(self):
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600109 return "\n".join(["#include <vulkan.h>",
110 "#include <vkLayer.h>",
Jon Ashburnaef65882015-05-04 09:16:41 -0600111 "#include <string.h>"])
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800112
113 def _generate_init(self):
114 stmts = []
115 for proto in self.protos:
Jon Ashburnaef65882015-05-04 09:16:41 -0600116 if proto.name != "GetGlobalExtensionInfo":
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600117 stmts.append("table->%s = (PFN_vk%s) gpa(gpu, \"vk%s\");" %
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800118 (proto.name, proto.name, proto.name))
Jon Ashburn55178862015-04-13 17:47:29 -0600119 else:
120 stmts.append("table->%s = vk%s; /* non-dispatchable */" %
121 (proto.name, proto.name))
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800122
123 func = []
Jon Ashburn301c5f02015-04-06 10:58:22 -0600124 func.append("static inline void %s_initialize_dispatch_table(VkLayerDispatchTable *table,"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800125 % self.prefix)
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600126 func.append("%s PFN_vkGetProcAddr gpa,"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800127 % (" " * len(self.prefix)))
Tony Barbour8205d902015-04-16 15:59:00 -0600128 func.append("%s VkPhysicalDevice gpu)"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800129 % (" " * len(self.prefix)))
130 func.append("{")
131 func.append(" %s" % "\n ".join(stmts))
132 func.append("}")
133
134 return "\n".join(func)
135
136 def _generate_lookup(self):
137 lookups = []
138 for proto in self.protos:
Jon Ashburnaef65882015-05-04 09:16:41 -0600139 if proto.name != "GetGlobalExtensionInfo":
Jon Ashburneb2728b2015-04-10 14:33:07 -0600140 lookups.append("if (!strcmp(name, \"%s\"))" % (proto.name))
141 lookups.append(" return (void *) table->%s;"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800142 % (proto.name))
143
144 func = []
Jon Ashburn301c5f02015-04-06 10:58:22 -0600145 func.append("static inline void *%s_lookup_dispatch_table(const VkLayerDispatchTable *table,"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800146 % self.prefix)
147 func.append("%s const char *name)"
148 % (" " * len(self.prefix)))
149 func.append("{")
Chia-I Wuf7d6d3c2015-01-05 12:55:13 +0800150 func.append(generate_get_proc_addr_check("name"))
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800151 func.append("")
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600152 func.append(" name += 2;")
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800153 func.append(" %s" % "\n ".join(lookups))
154 func.append("")
155 func.append(" return NULL;")
156 func.append("}")
157
158 return "\n".join(func)
159
160 def generate_body(self):
161 body = [self._generate_init(),
162 self._generate_lookup()]
163
164 return "\n\n".join(body)
165
Chia-I Wu731517d2015-01-03 23:48:15 +0800166class IcdDummyEntrypointsSubcommand(Subcommand):
Chia-I Wu30c78292014-08-04 10:08:08 +0800167 def run(self):
Chia-I Wu731517d2015-01-03 23:48:15 +0800168 if len(self.argv) == 1:
169 self.prefix = self.argv[0]
170 self.qual = "static"
171 else:
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600172 self.prefix = "vk"
Chia-I Wu731517d2015-01-03 23:48:15 +0800173 self.qual = "ICD_EXPORT"
Chia-I Wu30c78292014-08-04 10:08:08 +0800174
175 super().run()
176
177 def generate_header(self):
178 return "#include \"icd.h\""
179
180 def _generate_stub_decl(self, proto):
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600181 return proto.c_pretty_decl(self.prefix + proto.name, attr="VKAPI")
Chia-I Wu30c78292014-08-04 10:08:08 +0800182
183 def _generate_stubs(self):
184 stubs = []
185 for proto in self.protos:
Chia-I Wu30c78292014-08-04 10:08:08 +0800186 decl = self._generate_stub_decl(proto)
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600187 if proto.ret != "void":
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600188 stmt = " return VK_ERROR_UNKNOWN;\n"
Chia-I Wu30c78292014-08-04 10:08:08 +0800189 else:
190 stmt = ""
191
Chia-I Wu731517d2015-01-03 23:48:15 +0800192 stubs.append("%s %s\n{\n%s}" % (self.qual, decl, stmt))
Chia-I Wu30c78292014-08-04 10:08:08 +0800193
194 return "\n\n".join(stubs)
195
Chia-I Wu30c78292014-08-04 10:08:08 +0800196 def generate_body(self):
Chia-I Wu731517d2015-01-03 23:48:15 +0800197 return self._generate_stubs()
Chia-I Wu30c78292014-08-04 10:08:08 +0800198
Chia-I Wu58f20852015-01-04 00:11:17 +0800199class IcdGetProcAddrSubcommand(IcdDummyEntrypointsSubcommand):
200 def generate_header(self):
201 return "\n".join(["#include <string.h>", "#include \"icd.h\""])
202
203 def generate_body(self):
204 for proto in self.protos:
205 if proto.name == "GetProcAddr":
206 gpa_proto = proto
Jon Ashburn53c16772015-05-06 10:15:07 -0600207 if proto.name == "GetInstanceProcAddr":
208 gpa_instance_proto = proto
Chia-I Wu58f20852015-01-04 00:11:17 +0800209
Jon Ashburn53c16772015-05-06 10:15:07 -0600210 gpa_instance_decl = self._generate_stub_decl(gpa_instance_proto)
Chia-I Wu58f20852015-01-04 00:11:17 +0800211 gpa_decl = self._generate_stub_decl(gpa_proto)
212 gpa_pname = gpa_proto.params[-1].name
213
214 lookups = []
215 for proto in self.protos:
216 lookups.append("if (!strcmp(%s, \"%s\"))" %
217 (gpa_pname, proto.name))
218 lookups.append(" return (%s) %s%s;" %
219 (gpa_proto.ret, self.prefix, proto.name))
220
221 body = []
Jon Ashburn53c16772015-05-06 10:15:07 -0600222 body.append("%s %s" % (self.qual, gpa_instance_decl))
223 body.append("{")
224 body.append(" return NULL;")
225 body.append("}")
226 body.append("")
227
Chia-I Wu58f20852015-01-04 00:11:17 +0800228 body.append("%s %s" % (self.qual, gpa_decl))
229 body.append("{")
Chia-I Wuf7d6d3c2015-01-05 12:55:13 +0800230 body.append(generate_get_proc_addr_check(gpa_pname))
Chia-I Wu58f20852015-01-04 00:11:17 +0800231 body.append("")
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600232 body.append(" %s += 2;" % gpa_pname)
Chia-I Wu58f20852015-01-04 00:11:17 +0800233 body.append(" %s" % "\n ".join(lookups))
234 body.append("")
235 body.append(" return NULL;")
236 body.append("}")
237
238 return "\n".join(body)
239
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800240class LayerInterceptProcSubcommand(Subcommand):
241 def run(self):
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600242 self.prefix = "vk"
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800243
244 # we could get the list from argv if wanted
245 self.intercepted = [proto.name for proto in self.protos
Jon Ashburndcea6b12015-05-11 09:34:20 -0700246 if proto.name not in ["EnumeratePhysicalDevices", "GetInstanceProcAddr"]]
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800247
248 for proto in self.protos:
249 if proto.name == "GetProcAddr":
250 self.gpa = proto
251
252 super().run()
253
254 def generate_header(self):
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600255 return "\n".join(["#include <string.h>", "#include \"vkLayer.h\""])
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800256
257 def generate_body(self):
258 lookups = []
259 for proto in self.protos:
260 if proto.name not in self.intercepted:
261 lookups.append("/* no %s%s */" % (self.prefix, proto.name))
262 continue
263
264 lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
265 lookups.append(" return (%s) %s%s;" %
266 (self.gpa.ret, self.prefix, proto.name))
267
268 body = []
Ian Elliotta742a622015-02-18 12:38:04 -0700269 body.append("static inline %s layer_intercept_proc(const char *name)" %
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800270 self.gpa.ret)
271 body.append("{")
272 body.append(generate_get_proc_addr_check("name"))
273 body.append("")
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600274 body.append(" name += 2;")
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800275 body.append(" %s" % "\n ".join(lookups))
276 body.append("")
277 body.append(" return NULL;")
278 body.append("}")
279
280 return "\n".join(body)
281
Chia-I Wud98a23c2015-04-11 10:56:50 +0800282class WinDefFileSubcommand(Subcommand):
283 def run(self):
284 library_exports = {
285 "all": [],
286 "icd": [
Tony Barbour8205d902015-04-16 15:59:00 -0600287 "EnumeratePhysicalDevices",
Chia-I Wud98a23c2015-04-11 10:56:50 +0800288 "CreateInstance",
289 "DestroyInstance",
290 "GetProcAddr",
291 ],
292 "layer": [
293 "GetProcAddr",
294 "EnumerateLayers",
Jon Ashburnb67859d2015-04-24 14:10:50 -0700295 "GetGlobalExtensionInfo",
Chia-I Wud98a23c2015-04-11 10:56:50 +0800296 ],
297 }
298
299 if len(self.argv) != 2 or self.argv[1] not in library_exports:
300 print("WinDefFileSubcommand: <library-name> {%s}" %
301 "|".join(library_exports.keys()))
302 return
303
304 self.library = self.argv[0]
305 self.exports = library_exports[self.argv[1]]
306
307 super().run()
308
309 def generate_copyright(self):
310 return """; THIS FILE IS GENERATED. DO NOT EDIT.
311
312;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600313; Vulkan
Chia-I Wud98a23c2015-04-11 10:56:50 +0800314;
315; Copyright (C) 2015 LunarG, Inc.
316;
317; Permission is hereby granted, free of charge, to any person obtaining a
318; copy of this software and associated documentation files (the "Software"),
319; to deal in the Software without restriction, including without limitation
320; the rights to use, copy, modify, merge, publish, distribute, sublicense,
321; and/or sell copies of the Software, and to permit persons to whom the
322; Software is furnished to do so, subject to the following conditions:
323;
324; The above copyright notice and this permission notice shall be included
325; in all copies or substantial portions of the Software.
326;
327; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
328; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
329; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
330; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
331; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
332; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
333; DEALINGS IN THE SOFTWARE.
334;;;; End Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"""
335
336 def generate_header(self):
337 return "; The following is required on Windows, for exporting symbols from the DLL"
338
339 def generate_body(self):
340 body = []
341
342 body.append("LIBRARY " + self.library)
343 body.append("EXPORTS")
344
345 for proto in self.protos:
346 if self.exports and proto.name not in self.exports:
347 continue
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600348 body.append(" vk" + proto.name)
Chia-I Wud98a23c2015-04-11 10:56:50 +0800349
350 return "\n".join(body)
351
Chia-I Wufb2559d2014-08-01 11:19:52 +0800352def main():
353 subcommands = {
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800354 "dispatch-table-ops": DispatchTableOpsSubcommand,
Chia-I Wu731517d2015-01-03 23:48:15 +0800355 "icd-dummy-entrypoints": IcdDummyEntrypointsSubcommand,
Chia-I Wu58f20852015-01-04 00:11:17 +0800356 "icd-get-proc-addr": IcdGetProcAddrSubcommand,
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800357 "layer-intercept-proc": LayerInterceptProcSubcommand,
Chia-I Wud98a23c2015-04-11 10:56:50 +0800358 "win-def-file": WinDefFileSubcommand,
Chia-I Wufb2559d2014-08-01 11:19:52 +0800359 }
360
361 if len(sys.argv) < 2 or sys.argv[1] not in subcommands:
362 print("Usage: %s <subcommand> [options]" % sys.argv[0])
363 print
364 print("Available sucommands are: %s" % " ".join(subcommands))
365 exit(1)
366
367 subcmd = subcommands[sys.argv[1]](sys.argv[2:])
368 subcmd.run()
369
370if __name__ == "__main__":
371 main()