• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python3
2# Copyright 2017 The ANGLE Project Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5#
6# gen_proc_table.py:
7#  Code generation for entry point loading tables.
8#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.
9
10import os
11import sys
12import registry_xml
13
14out_file_name_gles = "../src/libGLESv2/proc_table_egl_autogen.cpp"
15out_file_name_wgl = "../src/libGLESv2/proc_table_wgl_autogen.cpp"
16out_file_name_glx = "../src/libGLESv2/proc_table_glx_autogen.cpp"
17out_file_name_cl = "../src/libGLESv2/proc_table_cl_autogen.cpp"
18out_file_name_cl_map = "../src/libOpenCL/libOpenCL_autogen.map"
19
20strip_suffixes = ["ANGLE", "EXT", "KHR", "OES", "CHROMIUM", "OVR"]
21
22template_cpp = """// GENERATED FILE - DO NOT EDIT.
23// Generated by {script_name} using data from {data_source_name}.
24//
25// Copyright 2019 The ANGLE Project Authors. All rights reserved.
26// Use of this source code is governed by a BSD-style license that can be
27// found in the LICENSE file.
28//
29// getProcAddress loader table:
30//   Mapping from a string entry point name to function address.
31//
32
33{includes}
34#define P(FUNC) reinterpret_cast<{cast}>(FUNC)
35{desktop_only_macro_definition}
36
37namespace {namespace}
38{{
39// clang-format off
40const ProcEntry g_procTable[] = {{
41{proc_data}
42}};
43// clang-format on
44const size_t g_numProcs = {num_procs};
45}}  // namespace {namespace}
46"""
47
48desktop_only_macro_definition = """
49#if defined(ANGLE_ENABLE_GL_DESKTOP_FRONTEND)
50#   define DESKTOP_ONLY(func, angleFunc) {func, P(angleFunc)},
51#else
52#   define DESKTOP_ONLY(func, angleFunc)
53#endif
54"""
55
56# FOR OPENCL
57template_map_cpp = """// GENERATED FILE - DO NOT EDIT.
58// Generated by {script_name} using data from {data_source_name}.
59//
60// Copyright 2021 The ANGLE Project Authors. All rights reserved.
61// Use of this source code is governed by a BSD-style license that can be
62// found in the LICENSE file.
63//
64// proc_table:
65//   Mapping from a string entry point name to function address.
66//
67
68{includes}
69#define P(FUNC) reinterpret_cast<{cast}>(FUNC)
70
71namespace {namespace}
72{{
73
74const ProcTable &GetProcTable()
75{{
76    static angle::base::NoDestructor<ProcTable> sProcTable(
77        {{{proc_data}}});
78    return *sProcTable;
79}}
80
81}}  // namespace {namespace}
82"""
83
84# FOR OPENCL
85template_map = """/* GENERATED FILE - DO NOT EDIT.
86 * Generated by {script_name} using data from {data_source_name}.
87 *
88 * Copyright 2021 The ANGLE Project Authors. All rights reserved.
89 * Use of this source code is governed by a BSD-style license that can be
90 * found in the LICENSE file.
91 *
92 * symbol version map: Maps versions to entry point names for a shared library.
93 */
94{symbol_maps}
95"""
96
97includes_gles = """#include "libGLESv2/proc_table_egl.h"
98
99#include "libGLESv2/entry_points_egl_autogen.h"
100#include "libGLESv2/entry_points_egl_ext_autogen.h"
101#include "libGLESv2/entry_points_gles_1_0_autogen.h"
102#include "libGLESv2/entry_points_gles_2_0_autogen.h"
103#include "libGLESv2/entry_points_gles_3_0_autogen.h"
104#include "libGLESv2/entry_points_gles_3_1_autogen.h"
105#include "libGLESv2/entry_points_gles_3_2_autogen.h"
106#include "libGLESv2/entry_points_gles_ext_autogen.h"
107#include "platform/PlatformMethods.h"
108
109#if defined(ANGLE_ENABLE_GL_DESKTOP_FRONTEND)
110#   include "libGLESv2/entry_points_gl_1_autogen.h"
111#   include "libGLESv2/entry_points_gl_2_autogen.h"
112#   include "libGLESv2/entry_points_gl_3_autogen.h"
113#   include "libGLESv2/entry_points_gl_4_autogen.h"
114#endif
115
116#include <iterator>
117"""
118
119includes_wgl = """#include "libGLESv2/proc_table_wgl.h"
120
121#include "libGLESv2/entry_points_egl_ext_autogen.h"
122#include "libGLESv2/entry_points_gles_1_0_autogen.h"
123#include "libGLESv2/entry_points_gles_2_0_autogen.h"
124#include "libGLESv2/entry_points_gles_3_0_autogen.h"
125#include "libGLESv2/entry_points_gles_3_1_autogen.h"
126#include "libGLESv2/entry_points_gles_3_2_autogen.h"
127#include "libGLESv2/entry_points_gles_ext_autogen.h"
128#include "platform/PlatformMethods.h"
129#include "libGLESv2/entry_points_gl_1_autogen.h"
130#include "libGLESv2/entry_points_gl_2_autogen.h"
131#include "libGLESv2/entry_points_gl_3_autogen.h"
132#include "libGLESv2/entry_points_gl_4_autogen.h"
133#include "libGLESv2/entry_points_wgl.h"
134
135#include <iterator>
136"""
137
138includes_glx = """#include "libGLESv2/proc_table_glx.h"
139
140#include "libGLESv2/entry_points_egl_ext_autogen.h"
141#include "libGLESv2/entry_points_gles_1_0_autogen.h"
142#include "libGLESv2/entry_points_gles_2_0_autogen.h"
143#include "libGLESv2/entry_points_gles_3_0_autogen.h"
144#include "libGLESv2/entry_points_gles_3_1_autogen.h"
145#include "libGLESv2/entry_points_gles_3_2_autogen.h"
146#include "libGLESv2/entry_points_gles_ext_autogen.h"
147#include "platform/PlatformMethods.h"
148#include "libGLESv2/entry_points_gl_1_autogen.h"
149#include "libGLESv2/entry_points_gl_2_autogen.h"
150#include "libGLESv2/entry_points_gl_3_autogen.h"
151#include "libGLESv2/entry_points_gl_4_autogen.h"
152#include "libGLESv2/entry_points_glx.h"
153
154#include <iterator>
155"""
156
157includes_cl = """#include "libGLESv2/proc_table_cl.h"
158
159#include "libGLESv2/entry_points_cl_autogen.h"
160
161#include "anglebase/no_destructor.h"
162
163// Using fully qualified entry point identifiers to make sure that missing entry points would not
164// pick up the global declarations of OpenCL
165"""
166
167sys.path.append('../src/libANGLE/renderer')
168import angle_format
169
170
171def _get_annotations(versions):
172    return ["%d_%d" % version for version in versions]
173
174
175def main():
176
177    # auto_script parameters.
178    if len(sys.argv) > 1:
179        inputs = [source for source in registry_xml.xml_inputs]
180        outputs = [
181            out_file_name_gles, out_file_name_wgl, out_file_name_glx, out_file_name_cl,
182            out_file_name_cl_map
183        ]
184        if sys.argv[1] == 'inputs':
185            print(','.join(inputs))
186        elif sys.argv[1] == 'outputs':
187            print(','.join(outputs))
188        else:
189            print('Invalid script parameters')
190            return 1
191        return 0
192
193    glesxml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml')
194
195    for annotation in _get_annotations(registry_xml.GLES_VERSIONS):
196        name_prefix = "GL_ES_VERSION_"
197        if annotation[0] == '1':
198            name_prefix = "GL_VERSION_ES_CM_"
199        feature_name = "{}{}".format(name_prefix, annotation)
200        glesxml.AddCommands(feature_name, annotation)
201
202    glesxml.AddExtensionCommands(registry_xml.supported_extensions, ['gles2', 'gles1'])
203
204    # Also don't add GLES extension commands to libGL proc table
205    extension_commands = []
206    for extension_name, ext_cmd_names in sorted(glesxml.ext_data.items()):
207        extension_commands.extend(glesxml.ext_data[extension_name])
208    for name in extension_commands:
209        name_no_suffix = name
210        for suffix in strip_suffixes:
211            if name_no_suffix.endswith(suffix):
212                name_no_suffix = name_no_suffix[0:-len(suffix)]
213
214    gles_data = glesxml.all_cmd_names.get_all_commands()
215    eglxml = registry_xml.RegistryXML('egl.xml', 'egl_angle_ext.xml')
216
217    for annotation in _get_annotations(registry_xml.EGL_VERSIONS):
218        name_prefix = "EGL_VERSION_"
219        feature_name = "{}{}".format(name_prefix, annotation)
220        eglxml.AddCommands(feature_name, annotation)
221
222    eglxml.AddExtensionCommands(registry_xml.supported_egl_extensions, ['gles2', 'gles1'])
223
224    gles_data.extend(eglxml.all_cmd_names.get_all_commands())
225
226    gles_data.append("ANGLEGetDisplayPlatform")
227    gles_data.append("ANGLEResetDisplayPlatform")
228    gles_data = set(gles_data)
229
230    glxml = registry_xml.RegistryXML('gl.xml')
231    for annotation in _get_annotations(registry_xml.DESKTOP_GL_VERSIONS):
232        name_prefix = "GL_VERSION_"
233        feature_name = "{}{}".format(name_prefix, annotation)
234        glxml.AddCommands(feature_name, annotation)
235
236    gl_data = set([cmd for cmd in glxml.all_cmd_names.get_all_commands()])
237
238    all_gl_data = list(set(gles_data).union(gl_data))
239    all_functions = {}
240    for function in all_gl_data:
241        if function.startswith("gl"):
242            all_functions[function] = "GL_" + function[2:]
243        elif function.startswith("egl"):
244            all_functions[function] = "EGL_" + function[3:]
245        else:
246            all_functions[function] = function
247
248    proc_data = []
249    gl_only_data = gl_data.difference(gles_data)
250    for func, angle_func in sorted(all_functions.items()):
251        if func in gl_only_data:
252            proc_data.append('    DESKTOP_ONLY("%s", %s)' % (func, angle_func))
253        else:
254            proc_data.append('    {"%s", P(%s)},' % (func, angle_func))
255
256    with open(out_file_name_gles, 'w') as out_file:
257        output_cpp = template_cpp.format(
258            script_name=os.path.basename(sys.argv[0]),
259            data_source_name="gl.xml, gl_angle_ext.xml, egl.xml, egl_angle_ext.xml",
260            includes=includes_gles,
261            cast="__eglMustCastToProperFunctionPointerType",
262            namespace="egl",
263            proc_data="\n".join(proc_data),
264            num_procs="std::size(g_procTable)",
265            desktop_only_macro_definition=desktop_only_macro_definition)
266        out_file.write(output_cpp)
267        out_file.close()
268
269    def WriteWindowingProcTable(api_name, out_file_name, includes, cast):
270        xml_file_name = '{}.xml'.format(api_name)
271        xml = registry_xml.RegistryXML(xml_file_name)
272        annotations = _get_annotations(
273            getattr(registry_xml, '{}_VERSIONS'.format(api_name.upper())))
274        for annotation in annotations:
275            name_prefix = "{}_VERSION_".format(api_name.upper())
276            feature_name = "{}{}".format(name_prefix, annotation)
277            xml.AddCommands(feature_name, annotation)
278
279        commands = [
280            # Some WGL EP's need to have "wgl" appended to their names
281            cmd if api_name != 'wgl' or cmd.startswith(api_name) else api_name + cmd
282            for cmd in xml.all_cmd_names.get_all_commands()
283        ]
284
285        # Start with all of the GLES + Desktop entry points, filtering out the EGL ones
286        proc_data = [
287            '    {"%s", P(%s)},' % (func, angle_func)
288            for func, angle_func in sorted(all_functions.items())
289            if not func.startswith('egl')
290        ]
291        proc_data.extend(['    {"%s", P(%s)},' % (cmd, cmd) for cmd in sorted(commands)])
292
293        with open(out_file_name, 'w') as out_file:
294            output_cpp = template_cpp.format(
295                script_name=os.path.basename(sys.argv[0]),
296                data_source_name="gl.xml, gl_angle_ext.xml, {}".format(xml_file_name),
297                includes=includes,
298                cast=cast,
299                namespace=api_name,
300                proc_data="\n".join(proc_data),
301                num_procs="std::size(g_procTable)",
302                desktop_only_macro_definition='')
303            out_file.write(output_cpp)
304            out_file.close()
305
306    WriteWindowingProcTable('wgl', out_file_name_wgl, includes_wgl, "PROC")
307    WriteWindowingProcTable('glx', out_file_name_glx, includes_glx, "__GLXextFuncPtr")
308
309    # libCL proc table
310    clxml = registry_xml.RegistryXML('cl.xml')
311    symbol_maps = []
312    symbol_map_dependency = ""
313
314    for major_version, minor_version in registry_xml.CL_VERSIONS:
315        name_prefix = "CL_VERSION_"
316        annotation = "%d_%d" % (major_version, minor_version)
317        feature_name = "%s%s" % (name_prefix, annotation)
318        clxml.AddCommands(feature_name, annotation)
319        symbol_version = "OPENCL_%d.%d" % (major_version, minor_version)
320        symbol_maps += ["\n%s {\n    global:" % symbol_version]
321        symbol_maps += ['        %s;' % cmd for cmd in clxml.commands[annotation]]
322        if not symbol_map_dependency:
323            symbol_maps += ["    local:\n        *;\n};"]
324        else:
325            symbol_maps += ["} %s;" % symbol_map_dependency]
326        symbol_map_dependency = symbol_version
327
328    clxml.AddExtensionCommands(registry_xml.supported_cl_extensions, ['cl'])
329    cl_commands = clxml.all_cmd_names.get_all_commands()
330    proc_data = ['{"%s", P(::cl::%s)}' % (cmd, cmd) for cmd in cl_commands]
331
332    with open(out_file_name_cl, 'w') as out_file:
333        output_cpp = template_map_cpp.format(
334            script_name=os.path.basename(sys.argv[0]),
335            data_source_name="cl.xml",
336            includes=includes_cl,
337            cast="void *",
338            namespace="cl",
339            proc_data=",\n         ".join(proc_data))
340        out_file.write(output_cpp)
341        out_file.close()
342
343    with open(out_file_name_cl_map, 'w') as out_file:
344        output_map = template_map.format(
345            script_name=os.path.basename(sys.argv[0]),
346            data_source_name="cl.xml",
347            symbol_maps="\n".join(symbol_maps))
348        out_file.write(output_map)
349        out_file.close()
350
351    return 0
352
353
354if __name__ == '__main__':
355    sys.exit(main())
356