Tested with win32 ffmpeg.
This merge request basically passes video.xml (and its parsed form) as an extra argument where vk.xml is passed. While this is ad-hoc and not very future-proof, there is no indication that Khronos will fragment its XMLs any further, and it does not seem worthwhile to me to try to generalize the parsing logic in that respect as long as only two XMLs are used. However, if the maintainers feel differently, I will endeavour to do so.
From: Elizabeth Figura zfigura@codeweavers.com
Some video.xml fields have e.g.
<name>foo</name> : 1
in comparison to existing vk.xml fields which lack the spaces. --- dlls/winevulkan/make_vulkan | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 6d68d794835..dd5b9f74485 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -1495,6 +1495,10 @@ class VkMember(VkVariable): if type_elem.tail is not None: pointer = type_elem.tail.strip() if type_elem.tail.strip() != "" else None
+ name_tail = None + if name_elem.tail and name_elem.tail.strip() != "": + name_tail = name_elem.tail.strip() + # Name of other member within, which stores the number of # elements pointed to be by this member. dyn_array_len = member.get("len") @@ -1511,22 +1515,22 @@ class VkMember(VkVariable): # Some members are arrays, attempt to parse these. Formats include: # <member><type>char</type><name>extensionName</name>[<enum>VK_MAX_EXTENSION_NAME_SIZE</enum>]</member> # <member><type>uint32_t</type><name>foo</name>[4]</member> - if name_elem.tail and name_elem.tail[0] == '[': + if name_tail and name_tail[0] == '[': LOGGER.debug("Found array type") enum_elem = member.find("enum") if enum_elem is not None: array_len = enum_elem.text else: # Remove brackets around length - array_len = name_elem.tail.strip("[]") + array_len = name_tail.strip("[]")
object_type = member.get("objecttype", None)
# Some members are bit field values: # <member><type>uint32_t</type> <name>mask</name>:8</member> - if name_elem.tail and name_elem.tail[0] == ':': + if name_tail and name_tail[0] == ':': LOGGER.debug("Found bit field") - bit_width = int(name_elem.tail[1:]) + bit_width = int(name_tail[1:])
selection = member.get("selection").split(',') if member.get("selection") else None selector = member.get("selector", None)
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/winevulkan/make_vulkan | 85 ++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 25 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index dd5b9f74485..babbcb2ef3f 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -101,8 +101,6 @@ UNSUPPORTED_EXTENSIONS = [ "VK_KHR_external_semaphore_win32", # Relates to external_semaphore and needs type conversions in bitflags. "VK_KHR_shared_presentable_image", # Needs WSI work. - "VK_KHR_video_encode_queue", - "VK_KHR_video_queue", # TODO Video extensions use separate headers + xml "VK_KHR_win32_keyed_mutex", "VK_NV_external_memory_rdma", # Needs shared resources work.
@@ -2709,10 +2707,13 @@ class VkGenerator(object):
def _generate_copyright(self, f, spec_file=False): f.write("# " if spec_file else "/* ") - f.write("Automatically generated from Vulkan vk.xml; DO NOT EDIT!\n") + f.write("Automatically generated from Vulkan vk.xml and video.xml; DO NOT EDIT!\n") lines = ["", "This file is generated from Vulkan vk.xml file covered", "by the following copyright and permission notice:"] lines.extend([l.rstrip(" ") for l in self.registry.copyright.splitlines()]) + lines.extend(["and from Vulkan video.xml file covered", + "by the following copyright and permission notice:"]) + lines.extend([l.rstrip(" ") for l in self.registry.video_copyright.splitlines()]) for line in lines: f.write("{0}{1}".format("# " if spec_file else " * ", line).rstrip(" ") + "\n") f.write("\n" if spec_file else " */\n\n") @@ -3220,7 +3221,7 @@ class VkGenerator(object):
class VkRegistry(object): - def __init__(self, reg_filename): + def __init__(self, vk_xml, video_xml): # Used for storage of type information. self.base_types = None self.bitmasks = None @@ -3250,15 +3251,20 @@ class VkRegistry(object): # features and extensions to decide which types / functions # to actually 'pull in' for code generation. For each type or # function call we want we set a member 'required' to True. - tree = ET.parse(reg_filename) + tree = ET.parse(vk_xml) root = tree.getroot() - self._parse_enums(root) - self._parse_types(root) + # The video XML currently only has enums, types, and part of the + # extension data in it. + # All of the relevant extensions and commands are in vk.xml. + video_tree = ET.parse(video_xml) + video_root = video_tree.getroot() + self._parse_enums(root, video_root) + self._parse_types(root, video_root) self._parse_commands(root)
# Pull in any required types and functions. self._parse_features(root) - self._parse_extensions(root) + self._parse_extensions(root, video_root)
for enum in self.enums.values(): enum.fixup_64bit_aliases() @@ -3266,6 +3272,7 @@ class VkRegistry(object): self._match_object_types()
self.copyright = root.find('./comment').text + self.video_copyright = video_root.find('./comment').text
def _is_feature_supported(self, feature): version = self.version_regex.match(feature) @@ -3406,11 +3413,11 @@ class VkRegistry(object): # calls when needed e.g. to adjust member variables. self.funcs = OrderedDict(sorted(funcs.items()))
- def _parse_enums(self, root): + def _parse_enums(self, root, video_root): """ Parse enums section or better described as constants section. """ enums = {} self.consts = [] - for enum in root.findall("./enums"): + for enum in root.findall("./enums") + video_root.findall("./enums"): name = enum.attrib.get("name") _type = enum.attrib.get("type")
@@ -3494,7 +3501,7 @@ class VkRegistry(object):
@staticmethod def _require_type(type_info): - if type_info.is_alias(): + if type(type_info) != VkDefine and type_info.is_alias(): type_info = type_info.alias type_info.required = True if type(type_info) == VkStruct: @@ -3502,10 +3509,10 @@ class VkRegistry(object): if "data" in member.type_info: VkRegistry._require_type(member.type_info["data"])
- def _parse_extensions(self, root): + def _parse_extensions(self, root, video_root): """ Parse extensions section and pull in any types and commands for this extension. """ extensions = [] - exts = root.findall("./extensions/extension") + exts = root.findall("./extensions/extension") + video_root.findall("./extensions/extension") deferred_exts = [] skipped_exts = UNSUPPORTED_EXTENSIONS.copy()
@@ -3588,8 +3595,14 @@ class VkRegistry(object): self._process_require_enum(enum_elem, ext)
for t in require.findall("type"): - type_info = self.types[t.attrib["name"]]["data"] - self._require_type(type_info) + # video.xml uses "type" to include various headers, + # including stdint.h (which we include manually) and + # specific vk_video/* headers (which we don't use). + # We don't even parse <type category="include"> tags. + # Therefore just skip any types that aren't found. + if t.attrib["name"] in self.types: + type_info = self.types[t.attrib["name"]]["data"] + self._require_type(type_info) feature = require.attrib.get("feature") if feature and not self._is_feature_supported(feature): continue @@ -3606,8 +3619,18 @@ class VkRegistry(object):
# Store a list with extensions. - ext_info = {"name" : ext_name, "type" : ext.attrib["type"]} - extensions.append(ext_info) + # Video extensions are for some reason split up across vk.xml and + # video.xml. + # vk.xml has the actual extension definition and most of the + # dependent type and enum definitions. + # video.xml has an <extension> whose "name" is the target header + # file and whose <require> has the remaining type and enum + # definitions. We parse those above for the <require> part, but we + # don't want to add the extension as a real extension here. + # Checking for the existence of "type" seems to achieve this. + if "type" in ext.attrib: + ext_info = {"name" : ext_name, "type" : ext.attrib["type"]} + extensions.append(ext_info)
# Process extensions, allowing for sortorder to defer extension processing @@ -3652,9 +3675,9 @@ class VkRegistry(object): type_info = self.types[name] type_info["data"].required = True
- def _parse_types(self, root): + def _parse_types(self, root, video_root): """ Parse types section, which contains all data types e.g. structs, typedefs etcetera. """ - types = root.findall("./types/type") + types = root.findall("./types/type") + video_root.findall("./types/type")
base_types = [] bitmasks = [] @@ -3679,6 +3702,11 @@ class VkRegistry(object): if type_info["category"] in ["include"]: continue
+ # video.xml redefines stdint types which we already parsed in vk.xml. + # For some reason, it doesn't define them the same way. + if type_info["requires"] == "stdint": + continue + if type_info["category"] == "basetype": name = t.find("name").text _type = None @@ -3846,15 +3874,16 @@ def set_working_directory(): path = os.path.dirname(path) os.chdir(path)
-def download_vk_xml(filename): - url = "https://raw.githubusercontent.com/KhronosGroup/Vulkan-Docs/v%7B0%7D/xml/vk.x...) - if not os.path.isfile(filename): - urllib.request.urlretrieve(url, filename) +def download_vk_xml(dst_filename, src_filename): + url = "https://raw.githubusercontent.com/KhronosGroup/Vulkan-Docs/v%7B0%7D/xml/%7B1..., src_filename) + if not os.path.isfile(dst_filename): + urllib.request.urlretrieve(url, dst_filename)
def main(): parser = argparse.ArgumentParser() parser.add_argument("-v", "--verbose", action="count", default=0, help="increase output verbosity") parser.add_argument("-x", "--xml", default=None, type=str, help="path to specification XML file") + parser.add_argument("-X", "--video-xml", default=None, type=str, help="path to specification video XML file")
args = parser.parse_args() if args.verbose == 0: @@ -3870,9 +3899,15 @@ def main(): vk_xml = args.xml else: vk_xml = "vk-{0}.xml".format(VK_XML_VERSION) - download_vk_xml(vk_xml) + download_vk_xml(vk_xml, "vk.xml") + + if args.video_xml: + video_xml = args.video_xml + else: + video_xml = "video-{0}.xml".format(VK_XML_VERSION) + download_vk_xml(video_xml, "video.xml")
- registry = VkRegistry(vk_xml) + registry = VkRegistry(vk_xml, video_xml) generator = VkGenerator(registry)
with open(WINE_VULKAN_H, "w") as f:
This merge request was approved by Jacek Caban.