blob: dec71753fa5051d2aa534493dd1504286682ca87 [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):
52 if proto.name in ["GetProcAddr", "EnumerateGpus", "EnumerateLayers"]:
53 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()
59 non_dispatch_objs = ["VkInstance"]
60 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)")
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800223 if proto.name == "GetProcAddr":
224 stmts.append("table->%s = gpa; /* direct assignment */" %
225 proto.name)
Jon Ashburneb2728b2015-04-10 14:33:07 -0600226 elif self.is_dispatchable_object_first_param(proto):
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600227 stmts.append("table->%s = (PFN_vk%s) gpa(gpu, \"vk%s\");" %
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800228 (proto.name, proto.name, proto.name))
Jon Ashburn55178862015-04-13 17:47:29 -0600229 else:
230 stmts.append("table->%s = vk%s; /* non-dispatchable */" %
231 (proto.name, proto.name))
Ian Elliott81ac44c2015-01-13 17:52:38 -0700232 stmts.append("#endif")
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800233
234 func = []
Jon Ashburn301c5f02015-04-06 10:58:22 -0600235 func.append("static inline void %s_initialize_dispatch_table(VkLayerDispatchTable *table,"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800236 % self.prefix)
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600237 func.append("%s PFN_vkGetProcAddr gpa,"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800238 % (" " * len(self.prefix)))
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600239 func.append("%s VkPhysicalGpu gpu)"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800240 % (" " * len(self.prefix)))
241 func.append("{")
242 func.append(" %s" % "\n ".join(stmts))
243 func.append("}")
244
245 return "\n".join(func)
246
247 def _generate_lookup(self):
248 lookups = []
249 for proto in self.protos:
Ian Elliott81ac44c2015-01-13 17:52:38 -0700250 if 'WsiX11AssociateConnection' == proto.name:
Ian Elliotte977a6c2015-02-26 14:34:52 -0700251 lookups.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
Jon Ashburneb2728b2015-04-10 14:33:07 -0600252 if self.is_dispatchable_object_first_param(proto):
253 lookups.append("if (!strcmp(name, \"%s\"))" % (proto.name))
254 lookups.append(" return (void *) table->%s;"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800255 % (proto.name))
Ian Elliott81ac44c2015-01-13 17:52:38 -0700256 lookups.append("#endif")
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800257
258 func = []
Jon Ashburn301c5f02015-04-06 10:58:22 -0600259 func.append("static inline void *%s_lookup_dispatch_table(const VkLayerDispatchTable *table,"
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800260 % self.prefix)
261 func.append("%s const char *name)"
262 % (" " * len(self.prefix)))
263 func.append("{")
Chia-I Wuf7d6d3c2015-01-05 12:55:13 +0800264 func.append(generate_get_proc_addr_check("name"))
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800265 func.append("")
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600266 func.append(" name += 2;")
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800267 func.append(" %s" % "\n ".join(lookups))
268 func.append("")
269 func.append(" return NULL;")
270 func.append("}")
271
272 return "\n".join(func)
273
274 def generate_body(self):
275 body = [self._generate_init(),
276 self._generate_lookup()]
277
278 return "\n\n".join(body)
279
Chia-I Wu731517d2015-01-03 23:48:15 +0800280class IcdDummyEntrypointsSubcommand(Subcommand):
Chia-I Wu30c78292014-08-04 10:08:08 +0800281 def run(self):
Chia-I Wu731517d2015-01-03 23:48:15 +0800282 if len(self.argv) == 1:
283 self.prefix = self.argv[0]
284 self.qual = "static"
285 else:
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600286 self.prefix = "vk"
Chia-I Wu731517d2015-01-03 23:48:15 +0800287 self.qual = "ICD_EXPORT"
Chia-I Wu30c78292014-08-04 10:08:08 +0800288
289 super().run()
290
291 def generate_header(self):
292 return "#include \"icd.h\""
293
294 def _generate_stub_decl(self, proto):
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600295 return proto.c_pretty_decl(self.prefix + proto.name, attr="VKAPI")
Chia-I Wu30c78292014-08-04 10:08:08 +0800296
297 def _generate_stubs(self):
298 stubs = []
299 for proto in self.protos:
Chia-I Wu30c78292014-08-04 10:08:08 +0800300 decl = self._generate_stub_decl(proto)
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600301 if proto.ret != "void":
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600302 stmt = " return VK_ERROR_UNKNOWN;\n"
Chia-I Wu30c78292014-08-04 10:08:08 +0800303 else:
304 stmt = ""
305
Chia-I Wu731517d2015-01-03 23:48:15 +0800306 stubs.append("%s %s\n{\n%s}" % (self.qual, decl, stmt))
Chia-I Wu30c78292014-08-04 10:08:08 +0800307
308 return "\n\n".join(stubs)
309
Chia-I Wu30c78292014-08-04 10:08:08 +0800310 def generate_body(self):
Chia-I Wu731517d2015-01-03 23:48:15 +0800311 return self._generate_stubs()
Chia-I Wu30c78292014-08-04 10:08:08 +0800312
Chia-I Wu58f20852015-01-04 00:11:17 +0800313class IcdGetProcAddrSubcommand(IcdDummyEntrypointsSubcommand):
314 def generate_header(self):
315 return "\n".join(["#include <string.h>", "#include \"icd.h\""])
316
317 def generate_body(self):
318 for proto in self.protos:
319 if proto.name == "GetProcAddr":
320 gpa_proto = proto
321
322 gpa_decl = self._generate_stub_decl(gpa_proto)
323 gpa_pname = gpa_proto.params[-1].name
324
325 lookups = []
326 for proto in self.protos:
Ian Elliott81ac44c2015-01-13 17:52:38 -0700327 if 'WsiX11AssociateConnection' == proto.name:
Ian Elliotte977a6c2015-02-26 14:34:52 -0700328 lookups.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
Chia-I Wu58f20852015-01-04 00:11:17 +0800329 lookups.append("if (!strcmp(%s, \"%s\"))" %
330 (gpa_pname, proto.name))
331 lookups.append(" return (%s) %s%s;" %
332 (gpa_proto.ret, self.prefix, proto.name))
Ian Elliott81ac44c2015-01-13 17:52:38 -0700333 lookups.append("#endif")
Chia-I Wu58f20852015-01-04 00:11:17 +0800334
335 body = []
336 body.append("%s %s" % (self.qual, gpa_decl))
337 body.append("{")
Chia-I Wuf7d6d3c2015-01-05 12:55:13 +0800338 body.append(generate_get_proc_addr_check(gpa_pname))
Chia-I Wu58f20852015-01-04 00:11:17 +0800339 body.append("")
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600340 body.append(" %s += 2;" % gpa_pname)
Chia-I Wu58f20852015-01-04 00:11:17 +0800341 body.append(" %s" % "\n ".join(lookups))
342 body.append("")
343 body.append(" return NULL;")
344 body.append("}")
345
346 return "\n".join(body)
347
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800348class LayerInterceptProcSubcommand(Subcommand):
349 def run(self):
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600350 self.prefix = "vk"
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800351
352 # we could get the list from argv if wanted
353 self.intercepted = [proto.name for proto in self.protos
Jon Ashburn457c5d12015-01-29 16:54:38 -0700354 if proto.name not in ["EnumerateGpus"]]
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800355
356 for proto in self.protos:
357 if proto.name == "GetProcAddr":
358 self.gpa = proto
359
360 super().run()
361
362 def generate_header(self):
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600363 return "\n".join(["#include <string.h>", "#include \"vkLayer.h\""])
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800364
365 def generate_body(self):
366 lookups = []
367 for proto in self.protos:
368 if proto.name not in self.intercepted:
369 lookups.append("/* no %s%s */" % (self.prefix, proto.name))
370 continue
371
Ian Elliott81ac44c2015-01-13 17:52:38 -0700372 if 'WsiX11AssociateConnection' == proto.name:
Ian Elliotte977a6c2015-02-26 14:34:52 -0700373 lookups.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800374 lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
375 lookups.append(" return (%s) %s%s;" %
376 (self.gpa.ret, self.prefix, proto.name))
Ian Elliott81ac44c2015-01-13 17:52:38 -0700377 lookups.append("#endif")
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800378
379 body = []
Ian Elliotta742a622015-02-18 12:38:04 -0700380 body.append("static inline %s layer_intercept_proc(const char *name)" %
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800381 self.gpa.ret)
382 body.append("{")
383 body.append(generate_get_proc_addr_check("name"))
384 body.append("")
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600385 body.append(" name += 2;")
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800386 body.append(" %s" % "\n ".join(lookups))
387 body.append("")
388 body.append(" return NULL;")
389 body.append("}")
390
391 return "\n".join(body)
392
Chia-I Wud98a23c2015-04-11 10:56:50 +0800393class WinDefFileSubcommand(Subcommand):
394 def run(self):
395 library_exports = {
396 "all": [],
397 "icd": [
398 "EnumerateGpus",
399 "CreateInstance",
400 "DestroyInstance",
401 "GetProcAddr",
402 ],
403 "layer": [
404 "GetProcAddr",
405 "EnumerateLayers",
406 ],
407 }
408
409 if len(self.argv) != 2 or self.argv[1] not in library_exports:
410 print("WinDefFileSubcommand: <library-name> {%s}" %
411 "|".join(library_exports.keys()))
412 return
413
414 self.library = self.argv[0]
415 self.exports = library_exports[self.argv[1]]
416
417 super().run()
418
419 def generate_copyright(self):
420 return """; THIS FILE IS GENERATED. DO NOT EDIT.
421
422;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600423; Vulkan
Chia-I Wud98a23c2015-04-11 10:56:50 +0800424;
425; Copyright (C) 2015 LunarG, Inc.
426;
427; Permission is hereby granted, free of charge, to any person obtaining a
428; copy of this software and associated documentation files (the "Software"),
429; to deal in the Software without restriction, including without limitation
430; the rights to use, copy, modify, merge, publish, distribute, sublicense,
431; and/or sell copies of the Software, and to permit persons to whom the
432; Software is furnished to do so, subject to the following conditions:
433;
434; The above copyright notice and this permission notice shall be included
435; in all copies or substantial portions of the Software.
436;
437; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
438; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
439; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
440; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
441; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
442; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
443; DEALINGS IN THE SOFTWARE.
444;;;; End Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"""
445
446 def generate_header(self):
447 return "; The following is required on Windows, for exporting symbols from the DLL"
448
449 def generate_body(self):
450 body = []
451
452 body.append("LIBRARY " + self.library)
453 body.append("EXPORTS")
454
455 for proto in self.protos:
456 if self.exports and proto.name not in self.exports:
457 continue
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600458 body.append(" vk" + proto.name)
Chia-I Wud98a23c2015-04-11 10:56:50 +0800459
460 return "\n".join(body)
461
Jon Ashburne18431b2015-04-13 18:10:06 -0600462class LoaderGetProcAddrSubcommand(Subcommand):
463 def run(self):
464 self.prefix = "vk"
465
466 # we could get the list from argv if wanted
467 self.intercepted = [proto.name for proto in self.protos]
468
469 for proto in self.protos:
470 if proto.name == "GetProcAddr":
471 self.gpa = proto
472
473 super().run()
474
475 def generate_header(self):
476 return "\n".join(["#include <string.h>"])
477
478 def generate_body(self):
479 lookups = []
480 for proto in self.protos:
481 if proto.name not in self.intercepted:
482 lookups.append("/* no %s%s */" % (self.prefix, proto.name))
483 continue
484
485 if 'WsiX11AssociateConnection' == proto.name:
486 lookups.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
487 lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
488 lookups.append(" return (%s) %s%s;" %
489 (self.gpa.ret, self.prefix, proto.name))
490 lookups.append("#endif")
491
492 special_lookups = []
493 # these functions require special trampoline code beyond just the normal create object trampoline code
494 special_names = ["AllocDescriptorSets", "GetMultiGpuCompatibility"]
495 for proto in self.protos:
496 if self._is_loader_special_case(proto) or self._does_function_create_object(proto) or proto.name in special_names:
497 special_lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
498 special_lookups.append(" return (%s) %s%s;" %
499 (self.gpa.ret, self.prefix, proto.name))
500 else:
501 continue
502 body = []
503 body.append("static inline %s globalGetProcAddr(const char *name)" %
504 self.gpa.ret)
505 body.append("{")
506 body.append(generate_get_proc_addr_check("name"))
507 body.append("")
508 body.append(" name += 2;")
509 body.append(" %s" % "\n ".join(lookups))
510 body.append("")
511 body.append(" return NULL;")
512 body.append("}")
513 body.append("")
514 body.append("static inline void *loader_non_passthrough_gpa(const char *name)")
515 body.append("{")
516 body.append(generate_get_proc_addr_check("name"))
517 body.append("")
518 body.append(" name += 2;")
519 body.append(" %s" % "\n ".join(special_lookups))
520 body.append("")
521 body.append(" return NULL;")
522 body.append("}")
523
524 return "\n".join(body)
525
Chia-I Wufb2559d2014-08-01 11:19:52 +0800526def main():
527 subcommands = {
Chia-I Wud4a76ae2015-01-04 10:15:48 +0800528 "loader-entrypoints": LoaderEntrypointsSubcommand,
Chia-I Wu28b8d8c2015-01-04 10:19:50 +0800529 "dispatch-table-ops": DispatchTableOpsSubcommand,
Chia-I Wu731517d2015-01-03 23:48:15 +0800530 "icd-dummy-entrypoints": IcdDummyEntrypointsSubcommand,
Chia-I Wu58f20852015-01-04 00:11:17 +0800531 "icd-get-proc-addr": IcdGetProcAddrSubcommand,
Chia-I Wuf4bd2e42015-01-05 12:56:13 +0800532 "layer-intercept-proc": LayerInterceptProcSubcommand,
Chia-I Wud98a23c2015-04-11 10:56:50 +0800533 "win-def-file": WinDefFileSubcommand,
Jon Ashburne18431b2015-04-13 18:10:06 -0600534 "loader-get-proc-addr": LoaderGetProcAddrSubcommand,
Chia-I Wufb2559d2014-08-01 11:19:52 +0800535 }
536
537 if len(sys.argv) < 2 or sys.argv[1] not in subcommands:
538 print("Usage: %s <subcommand> [options]" % sys.argv[0])
539 print
540 print("Available sucommands are: %s" % " ".join(subcommands))
541 exit(1)
542
543 subcmd = subcommands[sys.argv[1]](sys.argv[2:])
544 subcmd.run()
545
546if __name__ == "__main__":
547 main()