diff options
author | Dylan Baker <[email protected]> | 2017-02-15 15:41:50 -0800 |
---|---|---|
committer | Dylan Baker <[email protected]> | 2017-02-22 13:12:02 -0800 |
commit | e9dcb17962f7e58a81c93bae7bd33885675b1043 (patch) | |
tree | 55332d8cdb6783ab65fc8d34e4df8168fb38dcab /src/vulkan/util/gen_enum_to_str.py | |
parent | bda59f6e417b68985ffc8dbb92fcfe19ba12f7bf (diff) |
vulkan/util: Add generator for enum_to_str functions
This adds a python generator to produce enum_to_str functions for
Vulkan from the vk.xml API description. It supports extensions as well
as core API features, and the generator works with both python2 and
python3.
Signed-off-by: Dylan Baker <[email protected]>
Acked-by: Matt Turner <[email protected]>
Acked-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/vulkan/util/gen_enum_to_str.py')
-rw-r--r-- | src/vulkan/util/gen_enum_to_str.py | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/src/vulkan/util/gen_enum_to_str.py b/src/vulkan/util/gen_enum_to_str.py new file mode 100644 index 00000000000..0564b8e0280 --- /dev/null +++ b/src/vulkan/util/gen_enum_to_str.py @@ -0,0 +1,172 @@ +# encoding=utf-8 +# Copyright © 2017 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +"""Create enum to string functions for vulking using vk.xml.""" + +from __future__ import print_function +import os +import textwrap +import xml.etree.cElementTree as et + +from mako.template import Template + +VK_XML = os.path.join(os.path.dirname(__file__), '..', 'registry', 'vk.xml') + +COPYRIGHT = textwrap.dedent(u"""\ + * Copyright © 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE.""") + +C_TEMPLATE = Template(textwrap.dedent(u"""\ + /* Autogenerated file -- do not edit + * generated by ${file} + * + ${copyright} + */ + + #include <vulkan/vulkan.h> + #include "util/macros.h" + #include "vk_enum_to_str.h" + + % for enum in enums: + + const char * + vk_${enum.name[2:]}_to_str(${enum.name} input) + { + switch(input) { + % for v in enum.values: + case ${v}: + return "${v}"; + % endfor + default: + unreachable("Undefined enum value."); + } + } + %endfor"""), + output_encoding='utf-8') + +H_TEMPLATE = Template(textwrap.dedent(u"""\ + /* Autogenerated file -- do not edit + * generated by ${file} + * + ${copyright} + */ + + #ifndef MESA_VK_ENUM_TO_STR_H + #define MESA_VK_ENUM_TO_STR_H + + #include <vulkan/vulkan.h> + + % for enum in enums: + const char * vk_${enum.name[2:]}_to_str(${enum.name} input); + % endfor + + #endif"""), + output_encoding='utf-8') + + +class EnumFactory(object): + """Factory for creating enums.""" + + def __init__(self, type_): + self.registry = {} + self.type = type_ + + def __call__(self, name): + try: + return self.registry[name] + except KeyError: + n = self.registry[name] = self.type(name) + return n + + +class VkEnum(object): + """Simple struct-like class representing a single Vulkan Enum.""" + + def __init__(self, name, values=None): + self.name = name + self.values = values or [] + + +def xml_parser(filename): + """Parse the XML file and return parsed data. + + This parser is a memory efficient iterative XML parser that returns a list + of VkEnum objects. + """ + efactory = EnumFactory(VkEnum) + + with open(filename, 'rb') as f: + context = iter(et.iterparse(f, events=('start', 'end'))) + + # This gives the root element, since goal is to iterate over the + # elements without building a tree, this allows the root to be cleared + # (erase the elements) after the children have been processed. + _, root = next(context) + + for event, elem in context: + if event == 'end' and elem.tag == 'enums': + type_ = elem.attrib.get('type') + if type_ == 'enum': + enum = efactory(elem.attrib['name']) + enum.values.extend([e.attrib['name'] for e in elem + if e.tag == 'enum']) + elif event == 'end' and elem.tag == 'extension': + if elem.attrib['supported'] != 'vulkan': + continue + for e in elem.findall('.//enum[@extends][@offset]'): + enum = efactory(e.attrib['extends']) + enum.values.append(e.attrib['name']) + + root.clear() + + return efactory.registry.values() + + +def main(): + enums = xml_parser(VK_XML) + for template, file_ in [(C_TEMPLATE, 'vk_enum_to_str.c'), + (H_TEMPLATE, 'vk_enum_to_str.h')]: + with open(file_, 'wb') as f: + f.write(template.render( + file=os.path.basename(__file__), + enums=enums, + copyright=COPYRIGHT)) + + +if __name__ == '__main__': + main() |