[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