diff options
Diffstat (limited to 'registry/reg.py')
-rw-r--r-- | registry/reg.py | 91 |
1 files changed, 80 insertions, 11 deletions
diff --git a/registry/reg.py b/registry/reg.py index 699235a..254cfbd 100644 --- a/registry/reg.py +++ b/registry/reg.py @@ -762,12 +762,23 @@ class Registry: cmd = self.lookupElementInfo(cmdname, self.cmddict) if cmd is not None: cmd.required = required + # Tag command dependencies in 'alias' attribute as required - depname = cmd.elem.get('alias') - if depname: - self.gen.logMsg('diag', 'Generating dependent command', - depname, 'for alias', cmdname) - self.markCmdRequired(depname, required) + # + # This is usually not done, because command 'aliases' are not + # actual C language aliases like type and enum aliases. Instead + # they are just duplicates of the function signature of the + # alias. This means that there is no dependency of a command + # alias on what it aliases. One exception is validity includes, + # where the spec markup needs the promoted-to validity include + # even if only the promoted-from command is being built. + if self.genOpts.requireCommandAliases: + depname = cmd.elem.get('alias') + if depname: + self.gen.logMsg('diag', 'Generating dependent command', + depname, 'for alias', cmdname) + self.markCmdRequired(depname, required) + # Tag all parameter types of this command as required. # This DOES NOT remove types of commands in a <remove> # tag, because many other commands may use the same type. @@ -842,8 +853,13 @@ class Registry: - require - `<require>` block from the registry - tag - tag to look for in the require block""" - if alias and require.findall(tag + "[@name='" + alias + "']"): - return True + # For the time being, the code below is bypassed. It has the effect + # of excluding "spelling aliases" created to comply with the style + # guide, but this leaves references out of the specification and + # causes broken internal links. + # + # if alias and require.findall(tag + "[@name='" + alias + "']"): + # return True return False @@ -902,6 +918,9 @@ class Registry: if not typeextends in self.gen.featureDictionary[featurename][typecat][required_key]: self.gen.featureDictionary[featurename][typecat][required_key][typeextends] = [] self.gen.featureDictionary[featurename][typecat][required_key][typeextends].append(typename) + else: + self.gen.logMsg('warn', 'fillFeatureDictionary: NOT filling for {}'.format(typename)) + for enumElem in require.findall('enum'): enumname = enumElem.get('name') @@ -916,16 +935,18 @@ class Registry: if not enumextends in self.gen.featureDictionary[featurename]['enumconstant'][required_key]: self.gen.featureDictionary[featurename]['enumconstant'][required_key][enumextends] = [] self.gen.featureDictionary[featurename]['enumconstant'][required_key][enumextends].append(enumname) + else: + self.gen.logMsg('warn', 'fillFeatureDictionary: NOT filling for {}'.format(typename)) for cmdElem in require.findall('command'): - # Remove aliases in the same extension/feature; these are always added as a correction. Don't need the original to be visible. alias = self.getAlias(cmdElem, self.cmddict) if not self.checkForCorrectionAliases(alias, require, 'command'): if not required_key in self.gen.featureDictionary[featurename]['command']: self.gen.featureDictionary[featurename]['command'][required_key] = [] self.gen.featureDictionary[featurename]['command'][required_key].append(cmdElem.get('name')) - + else: + self.gen.logMsg('warn', 'fillFeatureDictionary: NOT filling for {}'.format(typename)) def requireAndRemoveFeatures(self, interface, featurename, api, profile): """Process `<require>` and `<remove>` tags for a `<version>` or `<extension>`. @@ -935,10 +956,12 @@ class Registry: - featurename - name of the feature - api - string specifying API name being generated - profile - string specifying API profile being generated""" + # <require> marks things that are required by this version/profile for feature in interface.findall('require'): if matchAPIProfile(api, profile, feature): self.markRequired(featurename, feature, True) + # <remove> marks things that are removed by this version/profile for feature in interface.findall('remove'): if matchAPIProfile(api, profile, feature): @@ -1167,6 +1190,32 @@ class Registry: genProc = self.gen.genSpirv genProc(spirv, name, alias) + def stripUnsupportedAPIs(self, dictionary, attribute, supportedDictionary): + """Strip unsupported APIs from attributes of APIs. + dictionary - *Info dictionary of APIs to be updated + attribute - attribute name to look for in each API + supportedDictionary - dictionary in which to look for supported + API elements in the attribute""" + + for key in dictionary: + eleminfo = dictionary[key] + attribstring = eleminfo.elem.get(attribute) + if attribstring is not None: + apis = [] + stripped = False + for api in attribstring.split(','): + ##print('Checking API {} referenced by {}'.format(api, key)) + if supportedDictionary[api].required: + apis.append(api) + else: + stripped = True + ##print('\t**STRIPPING API {} from {}'.format(api, key)) + + # Update the attribute after stripping stuff. + # Could sort apis before joining, but it's not a clear win + if stripped: + eleminfo.elem.set(attribute, ','.join(apis)) + def apiGen(self): """Generate interface for specified versions using the current generator and generator options""" @@ -1177,8 +1226,13 @@ class Registry: 'profile:', self.genOpts.profile) self.gen.logMsg('diag', '*******************************************') - # Reset required/declared flags for all features - self.apiReset() + # Could reset required/declared flags for all features here. + # This has been removed as never used. The initial motivation was + # the idea of calling apiGen() repeatedly for different targets, but + # this has never been done. The 20% or so build-time speedup that + # might result is not worth the effort to make it actually work. + # + #@@ self.apiReset() # Compile regexps used to select versions & extensions regVersions = re.compile(self.genOpts.versions) @@ -1316,6 +1370,21 @@ class Registry: self.requireAndRemoveFeatures(f.elem, f.name, self.genOpts.apiname, self.genOpts.profile) self.assignAdditionalValidity(f.elem, self.genOpts.apiname, self.genOpts.profile) + # Now, strip references to APIs that are not required. + # At present such references may occur in: + # Structs in <type category="struct"> 'structextends' attributes + # Enums in <command> 'successcodes' and 'errorcodes' attributes + self.stripUnsupportedAPIs(self.typedict, 'structextends', self.typedict) + self.stripUnsupportedAPIs(self.cmddict, 'successcodes', self.enumdict) + self.stripUnsupportedAPIs(self.cmddict, 'errorcodes', self.enumdict) + + # @@May need to strip <spirvcapability> / <spirvextension> <enable> + # tags of these forms: + # <enable version="VK_API_VERSION_1_0"/> + # <enable struct="VkPhysicalDeviceFeatures" feature="geometryShader" requires="VK_VERSION_1_0"/> + # <enable extension="VK_KHR_shader_draw_parameters"/> + # <enable property="VkPhysicalDeviceVulkan12Properties" member="shaderDenormPreserveFloat16" value="VK_TRUE" requires="VK_VERSION_1_2,VK_KHR_shader_float_controls"/> + # Pass 2: loop over specified API versions and extensions printing # declarations for required things which haven't already been # generated. |