-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgen-vulkan.py
More file actions
244 lines (207 loc) · 7.99 KB
/
gen-vulkan.py
File metadata and controls
244 lines (207 loc) · 7.99 KB
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
import sys
import re
def writeout( out, str ):
print( str )
if( out ):
out.write( '%s\n' % str )
return
def buildenums( vkpath ):
f = open( vkpath, "r" )
strLine = '\n'
result = """
#undef enum_ops
#define enum_ops( TYPE0, TYPE1 ) \\
inline constexpr TYPE0 operator |( TYPE0 r0, TYPE0 r1 ) \\
{\\
return static_cast<TYPE0>( (int)r0 | (int)r1 );\\
}\\
inline constexpr bool operator==( const TYPE1& r0, const TYPE0& r1 )\\
{\\
return static_cast<TYPE1>(r1) == r0;\
}\\
inline constexpr TYPE1 operator*( const TYPE0& bits )\\
{\\
return static_cast<TYPE1>( bits );\\
}\\
"""
enumlist = {}
while ( len( strLine ) ):
strLine = f.readline()
#strLine = f.readline().replace('NV', 'Nv').replace('EXT', 'Ext').replace('AMD', 'Amd').replace('KHR', 'Khr')
# look for enum
m = re.search( 'typedef enum Vk.* {', strLine )
if( m ):
decl = m.group(0)
decl = decl.replace('{', '').strip()
enumClassName = ((decl.split(' ')[2])[2:])
enumMap = 'Vk%s' % enumClassName
opsClassName = 'Vk%s' % enumClassName
if 'FlagBits' in enumClassName:
opsClassName = 'Vk%s' % enumClassName.replace( 'FlagBits', 'Flags' )
enumClassName = enumClassName.replace('FlagBits', 'Bit')
enumMap = opsClassName
enumlist[enumMap] = enumClassName
enumChunks = re.findall('[A-Z][^A-Z]*', decl)
enumChunks.extend( '3'*10 )
enumOut = '/* Enum: (%s, %s, %s) %s */\n' % (enumMap, enumClassName, opsClassName, decl.split(' ')[2])
enumOut += 'enum class %s {\n' % (enumClassName)
while True:
enumLine = f.readline()
#print(' %s' % enumLine)
if( enumLine.startswith('}') ):
break
valName = enumLine.split('=')[0]
valChunks = valName.split('_')
newValName = ''
for i in range( 0, len(valChunks ) ):
ec = enumChunks[i].upper().strip()
vc = valChunks[i].upper().strip();
#print(' > %s -> %s' % ( ec, vc ) )
if( ec != vc ):
if( (newValName == '') and (vc[0].isdigit()) ):
newValName = '_%s' % valChunks[i-1].upper().strip()
newValName += '_%s' % vc
enumOut += ' %s = ::%s,\n' % ( newValName[1:], valName.strip() )
enumOut += '};\n'
enumOut += 'enum_ops( %s, %s )\n\n' % ( enumClassName, opsClassName )
result += enumOut
f.close();
return result, enumlist
def write_comment( out ):
s ="""/****************************************************************************
* This file is AUTO-GENERATED and must not be modified manually.
* Use gen-vulkan.py script to regenerate it.
*
* Limitations:
* - Arrays are not supported ( like pipeline blendConstants[4] ), use 'info'
* instead.
* - No platform specific structures ( Xcb, Xlib etc. )
*
*/
"""
writeout( out, s )
return
def write_headers( out ):
writeout( out, '#include <vulkan/vulkan.h>');
writeout( out, '#include <inttypes.h>');
writeout( out, '#include <stdint.h>');
writeout( out, '#include <string.h>');
return
def write_macro( out, vktype ):
writeout( out, '\n/* Macro for Vk%s */\n' % vktype )
writeout( out, '#undef make_field')
writeout( out, '#define make_field( TYPE, NAME ) \\')
writeout( out, 'inline %s& NAME( TYPE value ) { info.NAME = value; return *this; } \\' % vktype )
writeout( out, 'template <typename T> \\')
writeout( out, 'inline %s& NAME( T value ) { info.NAME = (TYPE)value; return *this; } \\' % vktype )
writeout( out, 'template <typename T> \\')
writeout( out, 'inline %s& NAME( T* value ) { info.NAME = (TYPE)value; return *this; } \\' % vktype )
writeout( out, 'inline TYPE NAME() { return info.NAME; }\n')
writeout( out, '#undef make_field_enum')
writeout( out, '#define make_field_enum( TYPE, TYPE_VK, NAME ) \\')
writeout( out, 'inline %s& NAME( TYPE value ) { info.NAME = (TYPE_VK)value; return *this; } \\' % vktype )
writeout( out, '\n')
#writeout( out, 'const TYPE& _ ## NAME{ info.NAME } \\\n')
return
def get_stype( vktype ):
vk_newtype = vktype.replace("EXT", "Ext").replace("KHR", "Khr").replace("NV", "Nv").replace("AMD", "Amd")
result = re.findall('[A-Z][^A-Z]*', vk_newtype)
stype = 'VK_STRUCTURE_TYPE'
for s in result:
stype += '_%s' % s.upper()
return stype
def write_constructor( out, vktype, found_sType ):
writeout( out, ' %s() {' % vktype )
writeout( out, ' memset( &info, 0, sizeof(info));' )
if( found_sType ):
writeout( out, ' info.sType = %s;' % get_stype(vktype) )
writeout( out, ' }\n' )
return
def write_operators( out, vktype ):
writeout( out, ' inline operator %s*() { return &info; }' % vktype )
writeout( out, ' inline operator %s&() { return info; }' % vktype )
return
def write_field( out, strField, enumdict ):
fields = strField.split()
f = fields[ len(fields)-1 ]
if( (f == 'sType') or ( f == 'pNext' ) ):
return f, True
fieldType = '%s' % fields[0]
for i in range( 1, len(fields)-1 ):
fieldType += ' %s' % fields[i]
fieldType1 = fieldType;
bodyEnum = None
if 'Vk' in fieldType:
m = re.search( 'Vk[a-zA-Z0-9]*', fieldType )
if(m and enumdict.has_key( m.group(0))):
bodyEnum = '{0:32},{1:32}, {2}'.format( 'Vk::%s' % enumdict[m.group(0)], fieldType, f );
body = '{0:32}, {1}'.format( fieldType, f );
disabled = ''
if '[' in f:
disabled = '////'
writeout( out, ' %smake_field( %s )' % ( disabled, body ) )
if( bodyEnum ):
writeout( out, ' %smake_field_enum( %s )' % ( disabled, bodyEnum ) )
return f, False
def parse_header( headerPath, outPath ):
enums, enumdict = buildenums( headerPath )
f = open( headerPath, "r" )
qt_snippets = open( '/tmp/snippets.xml', "w" )
qt_snippets.write('<?xml version="1.0" encoding="UTF-8"?>\n<snippets>\n')
out = None
if( outPath ):
out = open( outPath, "w" )
strLine = '\n'
write_comment( out )
write_headers( out )
writeout( out, '\nnamespace Vk {')
writeout( out, enums )
while ( len( strLine ) ):
strLine = f.readline();
if ( not len(strLine) ):
break
m = re.search( 'typedef struct Vk.* {', strLine )
if( m ):
decl = m.group(0)
strStructName = re.search( 'Vk.* ', decl ).group(0)
# skip platform dependent structures
if( re.search( ".*Xcb.*|.*Win32.*|.*Xlib.*|.*Android.*|.*Mir.*|.*Wayland.*", strStructName ) ):
continue
write_macro( out, strStructName[2:] )
writeout( out, 'struct %s {' % strStructName[2:] )
writeout( out, ' %s info;' % strStructName );
snippet_xml = '<snippet group="C++" trigger="%s" id="" complement="Create Info Structure" removed="false" modified="false">' % strStructName[0:]
snippet_inl_xml = '<snippet group="C++" trigger="%s" id="" complement="Inline Info Structure" removed="false" modified="false">' % strStructName[0:]
snippet = 'Vk::%s$name$;\n' % strStructName[2:]
snippet += '$name$\n';
snippet_inl = 'Vk::%s()\n' % strStructName[2:]
# write fields
found_sType = False
while( True ):
strField = f.readline()
if ( strField[0] == "}" ):
break
strField = strField.replace(';', '')
res, ignored = write_field( out, strField, enumdict )
if ( res == 'sType' ):
found_sType = True
if( not ignored ):
snippet += ' .%s( 0 )\n' % res
snippet_inl += ' .%s( 0 )\n' % res
writeout( out, '\n // Constructor' )
write_constructor( out, strStructName[2:], found_sType );
write_operators( out, strStructName )
writeout( out, '};' )
qt_snippets.write( '%s%s;\n</snippet>\n' % ( snippet_xml, snippet ))
qt_snippets.write( '%s%s</snippet>\n' % ( snippet_inl_xml, snippet_inl ))
f.close();
qt_snippets.write("</snippets>\n")
qt_snippets.close()
writeout( out, '}')
return
outfile = None
if( len(sys.argv) == 3 ):
outfile = sys.argv[2]
parse_header( sys.argv[1], outfile )
#buildenums( sys.argv[1] )
#print( sys.argv )