3 # (C) Copyright Zack Rusin 2005. All Rights Reserved.
4 # Copyright (C) 2015 Intel Corporation
5 # Copyright (C) 2015 Broadcom Corporation
7 # Permission is hereby granted, free of charge, to any person obtaining a
8 # copy of this software and associated documentation files (the "Software"),
9 # to deal in the Software without restriction, including without limitation
10 # on the rights to use, copy, modify, merge, publish, distribute, sub
11 # license, and/or sell copies of the Software, and to permit persons to whom
12 # the Software is furnished to do so, subject to the following conditions:
14 # The above copyright notice and this permission notice (including the next
15 # paragraph) shall be included in all copies or substantial portions of the
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27 # Zack Rusin <zack@kde.org>
33 import xml
.etree
.ElementTree
as ET
37 class PrintGlEnums(gl_XML
.gl_print_base
):
40 gl_XML
.gl_print_base
.__init
__(self
)
42 self
.name
= "gl_enums.py (from Mesa)"
43 self
.license
= license
.bsd_license_template
% ( \
44 """Copyright (C) 1999-2005 Brian Paul All Rights Reserved.""", "BRIAN PAUL")
45 # Mapping from enum value to (name, priority) tuples.
47 # Mapping from enum name to value
48 self
.string_to_int
= {}
51 def printRealHeader(self
):
52 print '#include "main/glheader.h"'
53 print '#include "main/enums.h"'
54 print '#include "main/imports.h"'
55 print '#include "main/mtypes.h"'
57 print 'typedef struct PACKED {'
58 print ' uint32_t offset;'
66 typedef int (*cfunc)(const void *, const void *);
69 * Compare a key enum value to an element in the \c enum_string_table_offsets array.
71 * \c bsearch always passes the key as the first parameter and the pointer
72 * to the array element as the second parameter. We can elimiate some
73 * extra work by taking advantage of that fact.
75 * \param a Pointer to the desired enum name.
76 * \param b Pointer into the \c enum_string_table_offsets array.
78 static int compar_nr( const int *a, enum_elt *b )
84 static char token_tmp[20];
86 const char *_mesa_enum_to_string( int nr )
90 elt = bsearch(& nr, enum_string_table_offsets,
91 ARRAY_SIZE(enum_string_table_offsets),
92 sizeof(enum_string_table_offsets[0]),
96 return &enum_string_table[elt->offset];
99 /* this is not re-entrant safe, no big deal here */
100 _mesa_snprintf(token_tmp, sizeof(token_tmp) - 1, "0x%x", nr);
101 token_tmp[sizeof(token_tmp) - 1] = '\\0';
109 static const char *prim_names[PRIM_MAX+3] = {
120 "GL_LINES_ADJACENCY",
121 "GL_LINE_STRIP_ADJACENCY",
122 "GL_TRIANGLES_ADJACENCY",
123 "GL_TRIANGLE_STRIP_ADJACENCY",
130 /* Get the name of an enum given that it is a primitive type. Avoids
131 * GL_FALSE/GL_POINTS ambiguity and others.
134 _mesa_lookup_prim_by_nr(GLuint nr)
136 if (nr < ARRAY_SIZE(prim_names))
137 return prim_names[nr];
139 return "invalid mode";
147 def printBody(self
, xml
):
148 self
.process_enums(xml
)
150 sorted_enum_values
= sorted(self
.enum_table
.keys())
153 print '#if defined(__GNUC__)'
154 print '# define LONGSTRING __extension__'
156 print '# define LONGSTRING'
159 print 'LONGSTRING static const char enum_string_table[] = {'
160 # We express the very long concatenation of enum strings as an array
161 # of characters rather than as a string literal to work-around MSVC's
162 # 65535 character limit.
163 for enum
in sorted_enum_values
:
164 (name
, pri
) = self
.enum_table
[enum
]
170 string_offsets
[ enum
] = i
177 print 'static const enum_elt enum_string_table_offsets[%u] =' % (len(self
.enum_table
))
179 for enum
in sorted_enum_values
:
180 (name
, pri
) = self
.enum_table
[enum
]
181 print ' { %5u, 0x%08X }, /* %s */' % (string_offsets
[enum
], enum
, name
)
188 def add_enum_provider(self
, name
, priority
):
189 value
= self
.string_to_int
[name
]
191 # We don't want the weird GL_SKIP_COMPONENTS1_NV enums.
194 # We don't want the 64-bit GL_TIMEOUT_IGNORED "enums"
195 if value
> 0xffffffff:
198 # We don't want bitfields in the enum-to-string table --
199 # individual bits have so many names, it's pointless. Note
200 # that we check for power-of-two, since some getters have
201 # "_BITS" in their name, but none have a power-of-two enum
203 if not (value
& (value
- 1)) and '_BIT' in name
:
206 # Also drop the GL_*_ATTRIB_BITS bitmasks.
207 if value
== 0xffffffff:
210 if value
in self
.enum_table
:
211 (n
, p
) = self
.enum_table
[value
]
213 self
.enum_table
[value
] = (name
, priority
)
215 self
.enum_table
[value
] = (name
, priority
)
217 def process_extension(self
, extension
):
218 if extension
.get('name').startswith('GL_ARB_'):
220 elif extension
.get('name').startswith('GL_EXT_'):
225 for enum
in extension
.findall('require/enum'):
226 self
.add_enum_provider(enum
.get('name'), extension_prio
)
228 def process_enums(self
, xml
):
229 # First, process the XML entries that define the hex values
230 # for all of the enum names.
231 for enum
in xml
.findall('enums/enum'):
232 name
= enum
.get('name')
233 value
= int(enum
.get('value'), base
=16)
235 # If the same name ever maps to multiple values, that can
236 # confuse us. GL_ACTIVE_PROGRAM_EXT is OK to lose because
237 # we choose GL_ACTIVE PROGRAM instead.
238 if name
in self
.string_to_int
and name
!= "GL_ACTIVE_PROGRAM_EXT":
239 print "#error Renumbering {0} from {1} to {2}".format(name
, self
.string_to_int
[name
], value
)
241 self
.string_to_int
[name
] = value
243 # Now, process all of the API versions and extensions that
244 # provide enums, so we can decide what name to call any hex
246 for feature
in xml
.findall('feature'):
247 feature_name
= feature
.get('name')
249 # When an enum gets renamed in a newer version (generally
250 # because of some generalization of the functionality),
251 # prefer the newer name. Also, prefer desktop GL names to
253 m
= re
.match('GL_VERSION_([0-9])_([0-9])', feature_name
)
255 feature_prio
= 100 - int(m
.group(1) + m
.group(2))
257 m
= re
.match('GL_ES_VERSION_([0-9])_([0-9])', feature_name
)
259 feature_prio
= 200 - int(m
.group(1) + m
.group(2))
263 for enum
in feature
.findall('require/enum'):
264 self
.add_enum_provider(enum
.get('name'), feature_prio
)
266 for extension
in xml
.findall('extensions/extension'):
267 self
.process_extension(extension
)
271 parser
= argparse
.ArgumentParser()
272 parser
.add_argument('-f', '--input_file',
274 help="Choose an xml file to parse.")
275 return parser
.parse_args()
280 xml
= ET
.parse(args
.input_file
)
282 printer
= PrintGlEnums()
286 if __name__
== '__main__':