mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-30 11:40:32 +00:00
54c1759f45
Avoids painful manual loading and wrapping function pointers everywhere ... Reusable for cores, so move to libretro-common. Also update built-in Vulkan headers.
175 lines
6.7 KiB
Python
Executable File
175 lines
6.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
import re
|
|
|
|
def entry_is_device(entry):
|
|
first_arg_type = entry[1][1:].split(' ')[0]
|
|
device_types = ['VkDevice', 'VkCommandBuffer', 'VkQueue']
|
|
return (first_arg_type in device_types) and (entry[0] != 'vkGetDeviceProcAddr')
|
|
|
|
def main():
|
|
pure_entrypoints = []
|
|
entrypoints = []
|
|
extensions = []
|
|
pure_list = ['vkCreateInstance', 'vkEnumerateInstanceExtensionProperties', 'vkEnumerateInstanceLayerProperties']
|
|
with open(sys.argv[1], 'r') as f:
|
|
header = f.readlines()
|
|
|
|
for line in header:
|
|
m = re.search('typedef \S+.*PFN_([^\)]+)\)(.*);$', line)
|
|
if m and m.group(1)[-3:] != 'KHR' and m.group(1)[-3:] != 'EXT' and m.group(2) != '(void)':
|
|
entry = m.group(1)
|
|
if entry == 'vkGetInstanceProcAddr':
|
|
continue
|
|
|
|
if entry in pure_list:
|
|
pure_entrypoints.append((m.group(1), m.group(2)))
|
|
else:
|
|
entrypoints.append((m.group(1), m.group(2)))
|
|
elif m and (m.group(1)[-3:] == 'KHR' or m.group(1)[-3:] == 'EXT') and m.group(2) != '(void)':
|
|
entry = m.group(1)
|
|
if 'Android' in entry:
|
|
continue
|
|
if 'Xlib' in entry:
|
|
continue
|
|
if 'Xcb' in entry:
|
|
continue
|
|
if 'Win32' in entry:
|
|
continue
|
|
if 'Wayland' in entry:
|
|
continue
|
|
if 'Mir' in entry:
|
|
continue
|
|
extensions.append((m.group(1), m.group(2)))
|
|
|
|
|
|
with open(sys.argv[2], 'w') as f:
|
|
print('''
|
|
/* This header is autogenerated by vulkan_loader_generator.py */
|
|
#ifndef VULKAN_SYMBOL_WRAPPER_H
|
|
#define VULKAN_SYMBOL_WRAPPER_H
|
|
#define VK_NO_PROTOTYPES
|
|
#include <vulkan/vulkan.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
''', file = f)
|
|
|
|
for entry in pure_entrypoints:
|
|
s = entry[0]
|
|
print('extern PFN_{} vulkan_symbol_wrapper_{};'.format(s, s), file = f)
|
|
print('#define {} vulkan_symbol_wrapper_{}'.format(s, s), file = f)
|
|
for entry in entrypoints:
|
|
s = entry[0]
|
|
print('extern PFN_{} vulkan_symbol_wrapper_{};'.format(s, s), file = f)
|
|
print('#define {} vulkan_symbol_wrapper_{}'.format(s, s), file = f)
|
|
for entry in extensions:
|
|
s = entry[0]
|
|
print('extern PFN_{} vulkan_symbol_wrapper_{};'.format(s, s), file = f)
|
|
print('#define {} vulkan_symbol_wrapper_{}'.format(s, s), file = f)
|
|
|
|
print('''
|
|
void vulkan_symbol_wrapper_init(PFN_vkGetInstanceProcAddr get_instance_proc_addr);
|
|
PFN_vkGetInstanceProcAddr vulkan_symbol_wrapper_instance_proc_addr(void);
|
|
VkBool32 vulkan_symbol_wrapper_load_global_symbols(void);
|
|
VkBool32 vulkan_symbol_wrapper_load_core_instance_symbols(VkInstance instance);
|
|
VkBool32 vulkan_symbol_wrapper_load_core_symbols(VkInstance instance);
|
|
VkBool32 vulkan_symbol_wrapper_load_core_device_symbols(VkDevice device);
|
|
VkBool32 vulkan_symbol_wrapper_load_instance_symbol(VkInstance instance, const char *name, PFN_vkVoidFunction *ppSymbol);
|
|
VkBool32 vulkan_symbol_wrapper_load_device_symbol(VkDevice device, const char *name, PFN_vkVoidFunction *ppSymbol);
|
|
|
|
#define VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_SYMBOL(instance, name, pfn) vulkan_symbol_wrapper_load_instance_symbol(instance, name, (PFN_vkVoidFunction*) &(pfn))
|
|
#define VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, name) vulkan_symbol_wrapper_load_instance_symbol(instance, #name, (PFN_vkVoidFunction*) & name)
|
|
#define VULKAN_SYMBOL_WRAPPER_LOAD_DEVICE_SYMBOL(device, name, pfn) vulkan_symbol_wrapper_load_device_symbol(device, name, (PFN_vkVoidFunction*) &(pfn))
|
|
#define VULKAN_SYMBOL_WRAPPER_LOAD_DEVICE_EXTENSION_SYMBOL(device, name) vulkan_symbol_wrapper_load_device_symbol(device, #name, (PFN_vkVoidFunction*) & name)
|
|
''', file = f)
|
|
|
|
print('''
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif
|
|
''', file = f)
|
|
|
|
with open(sys.argv[3], 'w') as f:
|
|
print('''
|
|
/* This header is autogenerated by vulkan_loader_generator.py */
|
|
#include "vulkan_symbol_wrapper.h"
|
|
''', file = f)
|
|
|
|
for entry in pure_entrypoints:
|
|
s = entry[0]
|
|
print('PFN_{} vulkan_symbol_wrapper_{};'.format(s, s), file = f)
|
|
for entry in entrypoints:
|
|
s = entry[0]
|
|
print('PFN_{} vulkan_symbol_wrapper_{};'.format(s, s), file = f)
|
|
for entry in extensions:
|
|
s = entry[0]
|
|
print('PFN_{} vulkan_symbol_wrapper_{};'.format(s, s), file = f)
|
|
|
|
print('''
|
|
static PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
|
|
void vulkan_symbol_wrapper_init(PFN_vkGetInstanceProcAddr get_instance_proc_addr)
|
|
{
|
|
GetInstanceProcAddr = get_instance_proc_addr;
|
|
}
|
|
|
|
PFN_vkGetInstanceProcAddr vulkan_symbol_wrapper_instance_proc_addr(void)
|
|
{
|
|
return GetInstanceProcAddr;
|
|
}
|
|
''', file = f)
|
|
|
|
print('''
|
|
VkBool32 vulkan_symbol_wrapper_load_instance_symbol(VkInstance instance, const char *name, PFN_vkVoidFunction *ppSymbol)
|
|
{
|
|
*ppSymbol = GetInstanceProcAddr(instance, name);
|
|
return *ppSymbol != NULL;
|
|
}''', file = f)
|
|
|
|
print('''
|
|
VkBool32 vulkan_symbol_wrapper_load_device_symbol(VkDevice device, const char *name, PFN_vkVoidFunction *ppSymbol)
|
|
{
|
|
*ppSymbol = vkGetDeviceProcAddr(device, name);
|
|
return *ppSymbol != NULL;
|
|
}''', file = f)
|
|
|
|
print('''
|
|
VkBool32 vulkan_symbol_wrapper_load_global_symbols(void)
|
|
{''', file = f)
|
|
for pure in pure_entrypoints:
|
|
print(' if (!VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_SYMBOL(NULL, "{}", {})) return VK_FALSE;'.format(pure[0], pure[0]), file = f)
|
|
print(' return VK_TRUE;', file = f)
|
|
print('}', file = f)
|
|
|
|
print('''
|
|
VkBool32 vulkan_symbol_wrapper_load_core_symbols(VkInstance instance)
|
|
{''', file = f)
|
|
for entry in entrypoints:
|
|
print(' if (!VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_SYMBOL(instance, "{}", {})) return VK_FALSE;'.format(entry[0], entry[0]), file = f)
|
|
print(' return VK_TRUE;', file = f)
|
|
print('}', file = f)
|
|
|
|
print('''
|
|
VkBool32 vulkan_symbol_wrapper_load_core_instance_symbols(VkInstance instance)
|
|
{''', file = f)
|
|
for entry in entrypoints:
|
|
if not entry_is_device(entry):
|
|
print(' if (!VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_SYMBOL(instance, "{}", {})) return VK_FALSE;'.format(entry[0], entry[0]), file = f)
|
|
print(' return VK_TRUE;', file = f)
|
|
print('}', file = f)
|
|
|
|
print('''
|
|
VkBool32 vulkan_symbol_wrapper_load_core_device_symbols(VkDevice device)
|
|
{''', file = f)
|
|
for entry in entrypoints:
|
|
if entry_is_device(entry):
|
|
print(' if (!VULKAN_SYMBOL_WRAPPER_LOAD_DEVICE_SYMBOL(device, "{}", {})) return VK_FALSE;'.format(entry[0], entry[0]), file = f)
|
|
print(' return VK_TRUE;', file = f)
|
|
print('}', file = f)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|