forked from LightenPan/RetroArch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvulkan_loader_generator.py
executable file
·173 lines (151 loc) · 6.74 KB
/
vulkan_loader_generator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/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()