blob: 120d7b4c33f79ce9d3b249cb7e4a979131ef9b55 [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
Jon Ashburne18431b2015-04-13 18:10:06 -060045 def _does_function_create_object(self, proto):
46 out_objs = proto.object_out_params()
47 if proto.name == "ResetFences":
48 return False
49 return out_objs and out_objs[-1] == proto.params[-1]
50
51 def _is_loader_special_case(self, proto):
Tony Barbour8eddca62015-04-14 10:22:46 -060052 if proto.name in ["GetProcAddr", "EnumerateGpus", "EnumerateLayers", "DbgRegisterMsgCallback", "DbgUnregisterMsgCallback", "DbgSetGlobalOption", "DestroyInstance"]:
Jon Ashburne18431b2015-04-13 18:10:06 -060053 return True
54 return not self.is_dispatchable_object_first_param(proto)
55
56
Jon Ashburneb2728b2015-04-10 14:33:07 -060057 def is_dispatchable_object_first_param(self, proto):
58 in_objs = proto.object_in_params()
Tony Barbour8eddca62015-04-14 10:22:46 -060059 non_dispatch_objs = []
Jon Ashburneb2728b2015-04-10 14:33:07 -060060 param0 = proto.params[0]
61 return (len(in_objs) > 0) and (in_objs[0].ty == param0.ty) and (param0.ty not in non_dispatch_objs)
62
Chia-I Wufb2559d2014-08-01 11:19:52 +080063 def generate(self):
64 copyright = self.generate_copyright()
65 header = self.generate_header()
66 body = self.generate_body()
67 footer = self.generate_footer()
68
69 contents = []
70 if copyright:
71 contents.append(copyright)
72 if header:
73 contents.append(header)
74 if body:
75 contents.append(body)
76 if footer:
77 contents.append(footer)
78
79 return "\n\n".join(contents)
80
81 def generate_copyright(self):
82 return """/* THIS FILE IS GENERATED. DO NOT EDIT. */
83
84/*
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060085 * Vulkan
Chia-I Wufb2559d2014-08-01 11:19:52 +080086 *
87 * Copyright (C) 2014 LunarG, Inc.
88 *
89 * Permission is hereby granted, free of charge, to any person obtaining a
90 * copy of this software and associated documentation files (the "Software"),
91 * to deal in the Software without restriction, including without limitation
92 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
93 * and/or sell copies of the Software, and to permit persons to whom the
94 * Software is furnished to do so, subject to the following conditions:
95 *
96 * The above copyright notice and this permission notice shall be included
97 * in all copies or substantial portions of the Software.
98 *
99 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
100 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
101 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
102 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
103 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
104 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
105 * DEALINGS IN THE SOFTWARE.
106 */"""
107
108 def generate_header(self):
Chia-I Wu6ae460f2014-09-13 13:36:06 +0800109 return "\n".join(["#include <" + h + ">" for h in self.headers])
Chia-I Wufb2559d2014-08-01 11:19:52 +0800110
111 def generate_body(self):
112 pass
113
114 def generate_footer(self):
115 pass
116
Chia-I Wud4a76ae2015-01-04 10:15:48 +0800117class LoaderEntrypointsSubcommand(Subcommand):
Chia-I Wu26864352015-01-02 00:21:24 +0800118 def generate_header(self):
Chia-I Wu1d6731b2015-04-11 15:34:07 +0800119 return "#include \"loader.h\""
Chia-I Wu26864352015-01-02 00:21:24 +0800120
Chia-I Wu67a81c82015-04-11 16:07:13 +0800121 def _generate_object_setup(self, proto):
122 method = "loader_init_data"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600123 cond = "res == VK_SUCCESS"
Chia-I Wu67a81c82015-04-11 16:07:13 +0800124
125 if "Get" in proto.name:
126 method = "loader_set_data"
127
128 setup = []
129
130 if proto.name == "AllocDescriptorSets":
131 psets = proto.params[-2].name
132 pcount = proto.params[-1].name
133 setup.append("uint32_t i;")
134 setup.append("for (i = 0; i < *%s; i++)" % pcount)
135 setup.append(" %s(%s[i], disp);" % (method, psets))
136 else:
137 obj_params = proto.object_out_params()
138 for param in obj_params:
139 setup.append("%s(*%s, disp);" % (method, param.name))
140
141 if setup:
142 joined = "\n ".join(setup)
143 setup = []
144 setup.append(" if (%s) {" % cond)
145 setup.append(" " + joined)
146 setup.append(" }")
147
148 return "\n".join(setup)
149
Chia-I Wu26864352015-01-02 00:21:24 +0800150 def _generate_loader_dispatch_entrypoints(self, qual=""):
Chia-I Wu468e3c32014-08-04 08:03:57 +0800151 if qual:
152 qual += " "
153
Chia-I Wudac3e492014-08-02 23:49:43 +0800154 funcs = []
155 for proto in self.protos:
Jon Ashburneb2728b2015-04-10 14:33:07 -0600156 if self._is_loader_special_case(proto):
Tobin Ehlis66bbbf52014-11-12 11:47:07 -0700157 continue
Chia-I Wu67a81c82015-04-11 16:07:13 +0800158 func = []
159
160 obj_setup = self._generate_object_setup(proto)
161
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600162 func.append(qual + proto.c_func(prefix="vk", attr="VKAPI"))
Chia-I Wu67a81c82015-04-11 16:07:13 +0800163 func.append("{")
164
165 # declare local variables
Jon Ashburn301c5f02015-04-06 10:58:22 -0600166 func.append(" const VkLayerDispatchTable *disp;")
Chia-I Wu67a81c82015-04-11 16:07:13 +0800167 if proto.ret != 'void' and obj_setup:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600168 func.append(" VkResult res;")
Chia-I Wu67a81c82015-04-11 16:07:13 +0800169 func.append("")
170
Jon Ashburn630e44f2015-04-08 21:33:34 -0600171 # get dispatch table
172 func.append(" disp = loader_get_data(%s);" %
173 proto.params[0].name)
Chia-I Wu67a81c82015-04-11 16:07:13 +0800174 func.append("")
175
176 # dispatch!
177 dispatch = "disp->%s;" % proto.c_call()
178 if proto.ret == 'void':
179 func.append(" " + dispatch)
180 elif not obj_setup:
181 func.append(" return " + dispatch)
182 else:
183 func.append(" res = " + dispatch)
184 func.append(obj_setup)
185 func.append("")
186 func.append(" return res;")
187
188 func.append("}")
189
Ian Elliott81ac44c2015-01-13 17:52:38 -0700190 if 'WsiX11AssociateConnection' == proto.name:
Ian Elliotte977a6c2015-02-26 14:34:52 -0700191 funcs.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
Chia-I Wu67a81c82015-04-11 16:07:13 +0800192
193 funcs.append("\n".join(func))
Chia-I Wudac3e492014-08-02 23:49:43 +0800194
Ian Elliott81ac44c2015-01-13 17:52:38 -0700195 funcs.append("#endif")
Chia-I Wudac3e492014-08-02 23:49:43 +0800196 return "\n\n".join(funcs)
197
Chia-I Wufb2559d2014-08-01 11:19:52 +0800198 def generate_body(self):
Chia-I Wu26864352015-01-02 00:21:24 +0800199 body = [self._generate_loader_dispatch_entrypoints("LOADER_EXPORT")]
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600200
201 return "\n\n".join(body)
202
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800203class DispatchTableOpsSubcommand(Subcommand):
204 def run(self):
205 if len(self.argv) != 1:
206 print("DispatchTableOpsSubcommand: <prefix> unspecified")
207 return
208
209 self.prefix = self.argv[0]
210 super().run()
211
212 def generate_header(self):
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600213 return "\n".join(["#include <vulkan.h>",
214 "#include <vkLayer.h>",
Ian Elliott81ac44c2015-01-13 17:52:38 -0700215 "#include <string.h>",
216 "#include \"loader_platform.h\""])
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800217
218 def _generate_init(self):
219 stmts = []
220 for proto in self.protos:
Ian Elliott81ac44c2015-01-13 17:52:38 -0700221 if 'WsiX11AssociateConnection' == proto.name:
Ian Elliotte977a6c2015-02-26 14:34:52 -0700222 stmts.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
Mike Stroyan9cb208b2015-04-08 10:31:48 -0600223 if self.is_dispatchable_object_first_param(proto) or proto.name == "CreateInstance":
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600224 stmts.append("table->%s = (PFN_vk%s) gpa(gpu, \"vk%s\");" %
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800225 (proto.name, proto.name, proto.name))
Jon Ashburn55178862015-04-13 17:47:29 -0600226 else:
227 stmts.append("table->%s = vk%s; /* non-dispatchable */" %
228 (proto.name, proto.name))
Ian Elliott81ac44c2015-01-13 17:52:38 -0700229 stmts.append("#endif")
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800230
231 func = []
Jon Ashburn301c5f02015-04-06 10:58:22 -0600232 func.append("static inline void %s_initialize_dispatch_table(VkLayerDispatchTable *table,"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800233 % self.prefix)
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600234 func.append("%s PFN_vkGetProcAddr gpa,"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800235 % (" " * len(self.prefix)))
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600236 func.append("%s VkPhysicalGpu gpu)"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800237 % (" " * len(self.prefix)))
238 func.append("{")
239 func.append(" %s" % "\n ".join(stmts))
240 func.append("}")
241
242 return "\n".join(func)
243
244 def _generate_lookup(self):
245 lookups = []
246 for proto in self.protos:
Ian Elliott81ac44c2015-01-13 17:52:38 -0700247 if 'WsiX11AssociateConnection' == proto.name:
Ian Elliotte977a6c2015-02-26 14:34:52 -0700248 lookups.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
Jon Ashburneb2728b2015-04-10 14:33:07 -0600249 if self.is_dispatchable_object_first_param(proto):
250 lookups.append("if (!strcmp(name, \"%s\"))" % (proto.name))
251 lookups.append(" return (void *) table->%s;"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800252 % (proto.name))
Ian Elliott81ac44c2015-01-13 17:52:38 -0700253 lookups.append("#endif")
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800254
255 func = []
Jon Ashburn301c5f02015-04-06 10:58:22 -0600256 func.append("static inline void *%s_lookup_dispatch_table(const VkLayerDispatchTable *table,"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800257 % self.prefix)
258 func.append("%s const char *name)"
259 % (" " * len(self.prefix)))
260 func.append("{")
Chia-I Wuf7d6d3c2015-01-05 12:55:13 +0800261 func.append(generate_get_proc_addr_check("name"))
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800262 func.append("")
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600263 func.append(" name += 2;")
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800264 func.append(" %s" % "\n ".join(lookups))
265 func.append("")
266 func.append(" return NULL;")
267 func.append("}")
268
269 return "\n".join(func)
270
271 def generate_body(self):
272 body = [self._generate_init(),
273 self._generate_lookup()]
274
275 return "\n\n".join(body)
276
Chia-I Wu731517d2015-01-03 23:48:15 +0800277class IcdDummyEntrypointsSubcommand(Subcommand):
Chia-I Wu30c78292014-08-04 10:08:08 +0800278 def run(self):
Chia-I Wu731517d2015-01-03 23:48:15 +0800279 if len(self.argv) == 1:
280 self.prefix = self.argv[0]
281 self.qual = "static"
282 else:
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600283 self.prefix = "vk"
Chia-I Wu731517d2015-01-03 23:48:15 +0800284 self.qual = "ICD_EXPORT"
Chia-I Wu30c78292014-08-04 10:08:08 +0800285
286 super().run()
287
288 def generate_header(self):
289 return "#include \"icd.h\""
290
291 def _generate_stub_decl(self, proto):
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600292 return proto.c_pretty_decl(self.prefix + proto.name, attr="VKAPI")
Chia-I Wu30c78292014-08-04 10:08:08 +0800293
294 def _generate_stubs(self):
295 stubs = []
296 for proto in self.protos:
Chia-I Wu30c78292014-08-04 10:08:08 +0800297 decl = self._generate_stub_decl(proto)
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600298 if proto.ret != "void":
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600299 stmt = " return VK_ERROR_UNKNOWN;\n"
Chia-I Wu30c78292014-08-04 10:08:08 +0800300 else:
301 stmt = ""
302
Chia-I Wu731517d2015-01-03 23:48:15 +0800303 stubs.append("%s %s\n{\n%s}" % (self.qual, decl, stmt))
Chia-I Wu30c78292014-08-04 10:08:08 +0800304
305 return "\n\n".join(stubs)
306
Chia-I Wu30c78292014-08-04 10:08:08 +0800307 def generate_body(self):
Chia-I Wu731517d2015-01-03 23:48:15 +0800308 return self._generate_stubs()
Chia-I Wu30c78292014-08-04 10:08:08 +0800309
Chia-I Wu58f20852015-01-04 00:11:17 +0800310class IcdGetProcAddrSubcommand(IcdDummyEntrypointsSubcommand):
311 def generate_header(self):
312 return "\n".join(["#include <string.h>", "#include \"icd.h\""])
313
314 def generate_body(self):
315 for proto in self.protos:
316 if proto.name == "GetProcAddr":
317 gpa_proto = proto
318
319 gpa_decl = self._generate_stub_decl(gpa_proto)
320 gpa_pname = gpa_proto.params[-1].name
321
322 lookups = []
323 for proto in self.protos:
Ian Elliott81ac44c2015-01-13 17:52:38 -0700324 if 'WsiX11AssociateConnection' == proto.name:
Ian Elliotte977a6c2015-02-26 14:34:52 -0700325 lookups.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
Chia-I Wu58f20852015-01-04 00:11:17 +0800326 lookups.append("if (!strcmp(%s, \"%s\"))" %
327 (gpa_pname, proto.name))
328 lookups.append(" return (%s) %s%s;" %
329 (gpa_proto.ret, self.prefix, proto.name))
Ian Elliott81ac44c2015-01-13 17:52:38 -0700330 lookups.append("#endif")
Chia-I Wu58f20852015-01-04 00:11:17 +0800331
332 body = []
333 body.append("%s %s" % (self.qual, gpa_decl))
334 body.append("{")
Chia-I Wuf7d6d3c2015-01-05 12:55:13 +0800335 body.append(generate_get_proc_addr_check(gpa_pname))
Chia-I Wu58f20852015-01-04 00:11:17 +0800336 body.append("")
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600337 body.append(" %s += 2;" % gpa_pname)
Chia-I Wu58f20852015-01-04 00:11:17 +0800338 body.append(" %s" % "\n ".join(lookups))
339 body.append("")
340 body.append(" return NULL;")
341 body.append("}")
342
343 return "\n".join(body)
344
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800345class LayerInterceptProcSubcommand(Subcommand):
346 def run(self):
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600347 self.prefix = "vk"
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800348
349 # we could get the list from argv if wanted
350 self.intercepted = [proto.name for proto in self.protos
Jon Ashburn457c5d12015-01-29 16:54:38 -0700351 if proto.name not in ["EnumerateGpus"]]
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800352
353 for proto in self.protos:
354 if proto.name == "GetProcAddr":
355 self.gpa = proto
356
357 super().run()
358
359 def generate_header(self):
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600360 return "\n".join(["#include <string.h>", "#include \"vkLayer.h\""])
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800361
362 def generate_body(self):
363 lookups = []
364 for proto in self.protos:
365 if proto.name not in self.intercepted:
366 lookups.append("/* no %s%s */" % (self.prefix, proto.name))
367 continue
368
Ian Elliott81ac44c2015-01-13 17:52:38 -0700369 if 'WsiX11AssociateConnection' == proto.name:
Ian Elliotte977a6c2015-02-26 14:34:52 -0700370 lookups.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800371 lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
372 lookups.append(" return (%s) %s%s;" %
373 (self.gpa.ret, self.prefix, proto.name))
Ian Elliott81ac44c2015-01-13 17:52:38 -0700374 lookups.append("#endif")
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800375
376 body = []
Ian Elliotta742a622015-02-18 12:38:04 -0700377 body.append("static inline %s layer_intercept_proc(const char *name)" %
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800378 self.gpa.ret)
379 body.append("{")
380 body.append(generate_get_proc_addr_check("name"))
381 body.append("")
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600382 body.append(" name += 2;")
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800383 body.append(" %s" % "\n ".join(lookups))
384 body.append("")
385 body.append(" return NULL;")
386 body.append("}")
387
388 return "\n".join(body)
389
Chia-I Wud98a23c2015-04-11 10:56:50 +0800390class WinDefFileSubcommand(Subcommand):
391 def run(self):
392 library_exports = {
393 "all": [],
394 "icd": [
395 "EnumerateGpus",
396 "CreateInstance",
397 "DestroyInstance",
398 "GetProcAddr",
399 ],
400 "layer": [
401 "GetProcAddr",
402 "EnumerateLayers",
403 ],
404 }
405
406 if len(self.argv) != 2 or self.argv[1] not in library_exports:
407 print("WinDefFileSubcommand: <library-name> {%s}" %
408 "|".join(library_exports.keys()))
409 return
410
411 self.library = self.argv[0]
412 self.exports = library_exports[self.argv[1]]
413
414 super().run()
415
416 def generate_copyright(self):
417 return """; THIS FILE IS GENERATED. DO NOT EDIT.
418
419;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600420; Vulkan
Chia-I Wud98a23c2015-04-11 10:56:50 +0800421;
422; Copyright (C) 2015 LunarG, Inc.
423;
424; Permission is hereby granted, free of charge, to any person obtaining a
425; copy of this software and associated documentation files (the "Software"),
426; to deal in the Software without restriction, including without limitation
427; the rights to use, copy, modify, merge, publish, distribute, sublicense,
428; and/or sell copies of the Software, and to permit persons to whom the
429; Software is furnished to do so, subject to the following conditions:
430;
431; The above copyright notice and this permission notice shall be included
432; in all copies or substantial portions of the Software.
433;
434; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
435; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
436; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
437; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
438; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
439; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
440; DEALINGS IN THE SOFTWARE.
441;;;; End Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"""
442
443 def generate_header(self):
444 return "; The following is required on Windows, for exporting symbols from the DLL"
445
446 def generate_body(self):
447 body = []
448
449 body.append("LIBRARY " + self.library)
450 body.append("EXPORTS")
451
452 for proto in self.protos:
453 if self.exports and proto.name not in self.exports:
454 continue
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600455 body.append(" vk" + proto.name)
Chia-I Wud98a23c2015-04-11 10:56:50 +0800456
457 return "\n".join(body)
458
Jon Ashburne18431b2015-04-13 18:10:06 -0600459class LoaderGetProcAddrSubcommand(Subcommand):
460 def run(self):
461 self.prefix = "vk"
462
463 # we could get the list from argv if wanted
464 self.intercepted = [proto.name for proto in self.protos]
465
466 for proto in self.protos:
467 if proto.name == "GetProcAddr":
468 self.gpa = proto
469
470 super().run()
471
472 def generate_header(self):
473 return "\n".join(["#include <string.h>"])
474
475 def generate_body(self):
476 lookups = []
477 for proto in self.protos:
478 if proto.name not in self.intercepted:
479 lookups.append("/* no %s%s */" % (self.prefix, proto.name))
480 continue
481
482 if 'WsiX11AssociateConnection' == proto.name:
483 lookups.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
484 lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
485 lookups.append(" return (%s) %s%s;" %
486 (self.gpa.ret, self.prefix, proto.name))
487 lookups.append("#endif")
488
489 special_lookups = []
490 # these functions require special trampoline code beyond just the normal create object trampoline code
491 special_names = ["AllocDescriptorSets", "GetMultiGpuCompatibility"]
492 for proto in self.protos:
493 if self._is_loader_special_case(proto) or self._does_function_create_object(proto) or proto.name in special_names:
494 special_lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
495 special_lookups.append(" return (%s) %s%s;" %
496 (self.gpa.ret, self.prefix, proto.name))
497 else:
498 continue
499 body = []
500 body.append("static inline %s globalGetProcAddr(const char *name)" %
501 self.gpa.ret)
502 body.append("{")
503 body.append(generate_get_proc_addr_check("name"))
504 body.append("")
505 body.append(" name += 2;")
506 body.append(" %s" % "\n ".join(lookups))
507 body.append("")
508 body.append(" return NULL;")
509 body.append("}")
510 body.append("")
511 body.append("static inline void *loader_non_passthrough_gpa(const char *name)")
512 body.append("{")
513 body.append(generate_get_proc_addr_check("name"))
514 body.append("")
515 body.append(" name += 2;")
516 body.append(" %s" % "\n ".join(special_lookups))
517 body.append("")
518 body.append(" return NULL;")
519 body.append("}")
520
521 return "\n".join(body)
522
Chia-I Wufb2559d2014-08-01 11:19:52 +0800523def main():
524 subcommands = {
Chia-I Wud4a76ae2015-01-04 10:15:48 +0800525 "loader-entrypoints": LoaderEntrypointsSubcommand,
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800526 "dispatch-table-ops": DispatchTableOpsSubcommand,
Chia-I Wu731517d2015-01-03 23:48:15 +0800527 "icd-dummy-entrypoints": IcdDummyEntrypointsSubcommand,
Chia-I Wu58f20852015-01-04 00:11:17 +0800528 "icd-get-proc-addr": IcdGetProcAddrSubcommand,
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800529 "layer-intercept-proc": LayerInterceptProcSubcommand,
Chia-I Wud98a23c2015-04-11 10:56:50 +0800530 "win-def-file": WinDefFileSubcommand,
Jon Ashburne18431b2015-04-13 18:10:06 -0600531 "loader-get-proc-addr": LoaderGetProcAddrSubcommand,
Chia-I Wufb2559d2014-08-01 11:19:52 +0800532 }
533
534 if len(sys.argv) < 2 or sys.argv[1] not in subcommands:
535 print("Usage: %s <subcommand> [options]" % sys.argv[0])
536 print
537 print("Available sucommands are: %s" % " ".join(subcommands))
538 exit(1)
539
540 subcmd = subcommands[sys.argv[1]](sys.argv[2:])
541 subcmd.run()
542
543if __name__ == "__main__":
544 main()