aboutsummaryrefslogtreecommitdiffhomepage
path: root/registry/reg.py
diff options
context:
space:
mode:
Diffstat (limited to 'registry/reg.py')
-rw-r--r--registry/reg.py121
1 files changed, 101 insertions, 20 deletions
diff --git a/registry/reg.py b/registry/reg.py
index aac71c2..317d583 100644
--- a/registry/reg.py
+++ b/registry/reg.py
@@ -1552,8 +1552,31 @@ class Registry:
for cmd in self.apidict:
self.apidict[cmd].resetState()
- def __validateStructLimittypes(self, struct):
- """Validate 'limittype' attributes for a single struct."""
+ def __isLimittypeStruct(self, structName, structElem, allowedStructs):
+ """Check if a type element is a structure allowed to have 'limittype' attributes
+ structName - name of a structure
+ structElem - corresponding <type> Element
+ allowedStructs - set of struct names explicitly allowed"""
+
+ # Is this an explicitly allowed struct?
+ if structName in allowedStructs:
+ return True
+
+ # Is this a struct extending an explicitly allowed struct?
+ extends = structElem.get('structextends')
+ if extends is not None:
+ # See if any name in the structextends attribute is an allowed
+ # struct
+ if len(set(extends.split(',')) & allowedStructs) > 0:
+ return True
+
+ return False
+
+ def __validateStructLimittypes(self, struct, requiredLimittype):
+ """Validate 'limittype' attributes for a single struct.
+ struct - typeinfo for a struct <type>
+ requiredLimittype - True if members *must* have a limittype"""
+
limittypeDiags = namedtuple('limittypeDiags', ['missing', 'invalid'])
badFields = defaultdict(lambda : limittypeDiags(missing=[], invalid=[]))
validLimittypes = { 'min', 'max', 'bitmask', 'range', 'struct', 'noauto' }
@@ -1562,33 +1585,91 @@ class Registry:
if memberName in ['sType', 'pNext']:
continue
limittype = member.get('limittype')
- if not limittype:
- badFields[struct.elem.get('name')].missing.append(memberName)
+ if limittype is None:
+ # Do not tag this as missing if it is not required
+ if requiredLimittype:
+ badFields[struct.elem.get('name')].missing.append(memberName)
elif limittype == 'struct':
typeName = member.findtext('type')
memberType = self.typedict[typeName]
- badFields.update(self.__validateStructLimittypes(memberType))
+ badFields.update(self.__validateStructLimittypes(memberType, requiredLimittype))
elif limittype not in validLimittypes:
badFields[struct.elem.get('name')].invalid.append(memberName)
+
return badFields
def __validateLimittype(self):
"""Validate 'limittype' attributes."""
- badFields = self.__validateStructLimittypes(self.typedict['VkPhysicalDeviceProperties2'])
- for featStructName in self.validextensionstructs['VkPhysicalDeviceProperties2']:
- featStruct = self.typedict[featStructName]
- badFields.update(self.__validateStructLimittypes(featStruct))
-
- if badFields:
- self.gen.logMsg('diag', 'SUMMARY OF FIELDS WITH INCORRECT LIMITTYPES')
- for key in sorted(badFields.keys()):
- diags = badFields[key]
- if diags.missing:
- self.gen.logMsg('diag', ' ', key, 'missing limittype:', ', '.join(badFields[key].missing))
- if diags.invalid:
- self.gen.logMsg('diag', ' ', key, 'invalid limittype:', ', '.join(badFields[key].invalid))
- return False
- return True
+
+ # Structures explicitly allowed to have 'limittype' attributes
+ allowedStructs = set((
+ 'VkPhysicalDeviceProperties',
+ 'VkPhysicalDeviceProperties2',
+ 'VkPhysicalDeviceLimits',
+ 'VkFormatProperties',
+ 'VkFormatProperties2',
+ 'VkQueueFamilyProperties',
+ 'VkQueueFamilyProperties2',
+ ))
+ # Substructures of allowed structures. This can be found by looking
+ # at tags, but there are so few cases that it is hardwired for now.
+ nestedStructs = set((
+ 'VkPhysicalDeviceLimits',
+ 'VkPhysicalDeviceSparseProperties',
+ 'VkPhysicalDeviceProperties',
+ 'VkQueueFamilyProperties',
+ ))
+ # Structures all of whose (non pNext/sType) members are required to
+ # have 'limittype' attributes, as are their descendants
+ requiredStructs = set((
+ 'VkPhysicalDeviceProperties',
+ 'VkPhysicalDeviceProperties2',
+ 'VkPhysicalDeviceLimits',
+ ))
+
+ # Checks all structures, so accumulate a valid/invalid flag
+ valid = True
+
+ # Loop over all structure members, checking that there are no
+ # limittype attributes except for allowed structures.
+ for structName in self.typedict:
+ struct = self.typedict[structName]
+
+ # Do not check non-structs
+ if struct.elem.get('category') != 'struct':
+ continue
+
+ # Only check structs not allowed to have limittypes
+ if not self.__isLimittypeStruct(structName, struct.elem, allowedStructs.union(nestedStructs)):
+ for member in struct.getMembers():
+ if member.get('limittype') is not None:
+ memname = member.findtext('name')
+ self.gen.logMsg('diag', f' {structName} member {memname} has disallowed limittype attribute')
+ valid = False
+
+ # Loop over allowed structs and their extending structs checking for
+ # invalid and missing limittype attributes
+ for structName in allowedStructs:
+ # Assume that only extending structs of structs explicitly
+ # requiring limittypes also require them
+ requiredLimittype = (structName in requiredStructs)
+
+ badFields = self.__validateStructLimittypes(self.typedict[structName], requiredLimittype)
+ for extendingStructName in self.validextensionstructs[structName]:
+ extendingStruct = self.typedict[extendingStructName]
+ badFields.update(self.__validateStructLimittypes(extendingStruct, requiredLimittype))
+
+ if badFields:
+ self.gen.logMsg('diag', f'Incorrect limittype attributes for {structName}')
+ for key in sorted(badFields.keys()):
+ diags = badFields[key]
+ if diags.missing:
+ self.gen.logMsg('diag', ' ', key, 'missing limittype:', ', '.join(badFields[key].missing))
+ if diags.invalid:
+ self.gen.logMsg('diag', ' ', key, 'invalid limittype:', ', '.join(badFields[key].invalid))
+ valid = False
+
+ return valid
def validateRegistry(self):
"""Validate properties of the registry."""