xref: /aosp_15_r20/external/angle/scripts/gen_proc_table.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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_cl = "../src/libGLESv2/proc_table_cl_autogen.cpp"
16out_file_name_cl_map = "../src/libOpenCL/libOpenCL_autogen.map"
17
18strip_suffixes = ["ANGLE", "EXT", "KHR", "OES", "CHROMIUM", "OVR"]
19
20template_cpp = """// GENERATED FILE - DO NOT EDIT.
21// Generated by {script_name} using data from {data_source_name}.
22//
23// Copyright 2019 The ANGLE Project Authors. All rights reserved.
24// Use of this source code is governed by a BSD-style license that can be
25// found in the LICENSE file.
26//
27// getProcAddress loader table:
28//   Mapping from a string entry point name to function address.
29//
30
31{includes}
32#define P(FUNC) reinterpret_cast<{cast}>(FUNC)
33
34namespace {namespace}
35{{
36// clang-format off
37const ProcEntry g_procTable[] = {{
38{proc_data}
39}};
40// clang-format on
41const size_t g_numProcs = {num_procs};
42}}  // namespace {namespace}
43"""
44
45# FOR OPENCL
46template_map_cpp = """// GENERATED FILE - DO NOT EDIT.
47// Generated by {script_name} using data from {data_source_name}.
48//
49// Copyright 2021 The ANGLE Project Authors. All rights reserved.
50// Use of this source code is governed by a BSD-style license that can be
51// found in the LICENSE file.
52//
53// proc_table:
54//   Mapping from a string entry point name to function address.
55//
56
57{includes}
58#define P(FUNC) reinterpret_cast<{cast}>(FUNC)
59
60namespace {namespace}
61{{
62
63const ProcTable &GetProcTable()
64{{
65    static angle::base::NoDestructor<ProcTable> sProcTable(
66        {{{proc_data}}});
67    return *sProcTable;
68}}
69
70}}  // namespace {namespace}
71"""
72
73# FOR OPENCL
74template_map = """/* GENERATED FILE - DO NOT EDIT.
75 * Generated by {script_name} using data from {data_source_name}.
76 *
77 * Copyright 2021 The ANGLE Project Authors. All rights reserved.
78 * Use of this source code is governed by a BSD-style license that can be
79 * found in the LICENSE file.
80 *
81 * symbol version map: Maps versions to entry point names for a shared library.
82 */
83{symbol_maps}
84"""
85
86includes_gles = """#include "libGLESv2/proc_table_egl.h"
87
88#include "libGLESv2/entry_points_egl_autogen.h"
89#include "libGLESv2/entry_points_egl_ext_autogen.h"
90#include "libGLESv2/entry_points_gles_1_0_autogen.h"
91#include "libGLESv2/entry_points_gles_2_0_autogen.h"
92#include "libGLESv2/entry_points_gles_3_0_autogen.h"
93#include "libGLESv2/entry_points_gles_3_1_autogen.h"
94#include "libGLESv2/entry_points_gles_3_2_autogen.h"
95#include "libGLESv2/entry_points_gles_ext_autogen.h"
96#include "platform/PlatformMethods.h"
97
98#include <iterator>
99"""
100
101includes_cl = """#include "libGLESv2/proc_table_cl.h"
102
103#include "libGLESv2/entry_points_cl_autogen.h"
104
105#include "anglebase/no_destructor.h"
106
107// Using fully qualified entry point identifiers to make sure that missing entry points would not
108// pick up the global declarations of OpenCL
109"""
110
111sys.path.append('../src/libANGLE/renderer')
112import angle_format
113
114
115def _get_annotations(versions):
116    return ["%d_%d" % version for version in versions]
117
118
119def main():
120
121    # auto_script parameters.
122    if len(sys.argv) > 1:
123        inputs = [source for source in registry_xml.xml_inputs]
124        outputs = [out_file_name_gles, out_file_name_cl, out_file_name_cl_map]
125        if sys.argv[1] == 'inputs':
126            print(','.join(inputs))
127        elif sys.argv[1] == 'outputs':
128            print(','.join(outputs))
129        else:
130            print('Invalid script parameters')
131            return 1
132        return 0
133
134    glesxml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml')
135
136    for annotation in _get_annotations(registry_xml.GLES_VERSIONS):
137        name_prefix = "GL_ES_VERSION_"
138        if annotation[0] == '1':
139            name_prefix = "GL_VERSION_ES_CM_"
140        feature_name = "{}{}".format(name_prefix, annotation)
141        glesxml.AddCommands(feature_name, annotation)
142
143    glesxml.AddExtensionCommands(registry_xml.supported_extensions, ['gles2', 'gles1'])
144
145    # Also don't add GLES extension commands to libGL proc table
146    extension_commands = []
147    for extension_name, ext_cmd_names in sorted(glesxml.ext_data.items()):
148        extension_commands.extend(glesxml.ext_data[extension_name])
149    for name in extension_commands:
150        name_no_suffix = name
151        for suffix in strip_suffixes:
152            if name_no_suffix.endswith(suffix):
153                name_no_suffix = name_no_suffix[0:-len(suffix)]
154
155    gles_data = glesxml.all_cmd_names.get_all_commands()
156    eglxml = registry_xml.RegistryXML('egl.xml', 'egl_angle_ext.xml')
157
158    for annotation in _get_annotations(registry_xml.EGL_VERSIONS):
159        name_prefix = "EGL_VERSION_"
160        feature_name = "{}{}".format(name_prefix, annotation)
161        eglxml.AddCommands(feature_name, annotation)
162
163    eglxml.AddExtensionCommands(registry_xml.supported_egl_extensions, ['gles2', 'gles1'])
164
165    gles_data.extend(eglxml.all_cmd_names.get_all_commands())
166
167    gles_data.append("ANGLEGetDisplayPlatform")
168    gles_data.append("ANGLEResetDisplayPlatform")
169    gles_data = set(gles_data)
170
171    all_functions = {}
172    for function in gles_data:
173        if function.startswith("gl"):
174            all_functions[function] = "GL_" + function[2:]
175        elif function.startswith("egl"):
176            all_functions[function] = "EGL_" + function[3:]
177        else:
178            all_functions[function] = function
179
180    proc_data = []
181    for func, angle_func in sorted(all_functions.items()):
182        proc_data.append('    {"%s", P(%s)},' % (func, angle_func))
183
184    with open(out_file_name_gles, 'w') as out_file:
185        output_cpp = template_cpp.format(
186            script_name=os.path.basename(sys.argv[0]),
187            data_source_name="gl.xml, gl_angle_ext.xml, egl.xml, egl_angle_ext.xml",
188            includes=includes_gles,
189            cast="__eglMustCastToProperFunctionPointerType",
190            namespace="egl",
191            proc_data="\n".join(proc_data),
192            num_procs="std::size(g_procTable)")
193        out_file.write(output_cpp)
194        out_file.close()
195
196    # libCL proc table
197    clxml = registry_xml.RegistryXML('cl.xml')
198    symbol_maps = []
199    symbol_map_dependency = ""
200
201    for major_version, minor_version in registry_xml.CL_VERSIONS:
202        name_prefix = "CL_VERSION_"
203        annotation = "%d_%d" % (major_version, minor_version)
204        feature_name = "%s%s" % (name_prefix, annotation)
205        clxml.AddCommands(feature_name, annotation)
206        symbol_version = "OPENCL_%d.%d" % (major_version, minor_version)
207        symbol_maps += ["\n%s {\n    global:" % symbol_version]
208        symbol_maps += ['        %s;' % cmd for cmd in clxml.commands[annotation]]
209        if not symbol_map_dependency:
210            symbol_maps += ["    local:\n        *;\n};"]
211        else:
212            symbol_maps += ["} %s;" % symbol_map_dependency]
213        symbol_map_dependency = symbol_version
214
215    clxml.AddExtensionCommands(registry_xml.supported_cl_extensions, ['cl'])
216    cl_commands = clxml.all_cmd_names.get_all_commands()
217    proc_data = ['{"%s", P(::cl::%s)}' % (cmd, cmd) for cmd in cl_commands]
218
219    with open(out_file_name_cl, 'w') as out_file:
220        output_cpp = template_map_cpp.format(
221            script_name=os.path.basename(sys.argv[0]),
222            data_source_name="cl.xml",
223            includes=includes_cl,
224            cast="void *",
225            namespace="cl",
226            proc_data=",\n         ".join(proc_data))
227        out_file.write(output_cpp)
228        out_file.close()
229
230    with open(out_file_name_cl_map, 'w') as out_file:
231        output_map = template_map.format(
232            script_name=os.path.basename(sys.argv[0]),
233            data_source_name="cl.xml",
234            symbol_maps="\n".join(symbol_maps))
235        out_file.write(output_map)
236        out_file.close()
237
238    return 0
239
240
241if __name__ == '__main__':
242    sys.exit(main())
243