Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/egl/generate/gen_egl_dispatch.py
4560 views
1
#!/usr/bin/env python
2
3
# (C) Copyright 2016, NVIDIA CORPORATION.
4
# All Rights Reserved.
5
#
6
# Permission is hereby granted, free of charge, to any person obtaining a
7
# copy of this software and associated documentation files (the "Software"),
8
# to deal in the Software without restriction, including without limitation
9
# on the rights to use, copy, modify, merge, publish, distribute, sub
10
# license, and/or sell copies of the Software, and to permit persons to whom
11
# the Software is furnished to do so, subject to the following conditions:
12
#
13
# The above copyright notice and this permission notice (including the next
14
# paragraph) shall be included in all copies or substantial portions of the
15
# 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 NON-INFRINGEMENT. IN NO EVENT SHALL
20
# IBM AND/OR ITS SUPPLIERS 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 DEALINGS
23
# IN THE SOFTWARE.
24
#
25
# Authors:
26
# Kyle Brenneman <[email protected]>
27
28
"""
29
Generates dispatch functions for EGL.
30
31
The list of functions and arguments is read from the Khronos's XML files, with
32
additional information defined in the module eglFunctionList.
33
"""
34
35
import argparse
36
import collections
37
import eglFunctionList
38
import sys
39
import textwrap
40
41
import os
42
NEWAPI = os.path.join(os.path.dirname(__file__), "..", "..", "mapi", "new")
43
sys.path.insert(0, NEWAPI)
44
import genCommon
45
46
def main():
47
parser = argparse.ArgumentParser()
48
parser.add_argument("target", choices=("header", "source"),
49
help="Whether to build the source or header file.")
50
parser.add_argument("xml_files", nargs="+", help="The XML files with the EGL function lists.")
51
52
args = parser.parse_args()
53
54
xmlFunctions = genCommon.getFunctions(args.xml_files)
55
xmlByName = dict((f.name, f) for f in xmlFunctions)
56
functions = []
57
for (name, eglFunc) in eglFunctionList.EGL_FUNCTIONS:
58
func = xmlByName[name]
59
eglFunc = fixupEglFunc(func, eglFunc)
60
functions.append((func, eglFunc))
61
62
# Sort the function list by name.
63
functions = sorted(functions, key=lambda f: f[0].name)
64
65
if args.target == "header":
66
text = generateHeader(functions)
67
elif args.target == "source":
68
text = generateSource(functions)
69
sys.stdout.write(text)
70
71
def fixupEglFunc(func, eglFunc):
72
result = dict(eglFunc)
73
if result.get("prefix") is None:
74
result["prefix"] = ""
75
76
if result.get("extension") is not None:
77
text = "defined(" + result["extension"] + ")"
78
result["extension"] = text
79
80
if result["method"] in ("none", "custom"):
81
return result
82
83
if result["method"] not in ("display", "device", "current"):
84
raise ValueError("Invalid dispatch method %r for function %r" % (result["method"], func.name))
85
86
if func.hasReturn():
87
if result.get("retval") is None:
88
result["retval"] = getDefaultReturnValue(func.rt)
89
90
return result
91
92
def generateHeader(functions):
93
text = textwrap.dedent(r"""
94
#ifndef G_EGLDISPATCH_STUBS_H
95
#define G_EGLDISPATCH_STUBS_H
96
97
#ifdef __cplusplus
98
extern "C" {
99
#endif
100
101
#include <EGL/egl.h>
102
#include <EGL/eglext.h>
103
#include <EGL/eglmesaext.h>
104
#include <EGL/eglextchromium.h>
105
#include "glvnd/libeglabi.h"
106
107
""".lstrip("\n"))
108
109
text += "enum {\n"
110
for (func, eglFunc) in functions:
111
text += generateGuardBegin(func, eglFunc)
112
text += " __EGL_DISPATCH_" + func.name + ",\n"
113
text += generateGuardEnd(func, eglFunc)
114
text += " __EGL_DISPATCH_COUNT\n"
115
text += "};\n"
116
117
for (func, eglFunc) in functions:
118
if eglFunc["inheader"]:
119
text += generateGuardBegin(func, eglFunc)
120
text += "{f.rt} EGLAPIENTRY {ex[prefix]}{f.name}({f.decArgs});\n".format(f=func, ex=eglFunc)
121
text += generateGuardEnd(func, eglFunc)
122
123
text += textwrap.dedent(r"""
124
#ifdef __cplusplus
125
}
126
#endif
127
#endif // G_EGLDISPATCH_STUBS_H
128
""")
129
return text
130
131
def generateSource(functions):
132
# First, sort the function list by name.
133
text = ""
134
text += '#include "egldispatchstubs.h"\n'
135
text += '#include "g_egldispatchstubs.h"\n'
136
text += '#include <stddef.h>\n'
137
text += "\n"
138
139
for (func, eglFunc) in functions:
140
if eglFunc["method"] not in ("custom", "none"):
141
text += generateGuardBegin(func, eglFunc)
142
text += generateDispatchFunc(func, eglFunc)
143
text += generateGuardEnd(func, eglFunc)
144
145
text += "\n"
146
text += "const char * const __EGL_DISPATCH_FUNC_NAMES[__EGL_DISPATCH_COUNT + 1] = {\n"
147
for (func, eglFunc) in functions:
148
text += generateGuardBegin(func, eglFunc)
149
text += ' "' + func.name + '",\n'
150
text += generateGuardEnd(func, eglFunc)
151
text += " NULL\n"
152
text += "};\n"
153
154
text += "const __eglMustCastToProperFunctionPointerType __EGL_DISPATCH_FUNCS[__EGL_DISPATCH_COUNT + 1] = {\n"
155
for (func, eglFunc) in functions:
156
text += generateGuardBegin(func, eglFunc)
157
if eglFunc["method"] != "none":
158
text += " (__eglMustCastToProperFunctionPointerType) " + eglFunc.get("prefix", "") + func.name + ",\n"
159
else:
160
text += " NULL, // " + func.name + "\n"
161
text += generateGuardEnd(func, eglFunc)
162
text += " NULL\n"
163
text += "};\n"
164
165
return text
166
167
def generateGuardBegin(func, eglFunc):
168
ext = eglFunc.get("extension")
169
if ext is not None:
170
return "#if " + ext + "\n"
171
else:
172
return ""
173
174
def generateGuardEnd(func, eglFunc):
175
if eglFunc.get("extension") is not None:
176
return "#endif\n"
177
else:
178
return ""
179
180
def generateDispatchFunc(func, eglFunc):
181
text = ""
182
183
if eglFunc.get("static"):
184
text += "static "
185
elif eglFunc.get("public"):
186
text += "PUBLIC "
187
text += textwrap.dedent(
188
r"""
189
{f.rt} EGLAPIENTRY {ef[prefix]}{f.name}({f.decArgs})
190
{{
191
typedef {f.rt} EGLAPIENTRY (* _pfn_{f.name})({f.decArgs});
192
""").lstrip("\n").format(f=func, ef=eglFunc)
193
194
if func.hasReturn():
195
text += " {f.rt} _ret = {ef[retval]};\n".format(f=func, ef=eglFunc)
196
197
text += " _pfn_{f.name} _ptr_{f.name} = (_pfn_{f.name}) ".format(f=func)
198
if eglFunc["method"] == "current":
199
text += "__eglDispatchFetchByCurrent(__EGL_DISPATCH_{f.name});\n".format(f=func)
200
201
elif eglFunc["method"] in ("display", "device"):
202
if eglFunc["method"] == "display":
203
lookupFunc = "__eglDispatchFetchByDisplay"
204
lookupType = "EGLDisplay"
205
else:
206
assert eglFunc["method"] == "device"
207
lookupFunc = "__eglDispatchFetchByDevice"
208
lookupType = "EGLDeviceEXT"
209
210
lookupArg = None
211
for arg in func.args:
212
if arg.type == lookupType:
213
lookupArg = arg.name
214
break
215
if lookupArg is None:
216
raise ValueError("Can't find %s argument for function %s" % (lookupType, func.name,))
217
218
text += "{lookupFunc}({lookupArg}, __EGL_DISPATCH_{f.name});\n".format(
219
f=func, lookupFunc=lookupFunc, lookupArg=lookupArg)
220
else:
221
raise ValueError("Unknown dispatch method: %r" % (eglFunc["method"],))
222
223
text += " if(_ptr_{f.name} != NULL) {{\n".format(f=func)
224
text += " "
225
if func.hasReturn():
226
text += "_ret = "
227
text += "_ptr_{f.name}({f.callArgs});\n".format(f=func)
228
text += " }\n"
229
230
if func.hasReturn():
231
text += " return _ret;\n"
232
text += "}\n"
233
return text
234
235
def getDefaultReturnValue(typename):
236
if typename.endswith("*"):
237
return "NULL"
238
elif typename == "EGLDisplay":
239
return "EGL_NO_DISPLAY"
240
elif typename == "EGLContext":
241
return "EGL_NO_CONTEXT"
242
elif typename == "EGLSurface":
243
return "EGL_NO_SURFACE"
244
elif typename == "EGLBoolean":
245
return "EGL_FALSE";
246
247
return "0"
248
249
if __name__ == "__main__":
250
main()
251
252
253