blob: f5c2319482434e8771cbf4aa01b76138c9ae9a27 [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>",
Tobin Ehlis2d1d9702015-07-03 09:42:57 -0600110 "#include <vk_layer.h>",
Jon Ashburnaef65882015-05-04 09:16:41 -0600111 "#include <string.h>"])
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800112
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600113 def _generate_init_dispatch(self, type):
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800114 stmts = []
Jon Ashburnd9564002015-05-07 10:27:37 -0600115 func = []
116 if type == "device":
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600117 # GPA has to be first one and uses wrapped object
118 stmts.append("VkDevice device = (VkDevice) devw->nextObject;")
119 stmts.append("PFN_vkGetDeviceProcAddr gpa = (PFN_vkGetDeviceProcAddr) devw->pGPA;")
120 stmts.append("VkDevice baseDevice = (VkDevice) devw->baseObject;")
121 stmts.append("// GPA has to be first entry inited and uses wrapped object since it triggers init")
Courtney Goeltzenleuchterf83cd4a2015-06-26 15:05:29 -0600122 stmts.append("memset(table, 0, sizeof(*table));")
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600123 stmts.append("table->GetDeviceProcAddr =(PFN_vkGetDeviceProcAddr) gpa(device,\"vkGetDeviceProcAddr\");")
Jon Ashburnd9564002015-05-07 10:27:37 -0600124 for proto in self.protos:
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600125 if proto.name == "CreateInstance" or proto.name == "EnumerateInstanceExtensionProperties" or proto.name == "EnumerateInstanceLayerProperties" or proto.params[0].ty == "VkInstance" or (proto.params[0].ty == "VkPhysicalDevice" and proto.name != "CreateDevice"):
Jon Ashburn2666e2f2015-05-15 15:09:35 -0600126 continue
Jon Ashburn83334db2015-09-16 18:08:32 -0600127 if proto.name != "GetDeviceProcAddr" and 'KHR' not in proto.name:
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600128 stmts.append("table->%s = (PFN_vk%s) gpa(baseDevice, \"vk%s\");" %
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800129 (proto.name, proto.name, proto.name))
Jon Ashburnd9564002015-05-07 10:27:37 -0600130 func.append("static inline void %s_initialize_dispatch_table(VkLayerDispatchTable *table,"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800131 % self.prefix)
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600132 func.append("%s const VkBaseLayerObject *devw)"
Jon Ashburnd9564002015-05-07 10:27:37 -0600133 % (" " * len(self.prefix)))
134 else:
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600135 # GPA has to be first one and uses wrapped object
136 stmts.append("VkInstance instance = (VkInstance) instw->nextObject;")
137 stmts.append("PFN_vkGetInstanceProcAddr gpa = (PFN_vkGetInstanceProcAddr) instw->pGPA;")
138 stmts.append("VkInstance baseInstance = (VkInstance) instw->baseObject;")
139 stmts.append("// GPA has to be first entry inited and uses wrapped object since it triggers init")
140 stmts.append("table->GetInstanceProcAddr =(PFN_vkGetInstanceProcAddr) gpa(instance,\"vkGetInstanceProcAddr\");")
Jon Ashburnd9564002015-05-07 10:27:37 -0600141 for proto in self.protos:
Jon Ashburnba4a1952015-06-16 12:44:51 -0600142 if proto.name != "CreateInstance" and proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice":
Jon Ashburnd9564002015-05-07 10:27:37 -0600143 continue
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600144 if proto.name == "CreateDevice":
145 continue
Jon Ashburn83334db2015-09-16 18:08:32 -0600146 if proto.name != "GetInstanceProcAddr" and 'KHR' not in proto.name:
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600147 stmts.append("table->%s = (PFN_vk%s) gpa(baseInstance, \"vk%s\");" %
Jon Ashburnd9564002015-05-07 10:27:37 -0600148 (proto.name, proto.name, proto.name))
149 func.append("static inline void %s_init_instance_dispatch_table(VkLayerInstanceDispatchTable *table,"
150 % self.prefix)
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600151 func.append("%s const VkBaseLayerObject *instw)"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800152 % (" " * len(self.prefix)))
153 func.append("{")
154 func.append(" %s" % "\n ".join(stmts))
155 func.append("}")
156
157 return "\n".join(func)
158
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800159 def generate_body(self):
Jon Ashburn4f2575f2015-05-28 16:25:02 -0600160 body = [self._generate_init_dispatch("device"),
161 self._generate_init_dispatch("instance")]
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800162
163 return "\n\n".join(body)
164
Chia-I Wu731517d2015-01-03 23:48:15 +0800165class IcdDummyEntrypointsSubcommand(Subcommand):
Chia-I Wu30c78292014-08-04 10:08:08 +0800166 def run(self):
Chia-I Wu731517d2015-01-03 23:48:15 +0800167 if len(self.argv) == 1:
168 self.prefix = self.argv[0]
169 self.qual = "static"
170 else:
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600171 self.prefix = "vk"
Chia-I Wu731517d2015-01-03 23:48:15 +0800172 self.qual = "ICD_EXPORT"
Chia-I Wu30c78292014-08-04 10:08:08 +0800173
174 super().run()
175
176 def generate_header(self):
177 return "#include \"icd.h\""
178
179 def _generate_stub_decl(self, proto):
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600180 return proto.c_pretty_decl(self.prefix + proto.name, attr="VKAPI")
Chia-I Wu30c78292014-08-04 10:08:08 +0800181
182 def _generate_stubs(self):
183 stubs = []
184 for proto in self.protos:
Chia-I Wu30c78292014-08-04 10:08:08 +0800185 decl = self._generate_stub_decl(proto)
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600186 if proto.ret != "void":
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600187 stmt = " return VK_ERROR_UNKNOWN;\n"
Chia-I Wu30c78292014-08-04 10:08:08 +0800188 else:
189 stmt = ""
190
Chia-I Wu731517d2015-01-03 23:48:15 +0800191 stubs.append("%s %s\n{\n%s}" % (self.qual, decl, stmt))
Chia-I Wu30c78292014-08-04 10:08:08 +0800192
193 return "\n\n".join(stubs)
194
Chia-I Wu30c78292014-08-04 10:08:08 +0800195 def generate_body(self):
Chia-I Wu731517d2015-01-03 23:48:15 +0800196 return self._generate_stubs()
Chia-I Wu30c78292014-08-04 10:08:08 +0800197
Chia-I Wu58f20852015-01-04 00:11:17 +0800198class IcdGetProcAddrSubcommand(IcdDummyEntrypointsSubcommand):
199 def generate_header(self):
200 return "\n".join(["#include <string.h>", "#include \"icd.h\""])
201
202 def generate_body(self):
203 for proto in self.protos:
Jon Ashburn1245cec2015-05-18 13:20:15 -0600204 if proto.name == "GetDeviceProcAddr":
Chia-I Wu58f20852015-01-04 00:11:17 +0800205 gpa_proto = proto
Jon Ashburn53c16772015-05-06 10:15:07 -0600206 if proto.name == "GetInstanceProcAddr":
207 gpa_instance_proto = proto
Chia-I Wu58f20852015-01-04 00:11:17 +0800208
Jon Ashburn53c16772015-05-06 10:15:07 -0600209 gpa_instance_decl = self._generate_stub_decl(gpa_instance_proto)
Chia-I Wu58f20852015-01-04 00:11:17 +0800210 gpa_decl = self._generate_stub_decl(gpa_proto)
211 gpa_pname = gpa_proto.params[-1].name
212
213 lookups = []
214 for proto in self.protos:
215 lookups.append("if (!strcmp(%s, \"%s\"))" %
216 (gpa_pname, proto.name))
217 lookups.append(" return (%s) %s%s;" %
218 (gpa_proto.ret, self.prefix, proto.name))
219
220 body = []
Jon Ashburn53c16772015-05-06 10:15:07 -0600221 body.append("%s %s" % (self.qual, gpa_instance_decl))
222 body.append("{")
Jon Ashburn4ca01502015-07-16 10:12:59 -0600223 body.append(generate_get_proc_addr_check(gpa_pname))
224 body.append("")
225 body.append(" %s += 2;" % gpa_pname)
226 body.append(" %s" % "\n ".join(lookups))
227 body.append("")
Jon Ashburn53c16772015-05-06 10:15:07 -0600228 body.append(" return NULL;")
229 body.append("}")
230 body.append("")
231
Chia-I Wu58f20852015-01-04 00:11:17 +0800232 body.append("%s %s" % (self.qual, gpa_decl))
233 body.append("{")
Chia-I Wuf7d6d3c2015-01-05 12:55:13 +0800234 body.append(generate_get_proc_addr_check(gpa_pname))
Chia-I Wu58f20852015-01-04 00:11:17 +0800235 body.append("")
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600236 body.append(" %s += 2;" % gpa_pname)
Chia-I Wu58f20852015-01-04 00:11:17 +0800237 body.append(" %s" % "\n ".join(lookups))
238 body.append("")
239 body.append(" return NULL;")
240 body.append("}")
241
242 return "\n".join(body)
243
Chia-I Wud98a23c2015-04-11 10:56:50 +0800244class WinDefFileSubcommand(Subcommand):
245 def run(self):
246 library_exports = {
247 "all": [],
248 "icd": [
Jon Ashburn88049b12015-08-13 14:15:07 -0700249 "vkEnumeratePhysicalDevices",
250 "vkCreateInstance",
251 "vkDestroyInstance",
252 "vkGetDeviceProcAddr",
253 "vkGetInstanceProcAddr",
Chia-I Wud98a23c2015-04-11 10:56:50 +0800254 ],
255 "layer": [
Jon Ashburn88049b12015-08-13 14:15:07 -0700256 "vkGetInstanceProcAddr",
257 "vkGetDeviceProcAddr",
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600258 "vkEnumerateInstanceLayerProperties",
259 "vkEnumerateInstanceExtensionProperties"
Chia-I Wud98a23c2015-04-11 10:56:50 +0800260 ],
Jon Ashburn88049b12015-08-13 14:15:07 -0700261 "layerMulti": [
262 "multi2GetInstanceProcAddr",
263 "multi1GetDeviceProcAddr"
264 ]
Chia-I Wud98a23c2015-04-11 10:56:50 +0800265 }
266
267 if len(self.argv) != 2 or self.argv[1] not in library_exports:
268 print("WinDefFileSubcommand: <library-name> {%s}" %
269 "|".join(library_exports.keys()))
270 return
271
272 self.library = self.argv[0]
Jon Ashburn88049b12015-08-13 14:15:07 -0700273 if self.library == "VKLayerMulti":
274 self.exports = library_exports["layerMulti"]
275 else:
276 self.exports = library_exports[self.argv[1]]
Chia-I Wud98a23c2015-04-11 10:56:50 +0800277
278 super().run()
279
280 def generate_copyright(self):
281 return """; THIS FILE IS GENERATED. DO NOT EDIT.
282
283;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600284; Vulkan
Chia-I Wud98a23c2015-04-11 10:56:50 +0800285;
286; Copyright (C) 2015 LunarG, Inc.
287;
288; Permission is hereby granted, free of charge, to any person obtaining a
289; copy of this software and associated documentation files (the "Software"),
290; to deal in the Software without restriction, including without limitation
291; the rights to use, copy, modify, merge, publish, distribute, sublicense,
292; and/or sell copies of the Software, and to permit persons to whom the
293; Software is furnished to do so, subject to the following conditions:
294;
295; The above copyright notice and this permission notice shall be included
296; in all copies or substantial portions of the Software.
297;
298; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
299; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
300; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
301; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
302; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
303; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
304; DEALINGS IN THE SOFTWARE.
305;;;; End Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"""
306
307 def generate_header(self):
308 return "; The following is required on Windows, for exporting symbols from the DLL"
309
310 def generate_body(self):
311 body = []
312
313 body.append("LIBRARY " + self.library)
314 body.append("EXPORTS")
315
Jon Ashburn88049b12015-08-13 14:15:07 -0700316 for proto in self.exports:
Ian Elliott329da012015-09-22 10:51:24 -0600317 if self.library != "VKLayerSwapchain" or proto != "vkEnumerateInstanceExtensionProperties" and proto != "vkEnumerateInstanceLayerProperties":
318 body.append( proto)
Chia-I Wud98a23c2015-04-11 10:56:50 +0800319
320 return "\n".join(body)
321
Chia-I Wufb2559d2014-08-01 11:19:52 +0800322def main():
323 subcommands = {
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800324 "dispatch-table-ops": DispatchTableOpsSubcommand,
Chia-I Wu731517d2015-01-03 23:48:15 +0800325 "icd-dummy-entrypoints": IcdDummyEntrypointsSubcommand,
Chia-I Wu58f20852015-01-04 00:11:17 +0800326 "icd-get-proc-addr": IcdGetProcAddrSubcommand,
Chia-I Wud98a23c2015-04-11 10:56:50 +0800327 "win-def-file": WinDefFileSubcommand,
Chia-I Wufb2559d2014-08-01 11:19:52 +0800328 }
329
330 if len(sys.argv) < 2 or sys.argv[1] not in subcommands:
331 print("Usage: %s <subcommand> [options]" % sys.argv[0])
332 print
333 print("Available sucommands are: %s" % " ".join(subcommands))
334 exit(1)
335
336 subcmd = subcommands[sys.argv[1]](sys.argv[2:])
337 subcmd.run()
338
339if __name__ == "__main__":
340 main()