winevulkan: Check if conversion is required for pNext chains.

Unhandled conversions are only logged for now.

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2018-10-05 16:55:18 +02:00 committed by Alexandre Julliard
parent 6e87235523
commit 94a4dadd9a
1 changed files with 37 additions and 4 deletions

View File

@ -1028,9 +1028,12 @@ class VkMember(object):
# Collect any conversion for any member structs. # Collect any conversion for any member structs.
struct = self.type_info["data"] struct = self.type_info["data"]
for m in struct: for m in struct:
m.needs_struct_extensions_conversion()
if m.needs_conversion(): if m.needs_conversion():
conversions.extend(m.get_conversions()) conversions.extend(m.get_conversions())
struct.needs_struct_extensions_conversion()
struct = self.type_info["data"] struct = self.type_info["data"]
direction = Direction.OUTPUT if struct.returnedonly else Direction.INPUT direction = Direction.OUTPUT if struct.returnedonly else Direction.INPUT
if self.is_dynamic_array(): if self.is_dynamic_array():
@ -1119,6 +1122,13 @@ class VkMember(object):
# though none of this type have been encountered yet. # though none of this type have been encountered yet.
return False return False
def needs_struct_extensions_conversion(self):
if not self.is_struct():
return False
struct = self.type_info["data"]
return struct.needs_struct_extensions_conversion()
def set_type_info(self, type_info): def set_type_info(self, type_info):
""" Helper function to set type information from the type registry. """ Helper function to set type information from the type registry.
This is needed, because not all type data is available at time of This is needed, because not all type data is available at time of
@ -1356,6 +1366,10 @@ class VkParam(object):
if not self.is_struct(): if not self.is_struct():
return None return None
self.struct.needs_struct_extensions_conversion()
for m in self.struct:
m.needs_struct_extensions_conversion()
if not self.needs_conversion(): if not self.needs_conversion():
return None return None
@ -1485,14 +1499,16 @@ class VkParam(object):
class VkStruct(Sequence): class VkStruct(Sequence):
""" Class which represents the type union and struct. """ """ Class which represents the type union and struct. """
def __init__(self, name, members, returnedonly, alias=None, union=False): def __init__(self, name, members, returnedonly, structextends, alias=None, union=False):
self.name = name self.name = name
self.members = members self.members = members
self.returnedonly = returnedonly self.returnedonly = returnedonly
self.structextends = structextends
self.required = False self.required = False
self.alias = alias self.alias = alias
self.union = union self.union = union
self.type_info = None # To be set later. self.type_info = None # To be set later.
self.struct_extensions = []
def __getitem__(self, i): def __getitem__(self, i):
return self.members[i] return self.members[i]
@ -1503,7 +1519,7 @@ class VkStruct(Sequence):
@staticmethod @staticmethod
def from_alias(struct, alias): def from_alias(struct, alias):
name = struct.attrib.get("name") name = struct.attrib.get("name")
return VkStruct(name, alias.members, alias.returnedonly, alias=alias) return VkStruct(name, alias.members, alias.returnedonly, alias.structextends, alias=alias)
@staticmethod @staticmethod
def from_xml(struct): def from_xml(struct):
@ -1511,18 +1527,21 @@ class VkStruct(Sequence):
# know which one we are dealing with later on for code generation. # know which one we are dealing with later on for code generation.
union = True if struct.attrib["category"] == "union" else False union = True if struct.attrib["category"] == "union" else False
name = struct.attrib.get("name", None) name = struct.attrib.get("name")
# 'Output' structures for which data is filled in by the API are # 'Output' structures for which data is filled in by the API are
# marked as 'returnedonly'. # marked as 'returnedonly'.
returnedonly = True if struct.attrib.get("returnedonly") else False returnedonly = True if struct.attrib.get("returnedonly") else False
structextends = struct.attrib.get("structextends")
structextends = structextends.split(",") if structextends else []
members = [] members = []
for member in struct.findall("member"): for member in struct.findall("member"):
vk_member = VkMember.from_xml(member) vk_member = VkMember.from_xml(member)
members.append(vk_member) members.append(vk_member)
return VkStruct(name, members, returnedonly, union=union) return VkStruct(name, members, returnedonly, structextends, union=union)
@staticmethod @staticmethod
def decouple_structs(structs): def decouple_structs(structs):
@ -1648,6 +1667,16 @@ class VkStruct(Sequence):
return False return False
def needs_struct_extensions_conversion(self):
""" Checks if structure extensions in pNext chain need conversion. """
for e in self.struct_extensions:
if e.required and e.needs_conversion():
LOGGER.error("Unhandled pNext chain conversion for {0}".format(e.name))
return True
return False
def set_type_info(self, types): def set_type_info(self, types):
""" Helper function to set type information from the type registry. """ Helper function to set type information from the type registry.
This is needed, because not all type data is available at time of This is needed, because not all type data is available at time of
@ -2756,6 +2785,10 @@ class VkRegistry(object):
for struct in structs: for struct in structs:
struct.set_type_info(self.types) struct.set_type_info(self.types)
for structextend in struct.structextends:
s = self.types[structextend]["data"]
s.struct_extensions.append(struct)
# Guarantee everything is sorted, so code generation doesn't have # Guarantee everything is sorted, so code generation doesn't have
# to deal with this. # to deal with this.
self.base_types = sorted(base_types, key=lambda base_type: base_type.name) self.base_types = sorted(base_types, key=lambda base_type: base_type.name)