X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmapi%2Fglapi%2Fgen%2Fgl_enums.py;h=00f8134bae287dc40d149376fd16a0958b6ba168;hb=2ee1c86d71bee5ddca2c8795b4d343e31d28df99;hp=955f27d08185f3f2e63634fe3d7e2227be989f92;hpb=6c4dcef6dc704156115b8d3ad19c3020663c7ffc;p=mesa.git diff --git a/src/mapi/glapi/gen/gl_enums.py b/src/mapi/glapi/gen/gl_enums.py index 955f27d0818..00f8134bae2 100644 --- a/src/mapi/glapi/gen/gl_enums.py +++ b/src/mapi/glapi/gen/gl_enums.py @@ -1,8 +1,7 @@ -#!/usr/bin/python2 -# -*- Mode: Python; py-indent-offset: 8 -*- # (C) Copyright Zack Rusin 2005. All Rights Reserved. # Copyright (C) 2015 Intel Corporation +# Copyright (C) 2015 Broadcom Corporation # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), @@ -26,11 +25,15 @@ # Authors: # Zack Rusin +from __future__ import print_function + import argparse import license import gl_XML +import xml.etree.ElementTree as ET import sys, getopt +import re class PrintGlEnums(gl_XML.gl_print_base): @@ -40,24 +43,27 @@ class PrintGlEnums(gl_XML.gl_print_base): self.name = "gl_enums.py (from Mesa)" self.license = license.bsd_license_template % ( \ """Copyright (C) 1999-2005 Brian Paul All Rights Reserved.""", "BRIAN PAUL") + # Mapping from enum value to (name, priority) tuples. self.enum_table = {} + # Mapping from enum name to value + self.string_to_int = {} def printRealHeader(self): - print '#include "main/glheader.h"' - print '#include "main/enums.h"' - print '#include "main/imports.h"' - print '#include "main/mtypes.h"' - print '' - print 'typedef struct PACKED {' - print ' uint16_t offset;' - print ' int n;' - print '} enum_elt;' - print '' + print('#include "main/glheader.h"') + print('#include "main/enums.h"') + print('#include "main/imports.h"') + print('#include "main/mtypes.h"') + print('') + print('typedef struct PACKED {') + print(' uint32_t offset;') + print(' int n;') + print('} enum_elt;') + print('') return def print_code(self): - print """ + print(""" typedef int (*cfunc)(const void *, const void *); /** @@ -78,12 +84,15 @@ static int compar_nr( const int *a, enum_elt *b ) static char token_tmp[20]; -const char *_mesa_lookup_enum_by_nr( int nr ) +/** + * This function always returns a string. If the number is a valid enum, it + * returns the enum name. Otherwise, it returns a numeric string. + */ +const char * +_mesa_enum_to_string(int nr) { enum_elt *elt; - STATIC_ASSERT(sizeof(enum_string_table) < (1 << 16)); - elt = bsearch(& nr, enum_string_table_offsets, ARRAY_SIZE(enum_string_table_offsets), sizeof(enum_string_table_offsets[0]), @@ -118,6 +127,7 @@ static const char *prim_names[PRIM_MAX+3] = { "GL_LINE_STRIP_ADJACENCY", "GL_TRIANGLES_ADJACENCY", "GL_TRIANGLE_STRIP_ADJACENCY", + "GL_PATCHES", "outside begin/end", "unknown state" }; @@ -136,71 +146,131 @@ _mesa_lookup_prim_by_nr(GLuint nr) } -""" +""") return - def printBody(self, api_list): - self.enum_table = {} - for api in api_list: - self.process_enums( api ) - - enum_table = [] - - for enum in sorted(self.enum_table.keys()): - low_pri = 9 - best_name = '' - for [name, pri] in self.enum_table[ enum ]: - if pri < low_pri: - low_pri = pri - best_name = name - - enum_table.append((enum, best_name)) + def printBody(self, xml): + self.process_enums(xml) + sorted_enum_values = sorted(self.enum_table.keys()) string_offsets = {} i = 0; - print '#if defined(__GNUC__)' - print '# define LONGSTRING __extension__' - print '#else' - print '# define LONGSTRING' - print '#endif' - print '' - print 'LONGSTRING static const char enum_string_table[] = ' - for enum, name in enum_table: - print ' "%s\\0"' % (name) + print('#if defined(__GNUC__)') + print('# define LONGSTRING __extension__') + print('#else') + print('# define LONGSTRING') + print('#endif') + print('') + print('LONGSTRING static const char enum_string_table[] = {') + # We express the very long concatenation of enum strings as an array + # of characters rather than as a string literal to work-around MSVC's + # 65535 character limit. + for enum in sorted_enum_values: + (name, pri) = self.enum_table[enum] + print(" ", end=' ') + for ch in name: + print("'%c'," % ch, end=' ') + print("'\\0',") + string_offsets[ enum ] = i i += len(name) + 1 - print ' ;' - print '' + print('};') + print('') - print 'static const enum_elt enum_string_table_offsets[%u] =' % (len(enum_table)) - print '{' - for enum, name in enum_table: - print ' { %5u, 0x%08X }, /* %s */' % (string_offsets[enum], enum, name) - print '};' - print '' + print('static const enum_elt enum_string_table_offsets[%u] =' % (len(self.enum_table))) + print('{') + for enum in sorted_enum_values: + (name, pri) = self.enum_table[enum] + print(' { %5u, 0x%08X }, /* %s */' % (string_offsets[enum], enum, name)) + print('};') + print('') self.print_code() return - - def process_enums(self, api): - for obj in api.enumIterateByName(): - if obj.value not in self.enum_table: - self.enum_table[ obj.value ] = [] - - - enum = self.enum_table[ obj.value ] - name = "GL_" + obj.name - priority = obj.priority() - already_in = False; - for n, p in enum: - if n == name: - already_in = True - if not already_in: - enum.append( [name, priority] ) + def add_enum_provider(self, name, priority): + value = self.string_to_int[name] + + # We don't want the weird GL_SKIP_COMPONENTS1_NV enums. + if value < 0: + return + # We don't want the 64-bit GL_TIMEOUT_IGNORED "enums" + if value > 0xffffffff: + return + + # We don't want bitfields in the enum-to-string table -- + # individual bits have so many names, it's pointless. Note + # that we check for power-of-two, since some getters have + # "_BITS" in their name, but none have a power-of-two enum + # number. + if not (value & (value - 1)) and '_BIT' in name: + return + + # Also drop the GL_*_ATTRIB_BITS bitmasks. + if value == 0xffffffff: + return + + if value in self.enum_table: + (n, p) = self.enum_table[value] + if priority < p: + self.enum_table[value] = (name, priority) + else: + self.enum_table[value] = (name, priority) + + def process_extension(self, extension): + if extension.get('name').startswith('GL_ARB_'): + extension_prio = 400 + elif extension.get('name').startswith('GL_EXT_'): + extension_prio = 600 + else: + extension_prio = 800 + + for enum in extension.findall('require/enum'): + self.add_enum_provider(enum.get('name'), extension_prio) + + def process_enums(self, xml): + # First, process the XML entries that define the hex values + # for all of the enum names. + for enum in xml.findall('enums/enum'): + name = enum.get('name') + value = int(enum.get('value'), base=16) + + # If the same name ever maps to multiple values, that can + # confuse us. GL_ACTIVE_PROGRAM_EXT is OK to lose because + # we choose GL_ACTIVE PROGRAM instead. + if name in self.string_to_int and name != "GL_ACTIVE_PROGRAM_EXT": + print("#error Renumbering {0} from {1} to {2}".format(name, self.string_to_int[name], value)) + + self.string_to_int[name] = value + + # Now, process all of the API versions and extensions that + # provide enums, so we can decide what name to call any hex + # value. + for feature in xml.findall('feature'): + feature_name = feature.get('name') + + # When an enum gets renamed in a newer version (generally + # because of some generalization of the functionality), + # prefer the newer name. Also, prefer desktop GL names to + # ES. + m = re.match('GL_VERSION_([0-9])_([0-9])', feature_name) + if m: + feature_prio = 100 - int(m.group(1) + m.group(2)) + else: + m = re.match('GL_ES_VERSION_([0-9])_([0-9])', feature_name) + if m: + feature_prio = 200 - int(m.group(1) + m.group(2)) + else: + feature_prio = 200 + + for enum in feature.findall('require/enum'): + self.add_enum_provider(enum.get('name'), feature_prio) + + for extension in xml.findall('extensions/extension'): + self.process_extension(extension) def _parser(): @@ -213,10 +283,10 @@ def _parser(): def main(): args = _parser() - api_list = [gl_XML.parse_GL_API(args.input_file)] + xml = ET.parse(args.input_file) printer = PrintGlEnums() - printer.Print(api_list) + printer.Print(xml) if __name__ == '__main__':