Fix autogen using wrong macro guards and types

The autogen accidentally took a reference instead of a copy, so all the aliases
were using the same data as the base type, leading to incorrect macro guards.

In addition, any aliased function would use the base funciton's types, leading
to incompatibilities when compiling with older headers. The chosen solution is
to always use the alias type if it exists.

Lastly, NVX was added to a blacklist, no functions from NVX extensions will be
generated, since they are experimental in nature.
This commit is contained in:
Charles Giessen 2022-02-05 20:36:34 -07:00 committed by Charles Giessen
parent d2898f822d
commit a1e58b4227
2 changed files with 521 additions and 578 deletions

View File

@ -35,6 +35,11 @@ exclusions = [
'vkDestroyDevice' 'vkDestroyDevice'
] ]
# Excluded extension authors - don't generate anything for these types of extensions
excluded_extension_authors = [
'NVX'
]
# Check for/install xmltodict # Check for/install xmltodict
import sys import sys
import subprocess import subprocess
@ -48,17 +53,17 @@ xmltodict_missing = {'xmltodict'} - installed
# Install xmltodict # Install xmltodict
if xmltodict_missing: if xmltodict_missing:
val = input("xmltodict is required to run this script. Would you like to install? (y/n): "); val = input("xmltodict is required to run this script. Would you like to install? (y/n): ")
if(val.lower() == "y"): if(val.lower() == "y"):
try: try:
subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'xmltodict']) subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'xmltodict'])
except subprocess.CalledProcessError as error: except subprocess.CalledProcessError as error:
print("Failed to install xmltodict due to error:"); print("Failed to install xmltodict due to error:")
print(error); print(error)
input("Press Enter to continue..."); input("Press Enter to continue...")
sys.exit(); sys.exit()
else: else:
sys.exit(); sys.exit()
# Fetch fresh vk.xml from Khronos repo # Fetch fresh vk.xml from Khronos repo
import urllib.request import urllib.request
@ -67,10 +72,10 @@ import xmltodict
try: try:
response = urllib.request.urlopen('https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/registry/vk.xml') response = urllib.request.urlopen('https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/registry/vk.xml')
except urllib.error.URLError as error: except urllib.error.URLError as error:
print("Failed to download vk.xml due to error:"); print("Failed to download vk.xml due to error:")
print(error.reason) print(error.reason)
input("Press Enter to continue..."); input("Press Enter to continue...")
sys.exit(); sys.exit()
vk_xml_raw = response.read() vk_xml_raw = response.read()
vk_xml = xmltodict.parse(vk_xml_raw,process_namespaces=True) vk_xml = xmltodict.parse(vk_xml_raw,process_namespaces=True)
@ -79,6 +84,12 @@ command_params = {'return_type': '', 'args': [], 'requirements': [], 'macro_temp
device_commands = {} device_commands = {}
aliased_types = {}
types_node = vk_xml['registry']['types']['type']
for type_node in types_node:
if '@alias' in type_node:
aliased_types[type_node['@alias']] = type_node['@name']
# Gather all device functions/aliases for filtering core/extension function fetching # Gather all device functions/aliases for filtering core/extension function fetching
commands_node = vk_xml['registry']['commands']['command'] commands_node = vk_xml['registry']['commands']['command']
aliases = {} aliases = {}
@ -92,16 +103,17 @@ for command_node in commands_node:
else: else:
new_command_params['args'] = [command_node['param']] new_command_params['args'] = [command_node['param']]
if not command_name in exclusions: if not command_name in exclusions:
if new_command_params['args'][0]['type'] == 'VkDevice' or new_command_params['args'][0]['type'] == 'VkCommandBuffer' or new_command_params['args'][0]['type'] == 'VkQueue': if new_command_params['args'][0]['type'] in ['VkDevice', 'VkCommandBuffer', 'VkQueue']:
device_commands[command_name] = new_command_params device_commands[command_name] = new_command_params
device_commands[command_name]['is_alias'] = False
elif '@alias' in command_node: elif '@alias' in command_node:
aliases[command_node['@alias']] = command_node['@name']; aliases[command_node['@alias']] = command_node['@name']
# Push the alias name as a device function if the alias exists in device commands # Push the alias name as a device function if the alias exists in device commands
for alias in aliases: for alias in aliases:
if alias in device_commands: if alias in device_commands:
aliased_command_params = device_commands[alias].copy() device_commands[aliases[alias]] = copy.deepcopy(device_commands[alias])
device_commands[aliases[alias]] = aliased_command_params; device_commands[aliases[alias]]['is_alias'] = True
# Add requirements for core PFN's # Add requirements for core PFN's
features_node = vk_xml['registry']['feature'] features_node = vk_xml['registry']['feature']
@ -124,7 +136,7 @@ for extension_node in extensions_node:
if 'require' in extension_node.keys(): if 'require' in extension_node.keys():
require_nodes = extension_node['require'] require_nodes = extension_node['require']
for require_node in require_nodes: for require_node in require_nodes:
requirements = [extension_name]; requirements = [extension_name]
if type(require_node) is not str: if type(require_node) is not str:
if 'command' in require_node.keys(): if 'command' in require_node.keys():
if '@feature' in require_node.keys(): if '@feature' in require_node.keys():
@ -135,13 +147,19 @@ for extension_node in extensions_node:
require_node['command'] = [require_node['command']] require_node['command'] = [require_node['command']]
for command_node in require_node['command']: for command_node in require_node['command']:
if command_node['@name'] in device_commands: if command_node['@name'] in device_commands:
device_commands[command_node['@name']]['requirements'] += [requirements] if '@author' in extension_node and extension_node['@author'] in excluded_extension_authors:
device_commands.pop(command_node['@name'])
else:
device_commands[command_node['@name']]['requirements'] += [requirements]
elif require_node == 'command': elif require_node == 'command':
if type(require_nodes['command']) is not list: if type(require_nodes['command']) is not list:
require_nodes['command'] = [require_nodes['command']] require_nodes['command'] = [require_nodes['command']]
for command_node in require_nodes['command']: for command_node in require_nodes['command']:
if command_node['@name'] in device_commands: if command_node['@name'] in device_commands:
device_commands[command_node['@name']]['requirements'] += [requirements] if '@author' in extension_node and extension_node['@author'] in excluded_extension_authors:
device_commands.pop(command_node['@name'])
else:
device_commands[command_node['@name']]['requirements'] += [requirements]
# Generate macro templates # Generate macro templates
for command in device_commands: for command in device_commands:
@ -226,9 +244,9 @@ for command in device_commands:
args_count = len(params['args']) args_count = len(params['args'])
i = args_count i = args_count
for arg in params['args']: for arg in params['args']:
front_mods = ''; front_mods = ''
back_mods = ' '; back_mods = ' '
array = ''; array = ''
arg_type = arg['type'] arg_type = arg['type']
arg_name = arg['name'] arg_name = arg['name']
if '#text' in arg: if '#text' in arg:
@ -260,6 +278,8 @@ for command in device_commands:
if i > 0: if i > 0:
args_names += ', ' args_names += ', '
else: else:
if arg_type in aliased_types:
arg_type = aliased_types[arg_type]
args_full += arg_template.substitute(front_mods = front_mods, arg_type = arg_type, back_mods = back_mods, arg_name = arg_name, array = array) args_full += arg_template.substitute(front_mods = front_mods, arg_type = arg_type, back_mods = back_mods, arg_name = arg_name, array = array)
args_names += arg_name args_names += arg_name
if i > 0: if i > 0:

File diff suppressed because it is too large Load Diff