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 sys 11import registry_xml 12 13out_file_name_gles = "../src/libGLESv2/proc_table_egl_autogen.cpp" 14out_file_name_gl = "../src/libGL/proc_table_wgl_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{{ 36const ProcEntry g_procTable[] = {{ 37{proc_data} 38}}; 39 40const size_t g_numProcs = {num_procs}; 41}} // namespace {namespace} 42""" 43 44template_map_cpp = """// GENERATED FILE - DO NOT EDIT. 45// Generated by {script_name} using data from {data_source_name}. 46// 47// Copyright 2021 The ANGLE Project Authors. All rights reserved. 48// Use of this source code is governed by a BSD-style license that can be 49// found in the LICENSE file. 50// 51// proc_table: 52// Mapping from a string entry point name to function address. 53// 54 55{includes} 56#define P(FUNC) reinterpret_cast<{cast}>(FUNC) 57 58namespace {namespace} 59{{ 60 61const ProcTable &GetProcTable() 62{{ 63 static angle::base::NoDestructor<ProcTable> sProcTable( 64 {{{proc_data}}}); 65 return *sProcTable; 66}} 67 68}} // namespace {namespace} 69""" 70 71template_map = """/* GENERATED FILE - DO NOT EDIT. 72 * Generated by {script_name} using data from {data_source_name}. 73 * 74 * Copyright 2021 The ANGLE Project Authors. All rights reserved. 75 * Use of this source code is governed by a BSD-style license that can be 76 * found in the LICENSE file. 77 * 78 * symbol version map: Maps versions to entry point names for a shared library. 79 */ 80{symbol_maps} 81""" 82 83includes_gles = """#include "libGLESv2/proc_table_egl.h" 84 85#include "libGLESv2/entry_points_egl_autogen.h" 86#include "libGLESv2/entry_points_egl_ext_autogen.h" 87#include "libGLESv2/entry_points_gles_1_0_autogen.h" 88#include "libGLESv2/entry_points_gles_2_0_autogen.h" 89#include "libGLESv2/entry_points_gles_3_0_autogen.h" 90#include "libGLESv2/entry_points_gles_3_1_autogen.h" 91#include "libGLESv2/entry_points_gles_3_2_autogen.h" 92#include "libGLESv2/entry_points_gles_ext_autogen.h" 93#include "platform/PlatformMethods.h" 94""" 95 96includes_gl = """#include "libGL/proc_table_wgl.h" 97 98#include "libGL/entry_points_wgl.h" 99#include "libGL/entry_points_gl_1_autogen.h" 100#include "libGL/entry_points_gl_2_autogen.h" 101#include "libGL/entry_points_gl_3_autogen.h" 102#include "libGL/entry_points_gl_4_autogen.h" 103#include "platform/PlatformMethods.h" 104""" 105 106includes_cl = """#include "libGLESv2/proc_table_cl.h" 107 108#include "libGLESv2/entry_points_cl_autogen.h" 109 110#include "anglebase/no_destructor.h" 111 112// Using fully qualified entry point identifiers to make sure that missing entry points would not 113// pick up the global declarations of OpenCL 114""" 115 116sys.path.append('../src/libANGLE/renderer') 117import angle_format 118 119 120def _get_annotations(versions): 121 return ["%d_%d" % version for version in versions] 122 123 124def main(): 125 126 # auto_script parameters. 127 if len(sys.argv) > 1: 128 inputs = [source for source in registry_xml.xml_inputs] 129 outputs = [out_file_name_gles, out_file_name_gl, out_file_name_cl, out_file_name_cl_map] 130 if sys.argv[1] == 'inputs': 131 print(','.join(inputs)) 132 elif sys.argv[1] == 'outputs': 133 print(','.join(outputs)) 134 else: 135 print('Invalid script parameters') 136 return 1 137 return 0 138 139 glesxml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml') 140 141 for annotation in _get_annotations(registry_xml.GLES_VERSIONS): 142 name_prefix = "GL_ES_VERSION_" 143 if annotation[0] == '1': 144 name_prefix = "GL_VERSION_ES_CM_" 145 feature_name = "{}{}".format(name_prefix, annotation) 146 glesxml.AddCommands(feature_name, annotation) 147 148 glesxml.AddExtensionCommands(registry_xml.supported_extensions, ['gles2', 'gles1']) 149 150 # Also don't add GLES extension commands to libGL proc table 151 extension_commands = [] 152 for extension_name, ext_cmd_names in sorted(glesxml.ext_data.items()): 153 extension_commands.extend(glesxml.ext_data[extension_name]) 154 for name in extension_commands: 155 name_no_suffix = name 156 for suffix in strip_suffixes: 157 if name_no_suffix.endswith(suffix): 158 name_no_suffix = name_no_suffix[0:-len(suffix)] 159 160 gles_data = glesxml.all_cmd_names.get_all_commands() 161 162 eglxml = registry_xml.RegistryXML('egl.xml', 'egl_angle_ext.xml') 163 164 for annotation in _get_annotations(registry_xml.EGL_VERSIONS): 165 name_prefix = "EGL_VERSION_" 166 feature_name = "{}{}".format(name_prefix, annotation) 167 eglxml.AddCommands(feature_name, annotation) 168 169 eglxml.AddExtensionCommands(registry_xml.supported_egl_extensions, ['gles2', 'gles1']) 170 171 gles_data.extend(eglxml.all_cmd_names.get_all_commands()) 172 173 gles_data.append("ANGLEGetDisplayPlatform") 174 gles_data.append("ANGLEResetDisplayPlatform") 175 176 all_functions = {} 177 178 for function in gles_data: 179 if function.startswith("gl"): 180 all_functions[function] = "GL_" + function[2:] 181 elif function.startswith("egl"): 182 all_functions[function] = "EGL_" + function[3:] 183 else: 184 all_functions[function] = function 185 186 proc_data = [(' {"%s", P(%s)}' % (func, angle_func)) 187 for func, angle_func in sorted(all_functions.items())] 188 189 with open(out_file_name_gles, 'w') as out_file: 190 output_cpp = template_cpp.format( 191 script_name=sys.argv[0], 192 data_source_name="gl.xml, gl_angle_ext.xml, egl.xml, egl_angle_ext.xml", 193 includes=includes_gles, 194 cast="__eglMustCastToProperFunctionPointerType", 195 namespace="egl", 196 proc_data=",\n".join(proc_data), 197 num_procs=len(proc_data)) 198 out_file.write(output_cpp) 199 out_file.close() 200 201 # libGL proc table 202 glxml = registry_xml.RegistryXML('gl.xml') 203 204 for annotation in _get_annotations(registry_xml.DESKTOP_GL_VERSIONS): 205 name_prefix = "GL_VERSION_" 206 feature_name = "{}{}".format(name_prefix, annotation) 207 glxml.AddCommands(feature_name, annotation) 208 209 gl_data = [cmd for cmd in glxml.all_cmd_names.get_all_commands()] 210 211 wglxml = registry_xml.RegistryXML('wgl.xml') 212 213 for annotation in _get_annotations(registry_xml.WGL_VERSIONS): 214 name_prefix = "WGL_VERSION_" 215 feature_name = "{}{}".format(name_prefix, annotation) 216 wglxml.AddCommands(feature_name, annotation) 217 218 gl_commands = wglxml.all_cmd_names.get_all_commands() 219 gl_data.extend([cmd if cmd[:3] == 'wgl' else 'wgl' + cmd for cmd in gl_commands]) 220 221 all_functions = {} 222 223 for function in gl_data: 224 if function.startswith("gl"): 225 all_functions[function] = "GL_" + function[2:] 226 else: 227 all_functions[function] = function 228 229 proc_data = [(' {"%s", P(%s)}' % (func, angle_func)) 230 for func, angle_func in sorted(all_functions.items())] 231 232 with open(out_file_name_gl, 'w') as out_file: 233 output_cpp = template_cpp.format( 234 script_name=sys.argv[0], 235 data_source_name="gl.xml, wgl.xml", 236 includes=includes_gl, 237 cast="PROC", 238 namespace="wgl", 239 proc_data=",\n".join(proc_data), 240 num_procs=len(proc_data)) 241 out_file.write(output_cpp) 242 out_file.close() 243 244 # libCL proc table 245 clxml = registry_xml.RegistryXML('cl.xml') 246 symbol_maps = [] 247 symbol_map_dependency = "" 248 249 for major_version, minor_version in registry_xml.CL_VERSIONS: 250 name_prefix = "CL_VERSION_" 251 annotation = "%d_%d" % (major_version, minor_version) 252 feature_name = "%s%s" % (name_prefix, annotation) 253 clxml.AddCommands(feature_name, annotation) 254 symbol_version = "OPENCL_%d.%d" % (major_version, minor_version) 255 symbol_maps += ["\n%s {\n global:" % symbol_version] 256 symbol_maps += [' %s;' % cmd for cmd in clxml.commands[annotation]] 257 if not symbol_map_dependency: 258 symbol_maps += [" local:\n *;\n};"] 259 else: 260 symbol_maps += ["} %s;" % symbol_map_dependency] 261 symbol_map_dependency = symbol_version 262 263 clxml.AddExtensionCommands(registry_xml.supported_cl_extensions, ['cl']) 264 cl_commands = clxml.all_cmd_names.get_all_commands() 265 proc_data = ['{"%s", P(::cl::%s)}' % (cmd, cmd) for cmd in cl_commands] 266 267 with open(out_file_name_cl, 'w') as out_file: 268 output_cpp = template_map_cpp.format( 269 script_name=sys.argv[0], 270 data_source_name="cl.xml", 271 includes=includes_cl, 272 cast="void *", 273 namespace="cl", 274 proc_data=",\n ".join(proc_data)) 275 out_file.write(output_cpp) 276 out_file.close() 277 278 with open(out_file_name_cl_map, 'w') as out_file: 279 output_map = template_map.format( 280 script_name=sys.argv[0], data_source_name="cl.xml", symbol_maps="\n".join(symbol_maps)) 281 out_file.write(output_map) 282 out_file.close() 283 284 return 0 285 286 287if __name__ == '__main__': 288 sys.exit(main()) 289