Path: blob/main_old/scripts/gen_gl_enum_utils.py
1693 views
#!/usr/bin/python31#2# Copyright 2019 The ANGLE Project Authors. All rights reserved.3# Use of this source code is governed by a BSD-style license that can be4# found in the LICENSE file.5#6# gen_gl_enum_utils.py:7# Generates GLenum value to string mapping for ANGLE8# NOTE: don't run this script directly. Run scripts/run_code_generation.py.910import sys11import os1213import registry_xml1415template_gl_enums_header = """// GENERATED FILE - DO NOT EDIT.16// Generated by {script_name} using data from {data_source_name}.17//18// Copyright 2019 The ANGLE Project Authors. All rights reserved.19// Use of this source code is governed by a BSD-style license that can be20// found in the LICENSE file.21//22// gl_enum_utils_autogen.h:23// mapping of GLenum value to string.2425# ifndef LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_26# define LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_2728namespace gl29{{30enum class GLenumGroup31{{32{gl_enum_groups}33}};34}} // namespace gl3536# endif // LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_37"""3839template_gl_enums_source = """// GENERATED FILE - DO NOT EDIT.40// Generated by {script_name} using data from {data_source_name}.41//42// Copyright 2019 The ANGLE Project Authors. All rights reserved.43// Use of this source code is governed by a BSD-style license that can be44// found in the LICENSE file.45//46// gl_enum_utils_autogen.cpp:47// mapping of GLenum value to string.4849#include "libANGLE/capture/gl_enum_utils_autogen.h"5051#include "libANGLE/capture/gl_enum_utils.h"5253namespace gl54{{55namespace56{{57const char *UnknownGLenumToString(unsigned int value)58{{59constexpr size_t kBufferSize = 64;60static thread_local char sBuffer[kBufferSize];61snprintf(sBuffer, kBufferSize, "0x%04X", value);62return sBuffer;63}}64}} // anonymous namespace6566const char *GLenumToString(GLenumGroup enumGroup, unsigned int value)67{{68switch (enumGroup)69{{70{gl_enums_value_to_string_table}71default:72return UnknownGLenumToString(value);73}}74}}75}} // namespace gl7677"""7879template_enum_group_case = """case GLenumGroup::{group_name}: {{80switch (value) {{81{inner_group_cases}82default:83return UnknownGLenumToString(value);84}}85}}86"""8788template_enum_value_to_string_case = """case {value}: return {name};"""8990exclude_gl_enums = {91'GL_NO_ERROR', 'GL_TIMEOUT_IGNORED', 'GL_INVALID_INDEX', 'GL_VERSION_ES_CL_1_0',92'GL_VERSION_ES_CM_1_1', 'GL_VERSION_ES_CL_1_1'93}94exclude_gl_enum_groups = {'SpecialNumbers'}959697def dump_value_to_string_mapping(gl_enum_in_groups, exporting_enums):98exporting_groups = list()99for group_name, inner_mapping in gl_enum_in_groups.items():100string_value_pairs = list(filter(lambda x: x[0] in exporting_enums, inner_mapping.items()))101if not string_value_pairs:102continue103104# sort according values105string_value_pairs.sort(key=lambda x: (x[1], x[0]))106107# remove all duplicate values from the pairs list108# some value may have more than one GLenum mapped to them, such as:109# GL_DRAW_FRAMEBUFFER_BINDING and GL_FRAMEBUFFER_BINDING110# GL_BLEND_EQUATION_RGB and GL_BLEND_EQUATION111# it is safe to output either one of them, for simplity here just112# choose the shorter one which comes first in the sorted list113exporting_string_value_pairs = list()114for index, pair in enumerate(string_value_pairs):115if index == 0 or pair[1] != string_value_pairs[index - 1][1]:116exporting_string_value_pairs.append(pair)117118inner_code_block = "\n".join([119template_enum_value_to_string_case.format(120value='0x%X' % value,121name='"%s"' % name,122) for name, value in exporting_string_value_pairs123])124125exporting_groups.append((group_name, inner_code_block))126127return "\n".join([128template_enum_group_case.format(129group_name=group_name,130inner_group_cases=inner_code_block,131) for group_name, inner_code_block in sorted(exporting_groups, key=lambda x: x[0])132])133134135def main(header_output_path, source_output_path):136xml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml')137138# build a map from GLenum name to its value139all_gl_enums = dict()140for enums_node in xml.root.findall('enums'):141for enum in enums_node.findall('enum'):142name = enum.attrib['name']143value = int(enum.attrib['value'], base=16)144all_gl_enums[name] = value145146# Parse groups of GLenums to build a {group, name} -> value mapping.147gl_enum_in_groups = dict()148enums_has_group = set()149for enums_group_node in xml.root.findall('groups/group'):150group_name = enums_group_node.attrib['name']151if group_name in exclude_gl_enum_groups:152continue153154if group_name not in gl_enum_in_groups:155gl_enum_in_groups[group_name] = dict()156157for enum_node in enums_group_node.findall('enum'):158enum_name = enum_node.attrib['name']159enums_has_group.add(enum_name)160gl_enum_in_groups[group_name][enum_name] = all_gl_enums[enum_name]161162# Find relevant GLenums according to enabled APIs and extensions.163exporting_enums = set()164# export all the apis165xpath = "./feature[@api='gles2']/require/enum"166for enum_tag in xml.root.findall(xpath):167enum_name = enum_tag.attrib['name']168if enum_name not in exclude_gl_enums:169exporting_enums.add(enum_name)170171for extension in registry_xml.supported_extensions:172xpath = "./extensions/extension[@name='%s']/require/enum" % extension173for enum_tag in xml.root.findall(xpath):174enum_name = enum_tag.attrib['name']175if enum_name not in exclude_gl_enums:176exporting_enums.add(enum_name)177178# For enums that do not have a group, add them to a default group179default_group_name = registry_xml.default_enum_group_name180gl_enum_in_groups[default_group_name] = dict()181default_group = gl_enum_in_groups[default_group_name]182for enum_name in exporting_enums:183if enum_name not in enums_has_group:184default_group[enum_name] = all_gl_enums[enum_name]185186# Write GLenum groups into the header file.187header_content = template_gl_enums_header.format(188script_name=os.path.basename(sys.argv[0]),189data_source_name="gl.xml and gl_angle_ext.xml",190gl_enum_groups=',\n'.join(sorted(gl_enum_in_groups.keys())))191192header_output_path = registry_xml.script_relative(header_output_path)193with open(header_output_path, 'w') as f:194f.write(header_content)195196# Write mapping to source file197gl_enums_value_to_string_table = dump_value_to_string_mapping(gl_enum_in_groups,198exporting_enums)199source_content = template_gl_enums_source.format(200script_name=os.path.basename(sys.argv[0]),201data_source_name="gl.xml and gl_angle_ext.xml",202gl_enums_value_to_string_table=gl_enums_value_to_string_table,203)204205source_output_path = registry_xml.script_relative(source_output_path)206with open(source_output_path, 'w') as f:207f.write(source_content)208209return 0210211212if __name__ == '__main__':213inputs = [214'gl.xml',215'gl_angle_ext.xml',216'registry_xml.py',217]218219gl_enum_utils_autogen_base_path = '../src/libANGLE/capture/gl_enum_utils_autogen'220outputs = [221gl_enum_utils_autogen_base_path + '.h',222gl_enum_utils_autogen_base_path + '.cpp',223]224225if len(sys.argv) > 1:226if sys.argv[1] == 'inputs':227print(','.join(inputs))228elif sys.argv[1] == 'outputs':229print(','.join(outputs))230else:231sys.exit(232main(233registry_xml.script_relative(outputs[0]),234registry_xml.script_relative(outputs[1])))235236237