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