blob: 44ba04c29e40e4a69807b8165f7cbbd35fa3a9a4 [file] [log] [blame]
Chia-I Wufb2559d2014-08-01 11:19:52 +08001#!/usr/bin/env python3
Chia-I Wu701f3f62014-09-02 08:32:09 +08002#
3# XGL
4#
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
30import xgl
31
Chia-I Wu6cdaedb2015-01-05 12:55:13 +080032def generate_get_proc_addr_check(name):
33 return " if (!%s || %s[0] != 'x' || %s[1] != 'g' || %s[2] != 'l')\n" \
34 " return NULL;" % ((name,) * 4)
35
Chia-I Wufb2559d2014-08-01 11:19:52 +080036class Subcommand(object):
37 def __init__(self, argv):
38 self.argv = argv
Chia-I Wuc4f24e82015-01-01 08:46:31 +080039 self.headers = xgl.headers
40 self.protos = xgl.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/*
67 * XGL
68 *
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 Wu6bdf0192014-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 Wub3d5e192015-01-04 10:15:48 +080099class LoaderEntrypointsSubcommand(Subcommand):
Chia-I Wu2e4f5302015-01-02 00:21:24 +0800100 def generate_header(self):
Courtney Goeltzenleuchter64ca9232015-02-10 18:40:14 -0700101 return "#include \"loader.h\"\n#include \"xglIcd.h\"\n#include \"assert.h\""
Chia-I Wu2e4f5302015-01-02 00:21:24 +0800102
Chia-I Wu47e5b6d2015-01-04 15:51:00 +0800103 def _does_function_create_object(self, proto):
104 out_objs = proto.object_out_params()
105 return out_objs and out_objs[-1] == proto.params[-1]
Chia-I Wu27697e42015-01-04 15:32:52 +0800106
Chia-I Wu27697e42015-01-04 15:32:52 +0800107 def _is_dispatchable(self, proto):
Jon Ashburn1beab2d2015-01-26 14:51:40 -0700108 if proto.name in ["GetProcAddr", "DestroyInstance", "EnumerateGpus", "EnumerateLayers"]:
Chia-I Wudf2d6392015-01-04 15:38:47 +0800109 return False
Chia-I Wu27697e42015-01-04 15:32:52 +0800110
Chia-I Wudf2d6392015-01-04 15:38:47 +0800111 in_objs = proto.object_in_params()
112 return in_objs and in_objs[0] == proto.params[0]
Chia-I Wu27697e42015-01-04 15:32:52 +0800113
Chia-I Wu2e4f5302015-01-02 00:21:24 +0800114 def _generate_loader_dispatch_entrypoints(self, qual=""):
Chia-I Wu19300602014-08-04 08:03:57 +0800115 if qual:
116 qual += " "
117
Chia-I Wudac3e492014-08-02 23:49:43 +0800118 funcs = []
Courtney Goeltzenleuchter64ca9232015-02-10 18:40:14 -0700119 obj_check_magic_stmt = "#ifdef DEBUG\n if (!valid_loader_magic_value(*%s)) {\n assert(0 && \"Incompatible ICD, first dword must be initialized to ICD_LOADER_MAGIC. See loader/README.md for details.\");\n }\n#endif"
Chia-I Wudac3e492014-08-02 23:49:43 +0800120 for proto in self.protos:
Chia-I Wu27697e42015-01-04 15:32:52 +0800121 if not self._is_dispatchable(proto):
Tobin Ehlisea7fe0b2014-11-12 11:47:07 -0700122 continue
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700123 if 'WsiX11AssociateConnection' == proto.name:
Ian Elliottd1597d22015-02-26 14:34:52 -0700124 funcs.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
Tobin Ehlisea7fe0b2014-11-12 11:47:07 -0700125 decl = proto.c_func(prefix="xgl", attr="XGLAPI")
126 stmt = "(*disp)->%s" % proto.c_call()
Chia-I Wu2e4f5302015-01-02 00:21:24 +0800127 if proto.name == "CreateDevice":
Courtney Goeltzenleuchter64ca9232015-02-10 18:40:14 -0700128 magic_stmt = obj_check_magic_stmt % proto.params[-1].name
Tobin Ehlisea7fe0b2014-11-12 11:47:07 -0700129 funcs.append("%s%s\n"
130 "{\n"
Jon Ashburn613b0c12014-11-17 10:17:37 -0700131 " loader_activate_layers(%s, %s);\n"
Tobin Ehlisea7fe0b2014-11-12 11:47:07 -0700132 " XGL_BASE_LAYER_OBJECT* wrapped_obj = (XGL_BASE_LAYER_OBJECT*)%s;\n"
Jon Ashburne05c8c62014-12-03 14:30:48 -0700133 " const XGL_LAYER_DISPATCH_TABLE **disp =\n"
134 " (const XGL_LAYER_DISPATCH_TABLE **) wrapped_obj->baseObject;\n"
Tobin Ehlisea7fe0b2014-11-12 11:47:07 -0700135 " %s = wrapped_obj->nextObject;\n"
Jon Ashburne05c8c62014-12-03 14:30:48 -0700136 " XGL_RESULT res = %s;\n"
Courtney Goeltzenleuchter64ca9232015-02-10 18:40:14 -0700137 " if (res == XGL_SUCCESS) {\n"
138 "%s\n"
Jon Ashburne04fd1b2015-01-09 10:13:48 -0700139 " *(const XGL_LAYER_DISPATCH_TABLE **) (*%s) = *disp;\n"
Courtney Goeltzenleuchter64ca9232015-02-10 18:40:14 -0700140 " }\n"
Jon Ashburne05c8c62014-12-03 14:30:48 -0700141 " return res;\n"
142 "}" % (qual, decl, proto.params[0].name, proto.params[1].name,
143 proto.params[0].name, proto.params[0].name, stmt,
Courtney Goeltzenleuchter64ca9232015-02-10 18:40:14 -0700144 magic_stmt,
Jon Ashburne05c8c62014-12-03 14:30:48 -0700145 proto.params[-1].name))
Courtney Goeltzenleuchter64ca9232015-02-10 18:40:14 -0700146 elif proto.name == "WsiX11CreatePresentableImage":
147 magic_stmt1 = obj_check_magic_stmt % proto.params[-1].name
148 magic_stmt2 = obj_check_magic_stmt % proto.params[-2].name
149 funcs.append("%s%s\n"
150 "{\n"
151 " const XGL_LAYER_DISPATCH_TABLE **disp =\n"
152 " (const XGL_LAYER_DISPATCH_TABLE **) %s;\n"
153 " XGL_RESULT res = %s;\n"
154 " if (res == XGL_SUCCESS) {\n"
155 "%s\n"
156 "%s\n"
157 " *(const XGL_LAYER_DISPATCH_TABLE **) (*%s) = *disp;\n"
158 " *(const XGL_LAYER_DISPATCH_TABLE **) (*%s) = *disp;\n"
159 " }\n"
160 " return res;\n"
161 "}"
162 % (qual, decl, proto.params[0].name, stmt, magic_stmt1, magic_stmt2, proto.params[-1].name, proto.params[-2].name))
163 elif proto.name == "GetDeviceQueue":
164 # GetDeviceQueue returns an existing Queue object so cannot check for magic header as
165 # it may have already been replaced with a function table pointer
Jon Ashburne05c8c62014-12-03 14:30:48 -0700166 funcs.append("%s%s\n"
167 "{\n"
168 " const XGL_LAYER_DISPATCH_TABLE **disp =\n"
169 " (const XGL_LAYER_DISPATCH_TABLE **) %s;\n"
170 " XGL_RESULT res = %s;\n"
Courtney Goeltzenleuchter64ca9232015-02-10 18:40:14 -0700171 " if (res == XGL_SUCCESS) {\n"
Jon Ashburne04fd1b2015-01-09 10:13:48 -0700172 " *(const XGL_LAYER_DISPATCH_TABLE **) (*%s) = *disp;\n"
173 " }\n"
Jon Ashburne05c8c62014-12-03 14:30:48 -0700174 " return res;\n"
Jon Ashburne04fd1b2015-01-09 10:13:48 -0700175 "}"
Courtney Goeltzenleuchter64ca9232015-02-10 18:40:14 -0700176 % (qual, decl, proto.params[0].name, stmt, proto.params[-1].name))
177 elif self._does_function_create_object(proto):
178 magic_stmt = obj_check_magic_stmt % proto.params[-1].name
179 funcs.append("%s%s\n"
180 "{\n"
181 " const XGL_LAYER_DISPATCH_TABLE **disp =\n"
182 " (const XGL_LAYER_DISPATCH_TABLE **) %s;\n"
183 " XGL_RESULT res = %s;\n"
184 " if (res == XGL_SUCCESS) {\n"
185 "%s\n"
186 " *(const XGL_LAYER_DISPATCH_TABLE **) (*%s) = *disp;\n"
187 " }\n"
188 " return res;\n"
189 "}"
190 % (qual, decl, proto.params[0].name, stmt, magic_stmt, proto.params[-1].name))
Chia-I Wu11078b02015-01-04 16:27:24 +0800191 elif proto.name == "AllocDescriptorSets":
192 funcs.append("%s%s\n"
193 "{\n"
194 " const XGL_LAYER_DISPATCH_TABLE **disp =\n"
195 " (const XGL_LAYER_DISPATCH_TABLE **) %s;\n"
196 " uint32_t i;\n"
197 " XGL_RESULT res = %s;\n"
Courtney Goeltzenleuchter64ca9232015-02-10 18:40:14 -0700198 " for (i = 0; i < *%s; i++) {\n"
199 "#ifdef DEBUG\n"
200 " if (!valid_loader_magic_value(%s[i])) {\n"
201 " assert(0 && \"Incompatible ICD, first dword must be initialized to ICD_LOADER_MAGIC. See loader/README.md for details.\");\n"
202 " }\n"
203 "#endif\n"
Chia-I Wu11078b02015-01-04 16:27:24 +0800204 " *(const XGL_LAYER_DISPATCH_TABLE **) (%s[i]) = *disp;\n"
Courtney Goeltzenleuchter64ca9232015-02-10 18:40:14 -0700205 " }\n"
Chia-I Wu11078b02015-01-04 16:27:24 +0800206 " return res;\n"
Courtney Goeltzenleuchter64ca9232015-02-10 18:40:14 -0700207 "}" % (qual, decl, proto.params[0].name, stmt, proto.params[-1].name, proto.params[-2].name, proto.params[-2].name))
Chia-I Wu2e4f5302015-01-02 00:21:24 +0800208 elif proto.name == "GetMultiGpuCompatibility":
Jon Ashburne05c8c62014-12-03 14:30:48 -0700209 funcs.append("%s%s\n"
210 "{\n"
211 " XGL_BASE_LAYER_OBJECT* wrapped_obj0 = (XGL_BASE_LAYER_OBJECT*)%s;\n"
212 " XGL_BASE_LAYER_OBJECT* wrapped_obj1 = (XGL_BASE_LAYER_OBJECT*)%s;\n"
213 " const XGL_LAYER_DISPATCH_TABLE * const *disp =\n"
214 " (const XGL_LAYER_DISPATCH_TABLE * const *) wrapped_obj0->baseObject;\n"
215 " %s = wrapped_obj0->nextObject;\n"
216 " %s = wrapped_obj1->nextObject;\n"
217 " return %s;\n"
218 "}" % (qual, decl, proto.params[0].name, proto.params[1].name,
219 proto.params[0].name, proto.params[1].name, stmt))
Chia-I Wu2e4f5302015-01-02 00:21:24 +0800220 elif proto.params[0].ty != "XGL_PHYSICAL_GPU":
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600221 if proto.ret != "void":
Jon Ashburne05c8c62014-12-03 14:30:48 -0700222 stmt = "return " + stmt
Tobin Ehlisea7fe0b2014-11-12 11:47:07 -0700223 funcs.append("%s%s\n"
224 "{\n"
225 " const XGL_LAYER_DISPATCH_TABLE * const *disp =\n"
226 " (const XGL_LAYER_DISPATCH_TABLE * const *) %s;\n"
227 " %s;\n"
228 "}" % (qual, decl, proto.params[0].name, stmt))
229 else:
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600230 if proto.ret != "void":
Jon Ashburne05c8c62014-12-03 14:30:48 -0700231 stmt = "return " + stmt
Tobin Ehlisea7fe0b2014-11-12 11:47:07 -0700232 funcs.append("%s%s\n"
233 "{\n"
234 " XGL_BASE_LAYER_OBJECT* wrapped_obj = (XGL_BASE_LAYER_OBJECT*)%s;\n"
235 " const XGL_LAYER_DISPATCH_TABLE * const *disp =\n"
236 " (const XGL_LAYER_DISPATCH_TABLE * const *) wrapped_obj->baseObject;\n"
237 " %s = wrapped_obj->nextObject;\n"
238 " %s;\n"
239 "}" % (qual, decl, proto.params[0].name, proto.params[0].name, stmt))
Chia-I Wudac3e492014-08-02 23:49:43 +0800240
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700241 funcs.append("#endif")
Chia-I Wudac3e492014-08-02 23:49:43 +0800242 return "\n\n".join(funcs)
243
Chia-I Wufb2559d2014-08-01 11:19:52 +0800244 def generate_body(self):
Chia-I Wu2e4f5302015-01-02 00:21:24 +0800245 body = [self._generate_loader_dispatch_entrypoints("LOADER_EXPORT")]
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600246
247 return "\n\n".join(body)
248
Chia-I Wu29271d72015-01-04 10:19:50 +0800249class DispatchTableOpsSubcommand(Subcommand):
250 def run(self):
251 if len(self.argv) != 1:
252 print("DispatchTableOpsSubcommand: <prefix> unspecified")
253 return
254
255 self.prefix = self.argv[0]
256 super().run()
257
258 def generate_header(self):
259 return "\n".join(["#include <xgl.h>",
260 "#include <xglLayer.h>",
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700261 "#include <string.h>",
262 "#include \"loader_platform.h\""])
Chia-I Wu29271d72015-01-04 10:19:50 +0800263
264 def _generate_init(self):
265 stmts = []
266 for proto in self.protos:
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700267 if 'WsiX11AssociateConnection' == proto.name:
Ian Elliottd1597d22015-02-26 14:34:52 -0700268 stmts.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
Chia-I Wu29271d72015-01-04 10:19:50 +0800269 if proto.name == "GetProcAddr":
270 stmts.append("table->%s = gpa; /* direct assignment */" %
271 proto.name)
272 else:
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600273 stmts.append("table->%s = (xgl%sType) gpa(gpu, \"xgl%s\");" %
Chia-I Wu29271d72015-01-04 10:19:50 +0800274 (proto.name, proto.name, proto.name))
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700275 stmts.append("#endif")
Chia-I Wu29271d72015-01-04 10:19:50 +0800276
277 func = []
Ian Elliottfeae4052015-02-18 12:38:04 -0700278 func.append("static inline void %s_initialize_dispatch_table(XGL_LAYER_DISPATCH_TABLE *table,"
Chia-I Wu29271d72015-01-04 10:19:50 +0800279 % self.prefix)
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600280 func.append("%s xglGetProcAddrType gpa,"
Chia-I Wu29271d72015-01-04 10:19:50 +0800281 % (" " * len(self.prefix)))
282 func.append("%s XGL_PHYSICAL_GPU gpu)"
283 % (" " * len(self.prefix)))
284 func.append("{")
285 func.append(" %s" % "\n ".join(stmts))
286 func.append("}")
287
288 return "\n".join(func)
289
290 def _generate_lookup(self):
291 lookups = []
292 for proto in self.protos:
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700293 if 'WsiX11AssociateConnection' == proto.name:
Ian Elliottd1597d22015-02-26 14:34:52 -0700294 lookups.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
Chia-I Wu29271d72015-01-04 10:19:50 +0800295 lookups.append("if (!strcmp(name, \"%s\"))" % (proto.name))
296 lookups.append(" return (void *) table->%s;"
297 % (proto.name))
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700298 lookups.append("#endif")
Chia-I Wu29271d72015-01-04 10:19:50 +0800299
300 func = []
Ian Elliottfeae4052015-02-18 12:38:04 -0700301 func.append("static inline void *%s_lookup_dispatch_table(const XGL_LAYER_DISPATCH_TABLE *table,"
Chia-I Wu29271d72015-01-04 10:19:50 +0800302 % self.prefix)
303 func.append("%s const char *name)"
304 % (" " * len(self.prefix)))
305 func.append("{")
Chia-I Wu6cdaedb2015-01-05 12:55:13 +0800306 func.append(generate_get_proc_addr_check("name"))
Chia-I Wu29271d72015-01-04 10:19:50 +0800307 func.append("")
308 func.append(" name += 3;")
309 func.append(" %s" % "\n ".join(lookups))
310 func.append("")
311 func.append(" return NULL;")
312 func.append("}")
313
314 return "\n".join(func)
315
316 def generate_body(self):
317 body = [self._generate_init(),
318 self._generate_lookup()]
319
320 return "\n\n".join(body)
321
Chia-I Wueeb0ab62015-01-03 23:48:15 +0800322class IcdDummyEntrypointsSubcommand(Subcommand):
Chia-I Wudf3c4322014-08-04 10:08:08 +0800323 def run(self):
Chia-I Wueeb0ab62015-01-03 23:48:15 +0800324 if len(self.argv) == 1:
325 self.prefix = self.argv[0]
326 self.qual = "static"
327 else:
328 self.prefix = "xgl"
329 self.qual = "ICD_EXPORT"
Chia-I Wudf3c4322014-08-04 10:08:08 +0800330
331 super().run()
332
333 def generate_header(self):
334 return "#include \"icd.h\""
335
336 def _generate_stub_decl(self, proto):
Chia-I Wu595ada12015-01-04 12:05:41 +0800337 return proto.c_pretty_decl(self.prefix + proto.name, attr="XGLAPI")
Chia-I Wudf3c4322014-08-04 10:08:08 +0800338
339 def _generate_stubs(self):
340 stubs = []
341 for proto in self.protos:
Chia-I Wudf3c4322014-08-04 10:08:08 +0800342 decl = self._generate_stub_decl(proto)
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600343 if proto.ret != "void":
Chia-I Wueeb0ab62015-01-03 23:48:15 +0800344 stmt = " return XGL_ERROR_UNKNOWN;\n"
Chia-I Wudf3c4322014-08-04 10:08:08 +0800345 else:
346 stmt = ""
347
Chia-I Wueeb0ab62015-01-03 23:48:15 +0800348 stubs.append("%s %s\n{\n%s}" % (self.qual, decl, stmt))
Chia-I Wudf3c4322014-08-04 10:08:08 +0800349
350 return "\n\n".join(stubs)
351
Chia-I Wudf3c4322014-08-04 10:08:08 +0800352 def generate_body(self):
Chia-I Wueeb0ab62015-01-03 23:48:15 +0800353 return self._generate_stubs()
Chia-I Wudf3c4322014-08-04 10:08:08 +0800354
Chia-I Wu7f6d66e2015-01-04 00:11:17 +0800355class IcdGetProcAddrSubcommand(IcdDummyEntrypointsSubcommand):
356 def generate_header(self):
357 return "\n".join(["#include <string.h>", "#include \"icd.h\""])
358
359 def generate_body(self):
360 for proto in self.protos:
361 if proto.name == "GetProcAddr":
362 gpa_proto = proto
363
364 gpa_decl = self._generate_stub_decl(gpa_proto)
365 gpa_pname = gpa_proto.params[-1].name
366
367 lookups = []
368 for proto in self.protos:
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700369 if 'WsiX11AssociateConnection' == proto.name:
Ian Elliottd1597d22015-02-26 14:34:52 -0700370 lookups.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
Chia-I Wu7f6d66e2015-01-04 00:11:17 +0800371 lookups.append("if (!strcmp(%s, \"%s\"))" %
372 (gpa_pname, proto.name))
373 lookups.append(" return (%s) %s%s;" %
374 (gpa_proto.ret, self.prefix, proto.name))
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700375 lookups.append("#endif")
Chia-I Wu7f6d66e2015-01-04 00:11:17 +0800376
377 body = []
378 body.append("%s %s" % (self.qual, gpa_decl))
379 body.append("{")
Chia-I Wu6cdaedb2015-01-05 12:55:13 +0800380 body.append(generate_get_proc_addr_check(gpa_pname))
Chia-I Wu7f6d66e2015-01-04 00:11:17 +0800381 body.append("")
382 body.append(" %s += 3;" % gpa_pname)
383 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 Wuef9f1822015-01-05 12:56:13 +0800390class LayerInterceptProcSubcommand(Subcommand):
391 def run(self):
392 self.prefix = "xgl"
393
394 # we could get the list from argv if wanted
395 self.intercepted = [proto.name for proto in self.protos
Jon Ashburne5f98b92015-01-29 16:54:38 -0700396 if proto.name not in ["EnumerateGpus"]]
Chia-I Wuef9f1822015-01-05 12:56:13 +0800397
398 for proto in self.protos:
399 if proto.name == "GetProcAddr":
400 self.gpa = proto
401
402 super().run()
403
404 def generate_header(self):
405 return "\n".join(["#include <string.h>", "#include \"xglLayer.h\""])
406
407 def generate_body(self):
408 lookups = []
409 for proto in self.protos:
410 if proto.name not in self.intercepted:
411 lookups.append("/* no %s%s */" % (self.prefix, proto.name))
412 continue
413
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700414 if 'WsiX11AssociateConnection' == proto.name:
Ian Elliottd1597d22015-02-26 14:34:52 -0700415 lookups.append("#if defined(__linux__) || defined(XCB_NVIDIA)")
Chia-I Wuef9f1822015-01-05 12:56:13 +0800416 lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
417 lookups.append(" return (%s) %s%s;" %
418 (self.gpa.ret, self.prefix, proto.name))
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700419 lookups.append("#endif")
Chia-I Wuef9f1822015-01-05 12:56:13 +0800420
421 body = []
Ian Elliottfeae4052015-02-18 12:38:04 -0700422 body.append("static inline %s layer_intercept_proc(const char *name)" %
Chia-I Wuef9f1822015-01-05 12:56:13 +0800423 self.gpa.ret)
424 body.append("{")
425 body.append(generate_get_proc_addr_check("name"))
426 body.append("")
427 body.append(" name += 3;")
428 body.append(" %s" % "\n ".join(lookups))
429 body.append("")
430 body.append(" return NULL;")
431 body.append("}")
432
433 return "\n".join(body)
434
Chia-I Wufb2559d2014-08-01 11:19:52 +0800435def main():
436 subcommands = {
Chia-I Wub3d5e192015-01-04 10:15:48 +0800437 "loader-entrypoints": LoaderEntrypointsSubcommand,
Chia-I Wu29271d72015-01-04 10:19:50 +0800438 "dispatch-table-ops": DispatchTableOpsSubcommand,
Chia-I Wueeb0ab62015-01-03 23:48:15 +0800439 "icd-dummy-entrypoints": IcdDummyEntrypointsSubcommand,
Chia-I Wu7f6d66e2015-01-04 00:11:17 +0800440 "icd-get-proc-addr": IcdGetProcAddrSubcommand,
Chia-I Wuef9f1822015-01-05 12:56:13 +0800441 "layer-intercept-proc": LayerInterceptProcSubcommand,
Chia-I Wufb2559d2014-08-01 11:19:52 +0800442 }
443
444 if len(sys.argv) < 2 or sys.argv[1] not in subcommands:
445 print("Usage: %s <subcommand> [options]" % sys.argv[0])
446 print
447 print("Available sucommands are: %s" % " ".join(subcommands))
448 exit(1)
449
450 subcmd = subcommands[sys.argv[1]](sys.argv[2:])
451 subcmd.run()
452
453if __name__ == "__main__":
454 main()