• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python3
2#
3# Copyright 2018 The ANGLE Project Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6#
7# registry_xml.py:
8#   Parses information from Khronos registry files..
9
10# List of supported extensions. Add to this list to enable new extensions
11# available in gl.xml.
12
13import os
14import sys
15import xml.etree.ElementTree as etree
16
17from enum import Enum
18
19xml_inputs = [
20    'cl.xml',
21    'gl.xml',
22    'gl_angle_ext.xml',
23    'egl.xml',
24    'egl_angle_ext.xml',
25    'wgl.xml',
26    'registry_xml.py',
27]
28
29angle_extensions = [
30    # ANGLE extensions
31    "GL_CHROMIUM_bind_uniform_location",
32    "GL_CHROMIUM_framebuffer_mixed_samples",
33    "GL_CHROMIUM_path_rendering",
34    "GL_CHROMIUM_copy_texture",
35    "GL_CHROMIUM_copy_compressed_texture",
36    "GL_CHROMIUM_lose_context",
37    "GL_ANGLE_copy_texture_3d",
38    "GL_ANGLE_get_image",
39    "GL_ANGLE_get_serialized_context_string",
40    "GL_ANGLE_get_tex_level_parameter",
41    "GL_ANGLE_program_binary",
42    "GL_ANGLE_request_extension",
43    "GL_ANGLE_robust_client_memory",
44    "GL_ANGLE_texture_external_update",
45]
46
47gles1_extensions = [
48    # ES1 (Possibly the min set of extensions needed by Android)
49    "GL_OES_draw_texture",
50    "GL_OES_framebuffer_object",
51    "GL_OES_matrix_palette",
52    "GL_OES_point_size_array",
53    "GL_OES_query_matrix",
54    "GL_OES_texture_cube_map",
55]
56
57gles_extensions = [
58    # ES2+
59    "GL_ANGLE_base_vertex_base_instance",
60    "GL_ANGLE_framebuffer_blit",
61    "GL_ANGLE_framebuffer_multisample",
62    "GL_ANGLE_instanced_arrays",
63    "GL_ANGLE_memory_object_flags",
64    "GL_ANGLE_memory_object_fuchsia",
65    "GL_ANGLE_multi_draw",
66    "GL_ANGLE_provoking_vertex",
67    "GL_ANGLE_semaphore_fuchsia",
68    "GL_ANGLE_texture_multisample",
69    "GL_ANGLE_translated_shader_source",
70    "GL_KHR_blend_equation_advanced",
71    "GL_EXT_blend_func_extended",
72    "GL_EXT_buffer_storage",
73    "GL_EXT_copy_image",
74    "GL_EXT_clip_control",
75    "GL_EXT_debug_label",
76    "GL_EXT_debug_marker",
77    "GL_EXT_discard_framebuffer",
78    "GL_EXT_disjoint_timer_query",
79    "GL_EXT_draw_buffers",
80    "GL_EXT_draw_buffers_indexed",
81    "GL_EXT_draw_elements_base_vertex",
82    "GL_EXT_EGL_image_array",
83    "GL_EXT_external_buffer",
84    "GL_EXT_geometry_shader",
85    "GL_EXT_instanced_arrays",
86    "GL_EXT_map_buffer_range",
87    "GL_EXT_memory_object",
88    "GL_EXT_memory_object_fd",
89    "GL_EXT_multisampled_render_to_texture",
90    "GL_EXT_multisampled_render_to_texture2",
91    "GL_EXT_occlusion_query_boolean",
92    "GL_EXT_primitive_bounding_box",
93    "GL_EXT_read_format_bgra",
94    "GL_EXT_robustness",
95    "GL_EXT_semaphore",
96    "GL_EXT_semaphore_fd",
97    "GL_EXT_separate_shader_objects",
98    "GL_EXT_shader_framebuffer_fetch_non_coherent",
99    "GL_EXT_shader_io_blocks",
100    "GL_EXT_sRGB",
101    "GL_EXT_sRGB_write_control",
102    "GL_EXT_tessellation_shader",
103    "GL_EXT_texture_border_clamp",
104    "GL_EXT_texture_buffer",
105    "GL_EXT_texture_compression_bptc",
106    "GL_EXT_texture_compression_dxt1",
107    "GL_EXT_texture_compression_rgtc",
108    "GL_EXT_texture_compression_s3tc",
109    "GL_EXT_texture_compression_s3tc_srgb",
110    "GL_EXT_texture_cube_map_array",
111    "GL_EXT_texture_filter_anisotropic",
112    "GL_EXT_texture_format_BGRA8888",
113    "GL_EXT_texture_storage",
114    "GL_EXT_texture_sRGB_R8",
115    "GL_EXT_texture_sRGB_RG8",
116    "GL_EXT_YUV_target",
117    "GL_KHR_debug",
118    "GL_KHR_parallel_shader_compile",
119    "GL_NV_fence",
120    "GL_NV_framebuffer_blit",
121    "GL_OES_compressed_ETC1_RGB8_texture",
122    "GL_EXT_compressed_ETC1_RGB8_sub_texture",
123    "GL_OES_copy_image",
124    "GL_OES_depth32",
125    "GL_OES_draw_buffers_indexed",
126    "GL_OES_draw_elements_base_vertex",
127    "GL_OES_EGL_image",
128    "GL_OES_geometry_shader",
129    "GL_OES_get_program_binary",
130    "GL_OES_mapbuffer",
131    "GL_OES_sample_shading",
132    "GL_OES_shader_io_blocks",
133    "GL_OES_texture_3D",
134    "GL_OES_texture_border_clamp",
135    "GL_OES_texture_buffer",
136    "GL_OES_texture_cube_map_array",
137    "GL_OES_texture_half_float",
138    "GL_OES_texture_stencil8",
139    "GL_OES_texture_storage_multisample_2d_array",
140    "GL_OES_vertex_array_object",
141    "GL_OVR_multiview",
142    "GL_OVR_multiview2",
143]
144
145supported_extensions = sorted(angle_extensions + gles1_extensions + gles_extensions)
146
147supported_egl_extensions = [
148    "EGL_ANDROID_blob_cache",
149    "EGL_ANDROID_create_native_client_buffer",
150    "EGL_ANDROID_framebuffer_target",
151    "EGL_ANDROID_get_frame_timestamps",
152    "EGL_ANDROID_get_native_client_buffer",
153    "EGL_ANDROID_native_fence_sync",
154    "EGL_ANDROID_presentation_time",
155    "EGL_ANGLE_d3d_share_handle_client_buffer",
156    "EGL_ANGLE_device_creation",
157    "EGL_ANGLE_device_d3d",
158    "EGL_ANGLE_display_semaphore_share_group",
159    "EGL_ANGLE_display_texture_share_group",
160    "EGL_ANGLE_feature_control",
161    "EGL_ANGLE_ggp_stream_descriptor",
162    "EGL_ANGLE_power_preference",
163    "EGL_ANGLE_program_cache_control",
164    "EGL_ANGLE_query_surface_pointer",
165    "EGL_ANGLE_stream_producer_d3d_texture",
166    "EGL_ANGLE_surface_d3d_texture_2d_share_handle",
167    "EGL_ANGLE_swap_with_frame_token",
168    "EGL_ANGLE_sync_control_rate",
169    "EGL_ANGLE_window_fixed_size",
170    "EGL_CHROMIUM_sync_control",
171    "EGL_EXT_create_context_robustness",
172    "EGL_EXT_device_query",
173    "EGL_EXT_gl_colorspace_display_p3",
174    "EGL_EXT_gl_colorspace_display_p3_linear",
175    "EGL_EXT_gl_colorspace_display_p3_passthrough",
176    "EGL_EXT_gl_colorspace_scrgb",
177    "EGL_EXT_gl_colorspace_scrgb_linear",
178    "EGL_EXT_image_gl_colorspace",
179    "EGL_EXT_pixel_format_float",
180    "EGL_EXT_platform_base",
181    "EGL_EXT_platform_device",
182    "EGL_EXT_protected_content",
183    "EGL_IMG_context_priority",
184    "EGL_KHR_debug",
185    "EGL_KHR_fence_sync",
186    "EGL_KHR_gl_colorspace",
187    "EGL_KHR_image",
188    "EGL_KHR_mutable_render_buffer",
189    "EGL_KHR_no_config_context",
190    "EGL_KHR_reusable_sync",
191    "EGL_KHR_stream",
192    "EGL_KHR_stream_consumer_gltexture",
193    "EGL_KHR_surfaceless_context",
194    "EGL_KHR_swap_buffers_with_damage",
195    "EGL_KHR_wait_sync",
196    "EGL_NV_post_sub_buffer",
197    "EGL_NV_stream_consumer_gltexture_yuv",
198]
199
200supported_cl_extensions = [
201    # Since OpenCL 1.1
202    "cl_khr_byte_addressable_store",
203    "cl_khr_global_int32_base_atomics",
204    "cl_khr_global_int32_extended_atomics",
205    "cl_khr_local_int32_base_atomics",
206    "cl_khr_local_int32_extended_atomics",
207
208    # OpenCL 2.0 - 2.2
209    "cl_khr_3d_image_writes",
210    "cl_khr_depth_images",
211    "cl_khr_image2d_from_buffer",
212
213    # Optional
214    "cl_khr_extended_versioning",
215    "cl_khr_fp64",
216    "cl_khr_icd",
217    "cl_khr_int64_base_atomics",
218    "cl_khr_int64_extended_atomics",
219]
220
221# Strip these suffixes from Context entry point names. NV is excluded (for now).
222strip_suffixes = ["ANGLE", "EXT", "KHR", "OES", "CHROMIUM"]
223
224# The EGL_ANGLE_explicit_context extension is generated differently from other extensions.
225# Toggle generation here.
226support_EGL_ANGLE_explicit_context = True
227
228# For ungrouped GLenum types
229default_enum_group_name = "DefaultGroup"
230
231# Group names that appear in command/param, but not present in groups/group
232unsupported_enum_group_names = {
233    'GetMultisamplePNameNV',
234    'BufferPNameARB',
235    'BufferPointerNameARB',
236    'VertexAttribPointerPropertyARB',
237    'VertexAttribPropertyARB',
238    'FenceParameterNameNV',
239    'FenceConditionNV',
240    'BufferPointerNameARB',
241    'MatrixIndexPointerTypeARB',
242    'PointParameterNameARB',
243    'ClampColorTargetARB',
244    'ClampColorModeARB',
245}
246
247# Versions (major, minor). Note that GLES intentionally places 1.0 last.
248DESKTOP_GL_VERSIONS = [(1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 0), (2, 1), (3, 0),
249                       (3, 1), (3, 2), (3, 3), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5),
250                       (4, 6)]
251GLES_VERSIONS = [(2, 0), (3, 0), (3, 1), (3, 2), (1, 0)]
252EGL_VERSIONS = [(1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5)]
253WGL_VERSIONS = [(1, 0)]
254CL_VERSIONS = [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (3, 0)]
255
256
257# API types
258class apis:
259    GL = 'GL'
260    GLES = 'GLES'
261    WGL = 'WGL'
262    EGL = 'EGL'
263    CL = 'CL'
264
265
266def script_relative(path):
267    return os.path.join(os.path.dirname(sys.argv[0]), path)
268
269
270def path_to(folder, file):
271    return os.path.join(script_relative(".."), "src", folder, file)
272
273
274def strip_api_prefix(cmd_name):
275    return cmd_name.lstrip("cwegl")
276
277
278def get_cmd_name(command_node):
279    proto = command_node.find('proto')
280    cmd_name = proto.find('name').text
281    return cmd_name
282
283
284class CommandNames:
285
286    def __init__(self):
287        self.command_names = {}
288
289    def get_commands(self, version):
290        return self.command_names[version]
291
292    def get_all_commands(self):
293        cmd_names = []
294        # Combine all the version lists into a single list
295        for version, version_cmd_names in sorted(self.command_names.items()):
296            cmd_names += version_cmd_names
297
298        return cmd_names
299
300    def add_commands(self, version, commands):
301        # Add key if it doesn't exist
302        if version not in self.command_names:
303            self.command_names[version] = []
304        # Add the commands that aren't duplicates
305        self.command_names[version] += commands
306
307
308class RegistryXML:
309
310    def __init__(self, xml_file, ext_file=None):
311        tree = etree.parse(script_relative(xml_file))
312        self.root = tree.getroot()
313        if (ext_file):
314            self._AppendANGLEExts(ext_file)
315        self.all_commands = self.root.findall('commands/command')
316        self.all_cmd_names = CommandNames()
317        self.commands = {}
318
319    def _AppendANGLEExts(self, ext_file):
320        angle_ext_tree = etree.parse(script_relative(ext_file))
321        angle_ext_root = angle_ext_tree.getroot()
322
323        insertion_point = self.root.findall("./commands")[0]
324        for command in angle_ext_root.iter('commands'):
325            insertion_point.extend(command)
326
327        insertion_point = self.root.findall("./extensions")[0]
328        for extension in angle_ext_root.iter('extensions'):
329            insertion_point.extend(extension)
330
331        insertion_point = self.root
332        for enums in angle_ext_root.iter('enums'):
333            insertion_point.append(enums)
334
335    def AddCommands(self, feature_name, annotation):
336        xpath = ".//feature[@name='%s']//command" % feature_name
337        commands = [cmd.attrib['name'] for cmd in self.root.findall(xpath)]
338
339        # Remove commands that have already been processed
340        current_cmds = self.all_cmd_names.get_all_commands()
341        commands = [cmd for cmd in commands if cmd not in current_cmds]
342
343        self.all_cmd_names.add_commands(annotation, commands)
344        self.commands[annotation] = commands
345
346    def _ClassifySupport(self, supported):
347        if 'gles2' in supported:
348            return 'gl2ext'
349        elif 'gles1' in supported:
350            return 'glext'
351        elif 'egl' in supported:
352            return 'eglext'
353        elif 'wgl' in supported:
354            return 'wglext'
355        elif 'cl' in supported:
356            return 'clext'
357        else:
358            assert False
359            return 'unknown'
360
361    def AddExtensionCommands(self, supported_extensions, apis):
362        # Use a first step to run through the extensions so we can generate them
363        # in sorted order.
364        self.ext_data = {}
365        self.ext_dupes = {}
366        ext_annotations = {}
367
368        for extension in self.root.findall("extensions/extension"):
369            extension_name = extension.attrib['name']
370            if not extension_name in supported_extensions:
371                continue
372
373            ext_annotations[extension_name] = self._ClassifySupport(extension.attrib['supported'])
374
375            ext_cmd_names = []
376
377            # There's an extra step here to filter out 'api=gl' extensions. This
378            # is necessary for handling KHR extensions, which have separate entry
379            # point signatures (without the suffix) for desktop GL. Note that this
380            # extra step is necessary because of Etree's limited Xpath support.
381            for require in extension.findall('require'):
382                if 'api' in require.attrib and require.attrib['api'] not in apis:
383                    continue
384
385                # A special case for EXT_texture_storage
386                filter_out_comment = "Supported only if GL_EXT_direct_state_access is supported"
387                if 'comment' in require.attrib and require.attrib['comment'] == filter_out_comment:
388                    continue
389
390                extension_commands = require.findall('command')
391                ext_cmd_names += [command.attrib['name'] for command in extension_commands]
392
393            self.ext_data[extension_name] = sorted(ext_cmd_names)
394
395        for extension_name, ext_cmd_names in sorted(self.ext_data.items()):
396
397            # Detect and filter duplicate extensions.
398            dupes = []
399            for ext_cmd in ext_cmd_names:
400                if ext_cmd in self.all_cmd_names.get_all_commands():
401                    dupes.append(ext_cmd)
402
403            for dupe in dupes:
404                ext_cmd_names.remove(dupe)
405
406            self.ext_data[extension_name] = sorted(ext_cmd_names)
407            self.ext_dupes[extension_name] = dupes
408            self.all_cmd_names.add_commands(ext_annotations[extension_name], ext_cmd_names)
409
410
411class EntryPoints:
412
413    def __init__(self, api, xml, commands):
414        self.api = api
415        self._cmd_info = []
416
417        for command_node in xml.all_commands:
418            cmd_name = get_cmd_name(command_node)
419
420            if api == apis.WGL:
421                cmd_name = cmd_name if cmd_name[:3] == 'wgl' else 'wgl' + cmd_name
422
423            if cmd_name not in commands:
424                continue
425
426            param_text = ["".join(param.itertext()) for param in command_node.findall('param')]
427
428            # Treat (void) as ()
429            if len(param_text) == 1 and param_text[0].strip() == 'void':
430                param_text = []
431
432            proto = command_node.find('proto')
433            proto_text = "".join(proto.itertext())
434
435            self._cmd_info.append((cmd_name, command_node, param_text, proto_text))
436
437    def get_infos(self):
438        return self._cmd_info
439