| # Copyright 2020 Intel Corporation |
| # |
| # Permission is hereby granted, free of charge, to any person obtaining a |
| # copy of this software and associated documentation files (the |
| # "Software"), to deal in the Software without restriction, including |
| # without limitation the rights to use, copy, modify, merge, publish, |
| # distribute, sub license, and/or sell copies of the Software, and to |
| # permit persons to whom the Software is furnished to do so, subject to |
| # the following conditions: |
| # |
| # The above copyright notice and this permission notice (including the |
| # next paragraph) shall be included in all copies or substantial portions |
| # of the Software. |
| # |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
| # IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
| # ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| |
| import xml.etree.ElementTree as et |
| |
| from collections import OrderedDict, namedtuple |
| |
| # Mesa-local imports must be declared in meson variable |
| # '{file_without_suffix}_depend_files'. |
| from vk_extensions import get_all_required, filter_api |
| |
| EntrypointParam = namedtuple('EntrypointParam', 'type name decl len') |
| |
| class EntrypointBase: |
| def __init__(self, name): |
| assert name.startswith('vk') |
| self.name = name[2:] |
| self.alias = None |
| self.guard = None |
| self.entry_table_index = None |
| # Extensions which require this entrypoint |
| self.core_version = None |
| self.extensions = [] |
| |
| def prefixed_name(self, prefix): |
| return prefix + '_' + self.name |
| |
| class Entrypoint(EntrypointBase): |
| def __init__(self, name, return_type, params): |
| super(Entrypoint, self).__init__(name) |
| self.return_type = return_type |
| self.params = params |
| self.guard = None |
| self.aliases = [] |
| self.disp_table_index = None |
| |
| def is_physical_device_entrypoint(self): |
| return self.params[0].type in ('VkPhysicalDevice', ) |
| |
| def is_device_entrypoint(self): |
| return self.params[0].type in ('VkDevice', 'VkCommandBuffer', 'VkQueue') |
| |
| def decl_params(self, start=0): |
| return ', '.join(p.decl for p in self.params[start:]) |
| |
| def call_params(self, start=0): |
| return ', '.join(p.name for p in self.params[start:]) |
| |
| class EntrypointAlias(EntrypointBase): |
| def __init__(self, name, entrypoint): |
| super(EntrypointAlias, self).__init__(name) |
| self.alias = entrypoint |
| entrypoint.aliases.append(self) |
| |
| def is_physical_device_entrypoint(self): |
| return self.alias.is_physical_device_entrypoint() |
| |
| def is_device_entrypoint(self): |
| return self.alias.is_device_entrypoint() |
| |
| def prefixed_name(self, prefix): |
| return self.alias.prefixed_name(prefix) |
| |
| @property |
| def params(self): |
| return self.alias.params |
| |
| @property |
| def return_type(self): |
| return self.alias.return_type |
| |
| @property |
| def disp_table_index(self): |
| return self.alias.disp_table_index |
| |
| def decl_params(self): |
| return self.alias.decl_params() |
| |
| def call_params(self): |
| return self.alias.call_params() |
| |
| def get_entrypoints(doc, api, beta): |
| """Extract the entry points from the registry.""" |
| entrypoints = OrderedDict() |
| |
| required = get_all_required(doc, 'command', api, beta) |
| |
| for command in doc.findall('./commands/command'): |
| if not filter_api(command, api): |
| continue |
| |
| if 'alias' in command.attrib: |
| name = command.attrib['name'] |
| target = command.attrib['alias'] |
| e = EntrypointAlias(name, entrypoints[target]) |
| else: |
| name = command.find('./proto/name').text |
| ret_type = command.find('./proto/type').text |
| params = [EntrypointParam( |
| type=p.find('./type').text, |
| name=p.find('./name').text, |
| decl=''.join(p.itertext()), |
| len=p.attrib.get('altlen', p.attrib.get('len', None)) |
| ) for p in command.findall('./param') if filter_api(p, api)] |
| # They really need to be unique |
| e = Entrypoint(name, ret_type, params) |
| |
| if name not in required: |
| continue |
| |
| r = required[name] |
| e.core_version = r.core_version |
| e.extensions = r.extensions |
| e.guard = r.guard |
| |
| assert name not in entrypoints, name |
| entrypoints[name] = e |
| |
| return entrypoints.values() |
| |
| def get_entrypoints_from_xml(xml_files, beta, api='vulkan'): |
| entrypoints = [] |
| |
| for filename in xml_files: |
| doc = et.parse(filename) |
| entrypoints += get_entrypoints(doc, api, beta) |
| |
| return entrypoints |