1e5c31af7Sopenharmony_ci#!/usr/bin/python3 -i 2e5c31af7Sopenharmony_ci# 3e5c31af7Sopenharmony_ci# Copyright 2013-2024 The Khronos Group Inc. 4e5c31af7Sopenharmony_ci# 5e5c31af7Sopenharmony_ci# SPDX-License-Identifier: Apache-2.0 6e5c31af7Sopenharmony_ci 7e5c31af7Sopenharmony_cifrom generator import OutputGenerator, write 8e5c31af7Sopenharmony_cifrom spec_tools.attributes import ExternSyncEntry 9e5c31af7Sopenharmony_cifrom spec_tools.validity import ValidityCollection, ValidityEntry 10e5c31af7Sopenharmony_cifrom spec_tools.util import getElemName 11e5c31af7Sopenharmony_ci 12e5c31af7Sopenharmony_ci 13e5c31af7Sopenharmony_ciclass HostSynchronizationOutputGenerator(OutputGenerator): 14e5c31af7Sopenharmony_ci """HostSynchronizationOutputGenerator - subclass of OutputGenerator. 15e5c31af7Sopenharmony_ci Generates AsciiDoc includes of the externsync parameter table for the 16e5c31af7Sopenharmony_ci fundamentals chapter of the API specification. Similar to 17e5c31af7Sopenharmony_ci DocOutputGenerator. 18e5c31af7Sopenharmony_ci 19e5c31af7Sopenharmony_ci ---- methods ---- 20e5c31af7Sopenharmony_ci HostSynchronizationOutputGenerator(errFile, warnFile, diagFile) - args as for 21e5c31af7Sopenharmony_ci OutputGenerator. Defines additional internal state. 22e5c31af7Sopenharmony_ci ---- methods overriding base class ---- 23e5c31af7Sopenharmony_ci genCmd(cmdinfo)""" 24e5c31af7Sopenharmony_ci # Generate Host Synchronized Parameters in a table at the top of the spec 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci threadsafety = { 27e5c31af7Sopenharmony_ci 'parameters': ValidityCollection(), 28e5c31af7Sopenharmony_ci 'parameterlists': ValidityCollection(), 29e5c31af7Sopenharmony_ci 'implicit': ValidityCollection() 30e5c31af7Sopenharmony_ci } 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ci def makeParameterName(self, name): 33e5c31af7Sopenharmony_ci return 'pname:' + name 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_ci def makeFLink(self, name): 36e5c31af7Sopenharmony_ci return 'flink:' + name 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_ci def writeBlock(self, basename, title, contents): 39e5c31af7Sopenharmony_ci """Generate an include file. 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_ci - directory - subdirectory to put file in 42e5c31af7Sopenharmony_ci - basename - base name of the file 43e5c31af7Sopenharmony_ci - contents - contents of the file (Asciidoc boilerplate aside)""" 44e5c31af7Sopenharmony_ci filename = self.genOpts.directory + '/' + basename 45e5c31af7Sopenharmony_ci self.logMsg('diag', '# Generating include file:', filename) 46e5c31af7Sopenharmony_ci with open(filename, 'w', encoding='utf-8') as fp: 47e5c31af7Sopenharmony_ci write(self.genOpts.conventions.warning_comment, file=fp) 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_ci if contents: 50e5c31af7Sopenharmony_ci write('.%s' % title, file=fp) 51e5c31af7Sopenharmony_ci write('****', file=fp) 52e5c31af7Sopenharmony_ci write(contents, file=fp, end='') 53e5c31af7Sopenharmony_ci write('****', file=fp) 54e5c31af7Sopenharmony_ci write('', file=fp) 55e5c31af7Sopenharmony_ci else: 56e5c31af7Sopenharmony_ci self.logMsg('diag', '# No contents for:', filename) 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_ci def writeInclude(self): 59e5c31af7Sopenharmony_ci "Generates the asciidoc include files.""" 60e5c31af7Sopenharmony_ci self.writeBlock('parameters.adoc', 61e5c31af7Sopenharmony_ci 'Externally Synchronized Parameters', 62e5c31af7Sopenharmony_ci self.threadsafety['parameters']) 63e5c31af7Sopenharmony_ci self.writeBlock('parameterlists.adoc', 64e5c31af7Sopenharmony_ci 'Externally Synchronized Parameter Lists', 65e5c31af7Sopenharmony_ci self.threadsafety['parameterlists']) 66e5c31af7Sopenharmony_ci self.writeBlock('implicit.adoc', 67e5c31af7Sopenharmony_ci 'Implicit Externally Synchronized Parameters', 68e5c31af7Sopenharmony_ci self.threadsafety['implicit']) 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ci def makeThreadSafetyBlocks(self, cmd, paramtext): 71e5c31af7Sopenharmony_ci # See also makeThreadSafetyBlock in validitygenerator.py - similar but not entirely identical 72e5c31af7Sopenharmony_ci protoname = cmd.find('proto/name').text 73e5c31af7Sopenharmony_ci 74e5c31af7Sopenharmony_ci # Find and add any parameters that are thread unsafe 75e5c31af7Sopenharmony_ci explicitexternsyncparams = cmd.findall(paramtext + "[@externsync]") 76e5c31af7Sopenharmony_ci if explicitexternsyncparams is not None: 77e5c31af7Sopenharmony_ci for param in explicitexternsyncparams: 78e5c31af7Sopenharmony_ci self.makeThreadSafetyForParam(protoname, param) 79e5c31af7Sopenharmony_ci 80e5c31af7Sopenharmony_ci # Find and add any "implicit" parameters that are thread unsafe 81e5c31af7Sopenharmony_ci implicitexternsyncparams = cmd.find('implicitexternsyncparams') 82e5c31af7Sopenharmony_ci if implicitexternsyncparams is not None: 83e5c31af7Sopenharmony_ci for elem in implicitexternsyncparams: 84e5c31af7Sopenharmony_ci entry = ValidityEntry() 85e5c31af7Sopenharmony_ci entry += elem.text 86e5c31af7Sopenharmony_ci entry += ' in ' 87e5c31af7Sopenharmony_ci entry += self.makeFLink(protoname) 88e5c31af7Sopenharmony_ci self.threadsafety['implicit'] += entry 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_ci # Add a VU for any command requiring host synchronization. 91e5c31af7Sopenharmony_ci # This could be further parameterized, if a future non-Vulkan API 92e5c31af7Sopenharmony_ci # requires it. 93e5c31af7Sopenharmony_ci if self.genOpts.conventions.is_externsync_command(protoname): 94e5c31af7Sopenharmony_ci entry = ValidityEntry() 95e5c31af7Sopenharmony_ci entry += 'The sname:VkCommandPool that pname:commandBuffer was allocated from, in ' 96e5c31af7Sopenharmony_ci entry += self.makeFLink(protoname) 97e5c31af7Sopenharmony_ci self.threadsafety['implicit'] += entry 98e5c31af7Sopenharmony_ci 99e5c31af7Sopenharmony_ci def makeThreadSafetyForParam(self, protoname, param): 100e5c31af7Sopenharmony_ci """Create thread safety validity for a single param of a command.""" 101e5c31af7Sopenharmony_ci externsyncattribs = ExternSyncEntry.parse_externsync_from_param(param) 102e5c31af7Sopenharmony_ci param_name = getElemName(param) 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_ci for attrib in externsyncattribs: 105e5c31af7Sopenharmony_ci entry = ValidityEntry() 106e5c31af7Sopenharmony_ci is_array = False 107e5c31af7Sopenharmony_ci if attrib.entirely_extern_sync: 108e5c31af7Sopenharmony_ci # "true" or "true_with_children" 109e5c31af7Sopenharmony_ci if self.paramIsArray(param): 110e5c31af7Sopenharmony_ci entry += 'Each element of the ' 111e5c31af7Sopenharmony_ci is_array = True 112e5c31af7Sopenharmony_ci elif self.paramIsPointer(param): 113e5c31af7Sopenharmony_ci entry += 'The object referenced by the ' 114e5c31af7Sopenharmony_ci else: 115e5c31af7Sopenharmony_ci entry += 'The ' 116e5c31af7Sopenharmony_ci 117e5c31af7Sopenharmony_ci entry += self.makeParameterName(param_name) 118e5c31af7Sopenharmony_ci entry += ' parameter' 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ci if attrib.children_extern_sync: 121e5c31af7Sopenharmony_ci entry += ', and any child handles,' 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_ci else: 124e5c31af7Sopenharmony_ci # parameter/member reference 125e5c31af7Sopenharmony_ci readable = attrib.get_human_readable(make_param_name=self.makeParameterName) 126e5c31af7Sopenharmony_ci is_array = (' element of ' in readable) 127e5c31af7Sopenharmony_ci entry += readable 128e5c31af7Sopenharmony_ci 129e5c31af7Sopenharmony_ci entry += ' in ' 130e5c31af7Sopenharmony_ci entry += self.makeFLink(protoname) 131e5c31af7Sopenharmony_ci 132e5c31af7Sopenharmony_ci if is_array: 133e5c31af7Sopenharmony_ci self.threadsafety['parameterlists'] += entry 134e5c31af7Sopenharmony_ci else: 135e5c31af7Sopenharmony_ci self.threadsafety['parameters'] += entry 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ci def genCmd(self, cmdinfo, name, alias): 138e5c31af7Sopenharmony_ci "Generate command." 139e5c31af7Sopenharmony_ci OutputGenerator.genCmd(self, cmdinfo, name, alias) 140e5c31af7Sopenharmony_ci 141e5c31af7Sopenharmony_ci # @@@ (Jon) something needs to be done here to handle aliases, probably 142e5c31af7Sopenharmony_ci 143e5c31af7Sopenharmony_ci self.makeThreadSafetyBlocks(cmdinfo.elem, 'param') 144e5c31af7Sopenharmony_ci 145e5c31af7Sopenharmony_ci self.writeInclude() 146