In progress rework

This commit is contained in:
Cody Goodson 2021-05-19 18:03:49 -05:00 committed by Charles Giessen
parent cd0959f37e
commit 88358fb9cf

View File

@ -54,334 +54,351 @@ with urllib.request.urlopen('https://raw.githubusercontent.com/KhronosGroup/Vulk
vk_xml = xmltodict.parse(vk_xml_raw,process_namespaces=True) vk_xml = xmltodict.parse(vk_xml_raw,process_namespaces=True)
criteria = { 'extension': '', 'feature': 'VK_VERSION_1_0' }
command_params = {'return_type': '', 'args': [], 'criterias': []}
device_commands = {} device_commands = {}
core_commands = {} core_commands = {}
extension_commands = {} extension_commands = {}
# Gather all device functions/aliases for filtering core/extension function fetching # Gather all device functions/aliases for filtering core/extension function fetching
commands = vk_xml['registry']['commands']['command'] commands_node = vk_xml['registry']['commands']['command']
aliases = {} aliases = {}
for command in commands: for command_node in commands_node:
if 'proto' in command: if 'proto' in command_node:
name = command['proto']['name'] command_name = command_node['proto']['name']
return_type = command['proto']['type'] new_command_params = command_params.copy()
types = [] new_command_params['return_type'] = command_node['proto']['type']
if type(command['param']) is list: if type(command_node['param']) is list:
types = command['param'] new_command_params['args'] = command_node['param']
else: else:
types = [command['param']] new_command_params['args'] = [command_node['param']]
if not name in exclusions: if not command_name in exclusions:
if types[0]['type'] == 'VkDevice' or types[0]['type'] == 'VkCommandBuffer' or types[0]['type'] == 'VkQueue': if new_command_params['args'][0]['type'] == 'VkDevice' or new_command_params['args'][0]['type'] == 'VkCommandBuffer' or new_command_params['args'][0]['type'] == 'VkQueue':
device_commands[name] = [types, return_type] device_commands[command_name] = new_command_params
elif '@alias' in command: elif '@alias' in command_node:
aliases[command['@alias']] = command['@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:
device_commands[aliases[alias]] = device_commands[alias] aliased_command_params = device_commands[alias].copy()
device_commands[aliases[alias]] = aliased_command_params;
# Gather all core feature levels and functions # Add criterias for core device pfns
levels = vk_xml['registry']['feature'] features_node = vk_xml['registry']['feature']
for level in levels: for feature_node in features_node:
core_commands[level['@name']] = [] for require_node in feature_node['require']:
for require in level['require']: for param_node in require_node:
params = require.keys() if param_node == 'command':
for param in params: if type(require_node[param_node]) is list:
if param == 'command': for param in require_node[param_node]:
if type(require[param]) is list: if param['@name'] in device_commands:
for n_param in require[param]: new_criteria = criteria.copy()
if n_param['@name'] in device_commands: new_criteria['feature'] = feature_node['@name']
core_commands[level['@name']] += [n_param['@name']] device_commands[param['@name']]['criterias'] += [new_criteria]
else:
if require[param]['@name'] in device_commands: extensions_node = vk_xml['registry']['extensions']['extension']
core_commands[level['@name']] += [require[param]['@name']] for extension_node in extensions_node:
extension_name = extension_node['@name']
new_criteria = criteria.copy()
new_criteria['extension'] = extension_name
new_criteria['feature'] = 'VK_VERSION_1_0'
if 'require' in extension_node:
for require_node in extension_node['require']:
if '@feature' in extension_node['require']:
print('aye')
new_criteria['feature'] = extension_node['require']['@feature']
#print(extension_node['require']['command'])
# for command_node in extension_node['require']['command']:
# for command_name in command_node['name']:
# print(command_name)
# Gather extension functions # Gather extension functions
extensions = vk_xml['registry']['extensions']['extension'] #extensions = vk_xml['registry']['extensions']['extension']
for extension in extensions: #for extension in extensions:
extension_name = extension['@name'] # extension_name = extension['@name']
extension_commands[(extension_name, 'VK_VERSION_1_0')] = [] # extension_commands[(extension_name, 'VK_VERSION_1_0')] = []
for key in extension.keys(): # for key in extension.keys():
if key == 'require': # if key == 'require':
requires = [extension[key]] # requires = [extension[key]]
for required in requires: # for required in requires:
if type(required) is list: # if type(required) is list:
for n_required in required: # for n_required in required:
if '@feature' in n_required and 'command' in n_required: # if '@feature' in n_required and 'command' in n_required:
extension_commands[(extension_name, n_required['@feature'])] = [] # extension_commands[(extension_name, n_required['@feature'])] = []
commands = [n_required['command']] # commands = [n_required['command']]
for command in commands: # for command in commands:
if type(command) is list: # if type(command) is list:
for n_command in command: # for n_command in command:
if n_command['@name'] in device_commands: # if n_command['@name'] in device_commands:
extension_commands[(extension_name, n_required['@feature'])] += [n_command['@name']] # extension_commands[(extension_name, n_required['@feature'])] += [n_command['@name']]
elif command['@name'] in device_commands: # elif command['@name'] in device_commands:
extension_commands[(extension_name, n_required['@feature'])] += [command['@name']] # extension_commands[(extension_name, n_required['@feature'])] += [command['@name']]
elif 'command' in n_required: # elif 'command' in n_required:
commands = [n_required['command']] # commands = [n_required['command']]
for command in commands: # for command in commands:
if type(command) is list: # if type(command) is list:
for n_command in command: # for n_command in command:
if n_command['@name'] in device_commands: # if n_command['@name'] in device_commands:
extension_commands[(extension_name, 'VK_VERSION_1_0')] += [n_command['@name']] # extension_commands[(extension_name, 'VK_VERSION_1_0')] += [n_command['@name']]
elif command['@name'] in device_commands: # elif command['@name'] in device_commands:
extension_commands[(extension_name, 'VK_VERSION_1_0')] += [command['@name']] # extension_commands[(extension_name, 'VK_VERSION_1_0')] += [command['@name']]
elif 'command' in required: # elif 'command' in required:
commands = [required['command']] # commands = [required['command']]
for command in commands: # for command in commands:
if type(command) is list: # if type(command) is list:
for n_command in command: # for n_command in command:
if n_command['@name'] in device_commands: # if n_command['@name'] in device_commands:
extension_commands[(extension_name, 'VK_VERSION_1_0')] += [n_command['@name']] # extension_commands[(extension_name, 'VK_VERSION_1_0')] += [n_command['@name']]
elif command['@name'] in device_commands: # elif command['@name'] in device_commands:
extension_commands[(extension_name, 'VK_VERSION_1_0')] += [command['@name']] # extension_commands[(extension_name, 'VK_VERSION_1_0')] += [command['@name']]
#
# Build header # Build header
# License # License
header = '/* \n' # header = '/* \n'
header += ' * Copyright © 2021 Cody Goodson (contact@vibimanx.com)\n' # header += ' * Copyright © 2021 Cody Goodson (contact@vibimanx.com)\n'
header += ' * \n' # header += ' * \n'
header += ' * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\n' # header += ' * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\n'
header += ' * documentation files (the “Software”), to deal in the Software without restriction, including without\n' # header += ' * documentation files (the “Software”), to deal in the Software without restriction, including without\n'
header += ' * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n' # header += ' * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n'
header += ' * of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n' # header += ' * of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n'
header += ' * \n' # header += ' * \n'
header += ' * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n' # header += ' * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n'
header += ' * \n' # header += ' * \n'
header += ' * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT\n' # header += ' * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT\n'
header += ' * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n' # header += ' * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n'
header += ' * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n' # header += ' * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n'
header += ' * 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.\n' # header += ' * 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.\n'
header += ' * \n' # header += ' * \n'
header += ' */\n\n' # header += ' */\n\n'
# Info # # Info
header += '// This file is a part of VkBootstrap\n' # header += '// This file is a part of VkBootstrap\n'
header += '// https://github.com/charles-lunarg/vk-bootstrap\n\n' # header += '// https://github.com/charles-lunarg/vk-bootstrap\n\n'
# Content # # Content
header += '\n#pragma once\n\n#include <vulkan/vulkan.h>\n\n' # header += '\n#pragma once\n\n#include <vulkan/vulkan.h>\n\n'
header += 'namespace vkb {\n\n' # header += 'namespace vkb {\n\n'
header += 'struct DispatchTable {\n' # header += 'struct DispatchTable {\n'
header += '\tDispatchTable() = default;\n' # header += '\tDispatchTable() = default;\n'
header += '\tDispatchTable(VkDevice const& device, PFN_vkGetDeviceProcAddr const& procAddr) : device(device) {\n' # header += '\tDispatchTable(VkDevice const& device, PFN_vkGetDeviceProcAddr const& procAddr) : device(device) {\n'
proxy_definition = '' # proxy_definition = ''
pfn_declaration = '' # pfn_declaration = ''
pfn_loading = '' # pfn_loading = ''
for level in core_commands: # for level in core_commands:
pfn_declaration += '#ifdef ' + level + '\n'; # pfn_declaration += '#ifdef ' + level + '\n';
pfn_loading += '#ifdef ' + level + '\n'; # pfn_loading += '#ifdef ' + level + '\n';
for command in core_commands[level]: # for command in core_commands[level]:
fptr_name = 'PFN_' + command # fptr_name = 'PFN_' + command
member_name = 'fp_' + command # member_name = 'fp_' + command
proxy_name = command[2].lower() + command[3:] # proxy_name = command[2].lower() + command[3:]
types = device_commands[command][0] # types = device_commands[command][0]
names = []; # names = [];
i = 0 # i = 0
length = len(types) - 1 # length = len(types) - 1
takes_device = False; # takes_device = False;
proxy_definition += '\t' # proxy_definition += '\t'
return_type = device_commands[command][1]; # return_type = device_commands[command][1];
proxy_definition += return_type # proxy_definition += return_type
proxy_definition += ' ' # proxy_definition += ' '
proxy_definition += proxy_name # proxy_definition += proxy_name
proxy_definition += '(' # proxy_definition += '('
for t in types: # for t in types:
if i == 0 and t['type'] == 'VkDevice': # if i == 0 and t['type'] == 'VkDevice':
takes_device = True # takes_device = True
else: # else:
if '#text' in t: # if '#text' in t:
text = t['#text'] # text = t['#text']
text = text.replace(' ', '') # text = text.replace(' ', '')
array = ''; # array = '';
array_index = text.find('[') # array_index = text.find('[')
if array_index != -1: # if array_index != -1:
array = text[array_index:] # array = text[array_index:]
text = text[0:array_index] # text = text[0:array_index]
if text == '*': # if text == '*':
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += '* ' # proxy_definition += '* '
proxy_definition += t['name'] # proxy_definition += t['name']
elif text == '**': # elif text == '**':
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += '** ' # proxy_definition += '** '
proxy_definition += t['name'] # proxy_definition += t['name']
elif text == 'const*': # elif text == 'const*':
proxy_definition += 'const ' # proxy_definition += 'const '
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += '* ' # proxy_definition += '* '
proxy_definition += t['name'] # proxy_definition += t['name']
elif text == 'const**': # elif text == 'const**':
proxy_definition += 'const ' # proxy_definition += 'const '
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += '** ' # proxy_definition += '** '
proxy_definition += t['name'] # proxy_definition += t['name']
elif text == 'const*const*': # elif text == 'const*const*':
proxy_definition += 'const ' # proxy_definition += 'const '
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += '* const* ' # proxy_definition += '* const* '
proxy_definition += t['name'] # proxy_definition += t['name']
else: # else:
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += ' ' # proxy_definition += ' '
proxy_definition += t['name'] # proxy_definition += t['name']
if array != '': # if array != '':
proxy_definition += array # proxy_definition += array
else: # else:
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += ' ' # proxy_definition += ' '
proxy_definition += t['name'] # proxy_definition += t['name']
names += [t['name']] # names += [t['name']]
if i < length: # if i < length:
proxy_definition += ', ' # proxy_definition += ', '
i += 1 # i += 1
proxy_definition += ') const {\n' # proxy_definition += ') const {\n'
proxy_definition += '\t\t' # proxy_definition += '\t\t'
if return_type != 'void': # if return_type != 'void':
proxy_definition += 'return ' # proxy_definition += 'return '
proxy_definition += member_name # proxy_definition += member_name
proxy_definition += '(' # proxy_definition += '('
if takes_device: # if takes_device:
proxy_definition +='device' # proxy_definition +='device'
if(len(names) > 0): # if(len(names) > 0):
proxy_definition += ', ' # proxy_definition += ', '
i = 0 # i = 0
length = len(names) - 1 # length = len(names) - 1
for name in names: # for name in names:
proxy_definition += name # proxy_definition += name
if i < length: # if i < length:
proxy_definition += ', ' # proxy_definition += ', '
i += 1 # i += 1
proxy_definition += ');\n' # proxy_definition += ');\n'
proxy_definition += '\t}\n' # proxy_definition += '\t}\n'
pfn_declaration += '\t' + fptr_name + ' ' + member_name + ' = nullptr;\n' # pfn_declaration += '\t' + fptr_name + ' ' + member_name + ' = nullptr;\n'
pfn_loading += '\t\t' + member_name + ' = (' + fptr_name + ')procAddr(device, "' + command + '");\n' # pfn_loading += '\t\t' + member_name + ' = (' + fptr_name + ')procAddr(device, "' + command + '");\n'
pfn_declaration += '#endif\n' # pfn_declaration += '#endif\n'
pfn_loading += '#endif\n' # pfn_loading += '#endif\n'
for extension in extension_commands: # for extension in extension_commands:
if len(extension_commands[extension]) > 0: # if len(extension_commands[extension]) > 0:
pfn_declaration += '#if defined(' + extension[0] + ') && defined(' + extension[1] + ')\n'; # pfn_declaration += '#if defined(' + extension[0] + ') && defined(' + extension[1] + ')\n';
pfn_loading += '#if defined(' + extension[0] + ') && defined(' + extension[1] + ')\n'; # pfn_loading += '#if defined(' + extension[0] + ') && defined(' + extension[1] + ')\n';
proxy_definition += '#if defined(' + extension[0] + ') && defined(' + extension[1] + ')\n'; # proxy_definition += '#if defined(' + extension[0] + ') && defined(' + extension[1] + ')\n';
for command in extension_commands[extension]: # for command in extension_commands[extension]:
fptr_name = 'PFN_' + command # fptr_name = 'PFN_' + command
member_name = 'fp_' + command # member_name = 'fp_' + command
proxy_name = command[2].lower() + command[3:] # proxy_name = command[2].lower() + command[3:]
#Duplication guards # #Duplication guards
pfn_declaration += '#ifndef ' + fptr_name + '_DECLARE\n' # pfn_declaration += '#ifndef ' + fptr_name + '_DECLARE\n'
pfn_declaration += '#define ' + fptr_name + '_DECLARE\n' # pfn_declaration += '#define ' + fptr_name + '_DECLARE\n'
pfn_declaration += '\t' + fptr_name + ' ' + member_name + ' = nullptr;\n' # pfn_declaration += '\t' + fptr_name + ' ' + member_name + ' = nullptr;\n'
pfn_declaration += '#endif\n' # pfn_declaration += '#endif\n'
#Duplication guards # #Duplication guards
pfn_loading += '#ifndef ' + fptr_name + '_LOAD\n' # pfn_loading += '#ifndef ' + fptr_name + '_LOAD\n'
pfn_loading += '#define ' + fptr_name + '_LOAD\n' # pfn_loading += '#define ' + fptr_name + '_LOAD\n'
pfn_loading += '\t\t' + member_name + ' = (' + fptr_name + ')procAddr(device, "' + command + '");\n' # pfn_loading += '\t\t' + member_name + ' = (' + fptr_name + ')procAddr(device, "' + command + '");\n'
pfn_loading += '#endif\n' # pfn_loading += '#endif\n'
#Duplication guards # #Duplication guards
proxy_definition += '#ifndef ' + fptr_name + '_PROXY\n' # proxy_definition += '#ifndef ' + fptr_name + '_PROXY\n'
proxy_definition += '#define ' + fptr_name + '_PROXY\n' # proxy_definition += '#define ' + fptr_name + '_PROXY\n'
#proxy_definition += '\t\tTEST '+ proxy_name +'\n' # #proxy_definition += '\t\tTEST '+ proxy_name +'\n'
types = device_commands[command][0] # types = device_commands[command][0]
names = []; # names = [];
i = 0 # i = 0
length = len(types) - 1 # length = len(types) - 1
takes_device = False; # takes_device = False;
proxy_definition += '\t' # proxy_definition += '\t'
return_type = device_commands[command][1]; # return_type = device_commands[command][1];
proxy_definition += return_type # proxy_definition += return_type
proxy_definition += ' ' # proxy_definition += ' '
proxy_definition += proxy_name # proxy_definition += proxy_name
proxy_definition += '(' # proxy_definition += '('
for t in types: # for t in types:
if i == 0 and t['type'] == 'VkDevice': # if i == 0 and t['type'] == 'VkDevice':
takes_device = True # takes_device = True
else: # else:
if '#text' in t: # if '#text' in t:
text = t['#text'] # text = t['#text']
text = text.replace(' ', '') # text = text.replace(' ', '')
array = ''; # array = '';
array_index = text.find('[') # array_index = text.find('[')
if array_index != -1: # if array_index != -1:
array = text[array_index:] # array = text[array_index:]
text = text[0:array_index] # text = text[0:array_index]
if text == '*': # if text == '*':
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += '* ' # proxy_definition += '* '
proxy_definition += t['name'] # proxy_definition += t['name']
elif text == '**': # elif text == '**':
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += '** ' # proxy_definition += '** '
proxy_definition += t['name'] # proxy_definition += t['name']
elif text == 'const*': # elif text == 'const*':
proxy_definition += 'const ' # proxy_definition += 'const '
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += '* ' # proxy_definition += '* '
proxy_definition += t['name'] # proxy_definition += t['name']
elif text == 'const**': # elif text == 'const**':
proxy_definition += 'const ' # proxy_definition += 'const '
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += '** ' # proxy_definition += '** '
proxy_definition += t['name'] # proxy_definition += t['name']
elif text == 'const*const*': # elif text == 'const*const*':
proxy_definition += 'const ' # proxy_definition += 'const '
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += '* const* ' # proxy_definition += '* const* '
proxy_definition += t['name'] # proxy_definition += t['name']
else: # else:
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += ' ' # proxy_definition += ' '
proxy_definition += t['name'] # proxy_definition += t['name']
if array != '': # if array != '':
proxy_definition += array # proxy_definition += array
else: # else:
proxy_definition += t['type'] # proxy_definition += t['type']
proxy_definition += ' ' # proxy_definition += ' '
proxy_definition += t['name'] # proxy_definition += t['name']
names += [t['name']] # names += [t['name']]
if i < length: # if i < length:
proxy_definition += ', ' # proxy_definition += ', '
i += 1 # i += 1
proxy_definition += ') const {\n' # proxy_definition += ') const {\n'
proxy_definition += '\t\t' # proxy_definition += '\t\t'
if return_type != 'void': # if return_type != 'void':
proxy_definition += 'return ' # proxy_definition += 'return '
proxy_definition += member_name # proxy_definition += member_name
proxy_definition += '(' # proxy_definition += '('
if takes_device: # if takes_device:
proxy_definition +='device' # proxy_definition +='device'
if(len(names) > 0): # if(len(names) > 0):
proxy_definition += ', ' # proxy_definition += ', '
i = 0 # i = 0
length = len(names) - 1 # length = len(names) - 1
for name in names: # for name in names:
proxy_definition += name # proxy_definition += name
if i < length: # if i < length:
proxy_definition += ', ' # proxy_definition += ', '
i += 1 # i += 1
proxy_definition += ');\n' # proxy_definition += ');\n'
proxy_definition += '\t}\n' # proxy_definition += '\t}\n'
proxy_definition += '#endif\n' # proxy_definition += '#endif\n'
pfn_declaration += '#endif\n' # pfn_declaration += '#endif\n'
pfn_loading += '#endif\n' # pfn_loading += '#endif\n'
proxy_definition += '#endif\n' # proxy_definition += '#endif\n'
header += pfn_loading # header += pfn_loading
header += '\t}\n' # header += '\t}\n'
header += proxy_definition # header += proxy_definition
header += pfn_declaration # header += pfn_declaration
header += '\tVkDevice device = VK_NULL_HANDLE;\n' # header += '\tVkDevice device = VK_NULL_HANDLE;\n'
header += '};\n\n' # header += '};\n\n'
header += '} // namespace vkb' # header += '} // namespace vkb'
header_file = open("../src/VkDispatchTable.h", "w") # header_file = open("../src/VkDispatchTable.h", "w")
header_file.write(header) # header_file.write(header)
header_file.close(); # header_file.close();