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: