Corentin Wallez | 59382b7 | 2020-04-17 20:43:07 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Austin Eng | cc2516a | 2023-10-17 20:57:54 +0000 | [diff] [blame] | 2 | # Copyright 2019 The Dawn & Tint Authors |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 3 | # |
Austin Eng | cc2516a | 2023-10-17 20:57:54 +0000 | [diff] [blame] | 4 | # Redistribution and use in source and binary forms, with or without |
| 5 | # modification, are permitted provided that the following conditions are met: |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 6 | # |
Austin Eng | cc2516a | 2023-10-17 20:57:54 +0000 | [diff] [blame] | 7 | # 1. Redistributions of source code must retain the above copyright notice, this |
| 8 | # list of conditions and the following disclaimer. |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 9 | # |
Austin Eng | cc2516a | 2023-10-17 20:57:54 +0000 | [diff] [blame] | 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, |
| 11 | # this list of conditions and the following disclaimer in the documentation |
| 12 | # and/or other materials provided with the distribution. |
| 13 | # |
| 14 | # 3. Neither the name of the copyright holder nor the names of its |
| 15 | # contributors may be used to endorse or promote products derived from |
| 16 | # this software without specific prior written permission. |
| 17 | # |
| 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
| 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 28 | |
Jiawei Shao | 9d9d76c | 2019-08-22 08:19:13 +0000 | [diff] [blame] | 29 | import os, json, sys |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 30 | from collections import namedtuple |
| 31 | import xml.etree.ElementTree as etree |
| 32 | |
Corentin Wallez | f4a01c9 | 2024-07-16 11:18:42 +0000 | [diff] [blame] | 33 | from generator_lib import Generator, run_generator, FileRender, GeneratorOutput |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 34 | |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 35 | |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 36 | class ProcName: |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 37 | def __init__(self, gl_name, proc_name=None): |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 38 | assert gl_name.startswith('gl') |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 39 | if proc_name == None: |
| 40 | proc_name = gl_name[2:] |
| 41 | |
| 42 | self.gl_name = gl_name |
| 43 | self.proc_name = proc_name |
| 44 | |
| 45 | def glProcName(self): |
| 46 | return self.gl_name |
| 47 | |
| 48 | def ProcName(self): |
| 49 | return self.proc_name |
| 50 | |
| 51 | def PFNPROCNAME(self): |
| 52 | return 'PFN' + self.gl_name.upper() + 'PROC' |
| 53 | |
| 54 | def __repr__(self): |
| 55 | return 'Proc("{}", "{}")'.format(self.gl_name, self.proc_name) |
| 56 | |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 57 | |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 58 | ProcParam = namedtuple('ProcParam', ['name', 'type']) |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 59 | |
| 60 | |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 61 | class Proc: |
| 62 | def __init__(self, element): |
| 63 | # Type declaration for return values and arguments all have the same |
| 64 | # (weird) format. |
| 65 | # <element>[A][<ptype>B</ptype>][C]<other stuff.../></element> |
| 66 | # |
| 67 | # Some examples are: |
| 68 | # <proto>void <name>glFinish</name></proto> |
| 69 | # <proto><ptype>GLenum</ptype><name>glFenceSync</name></proto> |
| 70 | # <proto>const <ptype>GLubyte</ptype> *<name>glGetString</name></proto> |
| 71 | # |
| 72 | # This handles all the shapes found in gl.xml except for this one that |
| 73 | # has an array specifier after </name>: |
| 74 | # <param><ptype>GLuint</ptype> <name>baseAndCount</name>[2]</param> |
| 75 | def parse_type_declaration(element): |
| 76 | result = '' |
| 77 | if element.text != None: |
| 78 | result += element.text |
| 79 | ptype = element.find('ptype') |
| 80 | if ptype != None: |
| 81 | result += ptype.text |
| 82 | if ptype.tail != None: |
| 83 | result += ptype.tail |
| 84 | return result.strip() |
| 85 | |
| 86 | proto = element.find('proto') |
| 87 | |
| 88 | self.return_type = parse_type_declaration(proto) |
| 89 | |
| 90 | self.params = [] |
| 91 | for param in element.findall('./param'): |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 92 | self.params.append( |
| 93 | ProcParam( |
| 94 | param.find('name').text, parse_type_declaration(param))) |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 95 | |
| 96 | self.gl_name = proto.find('name').text |
| 97 | self.alias = None |
| 98 | if element.find('alias') != None: |
| 99 | self.alias = element.find('alias').attrib['name'] |
| 100 | |
| 101 | def glProcName(self): |
| 102 | return self.gl_name |
| 103 | |
| 104 | def ProcName(self): |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 105 | assert self.gl_name.startswith('gl') |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 106 | return self.gl_name[2:] |
| 107 | |
| 108 | def PFNGLPROCNAME(self): |
| 109 | return 'PFN' + self.gl_name.upper() + 'PROC' |
| 110 | |
| 111 | def __repr__(self): |
| 112 | return 'Proc("{}")'.format(self.gl_name) |
| 113 | |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 114 | |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 115 | EnumDefine = namedtuple('EnumDefine', ['name', 'value']) |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 116 | Version = namedtuple('Version', ['major', 'minor']) |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 117 | VersionBlock = namedtuple('VersionBlock', ['version', 'procs', 'enums']) |
| 118 | HeaderBlock = namedtuple('HeaderBlock', ['description', 'procs', 'enums']) |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 119 | ExtensionBlock = namedtuple('ExtensionBlock', |
| 120 | ['extension', 'procs', 'enums', 'supported_specs']) |
| 121 | |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 122 | |
| 123 | def parse_version(version): |
| 124 | return Version(*map(int, version.split('.'))) |
| 125 | |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 126 | |
Jiawei Shao | 9d9d76c | 2019-08-22 08:19:13 +0000 | [diff] [blame] | 127 | def compute_params(root, supported_extensions): |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 128 | # Parse all the commands and enums |
| 129 | all_procs = {} |
| 130 | for command in root.findall('''commands[@namespace='GL']/command'''): |
| 131 | proc = Proc(command) |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 132 | assert proc.gl_name not in all_procs |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 133 | all_procs[proc.gl_name] = proc |
| 134 | |
| 135 | all_enums = {} |
| 136 | for enum in root.findall('''enums[@namespace='GL']/enum'''): |
| 137 | enum_name = enum.attrib['name'] |
| 138 | # Special case an enum we'll never use that has different values in GL and GLES |
| 139 | if enum_name == 'GL_ACTIVE_PROGRAM_EXT': |
| 140 | continue |
| 141 | |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 142 | assert enum_name not in all_enums |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 143 | all_enums[enum_name] = EnumDefine(enum_name, enum.attrib['value']) |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 144 | |
| 145 | # Get the list of all Desktop OpenGL function removed by the Core Profile. |
| 146 | core_removed_procs = set() |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 147 | for proc in root.findall('''feature/remove[@profile='core']/command'''): |
| 148 | core_removed_procs.add(proc.attrib['name']) |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 149 | |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 150 | # Get list of enums and procs per OpenGL ES/Desktop OpenGL version |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 151 | def parse_version_blocks(api, removed_procs=set()): |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 152 | blocks = [] |
| 153 | for section in root.findall('''feature[@api='{}']'''.format(api)): |
| 154 | section_procs = [] |
| 155 | for command in section.findall('./require/command'): |
| 156 | proc_name = command.attrib['name'] |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 157 | assert all_procs[proc_name].alias == None |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 158 | if proc_name not in removed_procs: |
| 159 | section_procs.append(all_procs[proc_name]) |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 160 | |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 161 | section_enums = [] |
| 162 | for enum in section.findall('./require/enum'): |
| 163 | section_enums.append(all_enums[enum.attrib['name']]) |
| 164 | |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 165 | blocks.append( |
| 166 | VersionBlock(parse_version(section.attrib['number']), |
| 167 | section_procs, section_enums)) |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 168 | |
| 169 | return blocks |
| 170 | |
| 171 | gles_blocks = parse_version_blocks('gles2') |
| 172 | desktop_gl_blocks = parse_version_blocks('gl', core_removed_procs) |
| 173 | |
Jiawei Shao | 9d9d76c | 2019-08-22 08:19:13 +0000 | [diff] [blame] | 174 | def parse_extension_block(extension): |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 175 | section = root.find( |
| 176 | '''extensions/extension[@name='{}']'''.format(extension)) |
Jiawei Shao | 9d9d76c | 2019-08-22 08:19:13 +0000 | [diff] [blame] | 177 | supported_specs = section.attrib['supported'].split('|') |
| 178 | section_procs = [] |
| 179 | for command in section.findall('./require/command'): |
| 180 | proc_name = command.attrib['name'] |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 181 | assert all_procs[proc_name].alias == None |
Stephen White | d0ebcba | 2021-05-06 18:34:14 +0000 | [diff] [blame] | 182 | section_procs.append(all_procs[proc_name]) |
Jiawei Shao | 9d9d76c | 2019-08-22 08:19:13 +0000 | [diff] [blame] | 183 | |
| 184 | section_enums = [] |
| 185 | for enum in section.findall('./require/enum'): |
| 186 | section_enums.append(all_enums[enum.attrib['name']]) |
| 187 | |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 188 | return ExtensionBlock(extension, section_procs, section_enums, |
| 189 | supported_specs) |
Jiawei Shao | 9d9d76c | 2019-08-22 08:19:13 +0000 | [diff] [blame] | 190 | |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 191 | extension_desktop_gl_blocks = [] |
| 192 | extension_gles_blocks = [] |
Jiawei Shao | 9d9d76c | 2019-08-22 08:19:13 +0000 | [diff] [blame] | 193 | for extension in supported_extensions: |
| 194 | extension_block = parse_extension_block(extension) |
| 195 | if 'gl' in extension_block.supported_specs: |
| 196 | extension_desktop_gl_blocks.append(extension_block) |
| 197 | if 'gles2' in extension_block.supported_specs: |
| 198 | extension_gles_blocks.append(extension_block) |
| 199 | |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 200 | # Compute the blocks for headers such that there is no duplicate definition |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 201 | already_added_header_procs = set() |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 202 | already_added_header_enums = set() |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 203 | header_blocks = [] |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 204 | |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 205 | def add_header_block(description, block): |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 206 | block_procs = [] |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 207 | for proc in block.procs: |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 208 | if not proc.glProcName() in already_added_header_procs: |
| 209 | already_added_header_procs.add(proc.glProcName()) |
| 210 | block_procs.append(proc) |
Corentin Wallez | 8f4046b | 2019-06-17 09:17:29 +0000 | [diff] [blame] | 211 | |
| 212 | block_enums = [] |
| 213 | for enum in block.enums: |
| 214 | if not enum.name in already_added_header_enums: |
| 215 | already_added_header_enums.add(enum.name) |
| 216 | block_enums.append(enum) |
| 217 | |
| 218 | if len(block_procs) > 0 or len(block_enums) > 0: |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 219 | header_blocks.append( |
| 220 | HeaderBlock(description, block_procs, block_enums)) |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 221 | |
| 222 | for block in gles_blocks: |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 223 | add_header_block( |
| 224 | 'OpenGL ES {}.{}'.format(block.version.major, block.version.minor), |
| 225 | block) |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 226 | |
| 227 | for block in desktop_gl_blocks: |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 228 | add_header_block( |
| 229 | 'Desktop OpenGL {}.{}'.format(block.version.major, |
| 230 | block.version.minor), block) |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 231 | |
Jiawei Shao | 9d9d76c | 2019-08-22 08:19:13 +0000 | [diff] [blame] | 232 | for block in extension_desktop_gl_blocks: |
| 233 | add_header_block(block.extension, block) |
| 234 | |
| 235 | for block in extension_gles_blocks: |
| 236 | add_header_block(block.extension, block) |
| 237 | |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 238 | return { |
| 239 | 'gles_blocks': gles_blocks, |
| 240 | 'desktop_gl_blocks': desktop_gl_blocks, |
Jiawei Shao | 9d9d76c | 2019-08-22 08:19:13 +0000 | [diff] [blame] | 241 | 'extension_desktop_gl_blocks': extension_desktop_gl_blocks, |
| 242 | 'extension_gles_blocks': extension_gles_blocks, |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 243 | 'header_blocks': header_blocks, |
| 244 | } |
| 245 | |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 246 | |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 247 | class OpenGLLoaderGenerator(Generator): |
| 248 | def get_description(self): |
| 249 | return 'Generates code to load OpenGL function pointers' |
| 250 | |
| 251 | def add_commandline_arguments(self, parser): |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 252 | parser.add_argument('--gl-xml', |
| 253 | required=True, |
| 254 | type=str, |
| 255 | help='The Khronos gl.xml to use.') |
| 256 | parser.add_argument( |
| 257 | '--supported-extensions', |
| 258 | required=True, |
| 259 | type=str, |
| 260 | help= |
| 261 | 'The JSON file that defines the OpenGL and GLES extensions to use.' |
| 262 | ) |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 263 | |
Corentin Wallez | f4a01c9 | 2024-07-16 11:18:42 +0000 | [diff] [blame] | 264 | def get_outputs(self, args): |
Jiawei Shao | 9d9d76c | 2019-08-22 08:19:13 +0000 | [diff] [blame] | 265 | supported_extensions = [] |
| 266 | with open(args.supported_extensions) as f: |
| 267 | supported_extensions_json = json.loads(f.read()) |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 268 | supported_extensions = supported_extensions_json[ |
| 269 | 'supported_extensions'] |
Jiawei Shao | 9d9d76c | 2019-08-22 08:19:13 +0000 | [diff] [blame] | 270 | |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 271 | params = compute_params( |
| 272 | etree.parse(args.gl_xml).getroot(), supported_extensions) |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 273 | |
Corentin Wallez | f4a01c9 | 2024-07-16 11:18:42 +0000 | [diff] [blame] | 274 | renders = [ |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 275 | FileRender( |
| 276 | 'opengl/OpenGLFunctionsBase.cpp', |
Ben Clayton | 818001d | 2022-02-04 17:07:46 +0000 | [diff] [blame] | 277 | 'src/dawn/native/opengl/OpenGLFunctionsBase_autogen.cpp', |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 278 | [params]), |
| 279 | FileRender('opengl/OpenGLFunctionsBase.h', |
Ben Clayton | 818001d | 2022-02-04 17:07:46 +0000 | [diff] [blame] | 280 | 'src/dawn/native/opengl/OpenGLFunctionsBase_autogen.h', |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 281 | [params]), |
| 282 | FileRender('opengl/opengl_platform.h', |
Ben Clayton | 818001d | 2022-02-04 17:07:46 +0000 | [diff] [blame] | 283 | 'src/dawn/native/opengl/opengl_platform_autogen.h', |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 284 | [params]), |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 285 | ] |
Corentin Wallez | f4a01c9 | 2024-07-16 11:18:42 +0000 | [diff] [blame] | 286 | return GeneratorOutput(renders=renders, imported_templates=[]) |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 287 | |
| 288 | def get_dependencies(self, args): |
Corentin Wallez | 615d6ea | 2021-05-05 16:06:23 +0000 | [diff] [blame] | 289 | return [ |
| 290 | os.path.abspath(args.gl_xml), |
| 291 | os.path.abspath(args.supported_extensions) |
| 292 | ] |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 293 | |
Kai Ninomiya | 01aeca2 | 2020-07-15 19:51:17 +0000 | [diff] [blame] | 294 | |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 295 | if __name__ == '__main__': |
| 296 | sys.exit(run_generator(OpenGLLoaderGenerator())) |