diff --git a/scripts/generate_entry_points.py b/scripts/generate_entry_points.py index bbaa27517..db0da234b 100755 --- a/scripts/generate_entry_points.py +++ b/scripts/generate_entry_points.py @@ -6,26 +6,12 @@ # # generate_entry_points.py: # Generates the OpenGL bindings and entry point layers for ANGLE. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. import sys, os, pprint, json from datetime import date import registry_xml -# Handle inputs/outputs for run_code_generation.py's auto_script -if len(sys.argv) == 2 and sys.argv[1] == 'inputs': - - inputs = [ - 'egl.xml', - 'egl_angle_ext.xml', - 'entry_point_packed_gl_enums.json', - 'gl.xml', - 'gl_angle_ext.xml', - 'registry_xml.py', - ] - - print(",".join(inputs)) - sys.exit(0) - # List of GLES1 extensions for which we don't need to add Context.h decls. gles1_no_context_decl_extensions = [ "GL_OES_framebuffer_object", @@ -640,158 +626,6 @@ def get_exports(commands, fmt = None): else: return [" %s" % cmd for cmd in sorted(commands)] -gles1decls = {} - -gles1decls['core'] = [] -gles1decls['exts'] = {} - -libgles_ep_defs = [] -libgles_ep_exports = [] - -xml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml') - -# First run through the main GLES entry points. Since ES2+ is the primary use -# case, we go through those first and then add ES1-only APIs at the end. -for major_version, minor_version in [[2, 0], [3, 0], [3, 1], [1, 0]]: - annotation = "{}_{}".format(major_version, minor_version) - name_prefix = "GL_ES_VERSION_" - - is_gles1 = major_version == 1 - if is_gles1: - name_prefix = "GL_VERSION_ES_CM_" - - comment = annotation.replace("_", ".") - feature_name = "{}{}".format(name_prefix, annotation) - - xml.AddCommands(feature_name, annotation) - - gles_commands = xml.commands[annotation] - all_commands = xml.all_commands - - decls, defs, libgles_defs, validation_protos = get_entry_points( - all_commands, gles_commands, False) - - # Write the version as a comment before the first EP. - libgles_defs.insert(0, "\n// OpenGL ES %s" % comment) - libgles_ep_exports.append("\n ; OpenGL ES %s" % comment) - - libgles_ep_defs += libgles_defs - libgles_ep_exports += get_exports(gles_commands) - - major_if_not_one = major_version if major_version != 1 else "" - minor_if_not_zero = minor_version if minor_version != 0 else "" - - header_includes = template_header_includes.format( - major=major_if_not_one, minor=minor_if_not_zero) - - # We include the platform.h header since it undefines the conflicting MemoryBarrier macro. - if major_version == 3 and minor_version == 1: - header_includes += "\n#include \"common/platform.h\"\n" - - source_includes = template_sources_includes.format( - annotation.lower(), major_version, minor_if_not_zero) - - write_file(annotation, comment, template_entry_point_header, - "\n".join(decls), "h", header_includes, "gl.xml") - write_file(annotation, comment, template_entry_point_source, - "\n".join(defs), "cpp", source_includes, "gl.xml") - if is_gles1: - gles1decls['core'] = get_gles1_decls(all_commands, gles_commands) - - validation_annotation = "%s%s" % (major_version, minor_if_not_zero) - write_validation_header(validation_annotation, comment, validation_protos) - - -# After we finish with the main entry points, we process the extensions. -extension_defs = [] -extension_decls = [] - -# Accumulated validation prototypes. -ext_validation_protos = [] - -for gles1ext in registry_xml.gles1_extensions: - gles1decls['exts'][gles1ext] = [] - -xml.AddExtensionCommands(registry_xml.supported_extensions, ['gles2', 'gles1']) - -for extension_name, ext_cmd_names in sorted(xml.ext_data.iteritems()): - - # Detect and filter duplicate extensions. - decls, defs, libgles_defs, validation_protos = get_entry_points( - xml.all_commands, ext_cmd_names, False) - - # Avoid writing out entry points defined by a prior extension. - for dupe in xml.ext_dupes[extension_name]: - msg = "// {} is already defined.\n".format(dupe[2:]) - defs.append(msg) - - # Write the extension name as a comment before the first EP. - comment = "\n// {}".format(extension_name) - defs.insert(0, comment) - decls.insert(0, comment) - libgles_defs.insert(0, comment) - libgles_ep_exports.append("\n ; %s" % extension_name) - - extension_defs += defs - extension_decls += decls - - ext_validation_protos += [comment] + validation_protos - - libgles_ep_defs += libgles_defs - libgles_ep_exports += get_exports(ext_cmd_names) - - if extension_name in registry_xml.gles1_extensions: - if extension_name not in gles1_no_context_decl_extensions: - gles1decls['exts'][extension_name] = get_gles1_decls(all_commands, ext_cmd_names) - -# Special handling for EGL_ANGLE_explicit_context extension -if registry_xml.support_EGL_ANGLE_explicit_context: - comment = "\n// EGL_ANGLE_explicit_context" - extension_defs.append(comment) - extension_decls.append(comment) - libgles_ep_defs.append(comment) - - cmds = xml.all_cmd_names.get_all_commands() - - # Get the explicit context entry points - decls, defs, libgles_defs, validation_protos = get_entry_points( - xml.all_commands, cmds, True) - - # Append the explicit context entry points - extension_decls += decls - extension_defs += defs - libgles_ep_defs += libgles_defs - - libgles_ep_exports.append("\n ; EGL_ANGLE_explicit_context") - libgles_ep_exports += get_exports(cmds, lambda x: "%sContextANGLE" % x) - - # Generate .inc files for extension function pointers and declarations - for major, minor in [[2, 0], [3, 0], [3, 1], [1, 0]]: - annotation = "{}_{}".format(major, minor) - - major_if_not_one = major if major != 1 else "" - minor_if_not_zero = minor if minor != 0 else "" - version = "{}{}".format(major_if_not_one, minor_if_not_zero) - - glext_ptrs, glext_protos = get_glext_decls(all_commands, - xml.all_cmd_names.get_commands(annotation), version, True) - - glext_ext_ptrs = [] - glext_ext_protos = [] - - # Append extensions for 1.0 and 2.0 - if(annotation == "1_0"): - glext_ext_ptrs, glext_ext_protos = get_glext_decls(all_commands, - xml.all_cmd_names.get_commands("glext"), version, True) - elif(annotation == "2_0"): - glext_ext_ptrs, glext_ext_protos = get_glext_decls(all_commands, - xml.all_cmd_names.get_commands("gl2ext"), version, True) - - glext_ptrs += glext_ext_ptrs - glext_protos += glext_ext_protos - - write_glext_explicit_context_inc(version, "\n".join(glext_ptrs), "\n".join(glext_protos)) - # Get EGL exports def get_egl_exports(): @@ -828,62 +662,260 @@ def get_egl_exports(): return exports -header_includes = template_header_includes.format( - major="", minor="") -header_includes += """ -#include -#include -#include -#include -""" +def main(): -source_includes = template_sources_includes.format("ext", "EXT", "") -source_includes += """ -#include "libANGLE/validationES1.h" -#include "libANGLE/validationES2.h" -#include "libANGLE/validationES3.h" -#include "libANGLE/validationES31.h" -""" + # auto_script parameters. + if len(sys.argv) > 1: + inputs = [ + 'egl.xml', + 'egl_angle_ext.xml', + 'entry_point_packed_gl_enums.json', + 'gl.xml', + 'gl_angle_ext.xml', + 'registry_xml.py', + ] + outputs = [ + '../src/libANGLE/Context_gles_1_0_autogen.h', + '../src/libANGLE/validationES1_autogen.h', + '../src/libANGLE/validationES2_autogen.h', + '../src/libANGLE/validationES31_autogen.h', + '../src/libANGLE/validationES3_autogen.h', + '../src/libANGLE/validationESEXT_autogen.h', + '../src/libGLESv2/entry_points_enum_autogen.h', + '../src/libGLESv2/entry_points_gles_1_0_autogen.cpp', + '../src/libGLESv2/entry_points_gles_1_0_autogen.h', + '../src/libGLESv2/entry_points_gles_2_0_autogen.cpp', + '../src/libGLESv2/entry_points_gles_2_0_autogen.h', + '../src/libGLESv2/entry_points_gles_3_0_autogen.cpp', + '../src/libGLESv2/entry_points_gles_3_0_autogen.h', + '../src/libGLESv2/entry_points_gles_3_1_autogen.cpp', + '../src/libGLESv2/entry_points_gles_3_1_autogen.h', + '../src/libGLESv2/entry_points_gles_ext_autogen.cpp', + '../src/libGLESv2/entry_points_gles_ext_autogen.h', + '../src/libGLESv2/libGLESv2_autogen.cpp', + '../src/libGLESv2/libGLESv2_autogen.def', + ] -write_file("ext", "extension", template_entry_point_header, - "\n".join([item for item in extension_decls]), "h", header_includes, - "gl.xml and gl_angle_ext.xml") -write_file("ext", "extension", template_entry_point_source, - "\n".join([item for item in extension_defs]), "cpp", source_includes, - "gl.xml and gl_angle_ext.xml") + 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 -write_validation_header("EXT", "extension", ext_validation_protos) + gles1decls = {} -write_context_api_decls("1_0", context_gles_header, gles1decls) + gles1decls['core'] = [] + gles1decls['exts'] = {} -sorted_cmd_names = ["Invalid"] + [cmd[2:] for cmd in sorted(xml.all_cmd_names.get_all_commands())] + libgles_ep_defs = [] + libgles_ep_exports = [] -entry_points_enum = template_entry_points_enum_header.format( - script_name = os.path.basename(sys.argv[0]), - data_source_name = "gl.xml and gl_angle_ext.xml", - year = date.today().year, - entry_points_list = ",\n".join([" " + cmd for cmd in sorted_cmd_names])) + xml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml') -entry_points_enum_header_path = path_to("libGLESv2", "entry_points_enum_autogen.h") -with open(entry_points_enum_header_path, "w") as out: - out.write(entry_points_enum) - out.close() + # First run through the main GLES entry points. Since ES2+ is the primary use + # case, we go through those first and then add ES1-only APIs at the end. + for major_version, minor_version in [[2, 0], [3, 0], [3, 1], [1, 0]]: + annotation = "{}_{}".format(major_version, minor_version) + name_prefix = "GL_ES_VERSION_" -source_includes = """ -#include "angle_gl.h" + is_gles1 = major_version == 1 + if is_gles1: + name_prefix = "GL_VERSION_ES_CM_" -#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_ext_autogen.h" + comment = annotation.replace("_", ".") + feature_name = "{}{}".format(name_prefix, annotation) -#include "common/event_tracer.h" -""" + xml.AddCommands(feature_name, annotation) -write_export_files("\n".join([item for item in libgles_ep_defs]), source_includes) + gles_commands = xml.commands[annotation] + all_commands = xml.all_commands -libgles_ep_exports += get_egl_exports() + decls, defs, libgles_defs, validation_protos = get_entry_points( + all_commands, gles_commands, False) -everything = "Khronos and ANGLE XML files" -write_windows_def_file(everything, "libGLESv2", libgles_ep_exports) + # Write the version as a comment before the first EP. + libgles_defs.insert(0, "\n// OpenGL ES %s" % comment) + libgles_ep_exports.append("\n ; OpenGL ES %s" % comment) + + libgles_ep_defs += libgles_defs + libgles_ep_exports += get_exports(gles_commands) + + major_if_not_one = major_version if major_version != 1 else "" + minor_if_not_zero = minor_version if minor_version != 0 else "" + + header_includes = template_header_includes.format( + major=major_if_not_one, minor=minor_if_not_zero) + + # We include the platform.h header since it undefines the conflicting MemoryBarrier macro. + if major_version == 3 and minor_version == 1: + header_includes += "\n#include \"common/platform.h\"\n" + + source_includes = template_sources_includes.format( + annotation.lower(), major_version, minor_if_not_zero) + + write_file(annotation, comment, template_entry_point_header, + "\n".join(decls), "h", header_includes, "gl.xml") + write_file(annotation, comment, template_entry_point_source, + "\n".join(defs), "cpp", source_includes, "gl.xml") + if is_gles1: + gles1decls['core'] = get_gles1_decls(all_commands, gles_commands) + + validation_annotation = "%s%s" % (major_version, minor_if_not_zero) + write_validation_header(validation_annotation, comment, validation_protos) + + + # After we finish with the main entry points, we process the extensions. + extension_defs = [] + extension_decls = [] + + # Accumulated validation prototypes. + ext_validation_protos = [] + + for gles1ext in registry_xml.gles1_extensions: + gles1decls['exts'][gles1ext] = [] + + xml.AddExtensionCommands(registry_xml.supported_extensions, ['gles2', 'gles1']) + + for extension_name, ext_cmd_names in sorted(xml.ext_data.iteritems()): + + # Detect and filter duplicate extensions. + decls, defs, libgles_defs, validation_protos = get_entry_points( + xml.all_commands, ext_cmd_names, False) + + # Avoid writing out entry points defined by a prior extension. + for dupe in xml.ext_dupes[extension_name]: + msg = "// {} is already defined.\n".format(dupe[2:]) + defs.append(msg) + + # Write the extension name as a comment before the first EP. + comment = "\n// {}".format(extension_name) + defs.insert(0, comment) + decls.insert(0, comment) + libgles_defs.insert(0, comment) + libgles_ep_exports.append("\n ; %s" % extension_name) + + extension_defs += defs + extension_decls += decls + + ext_validation_protos += [comment] + validation_protos + + libgles_ep_defs += libgles_defs + libgles_ep_exports += get_exports(ext_cmd_names) + + if extension_name in registry_xml.gles1_extensions: + if extension_name not in gles1_no_context_decl_extensions: + gles1decls['exts'][extension_name] = get_gles1_decls(all_commands, ext_cmd_names) + + # Special handling for EGL_ANGLE_explicit_context extension + if registry_xml.support_EGL_ANGLE_explicit_context: + comment = "\n// EGL_ANGLE_explicit_context" + extension_defs.append(comment) + extension_decls.append(comment) + libgles_ep_defs.append(comment) + + cmds = xml.all_cmd_names.get_all_commands() + + # Get the explicit context entry points + decls, defs, libgles_defs, validation_protos = get_entry_points( + xml.all_commands, cmds, True) + + # Append the explicit context entry points + extension_decls += decls + extension_defs += defs + libgles_ep_defs += libgles_defs + + libgles_ep_exports.append("\n ; EGL_ANGLE_explicit_context") + libgles_ep_exports += get_exports(cmds, lambda x: "%sContextANGLE" % x) + + # Generate .inc files for extension function pointers and declarations + for major, minor in [[2, 0], [3, 0], [3, 1], [1, 0]]: + annotation = "{}_{}".format(major, minor) + + major_if_not_one = major if major != 1 else "" + minor_if_not_zero = minor if minor != 0 else "" + version = "{}{}".format(major_if_not_one, minor_if_not_zero) + + glext_ptrs, glext_protos = get_glext_decls(all_commands, + xml.all_cmd_names.get_commands(annotation), version, True) + + glext_ext_ptrs = [] + glext_ext_protos = [] + + # Append extensions for 1.0 and 2.0 + if(annotation == "1_0"): + glext_ext_ptrs, glext_ext_protos = get_glext_decls(all_commands, + xml.all_cmd_names.get_commands("glext"), version, True) + elif(annotation == "2_0"): + glext_ext_ptrs, glext_ext_protos = get_glext_decls(all_commands, + xml.all_cmd_names.get_commands("gl2ext"), version, True) + + glext_ptrs += glext_ext_ptrs + glext_protos += glext_ext_protos + + write_glext_explicit_context_inc(version, "\n".join(glext_ptrs), "\n".join(glext_protos)) + + + header_includes = template_header_includes.format( + major="", minor="") + header_includes += """ + #include + #include + #include + """ + + source_includes = template_sources_includes.format("ext", "EXT", "") + source_includes += """ + #include "libANGLE/validationES1.h" + #include "libANGLE/validationES2.h" + #include "libANGLE/validationES3.h" + #include "libANGLE/validationES31.h" + """ + + write_file("ext", "extension", template_entry_point_header, + "\n".join([item for item in extension_decls]), "h", header_includes, + "gl.xml and gl_angle_ext.xml") + write_file("ext", "extension", template_entry_point_source, + "\n".join([item for item in extension_defs]), "cpp", source_includes, + "gl.xml and gl_angle_ext.xml") + + write_validation_header("EXT", "extension", ext_validation_protos) + + write_context_api_decls("1_0", context_gles_header, gles1decls) + + sorted_cmd_names = ["Invalid"] + [cmd[2:] for cmd in sorted(xml.all_cmd_names.get_all_commands())] + + entry_points_enum = template_entry_points_enum_header.format( + script_name = os.path.basename(sys.argv[0]), + data_source_name = "gl.xml and gl_angle_ext.xml", + year = date.today().year, + entry_points_list = ",\n".join([" " + cmd for cmd in sorted_cmd_names])) + + entry_points_enum_header_path = path_to("libGLESv2", "entry_points_enum_autogen.h") + with open(entry_points_enum_header_path, "w") as out: + out.write(entry_points_enum) + out.close() + + source_includes = """ + #include "angle_gl.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_ext_autogen.h" + + #include "common/event_tracer.h" + """ + + write_export_files("\n".join([item for item in libgles_ep_defs]), source_includes) + + libgles_ep_exports += get_egl_exports() + + everything = "Khronos and ANGLE XML files" + write_windows_def_file(everything, "libGLESv2", libgles_ep_exports) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/scripts/generate_loader.py b/scripts/generate_loader.py index de14bebac..a408dac4e 100755 --- a/scripts/generate_loader.py +++ b/scripts/generate_loader.py @@ -6,24 +6,12 @@ # # generate_loader.py: # Generates dynamic loaders for various binding interfaces. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. import sys, os, pprint, json from datetime import date import registry_xml -# Handle inputs/outputs for run_code_generation.py's auto_script -if len(sys.argv) == 2 and sys.argv[1] == 'inputs': - - inputs = [ - 'egl.xml', - 'egl_angle_ext.xml', - 'registry_xml.py', - 'wgl.xml', - ] - - print(",".join(inputs)) - sys.exit(0) - def write_header(data_source_name, all_cmds, api, preamble, path, lib, ns = "", prefix = None, export = ""): file_name = "%s_loader_autogen.h" % api header_path = registry_xml.path_to(path, file_name) @@ -175,10 +163,40 @@ def gen_wgl_loader(): write_source(source, all_cmds, "wgl", path, "_") def main(): + + # Handle inputs/outputs for run_code_generation.py's auto_script + if len(sys.argv) > 1: + inputs = [ + 'egl.xml', + 'egl_angle_ext.xml', + 'registry_xml.py', + 'wgl.xml', + ] + outputs = [ + '../src/libEGL/egl_loader_autogen.cpp', + '../src/libEGL/egl_loader_autogen.h', + '../util/egl_loader_autogen.cpp', + '../util/egl_loader_autogen.h', + '../util/gles_loader_autogen.cpp', + '../util/gles_loader_autogen.h', + '../util/windows/wgl_loader_autogen.cpp', + '../util/windows/wgl_loader_autogen.h', + ] + + 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 + gen_libegl_loader() gen_gl_loader() gen_egl_loader() gen_wgl_loader() + return 0 libegl_preamble = """#include diff --git a/scripts/run_code_generation.py b/scripts/run_code_generation.py index 0f65a4ce9..ecf6596ef 100755 --- a/scripts/run_code_generation.py +++ b/scripts/run_code_generation.py @@ -28,138 +28,65 @@ def clean_path_slashes(path): # Takes a script input file name which is relative to the code generation script's directory and # changes it to be relative to the angle root directory -def rebase_script_input_path(script_path, input_file_path): - return os.path.relpath(os.path.join(os.path.dirname(script_path), input_file_path), root_dir); +def rebase_script_path(script_path, input_file_path): + return os.path.relpath(os.path.join(os.path.dirname(script_path), input_file_path), root_dir) def grab_from_script(script, param): res = subprocess.check_output(['python', script, param]).strip() - return [clean_path_slashes(rebase_script_input_path(script, name)) for name in res.split(',')] + if res == '': + return [] + return [clean_path_slashes(rebase_script_path(script, name)) for name in res.split(',')] def auto_script(script): # Set the CWD to the script directory. os.chdir(get_child_script_dirname(script)) base_script = os.path.basename(script) return { - 'script': script, 'inputs': grab_from_script(base_script, 'inputs'), + 'outputs': grab_from_script(base_script, 'outputs') } hash_fname = "run_code_generation_hashes.json" -# TODO(jmadill): Convert everyting to auto-script. generators = { - 'ANGLE format': { - 'inputs': [ - 'src/libANGLE/renderer/angle_format.py', - 'src/libANGLE/renderer/angle_format_data.json', - 'src/libANGLE/renderer/angle_format_map.json', - ], - 'script': 'src/libANGLE/renderer/gen_angle_format_table.py', - }, - 'ANGLE load functions table': { - 'inputs': [ - 'src/libANGLE/renderer/load_functions_data.json', - ], - 'script': 'src/libANGLE/renderer/gen_load_functions_table.py', - }, - 'D3D11 blit shader selection': { - 'inputs': [], - 'script': 'src/libANGLE/renderer/d3d/d3d11/gen_blit11helper.py', - }, - 'D3D11 format': { - 'inputs': [ - 'src/libANGLE/renderer/angle_format.py', - 'src/libANGLE/renderer/d3d/d3d11/texture_format_data.json', - 'src/libANGLE/renderer/d3d/d3d11/texture_format_map.json', - ], - 'script': 'src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py', - }, - 'DXGI format': { - 'inputs': [ - 'src/libANGLE/renderer/angle_format.py', - 'src/libANGLE/renderer/angle_format_map.json', - 'src/libANGLE/renderer/d3d/d3d11/dxgi_format_data.json', - 'src/libANGLE/renderer/gen_angle_format_table.py', - ], - 'script': 'src/libANGLE/renderer/d3d/d3d11/gen_dxgi_format_table.py', - }, - 'DXGI format support': { - 'inputs': [ - 'src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json', - ], - 'script': 'src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py', - }, + 'ANGLE format': + 'src/libANGLE/renderer/gen_angle_format_table.py', + 'ANGLE load functions table': + 'src/libANGLE/renderer/gen_load_functions_table.py', + 'D3D11 blit shader selection': + 'src/libANGLE/renderer/d3d/d3d11/gen_blit11helper.py', + 'D3D11 format': + 'src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py', + 'DXGI format': + 'src/libANGLE/renderer/d3d/d3d11/gen_dxgi_format_table.py', + 'DXGI format support': + 'src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py', + 'GL copy conversion table': + 'src/libANGLE/gen_copy_conversion_table.py', 'GL/EGL/WGL loader': - auto_script('scripts/generate_loader.py'), + 'scripts/generate_loader.py', 'GL/EGL entry points': - auto_script('scripts/generate_entry_points.py'), - 'GL copy conversion table': { - 'inputs': [ - 'src/libANGLE/es3_copy_conversion_formats.json', - ], - 'script': 'src/libANGLE/gen_copy_conversion_table.py', - }, - 'GL format map': { - 'inputs': [ - 'src/libANGLE/es3_format_type_combinations.json', - 'src/libANGLE/format_map_data.json', - ], - 'script': 'src/libANGLE/gen_format_map.py', - }, - 'uniform type': { - 'inputs': [], - 'script': 'src/common/gen_uniform_type_table.py', - }, - 'OpenGL dispatch table': { - 'inputs': [ - 'scripts/gl.xml', - ], - 'script': 'src/libANGLE/renderer/gl/generate_gl_dispatch_table.py', - }, - 'packed enum': { - 'inputs': [ - 'src/common/packed_gl_enums.json', - 'src/common/packed_egl_enums.json', - ], - 'script': 'src/common/gen_packed_gl_enums.py', - }, - 'proc table': { - 'inputs': [ - 'src/libGLESv2/proc_table_data.json', - ], - 'script': 'src/libGLESv2/gen_proc_table.py', - }, - 'Vulkan format': { - 'inputs': [ - 'src/libANGLE/renderer/angle_format.py', - 'src/libANGLE/renderer/angle_format_map.json', - 'src/libANGLE/renderer/vulkan/vk_format_map.json', - ], - 'script': 'src/libANGLE/renderer/vulkan/gen_vk_format_table.py', - }, - 'Vulkan mandatory format support table': { - 'inputs': [ - 'src/libANGLE/renderer/angle_format.py', - 'third_party/vulkan-headers/src/registry/vk.xml', - 'src/libANGLE/renderer/vulkan/vk_mandatory_format_support_data.json', - ], - 'script': 'src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py', - }, + 'scripts/generate_entry_points.py', + 'GL format map': + 'src/libANGLE/gen_format_map.py', + 'uniform type': + 'src/common/gen_uniform_type_table.py', + 'OpenGL dispatch table': + 'src/libANGLE/renderer/gl/generate_gl_dispatch_table.py', + 'packed enum': + 'src/common/gen_packed_gl_enums.py', + 'proc table': + 'src/libGLESv2/gen_proc_table.py', + 'Vulkan format': + 'src/libANGLE/renderer/vulkan/gen_vk_format_table.py', + 'Vulkan mandatory format support table': + 'src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py', 'Vulkan internal shader programs': - auto_script('src/libANGLE/renderer/vulkan/gen_vk_internal_shaders.py'), - 'Emulated HLSL functions': { - 'inputs': [ - 'src/compiler/translator/emulated_builtin_function_data_hlsl.json' - ], - 'script': 'src/compiler/translator/gen_emulated_builtin_function_tables.py' - }, - 'ESSL static builtins': { - 'inputs': [ - 'src/compiler/translator/builtin_function_declarations.txt', - 'src/compiler/translator/builtin_variables.json', - ], - 'script': 'src/compiler/translator/gen_builtin_symbols.py', - }, + 'src/libANGLE/renderer/vulkan/gen_vk_internal_shaders.py', + 'Emulated HLSL functions': + 'src/compiler/translator/gen_emulated_builtin_function_tables.py', + 'ESSL static builtins': + 'src/compiler/translator/gen_builtin_symbols.py', } @@ -198,11 +125,12 @@ def main(): if len(sys.argv) > 1 and sys.argv[1] == '--verify-no-dirty': verify_only = True - for name, info in sorted(generators.iteritems()): + for name, script in sorted(generators.iteritems()): + + info = auto_script(script) # Reset the CWD to the root ANGLE directory. os.chdir(root_dir) - script = info['script'] if any_input_dirty(name, info['inputs'] + [script], new_hashes, old_hashes): any_dirty = True diff --git a/scripts/run_code_generation_hashes.json b/scripts/run_code_generation_hashes.json index ed63b87e3..8e0f46771 100644 --- a/scripts/run_code_generation_hashes.json +++ b/scripts/run_code_generation_hashes.json @@ -6,17 +6,17 @@ "ANGLE format:src/libANGLE/renderer/angle_format_map.json": "be9f9bdbdf785dda05920146e8c55dbb", "ANGLE format:src/libANGLE/renderer/gen_angle_format_table.py": - "00d5b2293e79d71e8d4212d1190a6426", + "3d9f679b65f39ccf19bd7bdf5498f837", "ANGLE load functions table:src/libANGLE/renderer/gen_load_functions_table.py": - "8afc7eecce2a3ba9f0b4beacb1aa7fe2", + "475de30b8552795ca928096543cec7f2", "ANGLE load functions table:src/libANGLE/renderer/load_functions_data.json": "4253e14cd3217f42b6fec75ee400655a", "D3D11 blit shader selection:src/libANGLE/renderer/d3d/d3d11/gen_blit11helper.py": - "fa59a0edd32890a018a7247e0484426c", + "38bff72bc17ac25c6b42c98d40c76e20", "D3D11 format:src/libANGLE/renderer/angle_format.py": "b18ca0fe4835114a4a2f54977b19e798", "D3D11 format:src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py": - "15fb2a9b3f81e39a22090bce2f071185", + "d3260e0390ad2cd8b07420b7426fad43", "D3D11 format:src/libANGLE/renderer/d3d/d3d11/texture_format_data.json": "d7483ece817e819588f4ca157716dc7b", "D3D11 format:src/libANGLE/renderer/d3d/d3d11/texture_format_map.json": @@ -24,7 +24,7 @@ "DXGI format support:src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json": "09195053f8829fc81efe08229b54a8b5", "DXGI format support:src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py": - "30158f76e168e014a1bee3925cd5910a", + "389a6358534ebad5e232a44944b6123b", "DXGI format:src/libANGLE/renderer/angle_format.py": "b18ca0fe4835114a4a2f54977b19e798", "DXGI format:src/libANGLE/renderer/angle_format_map.json": @@ -32,29 +32,27 @@ "DXGI format:src/libANGLE/renderer/d3d/d3d11/dxgi_format_data.json": "24f525b05dc665fbbc8c6d68fb863719", "DXGI format:src/libANGLE/renderer/d3d/d3d11/gen_dxgi_format_table.py": - "8ea01df6cb7f160772d3c85dd5164890", - "DXGI format:src/libANGLE/renderer/gen_angle_format_table.py": - "00d5b2293e79d71e8d4212d1190a6426", + "bed2688ca828fc9fd1904408d33ba007", "ESSL static builtins:src/compiler/translator/builtin_function_declarations.txt": "e5e567406476306ea06984d885be028d", "ESSL static builtins:src/compiler/translator/builtin_variables.json": "d07ec4348b35d0db1eeab3c99a5e91f9", "ESSL static builtins:src/compiler/translator/gen_builtin_symbols.py": - "932aafd053b3a64affdc7ad31d0a3c42", + "f056dba2fdeac5a5dbad9d8f7b17f55f", "Emulated HLSL functions:src/compiler/translator/emulated_builtin_function_data_hlsl.json": "002ad46d144c51fe98d73478aa554ba7", "Emulated HLSL functions:src/compiler/translator/gen_emulated_builtin_function_tables.py": - "6a00c1ba22c35a9b700a154efda6f861", + "c24de0c9ce5f201985c852d2b4b12b98", "GL copy conversion table:src/libANGLE/es3_copy_conversion_formats.json": "54608f6f7d9aa7c59a8458ccf3ab9935", "GL copy conversion table:src/libANGLE/gen_copy_conversion_table.py": - "ac1afe23d9578bd1d2ef74f4a7aa927a", + "92428cef9d97d33ee7063cfa387ccf56", "GL format map:src/libANGLE/es3_format_type_combinations.json": "a232823cd6430f14e28793ccabb968ee", "GL format map:src/libANGLE/format_map_data.json": "779798d4879e5f73a5a108e3e3fd3095", "GL format map:src/libANGLE/gen_format_map.py": - "a383ee79a7bf929d145165f3e76c1079", + "0fd8c00e8b5afb28a5f8b40d9628b9a4", "GL/EGL entry points:scripts/egl.xml": "842e24514c4cfe09fba703c17a0fd292", "GL/EGL entry points:scripts/egl_angle_ext.xml": @@ -62,7 +60,7 @@ "GL/EGL entry points:scripts/entry_point_packed_gl_enums.json": "afe2284956be2360463d0d036ad9cdde", "GL/EGL entry points:scripts/generate_entry_points.py": - "a959669b31f086510fb60c5b55de56d1", + "7bd73a78c638334a114ed027d49cb6df", "GL/EGL entry points:scripts/gl.xml": "b470cb06b06cbbe7adb2c8129ec85708", "GL/EGL entry points:scripts/gl_angle_ext.xml": @@ -74,25 +72,29 @@ "GL/EGL/WGL loader:scripts/egl_angle_ext.xml": "745534010f31fbe8e1a1fcddce15ed2d", "GL/EGL/WGL loader:scripts/generate_loader.py": - "2d9be1d0f4f54905f3372411522133d1", + "475030714c1644b6dfb1f6f08572039d", "GL/EGL/WGL loader:scripts/registry_xml.py": "be6628bdeb99e50868cf4af51ea63f54", "GL/EGL/WGL loader:scripts/wgl.xml": "aa96419c582af2f6673430e2847693f4", "OpenGL dispatch table:scripts/gl.xml": "b470cb06b06cbbe7adb2c8129ec85708", + "OpenGL dispatch table:src/libANGLE/renderer/angle_format.py": + "b18ca0fe4835114a4a2f54977b19e798", "OpenGL dispatch table:src/libANGLE/renderer/gl/generate_gl_dispatch_table.py": - "f527232452ecf930cfb1276883581342", + "8365d4130b9814eaa396915ae85734eb", + "OpenGL dispatch table:src/libANGLE/renderer/gl/gl_bindings_data.json": + "71079f089335ce1f67835d67a6d49d1a", "Vulkan format:src/libANGLE/renderer/angle_format.py": "b18ca0fe4835114a4a2f54977b19e798", "Vulkan format:src/libANGLE/renderer/angle_format_map.json": "be9f9bdbdf785dda05920146e8c55dbb", "Vulkan format:src/libANGLE/renderer/vulkan/gen_vk_format_table.py": - "61a7752424595e24edff0c1f1784e18e", + "9937d3c942f0a5fe08f1ca080d40d47e", "Vulkan format:src/libANGLE/renderer/vulkan/vk_format_map.json": "992749b88763adb66003fe5d801b5ded", "Vulkan internal shader programs:src/libANGLE/renderer/vulkan/gen_vk_internal_shaders.py": - "1c64f7187357d7561c984ec57d251e74", + "97e148951cbbf009ab963ca5a90ddf1a", "Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/BufferUtils.comp": "0c8c050841543da0d7faca2559212aa8", "Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/ConvertVertex.comp": @@ -106,21 +108,21 @@ "Vulkan mandatory format support table:src/libANGLE/renderer/angle_format.py": "b18ca0fe4835114a4a2f54977b19e798", "Vulkan mandatory format support table:src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py": - "d647fcb39acb9a18e08e3e604b19cfee", + "417772416d3082400ce05acc2f209c9f", "Vulkan mandatory format support table:src/libANGLE/renderer/vulkan/vk_mandatory_format_support_data.json": "fa2bd54c1bb0ab2cf1d386061a4bc5c5", "Vulkan mandatory format support table:third_party/vulkan-headers/src/registry/vk.xml": "f5c8c9b8e521644ded34d44b1016c25e", "packed enum:src/common/gen_packed_gl_enums.py": - "a9b1c38b4e4d8a1038e743be323f1a51", + "0cd1a1cb6d5fde8cbac2994db24eb901", "packed enum:src/common/packed_egl_enums.json": "5f591d220ee53b6e54a27d1523a3ab79", "packed enum:src/common/packed_gl_enums.json": "6e2e2845f96754509b8add1f77e203b3", "proc table:src/libGLESv2/gen_proc_table.py": - "ee265eada3dd238646010dd03874d242", + "20ebe54894d613de42b0b15ca34078d9", "proc table:src/libGLESv2/proc_table_data.json": "6deb74c7709ecb664b917a2f1e598399", "uniform type:src/common/gen_uniform_type_table.py": - "e185802e66950dfc5fc7a8fc19751206" + "fa40444d496ac07cd9dc0cd239e4a499" } \ No newline at end of file diff --git a/src/common/gen_packed_gl_enums.py b/src/common/gen_packed_gl_enums.py index e6bf599b6..2f77e7256 100644 --- a/src/common/gen_packed_gl_enums.py +++ b/src/common/gen_packed_gl_enums.py @@ -3,7 +3,8 @@ # found in the LICENSE file. # # gen_packed_gl_enums.py: -# Code generation for the packed enums. +# Code generation for the packed enums. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. import datetime, json, os, sys from collections import namedtuple @@ -204,7 +205,29 @@ def write_cpp(enums, path_prefix, file_name, data_source_name, namespace, api_en with (open(path_prefix + file_name, 'wt')) as f: f.write(cpp) -if __name__ == '__main__': + +def main(): + + # auto_script parameters. + if len(sys.argv) > 1: + inputs = [] + outputs = [] + for generator in Generators: + inputs += [generator['json']] + outputs += [ + generator['output'] + '_autogen.cpp', + generator['output'] + '_autogen.h', + ] + + 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 + path_prefix = os.path.dirname(os.path.realpath(__file__)) + os.path.sep for generator in Generators: @@ -215,3 +238,8 @@ if __name__ == '__main__': enums = load_enums(path_prefix + json_file) write_header(enums, path_prefix, output_file + '_autogen.h', json_file, namespace, enum_type) write_cpp(enums, path_prefix, output_file + '_autogen.cpp', json_file, namespace, enum_type) + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/common/gen_uniform_type_table.py b/src/common/gen_uniform_type_table.py index 0e36c528a..21891a8e3 100644 --- a/src/common/gen_uniform_type_table.py +++ b/src/common/gen_uniform_type_table.py @@ -5,6 +5,7 @@ # # gen_uniform_type_table.py: # Code generation for OpenGL uniform type info tables. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. from datetime import date @@ -265,15 +266,37 @@ def gen_type_info(uniform_type): def gen_type_index_case(index, uniform_type): return "case " + uniform_type + ": return " + str(index) + ";" -uniform_type_info_data = ",\n".join([gen_type_info(uniform_type) for uniform_type in all_uniform_types]) -uniform_type_index_cases = "\n".join([gen_type_index_case(index, uniform_type) for index, uniform_type in enumerate(all_uniform_types)]) -with open('uniform_type_info_autogen.cpp', 'wt') as out_file: - output_cpp = template_cpp.format( - script_name = sys.argv[0], - copyright_year = date.today().year, - total_count = len(all_uniform_types), - uniform_type_info_data = uniform_type_info_data, - uniform_type_index_cases = uniform_type_index_cases) - out_file.write(output_cpp) - out_file.close() +def main(): + + # auto_script parameters. + if len(sys.argv) > 1: + inputs = [] + outputs = ['uniform_type_info_autogen.cpp'] + + 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 + + uniform_type_info_data = ",\n".join([gen_type_info(uniform_type) for uniform_type in all_uniform_types]) + uniform_type_index_cases = "\n".join([gen_type_index_case(index, uniform_type) for index, uniform_type in enumerate(all_uniform_types)]) + + with open('uniform_type_info_autogen.cpp', 'wt') as out_file: + output_cpp = template_cpp.format( + script_name = sys.argv[0], + copyright_year = date.today().year, + total_count = len(all_uniform_types), + uniform_type_info_data = uniform_type_info_data, + uniform_type_index_cases = uniform_type_index_cases) + out_file.write(output_cpp) + out_file.close() + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/common/uniform_type_info_autogen.cpp b/src/common/uniform_type_info_autogen.cpp index 97d6f068d..1de2146dc 100644 --- a/src/common/uniform_type_info_autogen.cpp +++ b/src/common/uniform_type_info_autogen.cpp @@ -1,7 +1,7 @@ // GENERATED FILE - DO NOT EDIT. // Generated by gen_uniform_type_table.py. // -// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// 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. // diff --git a/src/compiler/translator/builtin_symbols_hash_autogen.txt b/src/compiler/translator/builtin_symbols_hash_autogen.txt index 50754b56c..6d8e87abd 100644 --- a/src/compiler/translator/builtin_symbols_hash_autogen.txt +++ b/src/compiler/translator/builtin_symbols_hash_autogen.txt @@ -1 +1 @@ -c0555364e16391744b56e1f5d9c614c0 \ No newline at end of file +0df8efe673974da147a740d6e084e0b5 \ No newline at end of file diff --git a/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp b/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp index 2fccf55d1..c61e77a11 100644 --- a/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp +++ b/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp @@ -2,7 +2,7 @@ // Generated by gen_emulated_builtin_function_tables.py using data from // emulated_builtin_function_data_hlsl.json. // -// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// 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. // diff --git a/src/compiler/translator/gen_builtin_symbols.py b/src/compiler/translator/gen_builtin_symbols.py index e5193914f..ff14b0a73 100644 --- a/src/compiler/translator/gen_builtin_symbols.py +++ b/src/compiler/translator/gen_builtin_symbols.py @@ -15,34 +15,6 @@ import re import os import sys -def set_working_dir(): - script_dir = os.path.dirname(os.path.abspath(__file__)) - os.chdir(script_dir) - -set_working_dir() - -variables_json_filename = 'builtin_variables.json' -functions_txt_filename = 'builtin_function_declarations.txt' -hash_filename = 'builtin_symbols_hash_autogen.txt' - -all_inputs = [os.path.abspath(__file__), variables_json_filename, functions_txt_filename] -# This script takes a while to run since it searches for hash collisions of mangled names. To avoid -# running it unnecessarily, we first check if we've already ran it with the same inputs. -m = hashlib.md5() -for input_path in all_inputs: - with open(input_path, 'rU') as input_file: - m.update(input_file.read()) -input_hash = m.hexdigest() -if os.path.exists(hash_filename): - with open(hash_filename) as hash_file: - if input_hash == hash_file.read(): - print "Canceling ESSL static builtins code generator - generated hash matches inputs." - sys.exit(0) - -parser = argparse.ArgumentParser() -parser.add_argument('--dump-intermediate-json', help='Dump parsed function data as a JSON file builtin_functions.json', action="store_true") -args = parser.parse_args() - template_immutablestringtest_cpp = """// GENERATED FILE - DO NOT EDIT. // Generated by {script_name} using data from {function_data_source_name}. // @@ -328,6 +300,12 @@ basic_types_enumeration = [ 'UImageCube' ] +id_counter = 0 + +def set_working_dir(): + script_dir = os.path.dirname(os.path.abspath(__file__)) + os.chdir(script_dir) + def get_basic_mangled_name(basic): index = basic_types_enumeration.index(basic) if index < 26: @@ -381,7 +359,7 @@ class GroupedList: def get_max_name_length(self): return self.max_name_length - def get_switch_code(self): + def get_switch_code(self, script_generated_hash_tests): code = [] for level in levels: if len(self.objs[level]) == 0: @@ -398,7 +376,7 @@ class GroupedList: switch = {} for name, obj in objs.iteritems(): - name_hash = mangledNameHash(name) + name_hash = mangledNameHash(name, script_generated_hash_tests) if name_hash not in switch: switch[name_hash] = [] switch[name_hash].append(obj['hash_matched_code']) @@ -575,7 +553,7 @@ class TType: raise Exception('Unrecognized type: ' + str(glsl_header_type)) -def get_parsed_functions(): +def get_parsed_functions(functions_txt_filename): def parse_function_parameters(parameters): if parameters == '': @@ -643,67 +621,6 @@ def get_parsed_functions(): return parsed_functions -parsed_functions = get_parsed_functions() - -if args.dump_intermediate_json: - with open('builtin_functions.json', 'w') as outfile: - def serialize_obj(obj): - if isinstance(obj, TType): - return obj.data - else: - raise "Cannot serialize to JSON: " + str(obj) - json.dump(parsed_functions, outfile, indent=4, separators=(',', ': '), default=serialize_obj) - -with open(variables_json_filename) as f: - parsed_variables = json.load(f, object_pairs_hook=OrderedDict) - -# Declarations of symbol unique ids -builtin_id_declarations = [] - -# Definitions of symbol unique ids needed for those ids used outside of constexpr expressions. -builtin_id_definitions = [] - -# Declarations of name string variables -name_declarations = set() - -# Declarations of builtin TVariables -variable_declarations = [] - -# Declarations of parameter arrays for builtin TFunctions. Map from C++ variable name to the full -# declaration. -parameter_declarations = {} - -# Declarations of builtin TFunctions -function_declarations = [] - -# Functions for querying the pointer to a specific TVariable. -get_variable_declarations = [] -get_variable_definitions = [] - -# Code for defining TVariables stored as members of TSymbolTable. -declare_member_variables = [] -init_member_variables = [] - -# Code for querying builtins. -get_builtin_if_statements = GroupedList() - -# Declarations of UnmangledBuiltIn objects -unmangled_builtin_declarations = set() - -# Code for querying builtin function unmangled names. -unmangled_function_if_statements = GroupedList() - -# Code for testing that script-generated hashes match with runtime computed hashes. -script_generated_hash_tests = OrderedDict() - -# Functions for testing whether a builtin belongs in group. -is_in_group_definitions = [] - -# Counts of variables with a certain name string: -variable_name_count = {} - -id_counter = 0 - fnvPrime = 16777619 def hash32(str): fnvOffsetBasis = 0x811c9dc5 @@ -713,7 +630,7 @@ def hash32(str): hash = (hash * fnvPrime) & 0xffffffff return hash -def mangledNameHash(str, save_test = True): +def mangledNameHash(str, script_generated_hash_tests, save_test = True): hash = hash32(str) index = 0 max_six_bit_value = (1 << 6) - 1 @@ -776,27 +693,14 @@ def get_function_human_readable_name(function_name, parameters): name += '_' + param.get_human_readable_name() return name -ttype_mangled_name_variants = [] -for basic_type in basic_types_enumeration: - primary_sizes = [1] - secondary_sizes = [1] - if basic_type in ['Float', 'Int', 'UInt', 'Bool']: - primary_sizes = [1, 2, 3, 4] - if basic_type == 'Float': - secondary_sizes = [1, 2, 3, 4] - for primary_size in primary_sizes: - for secondary_size in secondary_sizes: - type = TType({'basic': basic_type, 'primarySize': primary_size, 'secondarySize': secondary_size}) - ttype_mangled_name_variants.append(type.get_mangled_name()) - -def gen_parameters_variant_ids(str_len): +def gen_parameters_variant_ids(str_len, ttype_mangled_name_variants): # Note that this doesn't generate variants with array parameters or struct / interface block parameters. They are assumed to have been filtered out separately. if str_len % 2 != 0: raise Exception('Expecting parameters mangled name length to be divisible by two') num_variants = pow(len(ttype_mangled_name_variants), str_len / 2) return xrange(num_variants) -def get_parameters_mangled_name_variant(variant_id, paren_location, total_length): +def get_parameters_mangled_name_variant(variant_id, paren_location, total_length, ttype_mangled_name_variants): str_len = total_length - paren_location - 1 if str_len % 2 != 0: raise Exception('Expecting parameters mangled name length to be divisible by two') @@ -813,8 +717,8 @@ def get_parameters_mangled_name_variant(variant_id, paren_location, total_length # Calculate the mangled name hash of a common prefix string that's been pre-hashed with hash32() # plus a variant of the parameters. This is faster than constructing the whole string and then # calculating the hash for that. -num_type_variants = len(ttype_mangled_name_variants) -def get_mangled_name_variant_hash(prefix_hash32, variant_id, paren_location, total_length): +def get_mangled_name_variant_hash(prefix_hash32, variant_id, paren_location, total_length, + num_type_variants, ttype_mangled_name_variants): hash = prefix_hash32 parameter_count = (total_length - paren_location) >> 1 parameter_variant_id_base = variant_id @@ -828,16 +732,13 @@ def get_mangled_name_variant_hash(prefix_hash32, variant_id, paren_location, tot parameter_variant_id_base = parameter_variant_id_base / num_type_variants return ((hash >> 13) ^ (hash & 0x1fff)) | (total_length << 19) | (paren_location << 25) -# Sanity check for get_mangled_name_variant_hash: -if get_mangled_name_variant_hash(hash32("atan("), 3, 4, len("atan(0123")) != mangledNameHash("atan(" + get_parameters_mangled_name_variant(3, 4, len("atan(0123"))): - raise Exception("get_mangled_name_variant_hash sanity check failed") - -def mangled_name_hash_can_collide_with_different_parameters(function_variant_props): +def mangled_name_hash_can_collide_with_different_parameters(function_variant_props, num_type_variants, + ttype_mangled_name_variants, script_generated_hash_tests): # We exhaustively search through all possible lists of parameters and see if any other mangled # name has the same hash. mangled_name = function_variant_props['mangled_name'] mangled_name_len = len(mangled_name) - hash = mangledNameHash(mangled_name) + hash = mangledNameHash(mangled_name, script_generated_hash_tests) mangled_name_prefix = function_variant_props['name'] + '(' paren_location = len(mangled_name_prefix) - 1 prefix_hash32 = hash32(mangled_name_prefix) @@ -846,8 +747,12 @@ def mangled_name_hash_can_collide_with_different_parameters(function_variant_pro if (parameters_mangled_name_len > 6): # This increases the complexity of searching for hash collisions considerably, so rather than doing it we just conservatively assume that a hash collision may be possible. return True - for variant_id in gen_parameters_variant_ids(parameters_mangled_name_len): - if get_mangled_name_variant_hash(prefix_hash32, variant_id, paren_location, mangled_name_len) == hash and get_parameters_mangled_name_variant(variant_id, paren_location, mangled_name_len) != parameters_mangled_name: + for variant_id in gen_parameters_variant_ids(parameters_mangled_name_len, ttype_mangled_name_variants): + variant_hash = get_mangled_name_variant_hash(prefix_hash32, variant_id, paren_location, mangled_name_len, + num_type_variants, ttype_mangled_name_variants) + manged_name_variant = get_parameters_mangled_name_variant(variant_id, paren_location, mangled_name_len, + ttype_mangled_name_variants) + if variant_hash == hash and manged_name_variant != parameters_mangled_name: return True return False @@ -880,7 +785,7 @@ def get_variable_name_to_store_parameters(parameters): unique_name += param.get_mangled_name() return unique_name -def define_constexpr_variable(template_args): +def define_constexpr_variable(template_args, variable_declarations): template_variable_declaration = 'constexpr const TVariable kVar_{name_with_suffix}(BuiltInId::{name_with_suffix}, BuiltInName::{name}, SymbolType::BuiltIn, TExtension::{extension}, {type});' variable_declarations.append(template_variable_declaration.format(**template_args)) @@ -928,11 +833,12 @@ def gen_function_variants(function_name, function_props): function_variants.append(variant_props) return function_variants -defined_function_variants = set() -defined_parameter_names = set() - -def process_single_function_group(condition, group_name, group): +def process_single_function_group(condition, group_name, group, num_type_variants, parameter_declarations, ttype_mangled_name_variants, + name_declarations, unmangled_function_if_statements, unmangled_builtin_declarations, defined_function_variants, + builtin_id_declarations, builtin_id_definitions, defined_parameter_names, variable_declarations, function_declarations, + script_generated_hash_tests, get_builtin_if_statements): global id_counter + if 'functions' not in group: return @@ -1006,7 +912,7 @@ def process_single_function_group(condition, group_name, group): param_template_args['id'] = id_counter template_builtin_id_declaration = ' static constexpr const TSymbolUniqueId {name_with_suffix} = TSymbolUniqueId({id});' builtin_id_declarations.append(template_builtin_id_declaration.format(**param_template_args)) - define_constexpr_variable(param_template_args) + define_constexpr_variable(param_template_args, variable_declarations) defined_parameter_names.add(unique_param_name) parameters_list.append('&BuiltInVariable::kVar_{name_with_suffix}'.format(**param_template_args)); @@ -1026,7 +932,8 @@ def process_single_function_group(condition, group_name, group): # name and hash, then we can only check the mangled name length and the function name # instead of checking the whole mangled name. template_mangled_if = '' - if mangled_name_hash_can_collide_with_different_parameters(template_args): + if mangled_name_hash_can_collide_with_different_parameters(template_args, num_type_variants, + ttype_mangled_name_variants, script_generated_hash_tests): template_mangled_name_declaration = 'constexpr const ImmutableString {unique_name}("{mangled_name}");' name_declarations.add(template_mangled_name_declaration.format(**template_args)) template_mangled_if = """if (name == BuiltInName::{unique_name}) @@ -1044,7 +951,11 @@ def process_single_function_group(condition, group_name, group): id_counter += 1 -def process_function_group(group_name, group): +def process_function_group(group_name, group, num_type_variants, parameter_declarations, ttype_mangled_name_variants, + name_declarations, unmangled_function_if_statements, unmangled_builtin_declarations, + defined_function_variants, builtin_id_declarations, builtin_id_definitions, defined_parameter_names, + variable_declarations, function_declarations, script_generated_hash_tests, get_builtin_if_statements, + is_in_group_definitions): global id_counter first_id = id_counter @@ -1052,11 +963,18 @@ def process_function_group(group_name, group): if 'condition' in group: condition = group['condition'] - process_single_function_group(condition, group_name, group) + process_single_function_group(condition, group_name, group, num_type_variants, parameter_declarations, + ttype_mangled_name_variants, name_declarations, unmangled_function_if_statements, unmangled_builtin_declarations, + defined_function_variants, builtin_id_declarations, builtin_id_definitions, defined_parameter_names, + variable_declarations, function_declarations, script_generated_hash_tests, get_builtin_if_statements) if 'subgroups' in group: for subgroup_name, subgroup in group['subgroups'].iteritems(): - process_function_group(group_name + subgroup_name, subgroup) + process_function_group(group_name + subgroup_name, subgroup, num_type_variants, parameter_declarations, + ttype_mangled_name_variants, name_declarations, unmangled_function_if_statements, + unmangled_builtin_declarations, defined_function_variants, builtin_id_declarations, + builtin_id_definitions, defined_parameter_names, variable_declarations, function_declarations, + script_generated_hash_tests, get_builtin_if_statements, is_in_group_definitions) if 'queryFunction' in group: template_args = { @@ -1071,12 +989,8 @@ def process_function_group(group_name, group): }}""" is_in_group_definitions.append(template_is_in_group_definition.format(**template_args)) -for group_name, group in parsed_functions.iteritems(): - process_function_group(group_name, group) - -def prune_parameters_arrays(): +def prune_parameters_arrays(parameter_declarations, function_declarations): # We can share parameters arrays between functions in case one array is a subarray of another. - global parameter_declarations parameter_variable_name_replacements = {} used_param_variable_names = set() for param_variable_name, param_declaration in sorted(parameter_declarations.iteritems(), key=lambda item: -len(item[0])): @@ -1088,14 +1002,16 @@ def prune_parameters_arrays(): break if not replaced: used_param_variable_names.add(param_variable_name) - parameter_declarations = [value for key, value in parameter_declarations.iteritems() if key in used_param_variable_names] for i in xrange(len(function_declarations)): for replaced, replacement in parameter_variable_name_replacements.iteritems(): function_declarations[i] = function_declarations[i].replace('BuiltInParameters::' + replaced + ',', 'BuiltInParameters::' + replacement + ',') -prune_parameters_arrays() -def process_single_variable_group(condition, group_name, group): + return [value for key, value in parameter_declarations.iteritems() if key in used_param_variable_names] + +def process_single_variable_group(condition, group_name, group, builtin_id_declarations, builtin_id_definitions, name_declarations, + init_member_variables, get_variable_declarations, get_builtin_if_statements, declare_member_variables, variable_declarations, + get_variable_definitions, variable_name_count): global id_counter if 'variables' not in group: return @@ -1184,7 +1100,7 @@ def process_single_variable_group(condition, group_name, group): else: # Handle variables that can be stored as constexpr TVariable like # gl_Position, gl_FragColor etc. - define_constexpr_variable(template_args) + define_constexpr_variable(template_args, variable_declarations) is_member = False template_get_variable_declaration = 'const TVariable *{name_with_suffix}();' @@ -1232,7 +1148,7 @@ def process_single_variable_group(condition, group_name, group): id_counter += 1 -def count_variable_names(group): +def count_variable_names(group, variable_name_count): if 'variables' in group: for name in group['variables'].iterkeys(): if name not in variable_name_count: @@ -1241,9 +1157,12 @@ def count_variable_names(group): variable_name_count[name] += 1 if 'subgroups' in group: for subgroup_name, subgroup in group['subgroups'].iteritems(): - count_variable_names(subgroup) + count_variable_names(subgroup, variable_name_count) -def process_variable_group(parent_condition, group_name, group): +def process_variable_group(parent_condition, group_name, group, builtin_id_declarations, builtin_id_definitions, name_declarations, + init_member_variables, get_variable_declarations, get_builtin_if_statements, declare_member_variables, variable_declarations, + get_variable_definitions, variable_name_count): + global id_counter condition = 'NO_CONDITION' if 'condition' in group: condition = group['condition'] @@ -1254,69 +1173,231 @@ def process_variable_group(parent_condition, group_name, group): else: condition = '({cond1}) && ({cond2})'.format(cond1 = parent_condition, cond2 = condition) - process_single_variable_group(condition, group_name, group) + process_single_variable_group(condition, group_name, group, builtin_id_declarations, builtin_id_definitions, name_declarations, + init_member_variables, get_variable_declarations, get_builtin_if_statements, declare_member_variables, variable_declarations, + get_variable_definitions, variable_name_count) if 'subgroups' in group: for subgroup_name, subgroup in group['subgroups'].iteritems(): - process_variable_group(condition, subgroup_name, subgroup) + process_variable_group(condition, subgroup_name, subgroup, builtin_id_declarations, builtin_id_definitions, name_declarations, + init_member_variables, get_variable_declarations, get_builtin_if_statements, declare_member_variables, variable_declarations, + get_variable_definitions, variable_name_count) -for group_name, group in parsed_variables.iteritems(): - count_variable_names(group) -for group_name, group in parsed_variables.iteritems(): - process_variable_group('NO_CONDITION', group_name, group) +def main(): -output_strings = { - 'script_name': os.path.basename(__file__), - 'copyright_year': date.today().year, + set_working_dir() - 'builtin_id_declarations': '\n'.join(builtin_id_declarations), - 'builtin_id_definitions': '\n'.join(builtin_id_definitions), - 'last_builtin_id': id_counter - 1, - 'name_declarations': '\n'.join(sorted(list(name_declarations))), + parser = argparse.ArgumentParser() + parser.add_argument('--dump-intermediate-json', help='Dump parsed function data as a JSON file builtin_functions.json', action="store_true") + parser.add_argument('auto_script_command', nargs='?', default='') + args = parser.parse_args() - 'function_data_source_name': functions_txt_filename, - 'function_declarations': '\n'.join(function_declarations), - 'parameter_declarations': '\n'.join(sorted(parameter_declarations)), + test_filename = '../../tests/compiler_tests/ImmutableString_test_autogen.cpp' + variables_json_filename = 'builtin_variables.json' + functions_txt_filename = 'builtin_function_declarations.txt' + hash_filename = 'builtin_symbols_hash_autogen.txt' - 'is_in_group_definitions': '\n'.join(is_in_group_definitions), + # auto_script parameters. + if args.auto_script_command != '': + inputs = [ + functions_txt_filename, + variables_json_filename, + ] + outputs = [ + 'ParseContext_autogen.h', + 'SymbolTable_autogen.cpp', + 'SymbolTable_autogen.h', + 'tree_util/BuiltIn_autogen.h', + test_filename, + hash_filename, + ] - 'variable_data_source_name': variables_json_filename, - 'variable_declarations': '\n'.join(sorted(variable_declarations)), - 'get_variable_declarations': '\n'.join(sorted(get_variable_declarations)), - 'get_variable_definitions': '\n'.join(sorted(get_variable_definitions)), - 'unmangled_builtin_declarations': '\n'.join(sorted(unmangled_builtin_declarations)), + if args.auto_script_command == 'inputs': + print ','.join(inputs) + elif args.auto_script_command == 'outputs': + print ','.join(outputs) + else: + print('Invalid script parameters') + return 1 + return 0 - 'declare_member_variables': '\n'.join(declare_member_variables), - 'init_member_variables': '\n'.join(init_member_variables), - 'get_unmangled_builtin': unmangled_function_if_statements.get_switch_code(), - 'get_builtin': get_builtin_if_statements.get_switch_code(), - 'max_unmangled_name_length': unmangled_function_if_statements.get_max_name_length(), - 'max_mangled_name_length': get_builtin_if_statements.get_max_name_length(), + all_inputs = [os.path.abspath(__file__), variables_json_filename, functions_txt_filename] + # This script takes a while to run since it searches for hash collisions of mangled names. To avoid + # running it unnecessarily, we first check if we've already ran it with the same inputs. + m = hashlib.md5() + for input_path in all_inputs: + with open(input_path, 'rU') as input_file: + m.update(input_file.read()) + input_hash = m.hexdigest() + if os.path.exists(hash_filename): + with open(hash_filename) as hash_file: + if input_hash == hash_file.read(): + print "Canceling ESSL static builtins code generator - generated hash matches inputs." + sys.exit(0) - 'script_generated_hash_tests': '\n'.join(script_generated_hash_tests.iterkeys()) -} + # Declarations of symbol unique ids + builtin_id_declarations = [] -with open('../../tests/compiler_tests/ImmutableString_test_autogen.cpp', 'wt') as outfile_cpp: - output_cpp = template_immutablestringtest_cpp.format(**output_strings) - outfile_cpp.write(output_cpp) + # Definitions of symbol unique ids needed for those ids used outside of constexpr expressions. + builtin_id_definitions = [] -with open('tree_util/BuiltIn_autogen.h', 'wt') as outfile_header: - output_header = template_builtin_header.format(**output_strings) - outfile_header.write(output_header) + # Declarations of name string variables + name_declarations = set() -with open('SymbolTable_autogen.cpp', 'wt') as outfile_cpp: - output_cpp = template_symboltable_cpp.format(**output_strings) - outfile_cpp.write(output_cpp) + # Declarations of builtin TVariables + variable_declarations = [] -with open('ParseContext_autogen.h', 'wt') as outfile_header: - output_header = template_parsecontext_header.format(**output_strings) - outfile_header.write(output_header) + # Declarations of builtin TFunctions + function_declarations = [] -with open('SymbolTable_autogen.h', 'wt') as outfile_h: - output_h = template_symboltable_h.format(**output_strings) - outfile_h.write(output_h) + # Functions for querying the pointer to a specific TVariable. + get_variable_declarations = [] + get_variable_definitions = [] -with open(hash_filename, 'wt') as hash_file: - hash_file.write(input_hash) + # Code for defining TVariables stored as members of TSymbolTable. + declare_member_variables = [] + init_member_variables = [] + + # Code for querying builtins. + get_builtin_if_statements = GroupedList() + + # Declarations of UnmangledBuiltIn objects + unmangled_builtin_declarations = set() + + # Code for querying builtin function unmangled names. + unmangled_function_if_statements = GroupedList() + + # Code for testing that script-generated hashes match with runtime computed hashes. + script_generated_hash_tests = OrderedDict() + + # Functions for testing whether a builtin belongs in group. + is_in_group_definitions = [] + + # Counts of variables with a certain name string: + variable_name_count = {} + + # Declarations of parameter arrays for builtin TFunctions. Map from C++ variable name to the full + # declaration. + parameter_declarations = {} + + ttype_mangled_name_variants = [] + + defined_function_variants = set() + defined_parameter_names = set() + + + parsed_functions = get_parsed_functions(functions_txt_filename) + + if args.dump_intermediate_json: + with open('builtin_functions.json', 'w') as outfile: + def serialize_obj(obj): + if isinstance(obj, TType): + return obj.data + else: + raise "Cannot serialize to JSON: " + str(obj) + json.dump(parsed_functions, outfile, indent=4, separators=(',', ': '), default=serialize_obj) + + with open(variables_json_filename) as f: + parsed_variables = json.load(f, object_pairs_hook=OrderedDict) + + for basic_type in basic_types_enumeration: + primary_sizes = [1] + secondary_sizes = [1] + if basic_type in ['Float', 'Int', 'UInt', 'Bool']: + primary_sizes = [1, 2, 3, 4] + if basic_type == 'Float': + secondary_sizes = [1, 2, 3, 4] + for primary_size in primary_sizes: + for secondary_size in secondary_sizes: + type = TType({'basic': basic_type, 'primarySize': primary_size, 'secondarySize': secondary_size}) + ttype_mangled_name_variants.append(type.get_mangled_name()) + + num_type_variants = len(ttype_mangled_name_variants) + + # Sanity check for get_mangled_name_variant_hash: + variant_hash = get_mangled_name_variant_hash(hash32("atan("), 3, 4, len("atan(0123"), num_type_variants, + ttype_mangled_name_variants) + mangled_name_hash = mangledNameHash("atan(" + get_parameters_mangled_name_variant(3, 4, len("atan(0123"), + ttype_mangled_name_variants), script_generated_hash_tests) + if variant_hash != mangled_name_hash: + raise Exception("get_mangled_name_variant_hash sanity check failed") + + for group_name, group in parsed_functions.iteritems(): + process_function_group(group_name, group, num_type_variants, parameter_declarations, ttype_mangled_name_variants, + name_declarations, unmangled_function_if_statements, unmangled_builtin_declarations, + defined_function_variants, builtin_id_declarations, builtin_id_definitions, defined_parameter_names, + variable_declarations, function_declarations, script_generated_hash_tests, get_builtin_if_statements, + is_in_group_definitions) + + parameter_declarations = prune_parameters_arrays(parameter_declarations, function_declarations) + + for group_name, group in parsed_variables.iteritems(): + count_variable_names(group, variable_name_count) + + for group_name, group in parsed_variables.iteritems(): + process_variable_group('NO_CONDITION', group_name, group, builtin_id_declarations, builtin_id_definitions, name_declarations, + init_member_variables, get_variable_declarations, get_builtin_if_statements, declare_member_variables, variable_declarations, + get_variable_definitions, variable_name_count) + + output_strings = { + 'script_name': os.path.basename(__file__), + 'copyright_year': date.today().year, + + 'builtin_id_declarations': '\n'.join(builtin_id_declarations), + 'builtin_id_definitions': '\n'.join(builtin_id_definitions), + 'last_builtin_id': id_counter - 1, + 'name_declarations': '\n'.join(sorted(list(name_declarations))), + + 'function_data_source_name': functions_txt_filename, + 'function_declarations': '\n'.join(function_declarations), + 'parameter_declarations': '\n'.join(sorted(parameter_declarations)), + + 'is_in_group_definitions': '\n'.join(is_in_group_definitions), + + 'variable_data_source_name': variables_json_filename, + 'variable_declarations': '\n'.join(sorted(variable_declarations)), + 'get_variable_declarations': '\n'.join(sorted(get_variable_declarations)), + 'get_variable_definitions': '\n'.join(sorted(get_variable_definitions)), + 'unmangled_builtin_declarations': '\n'.join(sorted(unmangled_builtin_declarations)), + + 'declare_member_variables': '\n'.join(declare_member_variables), + 'init_member_variables': '\n'.join(init_member_variables), + + 'get_unmangled_builtin': unmangled_function_if_statements.get_switch_code(script_generated_hash_tests), + 'get_builtin': get_builtin_if_statements.get_switch_code(script_generated_hash_tests), + 'max_unmangled_name_length': unmangled_function_if_statements.get_max_name_length(), + 'max_mangled_name_length': get_builtin_if_statements.get_max_name_length(), + + 'script_generated_hash_tests': '\n'.join(script_generated_hash_tests.iterkeys()) + } + + with open(test_filename, 'wt') as outfile_cpp: + output_cpp = template_immutablestringtest_cpp.format(**output_strings) + outfile_cpp.write(output_cpp) + + with open('tree_util/BuiltIn_autogen.h', 'wt') as outfile_header: + output_header = template_builtin_header.format(**output_strings) + outfile_header.write(output_header) + + with open('SymbolTable_autogen.cpp', 'wt') as outfile_cpp: + output_cpp = template_symboltable_cpp.format(**output_strings) + outfile_cpp.write(output_cpp) + + with open('ParseContext_autogen.h', 'wt') as outfile_header: + output_header = template_parsecontext_header.format(**output_strings) + outfile_header.write(output_header) + + with open('SymbolTable_autogen.h', 'wt') as outfile_h: + output_h = template_symboltable_h.format(**output_strings) + outfile_h.write(output_h) + + with open(hash_filename, 'wt') as hash_file: + hash_file.write(input_hash) + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/compiler/translator/gen_emulated_builtin_function_tables.py b/src/compiler/translator/gen_emulated_builtin_function_tables.py index 7bf6b610e..6f003a9b5 100644 --- a/src/compiler/translator/gen_emulated_builtin_function_tables.py +++ b/src/compiler/translator/gen_emulated_builtin_function_tables.py @@ -5,6 +5,7 @@ # # gen_emulated_builtin_function_tables.py: # Generator for the builtin function maps. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. from datetime import date import json @@ -88,10 +89,6 @@ def enum_type(arg): return 'UI' + arg_type[2:] + suffix return arg_type.capitalize() + suffix -input_script = "emulated_builtin_function_data_hlsl.json" -hlsl_json = load_json(input_script) -emulated_functions = [] - def gen_emulated_function(data): func = "" @@ -109,17 +106,44 @@ def gen_emulated_function(data): func += "},\n" return [ func ] -for item in hlsl_json: - emulated_functions += gen_emulated_function(item) -hlsl_fname = "emulated_builtin_functions_hlsl_autogen.cpp" +def main(): -hlsl_gen = template_emulated_builtin_functions_hlsl.format( - script_name = sys.argv[0], - data_source_name = input_script, - copyright_year = date.today().year, - emulated_functions = "".join(emulated_functions)) + input_script = "emulated_builtin_function_data_hlsl.json" + hlsl_fname = "emulated_builtin_functions_hlsl_autogen.cpp" -with open(hlsl_fname, 'wt') as f: - f.write(hlsl_gen) - f.close() + # auto_script parameters. + if len(sys.argv) > 1: + inputs = [input_script] + outputs = [hlsl_fname] + + 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 + + hlsl_json = load_json(input_script) + emulated_functions = [] + + for item in hlsl_json: + emulated_functions += gen_emulated_function(item) + + hlsl_gen = template_emulated_builtin_functions_hlsl.format( + script_name = sys.argv[0], + data_source_name = input_script, + copyright_year = date.today().year, + emulated_functions = "".join(emulated_functions)) + + with open(hlsl_fname, 'wt') as f: + f.write(hlsl_gen) + f.close() + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/libANGLE/es3_copy_conversion_table_autogen.cpp b/src/libANGLE/es3_copy_conversion_table_autogen.cpp index d530dbd11..0fbb7dfd5 100644 --- a/src/libANGLE/es3_copy_conversion_table_autogen.cpp +++ b/src/libANGLE/es3_copy_conversion_table_autogen.cpp @@ -1,7 +1,7 @@ // GENERATED FILE - DO NOT EDIT. // Generated by gen_copy_conversion_table.py using data from es3_copy_conversion_formats.json. // -// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// 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. // diff --git a/src/libANGLE/format_map_autogen.cpp b/src/libANGLE/format_map_autogen.cpp index c7e6a0cbc..f88a2c8c7 100644 --- a/src/libANGLE/format_map_autogen.cpp +++ b/src/libANGLE/format_map_autogen.cpp @@ -2,7 +2,7 @@ // Generated by gen_format_map.py using data from format_map_data.json. // ES3 format info from es3_format_type_combinations.json. // -// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// 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. // diff --git a/src/libANGLE/gen_copy_conversion_table.py b/src/libANGLE/gen_copy_conversion_table.py index f2c9603d5..ad67ab13d 100644 --- a/src/libANGLE/gen_copy_conversion_table.py +++ b/src/libANGLE/gen_copy_conversion_table.py @@ -5,6 +5,7 @@ # # gen_copy_conversion_table.py: # Code generation for ES3 valid copy conversions table format map. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. from datetime import date import sys @@ -64,28 +65,51 @@ def parse_texture_format_case(texture_format, framebuffer_formats): return template_format_case.format( texture_format = texture_format, framebuffer_format_cases = framebuffer_format_cases) -data_source_name = 'es3_copy_conversion_formats.json' -json_data = angle_format.load_json(data_source_name) +def main(): -format_map = {} + data_source_name = 'es3_copy_conversion_formats.json' + out_file_name = 'es3_copy_conversion_table_autogen.cpp' -for description, data in json_data.iteritems(): - for texture_format, framebuffer_format in data: - if texture_format not in format_map: - format_map[texture_format] = [] - format_map[texture_format] += [ framebuffer_format ] + # auto_script parameters. + if len(sys.argv) > 1: + inputs = [data_source_name] + outputs = [out_file_name] -texture_format_cases = "" + 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 -for texture_format, framebuffer_formats in sorted(format_map.iteritems()): - texture_format_cases += parse_texture_format_case(texture_format, framebuffer_formats) + json_data = angle_format.load_json(data_source_name) -with open('es3_copy_conversion_table_autogen.cpp', 'wt') as out_file: - output_cpp = template_cpp.format( - script_name = sys.argv[0], - data_source_name = data_source_name, - copyright_year = date.today().year, - texture_format_cases = texture_format_cases) - out_file.write(output_cpp) - out_file.close() + format_map = {} + + for description, data in json_data.iteritems(): + for texture_format, framebuffer_format in data: + if texture_format not in format_map: + format_map[texture_format] = [] + format_map[texture_format] += [ framebuffer_format ] + + texture_format_cases = "" + + for texture_format, framebuffer_formats in sorted(format_map.iteritems()): + texture_format_cases += parse_texture_format_case(texture_format, framebuffer_formats) + + with open(out_file_name, 'wt') as out_file: + output_cpp = template_cpp.format( + script_name = sys.argv[0], + data_source_name = data_source_name, + copyright_year = date.today().year, + texture_format_cases = texture_format_cases) + out_file.write(output_cpp) + out_file.close() + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/libANGLE/gen_format_map.py b/src/libANGLE/gen_format_map.py index e150fc0bc..4bba7a6d8 100644 --- a/src/libANGLE/gen_format_map.py +++ b/src/libANGLE/gen_format_map.py @@ -6,6 +6,7 @@ # gen_format_map.py: # Code generation for GL format map. The format map matches between # {format,type} and internal format. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. from datetime import date import sys @@ -110,10 +111,12 @@ template_es3_combo_type_case = """ case {type}: }} """ + def parse_type_case(type, result): return template_simple_case.format( key = type, result = result) + def parse_format_case(format, type_map): type_cases = "" for type, internal_format in sorted(type_map.iteritems()): @@ -121,66 +124,88 @@ def parse_format_case(format, type_map): return template_format_case.format( format = format, type_cases = type_cases) -input_script = 'format_map_data.json' -format_map = angle_format.load_json(input_script) +def main(): -format_cases = "" + # auto_script parameters. + if len(sys.argv) > 1: + inputs = ['es3_format_type_combinations.json', 'format_map_data.json'] + outputs = ['format_map_autogen.cpp'] -for format, type_map in sorted(format_map.iteritems()): - format_cases += parse_format_case(format, type_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 -combo_data_file = 'es3_format_type_combinations.json' -es3_combo_data = angle_format.load_json(combo_data_file) -combo_data = [combo for sublist in es3_combo_data.values() for combo in sublist] + input_script = 'format_map_data.json' -types = set() -formats = set() -combos = {} + format_map = angle_format.load_json(input_script) -for internal_format, format, type in combo_data: - types.update([type]) - formats.update([format]) - if format not in combos: - combos[format] = {} - if type not in combos[format]: - combos[format][type] = [internal_format] - else: - combos[format][type] += [internal_format] + format_cases = "" -es3_format_cases = "" + for format, type_map in sorted(format_map.iteritems()): + format_cases += parse_format_case(format, type_map) -for format in sorted(formats): - es3_format_cases += " case " + format + ":\n" + combo_data_file = 'es3_format_type_combinations.json' + es3_combo_data = angle_format.load_json(combo_data_file) + combo_data = [combo for sublist in es3_combo_data.values() for combo in sublist] -es3_type_cases = "" + types = set() + formats = set() + combos = {} -for type in sorted(types): - es3_type_cases += " case " + type + ":\n" + for internal_format, format, type in combo_data: + types.update([type]) + formats.update([format]) + if format not in combos: + combos[format] = {} + if type not in combos[format]: + combos[format][type] = [internal_format] + else: + combos[format][type] += [internal_format] -es3_combo_cases = "" + es3_format_cases = "" -for format, type_combos in combos.iteritems(): - this_type_cases = "" - for type, combos in type_combos.iteritems(): - internal_format_cases = "" - for internal_format in combos: - internal_format_cases += " case " + internal_format + ":\n" + for format in sorted(formats): + es3_format_cases += " case " + format + ":\n" - this_type_cases += template_es3_combo_type_case.format( - type = type, internal_format_cases = internal_format_cases) + es3_type_cases = "" - es3_combo_cases += template_format_case.format( - format = format, type_cases = this_type_cases) + for type in sorted(types): + es3_type_cases += " case " + type + ":\n" -with open('format_map_autogen.cpp', 'wt') as out_file: - output_cpp = template_cpp.format( - script_name = sys.argv[0], - data_source_name = input_script, - es3_data_source_name = combo_data_file, - copyright_year = date.today().year, - format_cases = format_cases, - es3_format_cases = es3_format_cases, - es3_type_cases = es3_type_cases, - es3_combo_cases = es3_combo_cases) - out_file.write(output_cpp) + es3_combo_cases = "" + + for format, type_combos in combos.iteritems(): + this_type_cases = "" + for type, combos in type_combos.iteritems(): + internal_format_cases = "" + for internal_format in combos: + internal_format_cases += " case " + internal_format + ":\n" + + this_type_cases += template_es3_combo_type_case.format( + type = type, internal_format_cases = internal_format_cases) + + es3_combo_cases += template_format_case.format( + format = format, type_cases = this_type_cases) + + with open('format_map_autogen.cpp', 'wt') as out_file: + output_cpp = template_cpp.format( + script_name = sys.argv[0], + data_source_name = input_script, + es3_data_source_name = combo_data_file, + copyright_year = date.today().year, + format_cases = format_cases, + es3_format_cases = es3_format_cases, + es3_type_cases = es3_type_cases, + es3_combo_cases = es3_combo_cases) + out_file.write(output_cpp) + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp b/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table_autogen.cpp similarity index 100% rename from src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp rename to src/libANGLE/renderer/d3d/d3d11/dxgi_support_table_autogen.cpp diff --git a/src/libANGLE/renderer/d3d/d3d11/gen_blit11helper.py b/src/libANGLE/renderer/d3d/d3d11/gen_blit11helper.py index d262b43b8..4b69c5551 100644 --- a/src/libANGLE/renderer/d3d/d3d11/gen_blit11helper.py +++ b/src/libANGLE/renderer/d3d/d3d11/gen_blit11helper.py @@ -6,6 +6,7 @@ # # gen_blit11helper.py: # Generates the code for retrieving the various blit shaders for D3D11 +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. import sys, os, pprint from datetime import date @@ -335,22 +336,42 @@ def write_gni_file(shader_filename_list): out.close() -map_blitshader_cases = [] -shader_includes = [] -blitshadertype_cases = [] -blitshadertype_enums = [] -blitshaderop_enums = [] -shader_filenames = [] +def main(): -map_blitshader_cases = get_map_blitshader_cases() -shader_includes = get_shader_includes() -blitshadertype_cases = get_blitshader_cases() -blitshaderop_enums = get_blitshaderop_enums() -blitshadertype_enums = get_blitshadertype_enums() -shader_filenames = get_shader_filenames() + # auto_script parameters. + if len(sys.argv) > 1: + inputs = [] + outputs = ['Blit11Helper_autogen.inc', 'd3d11_blit_shaders_autogen.gni'] -write_inc_file("\n".join([d for d in blitshadertype_cases]), "\n".join( - [c for c in map_blitshader_cases]), "\n".join([i for i in shader_includes]), - "\n".join([e for e in blitshaderop_enums]), "\n".join( - [e for e in blitshadertype_enums])) -write_gni_file("\n".join([s for s in shader_filenames])) + 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 + + map_blitshader_cases = [] + shader_includes = [] + blitshadertype_cases = [] + blitshadertype_enums = [] + blitshaderop_enums = [] + shader_filenames = [] + + map_blitshader_cases = get_map_blitshader_cases() + shader_includes = get_shader_includes() + blitshadertype_cases = get_blitshader_cases() + blitshaderop_enums = get_blitshaderop_enums() + blitshadertype_enums = get_blitshadertype_enums() + shader_filenames = get_shader_filenames() + + write_inc_file("\n".join([d for d in blitshadertype_cases]), "\n".join( + [c for c in map_blitshader_cases]), "\n".join([i for i in shader_includes]), + "\n".join([e for e in blitshaderop_enums]), "\n".join( + [e for e in blitshadertype_enums])) + write_gni_file("\n".join([s for s in shader_filenames])) + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_format_table.py b/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_format_table.py index 38da20933..2b7e1755e 100644 --- a/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_format_table.py +++ b/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_format_table.py @@ -5,6 +5,7 @@ # # gen_dxgi_format_table.py: # Code generation for DXGI format map. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. from datetime import date import sys @@ -82,52 +83,78 @@ def format_case(dxgi_format, result): def undefined_case(dxgi_format): return template_undefined_case.format(dxgi_format = dxgi_format) -component_cases = "" -format_cases = "" -input_data = 'dxgi_format_data.json' +def main(): -dxgi_map = angle_format.load_json(input_data) + # auto_script parameters. + if len(sys.argv) > 1: + inputs = [ + '../../angle_format.py', + '../../angle_format_map.json', + 'dxgi_format_data.json', + ] + outputs = ['dxgi_format_map_autogen.cpp'] -types = { - 'SNORM': 'GL_SIGNED_NORMALIZED', - 'UNORM': 'GL_UNSIGNED_NORMALIZED', - 'SINT': 'GL_INT', - 'UINT': 'GL_UNSIGNED_INT', - 'FLOAT': 'GL_FLOAT', - 'SHAREDEXP': 'GL_FLOAT' -} + 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 -all_angle = angle_format.get_all_angle_formats() + component_cases = "" + format_cases = "" -for dxgi_format, angle_format in sorted(dxgi_map.iteritems()): + input_data = 'dxgi_format_data.json' - found = [ctype in dxgi_format for ctype in types.keys()] - count = reduce((lambda a, b: int(a) + int(b)), found) + dxgi_map = angle_format.load_json(input_data) - component_type = 'GL_NONE' + types = { + 'SNORM': 'GL_SIGNED_NORMALIZED', + 'UNORM': 'GL_UNSIGNED_NORMALIZED', + 'SINT': 'GL_INT', + 'UINT': 'GL_UNSIGNED_INT', + 'FLOAT': 'GL_FLOAT', + 'SHAREDEXP': 'GL_FLOAT' + } - if count == 1: - gltype = next(gltype for ctype, gltype in types.iteritems() if ctype in dxgi_format) - component_cases += format_case(dxgi_format, gltype) - else: - component_cases += undefined_case(dxgi_format) + all_angle = angle_format.get_all_angle_formats() - if angle_format == "": - angle_format = dxgi_format + for dxgi_format, a_format in sorted(dxgi_map.iteritems()): - if angle_format in all_angle: - angle_format = "Format::Get(FormatID::" + angle_format + ")" - format_cases += format_case(dxgi_format, angle_format) - else: - format_cases += undefined_case(dxgi_format) + found = [ctype in dxgi_format for ctype in types.keys()] + count = reduce((lambda a, b: int(a) + int(b)), found) -with open('dxgi_format_map_autogen.cpp', 'wt') as out_file: - output_cpp = template_cpp.format( - script_name = sys.argv[0], - data_source_name = input_data, - copyright_year = date.today().year, - component_type_cases = component_cases, - format_cases = format_cases) - out_file.write(output_cpp) - out_file.close() + component_type = 'GL_NONE' + + if count == 1: + gltype = next(gltype for ctype, gltype in types.iteritems() if ctype in dxgi_format) + component_cases += format_case(dxgi_format, gltype) + else: + component_cases += undefined_case(dxgi_format) + + if a_format == "": + a_format = dxgi_format + + if a_format in all_angle: + a_format = "Format::Get(FormatID::" + a_format + ")" + format_cases += format_case(dxgi_format, a_format) + else: + format_cases += undefined_case(dxgi_format) + + with open('dxgi_format_map_autogen.cpp', 'wt') as out_file: + output_cpp = template_cpp.format( + script_name = sys.argv[0], + data_source_name = input_data, + copyright_year = date.today().year, + component_type_cases = component_cases, + format_cases = format_cases) + out_file.write(output_cpp) + out_file.close() + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py b/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py index 593daf976..e31cb0ccf 100644 --- a/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py +++ b/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py @@ -6,8 +6,9 @@ # gen_dxgi_support_tables.py: # Code generation for the DXGI support tables. Determines which formats # are natively support in D3D10+. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. # -# TODO: The "never supported" formats should not be combined with the +# NOTE: The "never supported" formats should not be combined with the # "supported" and "optional" ones. At the moment, this does not cause # any issues as ANGLE does not internally check for "never supported". # @@ -167,8 +168,6 @@ const DXGISupport &GetDXGISupport(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL feat }} // namespace rx """ -table_init = "" - def do_format(format_data): table_data = {'9_3': '', '10_0': '', '10_1': '', '11_0': '', '11_1': ''} @@ -290,24 +289,45 @@ def join_table_data(table_data_1, table_data_2): '11_0': table_data_1['11_0'] + table_data_2['11_0'], '11_1': table_data_1['11_1'] + table_data_2['11_1']} -with open('dxgi_support_data.json') as dxgi_file: - file_data = dxgi_file.read() - dxgi_file.close() - json_data = json.loads(file_data) - table_data = {'9_3': '', '10_0': '', '10_1': '', '11_0': '', '11_1': ''} +def main(): - for format_data in json_data: - table_data = join_table_data(table_data, do_format(format_data)) + # auto_script parameters. + if len(sys.argv) > 1: + inputs = ['dxgi_support_data.json'] + outputs = ['dxgi_support_table_autogen.cpp'] - out_data = template.format(prefix=macro_prefix, - table_data_9_3=table_data['9_3'], - table_data_10_0=table_data['10_0'], - table_data_10_1=table_data['10_1'], - table_data_11_0=table_data['11_0'], - table_data_11_1=table_data['11_1']) + 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 - with open('dxgi_support_table.cpp', 'wt') as out_file: - out_file.write(out_data) - out_file.close() + with open('dxgi_support_data.json') as dxgi_file: + file_data = dxgi_file.read() + dxgi_file.close() + json_data = json.loads(file_data) + table_data = {'9_3': '', '10_0': '', '10_1': '', '11_0': '', '11_1': ''} + + for format_data in json_data: + table_data = join_table_data(table_data, do_format(format_data)) + + out_data = template.format(prefix=macro_prefix, + table_data_9_3=table_data['9_3'], + table_data_10_0=table_data['10_0'], + table_data_10_1=table_data['10_1'], + table_data_11_0=table_data['11_0'], + table_data_11_1=table_data['11_1']) + + with open('dxgi_support_table_autogen.cpp', 'wt') as out_file: + out_file.write(out_data) + out_file.close() + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py b/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py index d19d99ea1..1a4121a91 100644 --- a/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py +++ b/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py @@ -5,6 +5,7 @@ # # gen_texture_format_table.py: # Code generation for texture format map +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. # from datetime import date @@ -266,16 +267,38 @@ def parse_json_into_switch_angle_format_string(json_map, json_data): return table_data -json_map = angle_format.load_with_override(os.path.abspath('texture_format_map.json')) -data_source_name = 'texture_format_data.json' -json_data = angle_format.load_json(data_source_name) -angle_format_cases = parse_json_into_switch_angle_format_string(json_map, json_data) -output_cpp = template_texture_format_table_autogen_cpp.format( - script_name = sys.argv[0], - copyright_year = date.today().year, - angle_format_info_cases = angle_format_cases, - data_source_name = data_source_name) -with open('texture_format_table_autogen.cpp', 'wt') as out_file: - out_file.write(output_cpp) - out_file.close() +def main(): + + # auto_script parameters. + if len(sys.argv) > 1: + inputs = ['../../angle_format.py', 'texture_format_data.json', 'texture_format_map.json'] + outputs = ['texture_format_table_autogen.cpp'] + + 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 + + json_map = angle_format.load_with_override(os.path.abspath('texture_format_map.json')) + data_source_name = 'texture_format_data.json' + json_data = angle_format.load_json(data_source_name) + + angle_format_cases = parse_json_into_switch_angle_format_string(json_map, json_data) + output_cpp = template_texture_format_table_autogen_cpp.format( + script_name = sys.argv[0], + copyright_year = date.today().year, + angle_format_info_cases = angle_format_cases, + data_source_name = data_source_name) + with open('texture_format_table_autogen.cpp', 'wt') as out_file: + out_file.write(output_cpp) + out_file.close() + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp b/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp index b4933ab6e..0c94b4ea0 100644 --- a/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp +++ b/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp @@ -1,7 +1,7 @@ // GENERATED FILE - DO NOT EDIT. // Generated by gen_texture_format_table.py using data from texture_format_data.json // -// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// 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. // diff --git a/src/libANGLE/renderer/gen_angle_format_table.py b/src/libANGLE/renderer/gen_angle_format_table.py index 2b0262fb9..0f48129c8 100644 --- a/src/libANGLE/renderer/gen_angle_format_table.py +++ b/src/libANGLE/renderer/gen_angle_format_table.py @@ -5,6 +5,7 @@ # # gen_angle_format_table.py: # Code generation for ANGLE format map. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. # import angle_format @@ -90,11 +91,13 @@ const Format *GetFormatInfoTable() }} // namespace angle """ + def is_depth_stencil(angle_format): if not 'channels' in angle_format or not angle_format['channels']: return False return 'd' in angle_format['channels'] or 's' in angle_format['channels'] + def get_component_suffix(angle_format): if angle_format['componentType'] == 'float': return 'F' @@ -102,6 +105,7 @@ def get_component_suffix(angle_format): return 'S' return "" + def get_channel_struct(angle_format): if 'bits' not in angle_format or angle_format['bits'] is None: return None @@ -136,12 +140,14 @@ def get_channel_struct(angle_format): return struct_name + def get_mip_generation_function(angle_format): channel_struct = get_channel_struct(angle_format) if is_depth_stencil(angle_format) or channel_struct == None or "BLOCK" in angle_format["id"]: return 'nullptr' return 'GenerateMip<' + channel_struct + '>' + def get_color_read_write_component_type(angle_format): component_type_map = { 'uint': 'GLuint', @@ -152,6 +158,7 @@ def get_color_read_write_component_type(angle_format): } return component_type_map[angle_format['componentType']] + def get_color_read_function(angle_format): channel_struct = get_channel_struct(angle_format) if channel_struct == None: @@ -163,6 +170,7 @@ def get_color_read_function(angle_format): read_component_type = get_color_read_write_component_type(angle_format) return 'ReadColor<' + channel_struct + ', '+ read_component_type + '>' + def get_color_write_function(angle_format): channel_struct = get_channel_struct(angle_format) if channel_struct == None: @@ -194,6 +202,7 @@ def get_named_component_type(component_type): else: raise ValueError("Unknown component type for " + component_type) + def get_component_alignment_mask(channels, bits): if channels == None or bits == None: return "std::numeric_limits::max()" @@ -216,6 +225,7 @@ def get_component_alignment_mask(channels, bits): # Can happen for 4-bit RGBA. return "std::numeric_limits::max()" + def json_to_table_data(format_id, json, angle_to_gl): table_data = "" @@ -280,6 +290,7 @@ def json_to_table_data(format_id, json, angle_to_gl): return format_entry_template.format(**parsed) + def parse_angle_format_table(all_angle, json_data, angle_to_gl): table_data = '' for format_id in sorted(all_angle): @@ -289,6 +300,7 @@ def parse_angle_format_table(all_angle, json_data, angle_to_gl): return table_data + def gen_enum_string(all_angle): enum_data = ' NONE' for format_id in sorted(all_angle): @@ -301,6 +313,7 @@ case_template = """ case {gl_format}: return FormatID::{angle_format}; """ + def gen_map_switch_string(gl_to_angle): switch_data = ''; for gl_format in sorted(gl_to_angle.keys()): @@ -312,33 +325,56 @@ def gen_map_switch_string(gl_to_angle): switch_data += " return FormatID::NONE;" return switch_data; -gl_to_angle = angle_format.load_forward_table('angle_format_map.json') -angle_to_gl = angle_format.load_inverse_table('angle_format_map.json') -data_source_name = 'angle_format_data.json' -json_data = angle_format.load_json(data_source_name) -all_angle = angle_to_gl.keys() -angle_format_cases = parse_angle_format_table( - all_angle, json_data, angle_to_gl) -switch_data = gen_map_switch_string(gl_to_angle) -output_cpp = template_autogen_inl.format( - script_name = sys.argv[0], - copyright_year = date.today().year, - angle_format_info_cases = angle_format_cases, - angle_format_switch = switch_data, - data_source_name = data_source_name) -with open('Format_table_autogen.cpp', 'wt') as out_file: - out_file.write(output_cpp) - out_file.close() +def main(): -enum_data = gen_enum_string(all_angle) -num_angle_formats = len(all_angle) -output_h = template_autogen_h.format( - script_name = sys.argv[0], - copyright_year = date.today().year, - angle_format_enum = enum_data, - data_source_name = data_source_name, - num_angle_formats = num_angle_formats) -with open('FormatID_autogen.h', 'wt') as out_file: - out_file.write(output_h) - out_file.close() + # auto_script parameters. + if len(sys.argv) > 1: + inputs = ['angle_format.py', 'angle_format_data.json', 'angle_format_map.json'] + outputs = ['Format_table_autogen.cpp', 'FormatID_autogen.h'] + + 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 + + gl_to_angle = angle_format.load_forward_table('angle_format_map.json') + angle_to_gl = angle_format.load_inverse_table('angle_format_map.json') + data_source_name = 'angle_format_data.json' + json_data = angle_format.load_json(data_source_name) + all_angle = angle_to_gl.keys() + + angle_format_cases = parse_angle_format_table( + all_angle, json_data, angle_to_gl) + switch_data = gen_map_switch_string(gl_to_angle) + output_cpp = template_autogen_inl.format( + script_name = sys.argv[0], + copyright_year = date.today().year, + angle_format_info_cases = angle_format_cases, + angle_format_switch = switch_data, + data_source_name = data_source_name) + with open('Format_table_autogen.cpp', 'wt') as out_file: + out_file.write(output_cpp) + out_file.close() + + enum_data = gen_enum_string(all_angle) + num_angle_formats = len(all_angle) + output_h = template_autogen_h.format( + script_name = sys.argv[0], + copyright_year = date.today().year, + angle_format_enum = enum_data, + data_source_name = data_source_name, + num_angle_formats = num_angle_formats) + with open('FormatID_autogen.h', 'wt') as out_file: + out_file.write(output_h) + out_file.close() + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/libANGLE/renderer/gen_load_functions_table.py b/src/libANGLE/renderer/gen_load_functions_table.py index 75c6c009a..6b1951d7a 100755 --- a/src/libANGLE/renderer/gen_load_functions_table.py +++ b/src/libANGLE/renderer/gen_load_functions_table.py @@ -7,6 +7,7 @@ # Code generation for the load function tables used for texture formats. These mappings are # not renderer specific. The mappings are done from the GL internal format, to the ANGLE # format ID, and then for the specific data type. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. # import json, sys @@ -184,15 +185,35 @@ def parse_json(json_data): return table_data, load_functions_data -json_data = angle_format.load_json('load_functions_data.json') +def main(): -switch_data, load_functions_data = parse_json(json_data) -output = template.format(internal_format = internal_format_param, - angle_format = angle_format_param, - switch_data = switch_data, - load_functions_data = load_functions_data, - copyright_year = date.today().year) + # auto_script parameters. + if len(sys.argv) > 1: + inputs = ['load_functions_data.json'] + outputs = ['load_functions_table_autogen.cpp'] -with open('load_functions_table_autogen.cpp', 'wt') as out_file: - out_file.write(output) - out_file.close() + 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 + + json_data = angle_format.load_json('load_functions_data.json') + + switch_data, load_functions_data = parse_json(json_data) + output = template.format(internal_format = internal_format_param, + angle_format = angle_format_param, + switch_data = switch_data, + load_functions_data = load_functions_data, + copyright_year = date.today().year) + + with open('load_functions_table_autogen.cpp', 'wt') as out_file: + out_file.write(output) + out_file.close() + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/libANGLE/renderer/gl/generate_gl_dispatch_table.py b/src/libANGLE/renderer/gl/generate_gl_dispatch_table.py index 3ebf324d6..397a36613 100644 --- a/src/libANGLE/renderer/gl/generate_gl_dispatch_table.py +++ b/src/libANGLE/renderer/gl/generate_gl_dispatch_table.py @@ -5,6 +5,7 @@ # # generate_gl_dispatch_table.py: # Generation script for OpenGL bindings with ANGLE. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. import sys import os @@ -23,130 +24,6 @@ def safe_append(the_dict, key, element): the_dict[key] = [] the_dict[key].append(element) -gl_xml_path = os.path.join('..', '..', '..', '..', 'scripts', 'gl.xml') -dispatch_header_path = 'DispatchTableGL_autogen.h' -dispatch_source_path = 'DispatchTableGL_autogen.cpp' -null_functions_header_path = 'null_functions.h' -null_functions_source_path = 'null_functions.cpp' - -# Load the JSON and XML data. -data_source_name = 'gl_bindings_data.json' -json_data = angle_format.load_json(data_source_name) -xml_root = etree.parse(gl_xml_path).getroot() - -api_feature_info = {} - -core_removed_eps = [] -for core_removed_ep in xml_root.findall('feature/remove'): - assert(core_removed_ep.attrib['profile'] == 'core') - for command in core_removed_ep.findall('./command'): - core_removed_eps.append(command.attrib['name']) - -for feature in xml_root.findall('feature'): - api = feature.attrib['api'] - name = feature.attrib['name'] - number = feature.attrib['number'] - - # OpenGL ES 3.x versions are listed as api 'gles2' - if api != 'gl' and api != 'gles2': - continue - - for command in feature.findall('./require/command'): - command_name = command.attrib['name'] - safe_append(api_feature_info, command_name, (api, name, number)) - -gl_extension_commands = {} -gles2_extension_commands = {} -both_extension_commands = {} - -for extension in xml_root.findall('extensions/extension'): - extension_name = extension.attrib['name'] - support = extension.attrib['supported'].split('|') - for command in extension.findall('./require/command'): - command_name = command.attrib['name'] - if 'gl' in support and 'gles2' in support: - # Special case for KHR extensions, since in GLES they are suffixed. - if '_KHR_' in extension_name: - safe_append(gl_extension_commands, command_name, extension_name) - safe_append(gles2_extension_commands, command_name, extension_name) - else: - safe_append(both_extension_commands, command_name, extension_name) - elif 'gl' in support: - safe_append(gl_extension_commands, command_name, extension_name) - elif 'gles2' in support: - safe_append(gles2_extension_commands, command_name, extension_name) - -gl_requirements = {} -gles2_requirements = {} -gl_extension_requirements = {} -gles2_extension_requirements = {} -both_extension_requirements = {} - -# Used later in the NULL bindings. -all_entry_points = [] - -for comment, entry_points in json_data.iteritems(): - for entry_point_no_prefix in entry_points: - entry_point = "gl" + entry_point_no_prefix - - all_entry_points.append(entry_point) - - gl_required = None - gles2_required = None - - if entry_point in api_feature_info: - for api, name, number in api_feature_info[entry_point]: - major, minor = number.split(".") - reqs = (major, minor) - if api == 'gl': - if not gl_required: - gl_required = reqs - elif entry_point in core_removed_eps: - print('Upgrade ' + entry_point + ' to ' + str(reqs) + ' instead of ' + str(gl_required)) - gl_required = reqs - else: - print('Keep ' + entry_point + ' at ' + str(gl_required) + ' instead of ' + str(reqs)) - elif api == 'gles2': - if not gles2_required: - gles2_required = reqs - else: - print("Duplicate for " + entry_point + ": " + str(reqs) + " and " + str(gles2_required)) - else: - raise Exception('Bad api type: ' + api) - - if gl_required: - safe_append(gl_requirements, gl_required, entry_point) - - if gles2_required: - safe_append(gles2_requirements, gles2_required, entry_point) - - # Special case for finding extensions that overlap with core functions. - - extension = False - - for ep in [entry_point, entry_point + "EXT", entry_point + "ARB", entry_point + "OES"]: - if ep in both_extension_commands: - extension = True - for extension in both_extension_commands[ep]: - safe_append(both_extension_requirements, extension, (entry_point, ep)) - - else: - if ep in gl_extension_commands: - extension = True - for extension in gl_extension_commands[ep]: - safe_append(gl_extension_requirements, extension, (entry_point, ep)) - - if ep in gles2_extension_commands: - extension = True - for extension in gles2_extension_commands[ep]: - full_ep = ep - if '_KHR_' in extension: - full_ep += 'KHR' - safe_append(gles2_extension_requirements, extension, (entry_point, full_ep)) - - if not (gl_required or gles2_required or extension): - raise Exception('Entry point ' + entry_point + ' not found in the xml.') - # Template for the header declaration of the dispatch table. dispatch_table_header_template = """// GENERATED FILE - DO NOT EDIT. // Generated by {script_name} using data from {data_source_name} and gl.xml. @@ -206,23 +83,6 @@ def first_lower(str): def format_ep_decl(entry_point): return " PFNGL" + entry_point.upper() + "PROC " + first_lower(entry_point) + " = nullptr;" -table_data = [] -for comment, entry_points in sorted(json_data.iteritems()): - formatted = [" // " + comment] - formatted += [format_ep_decl(entry_point) for entry_point in sorted(entry_points)] - - table_data.append("\n".join(formatted)) - -dispatch_table_header = dispatch_table_header_template.format( - script_name = os.path.basename(sys.argv[0]), - data_source_name = data_source_name, - year = date.today().year, - file_name = dispatch_header_path, - table_data = "\n\n".join(table_data)) - -with open(dispatch_header_path, "w") as out: - out.write(dispatch_table_header) - # Template for the initialization file of the dispatch table. dispatch_table_source_template = """// GENERATED FILE - DO NOT EDIT. // Generated by {script_name} using data from {data_source_name} and gl.xml. @@ -309,26 +169,6 @@ def format_extension_requirements_lines(extension, entry_points, api): lines += [' }'] return '\n'.join(lines) -gl_data = [] -for gl_required, entry_points in sorted(gl_requirements.iteritems()): - gl_data.append(format_requirements_lines(gl_required, entry_points)) - -gl_extensions_data = [] -for extension, entry_points in sorted(gl_extension_requirements.iteritems()): - gl_extensions_data.append(format_extension_requirements_lines(extension, entry_points, "gl")) - -gles2_data = [] -for gles2_required, entry_points in sorted(gles2_requirements.iteritems()): - gles2_data.append(format_requirements_lines(gles2_required, entry_points)) - -gles2_extensions_data = [] -for extension, entry_points in sorted(gles2_extension_requirements.iteritems()): - gles2_extensions_data.append(format_extension_requirements_lines(extension, entry_points, "gles2")) - -both_extensions_data = [] -for extension, entry_points in sorted(both_extension_requirements.iteritems()): - both_extensions_data.append(format_extension_requirements_lines(extension, entry_points, "gles2|gl")) - def assign_null_line(line): m = re.match(r' ASSIGN\("gl.*", (.+)\);', line) if m: @@ -343,56 +183,9 @@ def assign_null(entry): def nullify(data): return [assign_null(entry) for entry in data] -dispatch_table_source = dispatch_table_source_template.format( - script_name = os.path.basename(sys.argv[0]), - data_source_name = data_source_name, - year = date.today().year, - file_name = dispatch_source_path, - gl_data = "\n\n".join(gl_data), - gl_extensions_data = "\n\n".join(gl_extensions_data), - gles2_data = "\n\n".join(gles2_data), - gles2_extensions_data = "\n\n".join(gles2_extensions_data), - both_extensions_data = "\n\n".join(both_extensions_data), - gl_null_data = "\n\n".join(nullify(gl_data)), - gl_null_extensions_data = "\n\n".join(nullify(gl_extensions_data)), - gles2_null_data = "\n\n".join(nullify(gles2_data)), - gles2_null_extensions_data = "\n\n".join(nullify(gles2_extensions_data)), - both_null_extensions_data = "\n\n".join(nullify(both_extensions_data))) - -with open(dispatch_source_path, "w") as out: - out.write(dispatch_table_source) - -# Generate the NULL/stub entry points. -# Process the whole set of commands - def format_param(param): return "".join(param.itertext()) -command_defs = {} -command_decls = {} - -for command in xml_root.findall('commands/command'): - proto = command.find('proto') - command_name = proto.find('name').text - entry = ''.join(proto.itertext()) - return_type = entry[:-len(command_name)] - entry = return_type + ' INTERNAL_GL_APIENTRY ' + entry[len(return_type):] + 'NULL(' - - param_text = [format_param(param) for param in command.findall('param')] - entry += ', '.join(param_text) + ')' - - command_decls[command_name] = entry + ';' - - entry += '\n{\n' - if return_type != 'void ': - entry += ' return static_cast<' + return_type + '>(0);\n' - entry += '}' - - command_defs[command_name] = entry - -null_decls = [command_decls[entry_point] for entry_point in sorted(all_entry_points)] -null_stubs = [command_defs[entry_point] for entry_point in sorted(all_entry_points)] - null_functions_header_template = """// GENERATED FILE - DO NOT EDIT. // Generated by {script_name} using data from {data_source_name} and gl.xml. // @@ -416,16 +209,6 @@ namespace rx #endif // LIBGLESV2_RENDERER_GL_NULL_GL_FUNCTIONS_AUTOGEN_H_ """ -null_functions_header = null_functions_header_template.format( - script_name = os.path.basename(sys.argv[0]), - data_source_name = data_source_name, - year = date.today().year, - file_name = null_functions_header_path, - table_data = "\n".join(null_decls)) - -with open(null_functions_header_path, "w") as out: - out.write(null_functions_header) - null_functions_source_template = """// GENERATED FILE - DO NOT EDIT. // Generated by {script_name} using data from {data_source_name} and gl.xml. // @@ -444,12 +227,260 @@ namespace rx }} // namespace rx """ -null_functions_source = null_functions_source_template.format( - script_name = os.path.basename(sys.argv[0]), - data_source_name = data_source_name, - year = date.today().year, - file_name = null_functions_source_path, - table_data = "\n\n".join(null_stubs)) +def main(): -with open(null_functions_source_path, "w") as out: - out.write(null_functions_source) + # auto_script parameters. + if len(sys.argv) > 1: + inputs = [ + '../../../../scripts/gl.xml', + '../angle_format.py', + 'gl_bindings_data.json', + ] + outputs = [ + 'DispatchTableGL_autogen.cpp', + 'DispatchTableGL_autogen.h', + 'null_functions.cpp', + 'null_functions.h', + ] + + 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 + + gl_xml_path = os.path.join('..', '..', '..', '..', 'scripts', 'gl.xml') + dispatch_header_path = 'DispatchTableGL_autogen.h' + dispatch_source_path = 'DispatchTableGL_autogen.cpp' + null_functions_header_path = 'null_functions.h' + null_functions_source_path = 'null_functions.cpp' + + # Load the JSON and XML data. + data_source_name = 'gl_bindings_data.json' + json_data = angle_format.load_json(data_source_name) + xml_root = etree.parse(gl_xml_path).getroot() + + api_feature_info = {} + + core_removed_eps = [] + for core_removed_ep in xml_root.findall('feature/remove'): + assert(core_removed_ep.attrib['profile'] == 'core') + for command in core_removed_ep.findall('./command'): + core_removed_eps.append(command.attrib['name']) + + for feature in xml_root.findall('feature'): + api = feature.attrib['api'] + name = feature.attrib['name'] + number = feature.attrib['number'] + + # OpenGL ES 3.x versions are listed as api 'gles2' + if api != 'gl' and api != 'gles2': + continue + + for command in feature.findall('./require/command'): + command_name = command.attrib['name'] + safe_append(api_feature_info, command_name, (api, name, number)) + + gl_extension_commands = {} + gles2_extension_commands = {} + both_extension_commands = {} + + for extension in xml_root.findall('extensions/extension'): + extension_name = extension.attrib['name'] + support = extension.attrib['supported'].split('|') + for command in extension.findall('./require/command'): + command_name = command.attrib['name'] + if 'gl' in support and 'gles2' in support: + # Special case for KHR extensions, since in GLES they are suffixed. + if '_KHR_' in extension_name: + safe_append(gl_extension_commands, command_name, extension_name) + safe_append(gles2_extension_commands, command_name, extension_name) + else: + safe_append(both_extension_commands, command_name, extension_name) + elif 'gl' in support: + safe_append(gl_extension_commands, command_name, extension_name) + elif 'gles2' in support: + safe_append(gles2_extension_commands, command_name, extension_name) + + gl_requirements = {} + gles2_requirements = {} + gl_extension_requirements = {} + gles2_extension_requirements = {} + both_extension_requirements = {} + + # Used later in the NULL bindings. + all_entry_points = [] + + for comment, entry_points in json_data.iteritems(): + for entry_point_no_prefix in entry_points: + entry_point = "gl" + entry_point_no_prefix + + all_entry_points.append(entry_point) + + gl_required = None + gles2_required = None + + if entry_point in api_feature_info: + for api, name, number in api_feature_info[entry_point]: + major, minor = number.split(".") + reqs = (major, minor) + if api == 'gl': + if not gl_required: + gl_required = reqs + elif entry_point in core_removed_eps: + print('Upgrade ' + entry_point + ' to ' + str(reqs) + ' instead of ' + str(gl_required)) + gl_required = reqs + else: + print('Keep ' + entry_point + ' at ' + str(gl_required) + ' instead of ' + str(reqs)) + elif api == 'gles2': + if not gles2_required: + gles2_required = reqs + else: + print("Duplicate for " + entry_point + ": " + str(reqs) + " and " + str(gles2_required)) + else: + raise Exception('Bad api type: ' + api) + + if gl_required: + safe_append(gl_requirements, gl_required, entry_point) + + if gles2_required: + safe_append(gles2_requirements, gles2_required, entry_point) + + # Special case for finding extensions that overlap with core functions. + + extension = False + + for ep in [entry_point, entry_point + "EXT", entry_point + "ARB", entry_point + "OES"]: + if ep in both_extension_commands: + extension = True + for extension in both_extension_commands[ep]: + safe_append(both_extension_requirements, extension, (entry_point, ep)) + + else: + if ep in gl_extension_commands: + extension = True + for extension in gl_extension_commands[ep]: + safe_append(gl_extension_requirements, extension, (entry_point, ep)) + + if ep in gles2_extension_commands: + extension = True + for extension in gles2_extension_commands[ep]: + full_ep = ep + if '_KHR_' in extension: + full_ep += 'KHR' + safe_append(gles2_extension_requirements, extension, (entry_point, full_ep)) + + if not (gl_required or gles2_required or extension): + raise Exception('Entry point ' + entry_point + ' not found in the xml.') + + table_data = [] + for comment, entry_points in sorted(json_data.iteritems()): + formatted = [" // " + comment] + formatted += [format_ep_decl(entry_point) for entry_point in sorted(entry_points)] + + table_data.append("\n".join(formatted)) + + dispatch_table_header = dispatch_table_header_template.format( + script_name = os.path.basename(sys.argv[0]), + data_source_name = data_source_name, + year = date.today().year, + file_name = dispatch_header_path, + table_data = "\n\n".join(table_data)) + + with open(dispatch_header_path, "w") as out: + out.write(dispatch_table_header) + + gl_data = [] + for gl_required, entry_points in sorted(gl_requirements.iteritems()): + gl_data.append(format_requirements_lines(gl_required, entry_points)) + + gl_extensions_data = [] + for extension, entry_points in sorted(gl_extension_requirements.iteritems()): + gl_extensions_data.append(format_extension_requirements_lines(extension, entry_points, "gl")) + + gles2_data = [] + for gles2_required, entry_points in sorted(gles2_requirements.iteritems()): + gles2_data.append(format_requirements_lines(gles2_required, entry_points)) + + gles2_extensions_data = [] + for extension, entry_points in sorted(gles2_extension_requirements.iteritems()): + gles2_extensions_data.append(format_extension_requirements_lines(extension, entry_points, "gles2")) + + both_extensions_data = [] + for extension, entry_points in sorted(both_extension_requirements.iteritems()): + both_extensions_data.append(format_extension_requirements_lines(extension, entry_points, "gles2|gl")) + + dispatch_table_source = dispatch_table_source_template.format( + script_name = os.path.basename(sys.argv[0]), + data_source_name = data_source_name, + year = date.today().year, + file_name = dispatch_source_path, + gl_data = "\n\n".join(gl_data), + gl_extensions_data = "\n\n".join(gl_extensions_data), + gles2_data = "\n\n".join(gles2_data), + gles2_extensions_data = "\n\n".join(gles2_extensions_data), + both_extensions_data = "\n\n".join(both_extensions_data), + gl_null_data = "\n\n".join(nullify(gl_data)), + gl_null_extensions_data = "\n\n".join(nullify(gl_extensions_data)), + gles2_null_data = "\n\n".join(nullify(gles2_data)), + gles2_null_extensions_data = "\n\n".join(nullify(gles2_extensions_data)), + both_null_extensions_data = "\n\n".join(nullify(both_extensions_data))) + + with open(dispatch_source_path, "w") as out: + out.write(dispatch_table_source) + + # Generate the NULL/stub entry points. + # Process the whole set of commands + + command_defs = {} + command_decls = {} + + for command in xml_root.findall('commands/command'): + proto = command.find('proto') + command_name = proto.find('name').text + entry = ''.join(proto.itertext()) + return_type = entry[:-len(command_name)] + entry = return_type + ' INTERNAL_GL_APIENTRY ' + entry[len(return_type):] + 'NULL(' + + param_text = [format_param(param) for param in command.findall('param')] + entry += ', '.join(param_text) + ')' + + command_decls[command_name] = entry + ';' + + entry += '\n{\n' + if return_type != 'void ': + entry += ' return static_cast<' + return_type + '>(0);\n' + entry += '}' + + command_defs[command_name] = entry + + null_decls = [command_decls[entry_point] for entry_point in sorted(all_entry_points)] + null_stubs = [command_defs[entry_point] for entry_point in sorted(all_entry_points)] + + null_functions_header = null_functions_header_template.format( + script_name = os.path.basename(sys.argv[0]), + data_source_name = data_source_name, + year = date.today().year, + file_name = null_functions_header_path, + table_data = "\n".join(null_decls)) + + with open(null_functions_header_path, "w") as out: + out.write(null_functions_header) + + null_functions_source = null_functions_source_template.format( + script_name = os.path.basename(sys.argv[0]), + data_source_name = data_source_name, + year = date.today().year, + file_name = null_functions_source_path, + table_data = "\n\n".join(null_stubs)) + + with open(null_functions_source_path, "w") as out: + out.write(null_functions_source) + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/libANGLE/renderer/load_functions_table_autogen.cpp b/src/libANGLE/renderer/load_functions_table_autogen.cpp index 256dd218a..6d4a0e9c6 100644 --- a/src/libANGLE/renderer/load_functions_table_autogen.cpp +++ b/src/libANGLE/renderer/load_functions_table_autogen.cpp @@ -1,7 +1,7 @@ // GENERATED FILE - DO NOT EDIT. // Generated by gen_load_functions_table.py using data from load_functions_data.json // -// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// 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. // diff --git a/src/libANGLE/renderer/vulkan/gen_vk_format_table.py b/src/libANGLE/renderer/vulkan/gen_vk_format_table.py index 2129a7180..6499a9f3b 100644 --- a/src/libANGLE/renderer/vulkan/gen_vk_format_table.py +++ b/src/libANGLE/renderer/vulkan/gen_vk_format_table.py @@ -5,6 +5,7 @@ # # gen_vk_format_table.py: # Code generation for vk format map. See vk_format_map.json for data source. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. from datetime import date import json @@ -95,89 +96,115 @@ static constexpr BufferFormatInitInfo kInfo[] = {{{buffer_list}}}; initBufferFallback(renderer, kInfo, ArraySize(kInfo)); }}""" + def is_packed(format_id): - return "true" if "_PACK" in format_id else "false" + return "true" if "_PACK" in format_id else "false" def gen_format_case(angle, internal_format, vk_json_data): - vk_map = vk_json_data["map"] - vk_overrides = vk_json_data["overrides"] - vk_fallbacks = vk_json_data["fallbacks"] - args = dict( - format_id=angle, - internal_format=internal_format, - texture_template="", - buffer_template="") + vk_map = vk_json_data["map"] + vk_overrides = vk_json_data["overrides"] + vk_fallbacks = vk_json_data["fallbacks"] + args = dict( + format_id=angle, + internal_format=internal_format, + texture_template="", + buffer_template="") - if ((angle not in vk_map) and (angle not in vk_overrides) and - (angle not in vk_fallbacks)) or angle == 'NONE': - return empty_format_entry_template.format(**args) + if ((angle not in vk_map) and (angle not in vk_overrides) and + (angle not in vk_fallbacks)) or angle == 'NONE': + return empty_format_entry_template.format(**args) - def get_formats(format, type): - format = vk_overrides.get(format, {}).get(type, format) - if format not in vk_map: - return [] - fallbacks = vk_fallbacks.get(format, {}).get(type, []) - if not isinstance(fallbacks, list): - fallbacks = [fallbacks] - return [format] + fallbacks + def get_formats(format, type): + format = vk_overrides.get(format, {}).get(type, format) + if format not in vk_map: + return [] + fallbacks = vk_fallbacks.get(format, {}).get(type, []) + if not isinstance(fallbacks, list): + fallbacks = [fallbacks] + return [format] + fallbacks - def texture_args(format): - return dict( - texture="angle::FormatID::" + format, - vk_texture_format=vk_map[format], - texture_initializer=angle_format.get_internal_format_initializer( - internal_format, format)) + def texture_args(format): + return dict( + texture="angle::FormatID::" + format, + vk_texture_format=vk_map[format], + texture_initializer=angle_format.get_internal_format_initializer( + internal_format, format)) - def buffer_args(format): - return dict( - buffer="angle::FormatID::" + format, - vk_buffer_format=vk_map[format], - vk_buffer_format_is_packed=is_packed(vk_map[format]), - vertex_load_function=angle_format.get_vertex_copy_function( - angle, format), - vertex_load_converts='false' if angle == format else 'true', - ) + def buffer_args(format): + return dict( + buffer="angle::FormatID::" + format, + vk_buffer_format=vk_map[format], + vk_buffer_format_is_packed=is_packed(vk_map[format]), + vertex_load_function=angle_format.get_vertex_copy_function( + angle, format), + vertex_load_converts='false' if angle == format else 'true', + ) - textures = get_formats(angle, "texture") - if len(textures) == 1: - args.update(texture_template=texture_basic_template) - args.update(texture_args(textures[0])) - elif len(textures) > 1: - args.update( - texture_template=texture_fallback_template, - texture_list=", ".join( - texture_struct_template.format(**texture_args(i)) - for i in textures)) + textures = get_formats(angle, "texture") + if len(textures) == 1: + args.update(texture_template=texture_basic_template) + args.update(texture_args(textures[0])) + elif len(textures) > 1: + args.update( + texture_template=texture_fallback_template, + texture_list=", ".join( + texture_struct_template.format(**texture_args(i)) + for i in textures)) - buffers = get_formats(angle, "buffer") - if len(buffers) == 1: - args.update(buffer_template=buffer_basic_template) - args.update(buffer_args(buffers[0])) - elif len(buffers) > 1: - args.update( - buffer_template=buffer_fallback_template, - buffer_list=", ".join( - buffer_struct_template.format(**buffer_args(i)) for i in buffers)) + buffers = get_formats(angle, "buffer") + if len(buffers) == 1: + args.update(buffer_template=buffer_basic_template) + args.update(buffer_args(buffers[0])) + elif len(buffers) > 1: + args.update( + buffer_template=buffer_fallback_template, + buffer_list=", ".join( + buffer_struct_template.format(**buffer_args(i)) for i in buffers)) - return format_entry_template.format(**args).format(**args) + return format_entry_template.format(**args).format(**args) -input_file_name = 'vk_format_map.json' -out_file_name = 'vk_format_table' +def main(): -angle_to_gl = angle_format.load_inverse_table(os.path.join('..', 'angle_format_map.json')) -vk_json_data = angle_format.load_json(input_file_name) -vk_cases = [gen_format_case(angle, gl, vk_json_data) - for angle, gl in sorted(angle_to_gl.iteritems())] + input_file_name = 'vk_format_map.json' + out_file_name = 'vk_format_table_autogen.cpp' -output_cpp = template_table_autogen_cpp.format( - copyright_year = date.today().year, - format_case_data = "\n".join(vk_cases), - script_name = __file__, - out_file_name = out_file_name, - input_file_name = input_file_name) + # auto_script parameters. + if len(sys.argv) > 1: + inputs = [ + '../angle_format.py', + '../angle_format_map.json', + input_file_name + ] + outputs = [out_file_name] -with open(out_file_name + '_autogen.cpp', 'wt') as out_file: - out_file.write(output_cpp) - out_file.close() + 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 + + angle_to_gl = angle_format.load_inverse_table(os.path.join('..', 'angle_format_map.json')) + vk_json_data = angle_format.load_json(input_file_name) + vk_cases = [gen_format_case(angle, gl, vk_json_data) + for angle, gl in sorted(angle_to_gl.iteritems())] + + output_cpp = template_table_autogen_cpp.format( + copyright_year = date.today().year, + format_case_data = "\n".join(vk_cases), + script_name = __file__, + out_file_name = out_file_name, + input_file_name = input_file_name) + + with open(out_file_name, 'wt') as out_file: + out_file.write(output_cpp) + out_file.close() + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/libANGLE/renderer/vulkan/gen_vk_internal_shaders.py b/src/libANGLE/renderer/vulkan/gen_vk_internal_shaders.py index a788a9890..993416605 100644 --- a/src/libANGLE/renderer/vulkan/gen_vk_internal_shaders.py +++ b/src/libANGLE/renderer/vulkan/gen_vk_internal_shaders.py @@ -6,6 +6,8 @@ # gen_vk_internal_shaders.py: # Code generation for internal Vulkan shaders. Should be run when an internal # shader program is changed, added or removed. +# Because this script can be slow direct invocation is supported. But before +# code upload please run scripts/run_code_generation.py. from datetime import date import json @@ -248,48 +250,8 @@ compact_newlines_regex = re.compile(r"\n\s*\n", re.MULTILINE) def cleanup_preprocessed_shader(shader_text): return compact_newlines_regex.sub('\n\n', shader_text.strip()) -# STEP 0: Handle inputs/outputs for run_code_generation.py's auto_script -shaders_dir = os.path.join('shaders', 'src') -if not os.path.isdir(shaders_dir): - raise Exception("Could not find shaders directory") - -print_inputs = len(sys.argv) == 2 and sys.argv[1] == 'inputs' -print_outputs = len(sys.argv) == 2 and sys.argv[1] == 'outputs' -# If an argument X is given that's not inputs or outputs, compile shaders that match *X*. -# This is useful in development to build only the shader of interest. -shader_files_to_compile = os.listdir(shaders_dir) -if not (print_inputs or print_outputs or len(sys.argv) < 2): - shader_files_to_compile = [f for f in shader_files_to_compile if f.find(sys.argv[1]) != -1] - -valid_extensions = ['.vert', '.frag', '.comp'] -input_shaders = sorted([os.path.join(shaders_dir, shader) - for shader in os.listdir(shaders_dir) - if any([os.path.splitext(shader)[1] == ext for ext in valid_extensions])]) -if print_inputs: - print(",".join(input_shaders)) - sys.exit(0) - -# STEP 1: Call glslang to generate the internal shaders into small .inc files. - -# a) Get the path to the glslang binary from the script directory. -build_path = find_build_path(".") -print("Using glslang_validator from '" + build_path + "'") -result = subprocess.call(['ninja', '-C', build_path, 'glslang_validator']) -if result != 0: - raise Exception("Error building glslang_validator") - -glslang_binary = 'glslang_validator' -if os.name == 'nt': - glslang_binary += '.exe' -glslang_path = os.path.join(build_path, glslang_binary) -if not os.path.isfile(glslang_path): - raise Exception("Could not find " + glslang_binary) - -# b) Iterate over the shaders and call glslang with the right arguments. -output_shaders = [] - -def compile_variation(shader_file, shader_basename, flags, enums, - flags_active, enum_indices, flags_bits, enum_bits, do_compile): +def compile_variation(glslang_path, shader_file, shader_basename, flags, enums, + flags_active, enum_indices, flags_bits, enum_bits, output_shaders): glslang_args = [glslang_path] @@ -322,7 +284,7 @@ def compile_variation(shader_file, shader_basename, flags, enums, output_path = get_output_path(output_name) output_shaders.append(output_path) - if do_compile: + if glslang_path is not None: glslang_preprocessor_output_args = glslang_args + ['-E'] glslang_preprocessor_output_args.append(shader_file) # Input GLSL shader @@ -350,40 +312,7 @@ class ShaderAndVariations: get_variation_bits(self.flags, self.enums) (self.flags_bits, self.enum_bits) = get_variation_bits(self.flags, self.enums) -input_shaders_and_variations = [ShaderAndVariations(shader_file) for shader_file in input_shaders] -for shader_and_variation in input_shaders_and_variations: - shader_file = shader_and_variation.shader_file - flags = shader_and_variation.flags - enums = shader_and_variation.enums - flags_bits = shader_and_variation.flags_bits - enum_bits = shader_and_variation.enum_bits - - # an array where each element i is in [0, len(enums[i])), - # telling which enum is currently selected - enum_indices = [0] * len(enums) - - output_name = os.path.basename(shader_file) - - while True: - do_compile = not print_outputs and output_name in shader_files_to_compile - # a number where each bit says whether a flag is active or not, - # with values in [0, 2^len(flags)) - for flags_active in range(1 << len(flags)): - compile_variation(shader_file, output_name, flags, enums, - flags_active, enum_indices, flags_bits, enum_bits, do_compile) - - if not next_enum_variation(enums, enum_indices): - break - -output_shaders = sorted(output_shaders) -outputs = output_shaders + [out_file_cpp, out_file_h] - -if print_outputs: - print("\n".join(outputs)) - sys.exit(0) - -# STEP 2: Consolidate the .inc files into an auto-generated cpp/h library. def get_variation_definition(shader_and_variation): shader_file = shader_and_variation.shader_file flags = shader_and_variation.flags @@ -516,52 +445,134 @@ def get_destroy_call(shader_and_variation): destroy += '{\nshader.get().destroy(device);\n}' return destroy -with open(out_file_cpp, 'w') as outfile: - includes = "\n".join([gen_shader_include(shader) for shader in output_shaders]) - shader_tables_cpp = '\n'.join([get_shader_table_cpp(s) - for s in input_shaders_and_variations]) - shader_destroy_calls = '\n'.join([get_destroy_call(s) - for s in input_shaders_and_variations]) - shader_get_functions_cpp = '\n'.join([get_get_function_cpp(s) - for s in input_shaders_and_variations]) - outcode = template_shader_library_cpp.format( - script_name = __file__, - copyright_year = date.today().year, - out_file_name = out_file_cpp, - input_file_name = 'shaders/src/*', - internal_shader_includes = includes, - shader_tables_cpp = shader_tables_cpp, - shader_destroy_calls = shader_destroy_calls, - shader_get_functions_cpp = shader_get_functions_cpp) - outfile.write(outcode) - outfile.close() +def main(): + # STEP 0: Handle inputs/outputs for run_code_generation.py's auto_script + shaders_dir = os.path.join('shaders', 'src') + if not os.path.isdir(shaders_dir): + raise Exception("Could not find shaders directory") -with open(out_file_h, 'w') as outfile: - shader_variation_definitions = '\n'.join([get_variation_definition(s) - for s in input_shaders_and_variations]) - shader_get_functions_h = '\n'.join([get_get_function_h(s) - for s in input_shaders_and_variations]) - shader_tables_h = '\n'.join([get_shader_table_h(s) - for s in input_shaders_and_variations]) - outcode = template_shader_library_h.format( - script_name = __file__, - copyright_year = date.today().year, - out_file_name = out_file_h, - input_file_name = 'shaders/src/*', - shader_variation_definitions = shader_variation_definitions, - shader_get_functions_h = shader_get_functions_h, - shader_tables_h = shader_tables_h) - outfile.write(outcode) - outfile.close() + print_inputs = len(sys.argv) == 2 and sys.argv[1] == 'inputs' + print_outputs = len(sys.argv) == 2 and sys.argv[1] == 'outputs' + # If an argument X is given that's not inputs or outputs, compile shaders that match *X*. + # This is useful in development to build only the shader of interest. + shader_files_to_compile = os.listdir(shaders_dir) + if not (print_inputs or print_outputs or len(sys.argv) < 2): + shader_files_to_compile = [f for f in shader_files_to_compile if f.find(sys.argv[1]) != -1] -# STEP 3: Create a gni file with the generated files. -with open(out_file_gni, 'w') as outfile: - outcode = template_shader_includes_gni.format( - script_name = __file__, - copyright_year = date.today().year, - out_file_name = out_file_gni, - input_file_name = 'shaders/src/*', - shaders_list = ',\n'.join([' "' + slash(shader) + '"' for shader in output_shaders])) - outfile.write(outcode) - outfile.close() + valid_extensions = ['.vert', '.frag', '.comp'] + input_shaders = sorted([os.path.join(shaders_dir, shader) + for shader in os.listdir(shaders_dir) + if any([os.path.splitext(shader)[1] == ext for ext in valid_extensions])]) + if print_inputs: + print(",".join(input_shaders)) + sys.exit(0) + + # STEP 1: Call glslang to generate the internal shaders into small .inc files. + + # a) Get the path to the glslang binary from the script directory. + glslang_path = None + if not print_outputs: + build_path = find_build_path(".") + print("Using glslang_validator from '" + build_path + "'") + result = subprocess.call(['ninja', '-C', build_path, 'glslang_validator']) + if result != 0: + raise Exception("Error building glslang_validator") + + glslang_binary = 'glslang_validator' + if os.name == 'nt': + glslang_binary += '.exe' + glslang_path = os.path.join(build_path, glslang_binary) + if not os.path.isfile(glslang_path): + raise Exception("Could not find " + glslang_binary) + + # b) Iterate over the shaders and call glslang with the right arguments. + output_shaders = [] + + input_shaders_and_variations = [ShaderAndVariations(shader_file) for shader_file in input_shaders] + + for shader_and_variation in input_shaders_and_variations: + shader_file = shader_and_variation.shader_file + flags = shader_and_variation.flags + enums = shader_and_variation.enums + flags_bits = shader_and_variation.flags_bits + enum_bits = shader_and_variation.enum_bits + + # an array where each element i is in [0, len(enums[i])), + # telling which enum is currently selected + enum_indices = [0] * len(enums) + + output_name = os.path.basename(shader_file) + + while True: + do_compile = not print_outputs and output_name in shader_files_to_compile + # a number where each bit says whether a flag is active or not, + # with values in [0, 2^len(flags)) + for flags_active in range(1 << len(flags)): + compile_variation(glslang_path, shader_file, output_name, flags, enums, + flags_active, enum_indices, flags_bits, enum_bits, output_shaders) + + if not next_enum_variation(enums, enum_indices): + break + + output_shaders = sorted(output_shaders) + outputs = output_shaders + [out_file_cpp, out_file_h] + + if print_outputs: + print(','.join(outputs)) + sys.exit(0) + + # STEP 2: Consolidate the .inc files into an auto-generated cpp/h library. + with open(out_file_cpp, 'w') as outfile: + includes = "\n".join([gen_shader_include(shader) for shader in output_shaders]) + shader_tables_cpp = '\n'.join([get_shader_table_cpp(s) + for s in input_shaders_and_variations]) + shader_destroy_calls = '\n'.join([get_destroy_call(s) + for s in input_shaders_and_variations]) + shader_get_functions_cpp = '\n'.join([get_get_function_cpp(s) + for s in input_shaders_and_variations]) + + outcode = template_shader_library_cpp.format( + script_name = __file__, + copyright_year = date.today().year, + out_file_name = out_file_cpp, + input_file_name = 'shaders/src/*', + internal_shader_includes = includes, + shader_tables_cpp = shader_tables_cpp, + shader_destroy_calls = shader_destroy_calls, + shader_get_functions_cpp = shader_get_functions_cpp) + outfile.write(outcode) + outfile.close() + + with open(out_file_h, 'w') as outfile: + shader_variation_definitions = '\n'.join([get_variation_definition(s) + for s in input_shaders_and_variations]) + shader_get_functions_h = '\n'.join([get_get_function_h(s) + for s in input_shaders_and_variations]) + shader_tables_h = '\n'.join([get_shader_table_h(s) + for s in input_shaders_and_variations]) + outcode = template_shader_library_h.format( + script_name = __file__, + copyright_year = date.today().year, + out_file_name = out_file_h, + input_file_name = 'shaders/src/*', + shader_variation_definitions = shader_variation_definitions, + shader_get_functions_h = shader_get_functions_h, + shader_tables_h = shader_tables_h) + outfile.write(outcode) + outfile.close() + + # STEP 3: Create a gni file with the generated files. + with open(out_file_gni, 'w') as outfile: + outcode = template_shader_includes_gni.format( + script_name = __file__, + copyright_year = date.today().year, + out_file_name = out_file_gni, + input_file_name = 'shaders/src/*', + shaders_list = ',\n'.join([' "' + slash(shader) + '"' for shader in output_shaders])) + outfile.write(outcode) + outfile.close() + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py b/src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py index bdf08e4c2..6a8953bf2 100644 --- a/src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py +++ b/src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py @@ -5,6 +5,7 @@ # # gen_vk_mandatory_format_support_table.py: # Code generation for mandatory formats supported by Vulkan. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. from datetime import date import sys @@ -85,30 +86,56 @@ def gen_format_case(index, vk_to_index_to_format_map, vk_map): buffer_features = buffer_features_str) -input_file_name = 'vk_mandatory_format_support_data.json' -out_file_name = 'vk_mandatory_format_support_table' +def main(): -tree = etree.parse(script_relative('../../../../third_party/vulkan-headers/src/registry/vk.xml')) -root = tree.getroot() -vk_format_enums = root.findall(".//enums[@name='VkFormat']/enum") -vk_format_name_to_index_map = {} -num_formats = len(vk_format_enums) -for format_enum in vk_format_enums: - index = int(format_enum.attrib['value']) - vk_format = format_enum.attrib['name'] - vk_format_name_to_index_map[index] = vk_format + input_file_name = 'vk_mandatory_format_support_data.json' + out_file_name = 'vk_mandatory_format_support_table_autogen.cpp' + vk_xml_file = '../../../../third_party/vulkan-headers/src/registry/vk.xml' -vk_map = angle_format.load_json(input_file_name) -vk_cases = [gen_format_case(index, vk_format_name_to_index_map, vk_map) for index in vk_format_name_to_index_map] + # auto_script parameters. + if len(sys.argv) > 1: + inputs = [ + '../angle_format.py', + input_file_name, + vk_xml_file, + ] + outputs = [out_file_name] -output_cpp = template_table_autogen_cpp.format( - copyright_year = date.today().year, - num_formats = num_formats, - format_case_data = "\n,".join(vk_cases), - script_name = __file__, - out_file_name = out_file_name, - input_file_name = input_file_name) + 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 -with open(out_file_name + '_autogen.cpp', 'wt') as out_file: - out_file.write(output_cpp) - out_file.close() + tree = etree.parse(script_relative(vk_xml_file)) + root = tree.getroot() + vk_format_enums = root.findall(".//enums[@name='VkFormat']/enum") + vk_format_name_to_index_map = {} + num_formats = len(vk_format_enums) + for format_enum in vk_format_enums: + index = int(format_enum.attrib['value']) + vk_format = format_enum.attrib['name'] + vk_format_name_to_index_map[index] = vk_format + + vk_map = angle_format.load_json(input_file_name) + vk_cases = [gen_format_case(index, vk_format_name_to_index_map, vk_map) for index in vk_format_name_to_index_map] + + output_cpp = template_table_autogen_cpp.format( + copyright_year = date.today().year, + num_formats = num_formats, + format_case_data = "\n,".join(vk_cases), + script_name = __file__, + out_file_name = out_file_name, + input_file_name = input_file_name) + + with open(out_file_name, 'wt') as out_file: + out_file.write(output_cpp) + out_file.close() + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp b/src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp index 0d793c046..5121a58f7 100644 --- a/src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp +++ b/src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp @@ -5,7 +5,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// vk_format_table: +// vk_format_table_autogen.cpp: // Queries for full Vulkan format information based on GL format. #include "libANGLE/renderer/vulkan/vk_format_utils.h" diff --git a/src/libANGLE/renderer/vulkan/vk_mandatory_format_support_table_autogen.cpp b/src/libANGLE/renderer/vulkan/vk_mandatory_format_support_table_autogen.cpp index 211864824..dbc2baaa5 100644 --- a/src/libANGLE/renderer/vulkan/vk_mandatory_format_support_table_autogen.cpp +++ b/src/libANGLE/renderer/vulkan/vk_mandatory_format_support_table_autogen.cpp @@ -7,7 +7,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// vk_mandatory_format_support_table: +// vk_mandatory_format_support_table_autogen.cpp: // Queries for full Vulkan mandatory format support information based on VK format. #include "libANGLE/renderer/vulkan/vk_format_utils.h" diff --git a/src/libGLESv2.gni b/src/libGLESv2.gni index dd4be32e6..25c28c28c 100644 --- a/src/libGLESv2.gni +++ b/src/libGLESv2.gni @@ -464,7 +464,7 @@ libangle_d3d11_sources = [ "src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp", "src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h", "src/libANGLE/renderer/d3d/d3d11/dxgi_format_map_autogen.cpp", - "src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp", + "src/libANGLE/renderer/d3d/d3d11/dxgi_support_table_autogen.cpp", "src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h", "src/libANGLE/renderer/d3d/d3d11/Fence11.cpp", "src/libANGLE/renderer/d3d/d3d11/Fence11.h", diff --git a/src/libGLESv2/gen_proc_table.py b/src/libGLESv2/gen_proc_table.py index 671758f0c..834222f86 100644 --- a/src/libGLESv2/gen_proc_table.py +++ b/src/libGLESv2/gen_proc_table.py @@ -5,6 +5,7 @@ # # gen_proc_table.py: # Code generation for entry point loading tables. +# NOTE: don't run this script directly. Run scripts/run_code_generation.py. # TODO(jmadill): Should be part of entry point generation. @@ -55,30 +56,51 @@ size_t g_numProcs = {num_procs}; sys.path.append('../libANGLE/renderer') import angle_format -json_data = angle_format.load_json(data_source_name) +def main(): -all_functions = {} + # auto_script parameters. + if len(sys.argv) > 1: + inputs = [data_source_name] + outputs = [out_file_name] -for description, functions in json_data.iteritems(): - for function in functions: - if function.startswith("gl"): - all_functions[function] = "gl::" + function[2:] - # Special handling for EGL_ANGLE_explicit_context extension - if support_egl_ANGLE_explicit_context: - all_functions[function + "ContextANGLE"] = "gl::" + function[2:] + "ContextANGLE" - elif function.startswith("egl"): - all_functions[function] = "EGL_" + function[3:] + if sys.argv[1] == 'inputs': + print ','.join(inputs) + elif sys.argv[1] == 'outputs': + print ','.join(outputs) else: - all_functions[function] = function + print('Invalid script parameters') + return 1 + return 0 -proc_data = [(' {"%s", P(%s)}' % (func, angle_func)) for func, angle_func in sorted(all_functions.iteritems())] + json_data = angle_format.load_json(data_source_name) -with open(out_file_name, 'wb') as out_file: - output_cpp = template_cpp.format( - script_name = sys.argv[0], - data_source_name = data_source_name, - copyright_year = date.today().year, - proc_data = ",\n".join(proc_data), - num_procs = len(proc_data)) - out_file.write(output_cpp) - out_file.close() \ No newline at end of file + all_functions = {} + + for description, functions in json_data.iteritems(): + for function in functions: + if function.startswith("gl"): + all_functions[function] = "gl::" + function[2:] + # Special handling for EGL_ANGLE_explicit_context extension + if support_egl_ANGLE_explicit_context: + all_functions[function + "ContextANGLE"] = "gl::" + function[2:] + "ContextANGLE" + 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.iteritems())] + + with open(out_file_name, 'w') as out_file: + output_cpp = template_cpp.format( + script_name = sys.argv[0], + data_source_name = data_source_name, + copyright_year = date.today().year, + proc_data = ",\n".join(proc_data), + num_procs = len(proc_data)) + out_file.write(output_cpp) + out_file.close() + return 0 + + +if __name__ == '__main__': + sys.exit(main())