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