1bf215546Sopenharmony_ci# Copyright 2020 Intel Corporation 2bf215546Sopenharmony_ci# 3bf215546Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a 4bf215546Sopenharmony_ci# copy of this software and associated documentation files (the 5bf215546Sopenharmony_ci# "Software"), to deal in the Software without restriction, including 6bf215546Sopenharmony_ci# without limitation the rights to use, copy, modify, merge, publish, 7bf215546Sopenharmony_ci# distribute, sub license, and/or sell copies of the Software, and to 8bf215546Sopenharmony_ci# permit persons to whom the Software is furnished to do so, subject to 9bf215546Sopenharmony_ci# the following conditions: 10bf215546Sopenharmony_ci# 11bf215546Sopenharmony_ci# The above copyright notice and this permission notice (including the 12bf215546Sopenharmony_ci# next paragraph) shall be included in all copies or substantial portions 13bf215546Sopenharmony_ci# of the Software. 14bf215546Sopenharmony_ci# 15bf215546Sopenharmony_ci# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16bf215546Sopenharmony_ci# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 18bf215546Sopenharmony_ci# IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 19bf215546Sopenharmony_ci# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20bf215546Sopenharmony_ci# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21bf215546Sopenharmony_ci# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ciimport xml.etree.ElementTree as et 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_cifrom collections import OrderedDict, namedtuple 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci# Mesa-local imports must be declared in meson variable 28bf215546Sopenharmony_ci# '{file_without_suffix}_depend_files'. 29bf215546Sopenharmony_cifrom vk_extensions import Extension, VkVersion 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ciEntrypointParam = namedtuple('EntrypointParam', 'type name decl len') 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ciclass EntrypointBase: 34bf215546Sopenharmony_ci def __init__(self, name): 35bf215546Sopenharmony_ci assert name.startswith('vk') 36bf215546Sopenharmony_ci self.name = name[2:] 37bf215546Sopenharmony_ci self.alias = None 38bf215546Sopenharmony_ci self.guard = None 39bf215546Sopenharmony_ci self.entry_table_index = None 40bf215546Sopenharmony_ci # Extensions which require this entrypoint 41bf215546Sopenharmony_ci self.core_version = None 42bf215546Sopenharmony_ci self.extensions = [] 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci def prefixed_name(self, prefix): 45bf215546Sopenharmony_ci return prefix + '_' + self.name 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ciclass Entrypoint(EntrypointBase): 48bf215546Sopenharmony_ci def __init__(self, name, return_type, params, guard=None): 49bf215546Sopenharmony_ci super(Entrypoint, self).__init__(name) 50bf215546Sopenharmony_ci self.return_type = return_type 51bf215546Sopenharmony_ci self.params = params 52bf215546Sopenharmony_ci self.guard = guard 53bf215546Sopenharmony_ci self.aliases = [] 54bf215546Sopenharmony_ci self.disp_table_index = None 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci def is_physical_device_entrypoint(self): 57bf215546Sopenharmony_ci return self.params[0].type in ('VkPhysicalDevice', ) 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci def is_device_entrypoint(self): 60bf215546Sopenharmony_ci return self.params[0].type in ('VkDevice', 'VkCommandBuffer', 'VkQueue') 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci def decl_params(self, start=0): 63bf215546Sopenharmony_ci return ', '.join(p.decl for p in self.params[start:]) 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci def call_params(self, start=0): 66bf215546Sopenharmony_ci return ', '.join(p.name for p in self.params[start:]) 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ciclass EntrypointAlias(EntrypointBase): 69bf215546Sopenharmony_ci def __init__(self, name, entrypoint): 70bf215546Sopenharmony_ci super(EntrypointAlias, self).__init__(name) 71bf215546Sopenharmony_ci self.alias = entrypoint 72bf215546Sopenharmony_ci entrypoint.aliases.append(self) 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci def is_physical_device_entrypoint(self): 75bf215546Sopenharmony_ci return self.alias.is_physical_device_entrypoint() 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci def is_device_entrypoint(self): 78bf215546Sopenharmony_ci return self.alias.is_device_entrypoint() 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci def prefixed_name(self, prefix): 81bf215546Sopenharmony_ci return self.alias.prefixed_name(prefix) 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci @property 84bf215546Sopenharmony_ci def params(self): 85bf215546Sopenharmony_ci return self.alias.params 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci @property 88bf215546Sopenharmony_ci def return_type(self): 89bf215546Sopenharmony_ci return self.alias.return_type 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci @property 92bf215546Sopenharmony_ci def disp_table_index(self): 93bf215546Sopenharmony_ci return self.alias.disp_table_index 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci def decl_params(self): 96bf215546Sopenharmony_ci return self.alias.decl_params() 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci def call_params(self): 99bf215546Sopenharmony_ci return self.alias.call_params() 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_cidef get_entrypoints(doc, entrypoints_to_defines): 102bf215546Sopenharmony_ci """Extract the entry points from the registry.""" 103bf215546Sopenharmony_ci entrypoints = OrderedDict() 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci for command in doc.findall('./commands/command'): 106bf215546Sopenharmony_ci if 'alias' in command.attrib: 107bf215546Sopenharmony_ci alias = command.attrib['name'] 108bf215546Sopenharmony_ci target = command.attrib['alias'] 109bf215546Sopenharmony_ci entrypoints[alias] = EntrypointAlias(alias, entrypoints[target]) 110bf215546Sopenharmony_ci else: 111bf215546Sopenharmony_ci name = command.find('./proto/name').text 112bf215546Sopenharmony_ci ret_type = command.find('./proto/type').text 113bf215546Sopenharmony_ci params = [EntrypointParam( 114bf215546Sopenharmony_ci type=p.find('./type').text, 115bf215546Sopenharmony_ci name=p.find('./name').text, 116bf215546Sopenharmony_ci decl=''.join(p.itertext()), 117bf215546Sopenharmony_ci len=p.attrib.get('len', None) 118bf215546Sopenharmony_ci ) for p in command.findall('./param')] 119bf215546Sopenharmony_ci guard = entrypoints_to_defines.get(name) 120bf215546Sopenharmony_ci # They really need to be unique 121bf215546Sopenharmony_ci assert name not in entrypoints 122bf215546Sopenharmony_ci entrypoints[name] = Entrypoint(name, ret_type, params, guard) 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci for feature in doc.findall('./feature'): 125bf215546Sopenharmony_ci assert feature.attrib['api'] == 'vulkan' 126bf215546Sopenharmony_ci version = VkVersion(feature.attrib['number']) 127bf215546Sopenharmony_ci for command in feature.findall('./require/command'): 128bf215546Sopenharmony_ci e = entrypoints[command.attrib['name']] 129bf215546Sopenharmony_ci assert e.core_version is None 130bf215546Sopenharmony_ci e.core_version = version 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci for extension in doc.findall('.extensions/extension'): 133bf215546Sopenharmony_ci if extension.attrib['supported'] != 'vulkan': 134bf215546Sopenharmony_ci continue 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci ext_name = extension.attrib['name'] 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci ext = Extension(ext_name, 1, True) 139bf215546Sopenharmony_ci ext.type = extension.attrib['type'] 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci for command in extension.findall('./require/command'): 142bf215546Sopenharmony_ci e = entrypoints[command.attrib['name']] 143bf215546Sopenharmony_ci assert e.core_version is None 144bf215546Sopenharmony_ci e.extensions.append(ext) 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci return entrypoints.values() 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_cidef get_entrypoints_defines(doc): 150bf215546Sopenharmony_ci """Maps entry points to extension defines.""" 151bf215546Sopenharmony_ci entrypoints_to_defines = {} 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci platform_define = {} 154bf215546Sopenharmony_ci for platform in doc.findall('./platforms/platform'): 155bf215546Sopenharmony_ci name = platform.attrib['name'] 156bf215546Sopenharmony_ci define = platform.attrib['protect'] 157bf215546Sopenharmony_ci platform_define[name] = define 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci for extension in doc.findall('./extensions/extension[@platform]'): 160bf215546Sopenharmony_ci platform = extension.attrib['platform'] 161bf215546Sopenharmony_ci define = platform_define[platform] 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci for entrypoint in extension.findall('./require/command'): 164bf215546Sopenharmony_ci fullname = entrypoint.attrib['name'] 165bf215546Sopenharmony_ci entrypoints_to_defines[fullname] = define 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci return entrypoints_to_defines 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_cidef get_entrypoints_from_xml(xml_files): 170bf215546Sopenharmony_ci entrypoints = [] 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci for filename in xml_files: 173bf215546Sopenharmony_ci doc = et.parse(filename) 174bf215546Sopenharmony_ci entrypoints += get_entrypoints(doc, get_entrypoints_defines(doc)) 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci return entrypoints 177