| #!/usr/bin/python3 |
| # Copyright 2017 The ANGLE Project Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| # |
| # gen_proc_table.py: |
| # Code generation for entry point loading tables. |
| # NOTE: don't run this script directly. Run scripts/run_code_generation.py. |
| |
| import sys |
| import registry_xml |
| |
| out_file_name_gles = "../src/libGLESv2/proc_table_egl_autogen.cpp" |
| out_file_name_gl = "../src/libGL/proc_table_wgl_autogen.cpp" |
| out_file_name_cl = "../src/libGLESv2/proc_table_cl_autogen.cpp" |
| out_file_name_cl_map = "../src/libOpenCL/libOpenCL_autogen.map" |
| |
| strip_suffixes = ["ANGLE", "EXT", "KHR", "OES", "CHROMIUM", "OVR"] |
| |
| template_cpp = """// GENERATED FILE - DO NOT EDIT. |
| // Generated by {script_name} using data from {data_source_name}. |
| // |
| // Copyright 2019 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // getProcAddress loader table: |
| // Mapping from a string entry point name to function address. |
| // |
| |
| {includes} |
| #define P(FUNC) reinterpret_cast<{cast}>(FUNC) |
| |
| namespace {namespace} |
| {{ |
| const ProcEntry g_procTable[] = {{ |
| {proc_data} |
| }}; |
| |
| const size_t g_numProcs = {num_procs}; |
| }} // namespace {namespace} |
| """ |
| |
| template_map_cpp = """// GENERATED FILE - DO NOT EDIT. |
| // Generated by {script_name} using data from {data_source_name}. |
| // |
| // Copyright 2021 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // proc_table: |
| // Mapping from a string entry point name to function address. |
| // |
| |
| {includes} |
| #define P(FUNC) reinterpret_cast<{cast}>(FUNC) |
| |
| namespace {namespace} |
| {{ |
| |
| const ProcTable &GetProcTable() |
| {{ |
| static angle::base::NoDestructor<ProcTable> sProcTable( |
| {{{proc_data}}}); |
| return *sProcTable; |
| }} |
| |
| }} // namespace {namespace} |
| """ |
| |
| template_map = """/* GENERATED FILE - DO NOT EDIT. |
| * Generated by {script_name} using data from {data_source_name}. |
| * |
| * Copyright 2021 The ANGLE Project Authors. All rights reserved. |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| * |
| * symbol version map: Maps versions to entry point names for a shared library. |
| */ |
| {symbol_maps} |
| """ |
| |
| includes_gles = """#include "libGLESv2/proc_table_egl.h" |
| |
| #include "libGLESv2/entry_points_egl_autogen.h" |
| #include "libGLESv2/entry_points_egl_ext_autogen.h" |
| #include "libGLESv2/entry_points_gles_1_0_autogen.h" |
| #include "libGLESv2/entry_points_gles_2_0_autogen.h" |
| #include "libGLESv2/entry_points_gles_3_0_autogen.h" |
| #include "libGLESv2/entry_points_gles_3_1_autogen.h" |
| #include "libGLESv2/entry_points_gles_3_2_autogen.h" |
| #include "libGLESv2/entry_points_gles_ext_autogen.h" |
| #include "platform/PlatformMethods.h" |
| """ |
| |
| includes_gl = """#include "libGL/proc_table_wgl.h" |
| |
| #include "libGL/entry_points_wgl.h" |
| #include "libGL/entry_points_gl_1_autogen.h" |
| #include "libGL/entry_points_gl_2_autogen.h" |
| #include "libGL/entry_points_gl_3_autogen.h" |
| #include "libGL/entry_points_gl_4_autogen.h" |
| #include "platform/PlatformMethods.h" |
| """ |
| |
| includes_cl = """#include "libGLESv2/proc_table_cl.h" |
| |
| #include "libGLESv2/entry_points_cl_autogen.h" |
| |
| #include "anglebase/no_destructor.h" |
| |
| // Using fully qualified entry point identifiers to make sure that missing entry points would not |
| // pick up the global declarations of OpenCL |
| """ |
| |
| sys.path.append('../src/libANGLE/renderer') |
| import angle_format |
| |
| |
| def _get_annotations(versions): |
| return ["%d_%d" % version for version in versions] |
| |
| |
| def main(): |
| |
| # auto_script parameters. |
| if len(sys.argv) > 1: |
| inputs = [source for source in registry_xml.xml_inputs] |
| outputs = [out_file_name_gles, out_file_name_gl, out_file_name_cl, out_file_name_cl_map] |
| if sys.argv[1] == 'inputs': |
| print(','.join(inputs)) |
| elif sys.argv[1] == 'outputs': |
| print(','.join(outputs)) |
| else: |
| print('Invalid script parameters') |
| return 1 |
| return 0 |
| |
| glesxml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml') |
| |
| for annotation in _get_annotations(registry_xml.GLES_VERSIONS): |
| name_prefix = "GL_ES_VERSION_" |
| if annotation[0] == '1': |
| name_prefix = "GL_VERSION_ES_CM_" |
| feature_name = "{}{}".format(name_prefix, annotation) |
| glesxml.AddCommands(feature_name, annotation) |
| |
| glesxml.AddExtensionCommands(registry_xml.supported_extensions, ['gles2', 'gles1']) |
| |
| # Also don't add GLES extension commands to libGL proc table |
| extension_commands = [] |
| for extension_name, ext_cmd_names in sorted(glesxml.ext_data.items()): |
| extension_commands.extend(glesxml.ext_data[extension_name]) |
| for name in extension_commands: |
| name_no_suffix = name |
| for suffix in strip_suffixes: |
| if name_no_suffix.endswith(suffix): |
| name_no_suffix = name_no_suffix[0:-len(suffix)] |
| |
| gles_data = glesxml.all_cmd_names.get_all_commands() |
| |
| eglxml = registry_xml.RegistryXML('egl.xml', 'egl_angle_ext.xml') |
| |
| for annotation in _get_annotations(registry_xml.EGL_VERSIONS): |
| name_prefix = "EGL_VERSION_" |
| feature_name = "{}{}".format(name_prefix, annotation) |
| eglxml.AddCommands(feature_name, annotation) |
| |
| eglxml.AddExtensionCommands(registry_xml.supported_egl_extensions, ['gles2', 'gles1']) |
| |
| gles_data.extend(eglxml.all_cmd_names.get_all_commands()) |
| |
| gles_data.append("ANGLEGetDisplayPlatform") |
| gles_data.append("ANGLEResetDisplayPlatform") |
| |
| all_functions = {} |
| |
| for function in gles_data: |
| if function.startswith("gl"): |
| all_functions[function] = "GL_" + function[2:] |
| elif function.startswith("egl"): |
| all_functions[function] = "EGL_" + function[3:] |
| else: |
| all_functions[function] = function |
| |
| proc_data = [(' {"%s", P(%s)}' % (func, angle_func)) |
| for func, angle_func in sorted(all_functions.items())] |
| |
| with open(out_file_name_gles, 'w') as out_file: |
| output_cpp = template_cpp.format( |
| script_name=sys.argv[0], |
| data_source_name="gl.xml, gl_angle_ext.xml, egl.xml, egl_angle_ext.xml", |
| includes=includes_gles, |
| cast="__eglMustCastToProperFunctionPointerType", |
| namespace="egl", |
| proc_data=",\n".join(proc_data), |
| num_procs=len(proc_data)) |
| out_file.write(output_cpp) |
| out_file.close() |
| |
| # libGL proc table |
| glxml = registry_xml.RegistryXML('gl.xml') |
| |
| for annotation in _get_annotations(registry_xml.DESKTOP_GL_VERSIONS): |
| name_prefix = "GL_VERSION_" |
| feature_name = "{}{}".format(name_prefix, annotation) |
| glxml.AddCommands(feature_name, annotation) |
| |
| gl_data = [cmd for cmd in glxml.all_cmd_names.get_all_commands()] |
| |
| wglxml = registry_xml.RegistryXML('wgl.xml') |
| |
| for annotation in _get_annotations(registry_xml.WGL_VERSIONS): |
| name_prefix = "WGL_VERSION_" |
| feature_name = "{}{}".format(name_prefix, annotation) |
| wglxml.AddCommands(feature_name, annotation) |
| |
| gl_commands = wglxml.all_cmd_names.get_all_commands() |
| gl_data.extend([cmd if cmd[:3] == 'wgl' else 'wgl' + cmd for cmd in gl_commands]) |
| |
| all_functions = {} |
| |
| for function in gl_data: |
| if function.startswith("gl"): |
| all_functions[function] = "GL_" + function[2:] |
| else: |
| all_functions[function] = function |
| |
| proc_data = [(' {"%s", P(%s)}' % (func, angle_func)) |
| for func, angle_func in sorted(all_functions.items())] |
| |
| with open(out_file_name_gl, 'w') as out_file: |
| output_cpp = template_cpp.format( |
| script_name=sys.argv[0], |
| data_source_name="gl.xml, wgl.xml", |
| includes=includes_gl, |
| cast="PROC", |
| namespace="wgl", |
| proc_data=",\n".join(proc_data), |
| num_procs=len(proc_data)) |
| out_file.write(output_cpp) |
| out_file.close() |
| |
| # libCL proc table |
| clxml = registry_xml.RegistryXML('cl.xml') |
| symbol_maps = [] |
| symbol_map_dependency = "" |
| |
| for major_version, minor_version in registry_xml.CL_VERSIONS: |
| name_prefix = "CL_VERSION_" |
| annotation = "%d_%d" % (major_version, minor_version) |
| feature_name = "%s%s" % (name_prefix, annotation) |
| clxml.AddCommands(feature_name, annotation) |
| symbol_version = "OPENCL_%d.%d" % (major_version, minor_version) |
| symbol_maps += ["\n%s {\n global:" % symbol_version] |
| symbol_maps += [' %s;' % cmd for cmd in clxml.commands[annotation]] |
| if not symbol_map_dependency: |
| symbol_maps += [" local:\n *;\n};"] |
| else: |
| symbol_maps += ["} %s;" % symbol_map_dependency] |
| symbol_map_dependency = symbol_version |
| |
| clxml.AddExtensionCommands(registry_xml.supported_cl_extensions, ['cl']) |
| cl_commands = clxml.all_cmd_names.get_all_commands() |
| proc_data = ['{"%s", P(::cl::%s)}' % (cmd, cmd) for cmd in cl_commands] |
| |
| with open(out_file_name_cl, 'w') as out_file: |
| output_cpp = template_map_cpp.format( |
| script_name=sys.argv[0], |
| data_source_name="cl.xml", |
| includes=includes_cl, |
| cast="void *", |
| namespace="cl", |
| proc_data=",\n ".join(proc_data)) |
| out_file.write(output_cpp) |
| out_file.close() |
| |
| with open(out_file_name_cl_map, 'w') as out_file: |
| output_map = template_map.format( |
| script_name=sys.argv[0], data_source_name="cl.xml", symbol_maps="\n".join(symbol_maps)) |
| out_file.write(output_map) |
| out_file.close() |
| |
| return 0 |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |