mesa: Use a 32-bit offset for the enums.c string offset table.
[mesa.git] / src / mapi / glapi / gen / gl_enums.py
1 #!/usr/bin/python2
2
3 # (C) Copyright Zack Rusin 2005. All Rights Reserved.
4 # Copyright (C) 2015 Intel Corporation
5 # Copyright (C) 2015 Broadcom Corporation
6 #
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:
13 #
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
16 # Software.
17 #
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
24 # IN THE SOFTWARE.
25 #
26 # Authors:
27 # Zack Rusin <zack@kde.org>
28
29 import argparse
30
31 import license
32 import gl_XML
33 import xml.etree.ElementTree as ET
34 import sys, getopt
35 import re
36
37 class PrintGlEnums(gl_XML.gl_print_base):
38
39 def __init__(self):
40 gl_XML.gl_print_base.__init__(self)
41
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.
46 self.enum_table = {}
47 # Mapping from enum name to value
48 self.string_to_int = {}
49
50
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"'
56 print ''
57 print 'typedef struct PACKED {'
58 print ' uint32_t offset;'
59 print ' int n;'
60 print '} enum_elt;'
61 print ''
62 return
63
64 def print_code(self):
65 print """
66 typedef int (*cfunc)(const void *, const void *);
67
68 /**
69 * Compare a key enum value to an element in the \c enum_string_table_offsets array.
70 *
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.
74 *
75 * \param a Pointer to the desired enum name.
76 * \param b Pointer into the \c enum_string_table_offsets array.
77 */
78 static int compar_nr( const int *a, enum_elt *b )
79 {
80 return a[0] - b->n;
81 }
82
83
84 static char token_tmp[20];
85
86 const char *_mesa_enum_to_string( int nr )
87 {
88 enum_elt *elt;
89
90 elt = bsearch(& nr, enum_string_table_offsets,
91 ARRAY_SIZE(enum_string_table_offsets),
92 sizeof(enum_string_table_offsets[0]),
93 (cfunc) compar_nr);
94
95 if (elt != NULL) {
96 return &enum_string_table[elt->offset];
97 }
98 else {
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';
102 return token_tmp;
103 }
104 }
105
106 /**
107 * Primitive names
108 */
109 static const char *prim_names[PRIM_MAX+3] = {
110 "GL_POINTS",
111 "GL_LINES",
112 "GL_LINE_LOOP",
113 "GL_LINE_STRIP",
114 "GL_TRIANGLES",
115 "GL_TRIANGLE_STRIP",
116 "GL_TRIANGLE_FAN",
117 "GL_QUADS",
118 "GL_QUAD_STRIP",
119 "GL_POLYGON",
120 "GL_LINES_ADJACENCY",
121 "GL_LINE_STRIP_ADJACENCY",
122 "GL_TRIANGLES_ADJACENCY",
123 "GL_TRIANGLE_STRIP_ADJACENCY",
124 "GL_PATCHES",
125 "outside begin/end",
126 "unknown state"
127 };
128
129
130 /* Get the name of an enum given that it is a primitive type. Avoids
131 * GL_FALSE/GL_POINTS ambiguity and others.
132 */
133 const char *
134 _mesa_lookup_prim_by_nr(GLuint nr)
135 {
136 if (nr < ARRAY_SIZE(prim_names))
137 return prim_names[nr];
138 else
139 return "invalid mode";
140 }
141
142
143 """
144 return
145
146
147 def printBody(self, xml):
148 self.process_enums(xml)
149
150 sorted_enum_values = sorted(self.enum_table.keys())
151 string_offsets = {}
152 i = 0;
153 print '#if defined(__GNUC__)'
154 print '# define LONGSTRING __extension__'
155 print '#else'
156 print '# define LONGSTRING'
157 print '#endif'
158 print ''
159 print 'LONGSTRING static const char enum_string_table[] = '
160 for enum in sorted_enum_values:
161 (name, pri) = self.enum_table[enum]
162 print ' "%s\\0"' % (name)
163 string_offsets[ enum ] = i
164 i += len(name) + 1
165
166 print ' ;'
167 print ''
168
169
170 print 'static const enum_elt enum_string_table_offsets[%u] =' % (len(self.enum_table))
171 print '{'
172 for enum in sorted_enum_values:
173 (name, pri) = self.enum_table[enum]
174 print ' { %5u, 0x%08X }, /* %s */' % (string_offsets[enum], enum, name)
175 print '};'
176 print ''
177
178 self.print_code()
179 return
180
181 def add_enum_provider(self, name, priority):
182 # Skip some enums, to reduce the diffs from this commit.
183 if name in ['GL_NEXT_BUFFER_NV',
184 # Mesa was choosing GL_LINES for this, which wasn't great.
185 'GL_TRUE',
186 # We're blacklisting 4.3, so also blacklist this
187 # to keep the 4.3/ARB_ssbo name for it.
188 'GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS',
189 # GL 2.0 name when Mesa was using GLES 1.0.
190 'GL_BLEND_EQUATION_RGB',
191 # GL3.x compat names that Mesa was missing.
192 'GL_ALPHA_SNORM',
193 'GL_LUMINANCE_SNORM',
194 'GL_LUMINANCE_ALPHA_SNORM',
195 'GL_INTENSITY_SNORM',
196 'GL_ALPHA8_SNORM',
197 'GL_LUMINANCE8_SNORM',
198 'GL_LUMINANCE8_ALPHA8_SNORM',
199 'GL_INTENSITY8_SNORM',
200 'GL_ALPHA16_SNORM',
201 'GL_LUMINANCE16_SNORM',
202 'GL_LUMINANCE16_ALPHA16_SNORM',
203 'GL_INTENSITY16_SNORM',
204 # ARB_imaging names that Mesa was missing.
205 'GL_COLOR_INDEX1_EXT',
206 'GL_COLOR_INDEX2_EXT',
207 'GL_COLOR_INDEX4_EXT',
208 'GL_COLOR_INDEX8_EXT',
209 'GL_COLOR_INDEX12_EXT',
210 'GL_COLOR_INDEX16_EXT',
211 'GL_CONSTANT_BORDER',
212 'GL_REPLICATE_BORDER',
213 'GL_TABLE_TOO_LARGE',
214 # ARB_texture_view names that Mesa was missing.
215 'GL_TEXTURE_VIEW_MIN_LEVEL',
216 'GL_TEXTURE_VIEW_NUM_LEVELS',
217 'GL_TEXTURE_VIEW_MIN_LAYER',
218 'GL_TEXTURE_VIEW_NUM_LAYERS',
219 # GL4.2 BPTC names that Mesa was missing.
220 'GL_COMPRESSED_RGBA_BPTC_UNORM',
221 'GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM',
222 'GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT',
223 'GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT',
224 # Mesa was choosing the EXT names for these
225 # instead of core.
226 'GL_ALPHA_INTEGER',
227 'GL_PROGRAM_SEPARABLE',
228 'GL_PROGRAM_PIPELINE_BINDING',
229 'GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS',
230 # Mesa was choosing the ARB names for these instead of core.
231 'GL_TEXTURE_CUBE_MAP_ARRAY',
232 'GL_TEXTURE_BINDING_CUBE_MAP_ARRAY',
233 'GL_PROXY_TEXTURE_CUBE_MAP_ARRAY',
234 'GL_SAMPLER_CUBE_MAP_ARRAY',
235 'GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW',
236 'GL_INT_SAMPLER_CUBE_MAP_ARRAY',
237 'GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY',
238 'GL_TRANSFORM_FEEDBACK_PAUSED',
239 'GL_TRANSFORM_FEEDBACK_ACTIVE',
240 'GL_VERTEX_ATTRIB_ARRAY_DIVISOR',
241 # Mesa was choosing the ANGLE names for these
242 # instead of EXT.
243 'GL_COMPRESSED_RGBA_S3TC_DXT3_EXT',
244 'GL_COMPRESSED_RGBA_S3TC_DXT5_EXT',
245 ]:
246 return
247
248 # Mesa didn't know about the second half of this set of enums.
249 m = re.match('GL_COLOR_ATTACHMENT([0-9]*)', name)
250 if m and int(m.group(1)) >= 16:
251 return
252
253 value = self.string_to_int[name]
254
255 # We don't want the weird GL_SKIP_COMPONENTS1_NV enums.
256 if value < 0:
257 return
258 # We don't want the 64-bit GL_TIMEOUT_IGNORED "enums"
259 if value > 0xffffffff:
260 return
261
262 # We don't want bitfields in the enum-to-string table --
263 # individual bits have so many names, it's pointless. Note
264 # that we check for power-of-two, since some getters have
265 # "_BITS" in their name, but none have a power-of-two enum
266 # number.
267 if not (value & (value - 1)) and '_BIT' in name:
268 return
269
270 # Also drop the GL_*_ATTRIB_BITS bitmasks.
271 if value == 0xffffffff:
272 return
273
274 if value in self.enum_table:
275 (n, p) = self.enum_table[value]
276 if priority < p:
277 self.enum_table[value] = (name, priority)
278 else:
279 self.enum_table[value] = (name, priority)
280
281 def process_extension(self, extension):
282 # Skip some of the extensions, to reduce the diffs from this commit.
283 extension_name = extension.get('name')
284 whitelist = ['GL_ANGLE_texture_compression_dxt3',
285 'GL_ANGLE_texture_compression_dxt5',
286 'GL_APPLE_flush_buffer_range',
287 'GL_APPLE_object_purgeable',
288 'GL_APPLE_texture_range',
289 'GL_SGIS_texture_color_mask',
290 'GL_SGIX_clipmap',
291 'GL_SGIX_texture_coordinate_clamp',
292 'GL_SGIX_fog_offset',
293 'GL_SGIX_texture_scale_bias',
294 'GL_SGIX_texture_lod_bias',
295 'GL_SGIX_shadow',
296 'GL_APPLE_ycbcr_422']
297 whitelist_only_prefixes = ['GL_APPLE',
298 'GL_ANGLE',
299 'GL_ARM',
300 'GL_DMP',
301 'GL_FJ',
302 'GL_INGR',
303 'GL_IMG_',
304 'GL_MESAX_',
305 'GL_MALI_',
306 'GL_NVX_',
307 'GL_OML_',
308 'GL_OVR_',
309 'GL_PGI_',
310 'GL_QCOM_',
311 'GL_REND_',
312 'GL_SGIS_',
313 'GL_SGIX_',
314 'GL_WIN_',
315 'GL_VIV_']
316
317 for prefix in whitelist_only_prefixes:
318 if extension_name.startswith(prefix):
319 if extension_name not in whitelist:
320 return
321
322 if extension_name in ['GL_ATI_element_array',
323 'GL_ATI_meminfo',
324 'GL_ATI_text_fragment_shader',
325 'GL_ATI_pixel_format_float',
326 'GL_ATI_pn_triangles',
327 'GL_ATI_vertex_array_object',
328 'GL_ATI_vertex_streams',
329 'GL_AMD_blend_minmax_factor',
330 'GL_AMD_compressed_3DC_texture',
331 'GL_AMD_compressed_ATC_texture',
332 'GL_AMD_debug_output',
333 'GL_AMD_depth_clamp_separate',
334 'GL_AMD_gpu_shader_int64',
335 'GL_AMD_query_buffer_object',
336 'GL_AMD_interleaved_elements',
337 'GL_AMD_name_gen_delete',
338 'GL_AMD_occlusion_query_event',
339 'GL_AMD_program_binary_Z400',
340 'GL_AMD_sample_positions',
341 'GL_AMD_sparse_texture',
342 'GL_AMD_stencil_operation_extended',
343 'GL_AMD_transform_feedback4',
344 'GL_AMD_vertex_shader_tessellator',
345 'GL_ARB_bindless_texture',
346 'GL_ARB_cl_event',
347 'GL_ARB_compute_variable_group_size',
348 'GL_ARB_cull_distance',
349 'GL_ARB_enhanced_layouts',
350 'GL_ARB_indirect_parameters',
351 'GL_ARB_internalformat_query2',
352 'GL_ARB_query_buffer_object',
353 'GL_ARB_shading_language_include',
354 'GL_ARB_sparse_buffer',
355 'GL_ARB_sparse_texture',
356 'GL_ARB_texture_compression_bptc',
357 'GL_ARB_texture_mirror_clamp_to_edge',
358 'GL_ARB_texture_view',
359 'GL_ARB_transform_feedback_overflow_query',
360 'GL_EXT_422_pixels',
361 'GL_EXT_bindable_uniform',
362 'GL_EXT_cmyka',
363 'GL_EXT_coordinate_frame',
364 'GL_EXT_debug_label',
365 'GL_EXT_direct_state_access',
366 'GL_EXT_disjoint_timer_query',
367 'GL_EXT_geometry_shader',
368 'GL_EXT_light_texture',
369 'GL_EXT_robustness',
370 'GL_EXT_tessellation_shader',
371 'GL_EXT_texture_compression_latc',
372 'GL_EXT_texture_filter_minmax',
373 'GL_EXT_texture_sRGB_R8',
374 'GL_EXT_texture_sRGB_RG8',
375 'GL_EXT_framebuffer_multisample_blit_scaled',
376 'GL_EXT_multisample',
377 'GL_EXT_multisampled_render_to_texture',
378 'GL_EXT_multiview_draw_buffers',
379 'GL_EXT_pixel_transform',
380 'GL_EXT_primitive_bounding_box',
381 'GL_EXT_pvrtc_sRGB',
382 'GL_EXT_raster_multisample',
383 'GL_EXT_shader_framebuffer_fetch',
384 'GL_EXT_shader_pixel_local_storage',
385 'GL_EXT_sparse_texture',
386 'GL_EXT_stencil_clear_tag',
387 'GL_EXT_tesselation_shader',
388 'GL_EXT_texture_perturb_normal',
389 'GL_EXT_texture_sRGB',
390 'GL_EXT_texture_storage',
391 'GL_EXT_texture_view',
392 'GL_EXT_vertex_shader',
393 'GL_EXT_vertex_weighting',
394 'GL_EXT_x11_sync_object',
395 'GL_EXT_YUV_target',
396 'GL_IBM_cull_vertex',
397 'GL_IBM_static_data',
398 'GL_IBM_vertex_array_lists',
399 'GL_INTEL_map_texture',
400 'GL_INTEL_parallel_arrays',
401 'GL_HP_image_transform',
402 'GL_HP_texture_lighting',
403 'GL_KHR_blend_equation_advanced',
404 'GL_KHR_blend_equation_advanced_coherent',
405 'GL_KHR_robustness',
406 'GL_NV_blend_equation_advanced',
407 'GL_NV_blend_equation_advanced_coherent',
408 'GL_NV_command_list',
409 'GL_NV_compute_program5',
410 'GL_NV_conservative_raster',
411 'GL_NV_coverage_sample',
412 'GL_NV_deep_texture3D',
413 'GL_NV_depth_buffer_float',
414 'GL_NV_depth_nonlinear',
415 'GL_NV_evaluators',
416 'GL_NV_explicit_multisample',
417 'GL_NV_fence',
418 'GL_NV_fill_rectangle',
419 'GL_NV_float_buffer',
420 'GL_NV_fragment_coverage_to_color',
421 'GL_NV_framebuffer_mixed_samples',
422 'GL_NV_framebuffer_multisample_coverage',
423 'GL_NV_geometry_program4',
424 'GL_NV_gpu_program4',
425 'GL_NV_gpu_program5',
426 'GL_NV_gpu_shader5',
427 'GL_NV_internalformat_sample_query',
428 'GL_NV_multisample_coverage',
429 'GL_NV_parameter_buffer_object',
430 'GL_NV_path_rendering',
431 'GL_NV_path_rendering_shared_edge',
432 'GL_NV_pixel_data_range',
433 'GL_NV_present_video',
434 'GL_NV_register_combiners',
435 'GL_NV_register_combiners2',
436 'GL_NV_sample_locations',
437 'GL_NV_shader_buffer_load',
438 'GL_NV_shader_image_load_store',
439 'GL_NV_shader_thread_group',
440 'GL_NV_sRGB_formats',
441 'GL_NV_tessellation_program5',
442 'GL_NV_texgen_emboss',
443 'GL_NV_texture_multisample',
444 'GL_NV_texture_shader',
445 'GL_NV_texture_shader2',
446 'GL_NV_texture_shader3',
447 'GL_NV_transform_feedback',
448 'GL_NV_uniform_buffer_unified_memory',
449 'GL_NV_vertex_array_range',
450 'GL_NV_vertex_array_range2',
451 'GL_NV_vertex_attrib_integer_64bit',
452 'GL_NV_vertex_buffer_unified_memory',
453 'GL_NV_video_capture',
454 'GL_OES_geometry_shader',
455 'GL_OES_primitive_bounding_box',
456 'GL_OES_tessellation_shader',
457 'GL_OES_texture_compression_astc',
458 'GL_OES_texture_view',
459 'GL_SGI_color_table',
460 'GL_SUN_global_alpha',
461 'GL_SUN_triangle_list',
462 'GL_SUNX_constant_data',
463 'GL_EXT_index_func',
464 'GL_EXT_index_array_formats',
465 'GL_EXT_index_material']:
466 return
467
468 if extension.get('name').startswith('GL_ARB_'):
469 extension_prio = 400
470 elif extension.get('name').startswith('GL_EXT_'):
471 extension_prio = 600
472 else:
473 extension_prio = 800
474
475 for enum in extension.findall('require/enum'):
476 self.add_enum_provider(enum.get('name'), extension_prio)
477
478 # Part of 4.4, but Mesa added it early.
479 self.add_enum_provider('GL_MAX_VERTEX_ATTRIB_STRIDE', 44)
480
481 def process_enums(self, xml):
482 # First, process the XML entries that define the hex values
483 # for all of the enum names.
484 for enum in xml.findall('enums/enum'):
485 name = enum.get('name')
486 value = int(enum.get('value'), base=16)
487
488 # If the same name ever maps to multiple values, that can
489 # confuse us. GL_ACTIVE_PROGRAM_EXT is OK to lose because
490 # we choose GL_ACTIVE PROGRAM instead.
491 if name in self.string_to_int and name != "GL_ACTIVE_PROGRAM_EXT":
492 print "#error Renumbering {0} from {1} to {2}".format(name, self.string_to_int[name], value)
493
494 self.string_to_int[name] = value
495
496 # Now, process all of the API versions and extensions that
497 # provide enums, so we can decide what name to call any hex
498 # value.
499 for feature in xml.findall('feature'):
500 feature_name = feature.get('name')
501 # Skip some of the extensions, to reduce the diffs from this commit.
502 if feature_name in ['GL_VERSION_4_3',
503 'GL_VERSION_4_4',
504 'GL_VERSION_4_5',
505 'GL_ES_VERSION_3_1']:
506 continue
507
508 # When an enum gets renamed in a newer version (generally
509 # because of some generalization of the functionality),
510 # prefer the newer name. Also, prefer desktop GL names to
511 # ES.
512 m = re.match('GL_VERSION_([0-9])_([0-9])', feature_name)
513 if m:
514 feature_prio = 100 - int(m.group(1) + m.group(2))
515 else:
516 m = re.match('GL_ES_VERSION_([0-9])_([0-9])', feature_name)
517 if m:
518 feature_prio = 200 - int(m.group(1) + m.group(2))
519 else:
520 feature_prio = 200
521
522 for enum in feature.findall('require/enum'):
523 self.add_enum_provider(enum.get('name'), feature_prio)
524
525 for extension in xml.findall('extensions/extension'):
526 self.process_extension(extension)
527
528
529 def _parser():
530 parser = argparse.ArgumentParser()
531 parser.add_argument('-f', '--input_file',
532 required=True,
533 help="Choose an xml file to parse.")
534 return parser.parse_args()
535
536
537 def main():
538 args = _parser()
539 xml = ET.parse(args.input_file)
540
541 printer = PrintGlEnums()
542 printer.Print(xml)
543
544
545 if __name__ == '__main__':
546 main()