[Mesa-dev] [PATCH] vulkan: enums: fix generation with enum aliases

Lionel Landwerlin lionel.g.landwerlin at intel.com
Tue Mar 14 11:04:19 UTC 2017


It seems new extensions will start to use aliases in enums, meaning
multiple enums with the same value. This forces us to track the values
of the enums to generate correct C code.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Cc: Dylan Baker <dylan at pnwbakers.com>
---
 src/vulkan/util/gen_enum_to_str.py | 49 ++++++++++++++++++++++++++++++--------
 1 file changed, 39 insertions(+), 10 deletions(-)

diff --git a/src/vulkan/util/gen_enum_to_str.py b/src/vulkan/util/gen_enum_to_str.py
index fb31addf94..1ffe4e362b 100644
--- a/src/vulkan/util/gen_enum_to_str.py
+++ b/src/vulkan/util/gen_enum_to_str.py
@@ -24,6 +24,7 @@
 from __future__ import print_function
 import argparse
 import os
+import re
 import textwrap
 import xml.etree.cElementTree as et
 
@@ -67,9 +68,9 @@ C_TEMPLATE = Template(textwrap.dedent(u"""\
         vk_${enum.name[2:]}_to_str(${enum.name} input)
         {
             switch(input) {
-            % for v in enum.values:
-                case ${v}:
-                    return "${v}";
+            % for k, v in enum.values.iteritems():
+                case ${v[0]}:
+                    return "${' / '.join(v)}";
             % endfor
             default:
                 unreachable("Undefined enum value.");
@@ -116,10 +117,17 @@ class EnumFactory(object):
 class VkEnum(object):
     """Simple struct-like class representing a single Vulkan Enum."""
 
-    def __init__(self, name, values=None):
+    def __init__(self, name):
         self.name = name
-        self.values = values or []
+        self.values = {}
+        self.names = {}
 
+    def add_item(self, name, value):
+        if value in self.values:
+            self.values[value].append(name)
+        else:
+            self.values[value] = [name]
+        self.names[name] = value
 
 def xml_parser(filename):
     """Parse the XML file and return parsed data.
@@ -129,6 +137,24 @@ def xml_parser(filename):
     """
     efactory = EnumFactory(VkEnum)
 
+    number_regexp = re.compile('^-?[0-9]+$')
+
+    def compute_enum_value(enum, elem, parent):
+        if 'offset' in elem.attrib:
+            # Formula taken from the src/spec/generator.py
+            # https://github.com/khronosGroup/Vulkan-Docs
+            value = 1000000000 + (int(parent.attrib['number']) - 1) * 1000
+            value += int(elem.attrib['offset'])
+            if 'dir' in e.attrib:
+                value = -value
+        else:
+            number = elem.attrib['value']
+            if re.match(number_regexp, number):
+                value = int(number)
+            else:
+                value = enum.names[number]
+        return value
+
     with open(filename, 'rb') as f:
         context = iter(et.iterparse(f, events=('start', 'end')))
 
@@ -140,16 +166,19 @@ def xml_parser(filename):
         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'])
+                if type_ != 'enum':
+                    continue
+                enum = efactory(elem.attrib['name'])
+                for e in elem:
+                    if e.tag != 'enum':
+                        continue
+                    enum.add_item(e.attrib['name'], compute_enum_value(enum, e, None))
             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'])
+                    enum.add_item(e.attrib['name'], compute_enum_value(enum, e, elem))
 
             root.clear()
 
-- 
2.11.0



More information about the mesa-dev mailing list