annotate svk/generate.nim @ 1479:172ac338f820 main

add: prep to add new vulkan api
author sam <sam@basx.dev>
date Sun, 20 Apr 2025 21:57:56 +0700
parents
children 0b302531f5c5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1479
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
1 import std/strtabs
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
2 import std/xmltree
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
3 import std/tables
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
4 import std/options
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
5 import std/sequtils
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
6 import std/strutils
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
7 import std/strformat
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
8 import std/xmlparser
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
9 import std/os
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
10 import std/paths
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
11
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
12 # helpers
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
13 func smartParseInt(value: string): int =
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
14 if value.startsWith("0x"):
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
15 parseHexInt(value)
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
16 else:
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
17 parseInt(value)
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
18
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
19 const TYPEMAP = {
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
20 "void": "void",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
21 "char": "char",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
22 "float": "float32",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
23 "double": "float64",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
24 "int8_t": "int8",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
25 "uint8_t": "uint8",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
26 "int16_t": "int16",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
27 "uint16_t": "uint16",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
28 "int32_t": "int32",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
29 "uint32_t": "uint32",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
30 "uint64_t": "uint64",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
31 "int64_t": "int64",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
32 "size_t": "csize_t",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
33 "int": "cint",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
34 "void*": "pointer",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
35 "char*": "cstring",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
36 "ptr char": "cstring",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
37 "ptr void": "pointer",
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
38 # "VK_DEFINE_HANDLE": "VkHandle", # not required, can directly defined as a distinct pointer, (in C is a pointer to an empty struct type)
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
39 # "VK_DEFINE_NON_DISPATCHABLE_HANDLE": "VkNonDispatchableHandle", # same here
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
40 }.toTable
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
41
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
42 # load xml
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
43 let xml = (system.currentSourcePath.parentDir() / "vk.xml").loadXml()
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
44 let platforms = xml.findAll("platforms")[0]
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
45 let types = xml.findAll("types")[0]
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
46 let xmlenums = xml.findAll("enums")
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
47 let commands = xml.findAll("commands")[0]
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
48 let features = xml.findAll("feature") # features has extends="<ENUM>"
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
49 let extensions = xml.findAll("extensions")[0] # extensions has extends="<ENUM>"
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
50 let formats = xml.findAll("formats")[0]
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
51
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
52 # gather all enums
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
53
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
54 type
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
55 EnumEntry = object
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
56 name: string
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
57 value: string
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
58
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
59 EnumDef = object
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
60 name: string
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
61 values: seq[EnumEntry]
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
62 isBitmask: bool
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
63
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
64 ConstantDef = object
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
65 name: string
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
66 datatype: string
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
67 value: string
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
68
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
69 var consts: seq[ConstantDef]
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
70 var enums: Table[string, EnumDef]
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
71
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
72 func addValue(edef: var EnumDef, n: XmlNode) =
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
73 if n.attr("deprecated") != "aliased" and n.attr("alias") == "":
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
74 if n.attr("name") in edef.values.mapIt(it.name):
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
75 return
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
76 if n.attr("name").endsWith("_EXT") and
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
77 n.attr("name")[0 ..< ^4] in edef.values.mapIt(it.name):
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
78 return
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
79
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
80 var value = ""
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
81 if n.attr("value") != "":
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
82 value = n.attr("value")
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
83 elif n.attr("bitpos") != "":
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
84 value = $(1 shl parseInt(n.attr("bitpos")))
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
85 elif n.attr("offset") != "":
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
86 var enumBase = 1000000000
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
87 if n.attr("extnumber") != "":
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
88 enumBase += (smartParseInt(n.attr("extnumber")) - 1) * 1000
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
89 var v = smartParseInt(n.attr("offset")) + enumBase
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
90 if n.attr("dir") == "-":
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
91 v = -v
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
92 value = $(v)
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
93
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
94 edef.values.add EnumEntry(name: n.attr("name"), value: value)
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
95
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
96 for e in xmlenums:
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
97 if e.attr("type") == "constants":
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
98 for c in e.findAll("enum"):
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
99 var value = c.attr("value").strip(chars = {'(', ')'})
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
100 consts.add ConstantDef(
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
101 name: c.attr("name"), datatype: TYPEMAP[c.attr("type")], value: value
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
102 )
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
103 elif e.attr("type") == "enum":
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
104 var edef = EnumDef(name: e.attr("name"), isBitmask: false)
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
105 for ee in e.findAll("enum"):
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
106 edef.addValue(ee)
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
107 enums[edef.name] = edef
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
108 elif e.attr("type") == "bitmask":
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
109 var edef = EnumDef(name: e.attr("name"), isBitmask: true)
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
110 for ee in e.findAll("enum"):
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
111 edef.addValue(ee)
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
112 enums[edef.name] = edef
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
113
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
114 for f in features:
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
115 for extendenum in f.findAll("enum"):
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
116 if extendenum.attr("extends") != "":
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
117 enums[extendenum.attr("extends")].addValue(extendenum)
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
118
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
119 for extension in extensions.findAll("extension"):
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
120 let extNum = extension.attr("number")
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
121 for extendenum in extension.findAll("enum"):
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
122 if extendenum.attr("extends") != "":
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
123 if extendenum.attr("extnumber") == "":
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
124 extendenum.attrs["extnumber"] = extNum
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
125 enums[extendenum.attr("extends")].addValue(extendenum)
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
126
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
127 # generate core types ===============================================================================
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
128 # preamble, much easier to hardcode than to generate from xml
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
129 echo """
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
130 when defined(linux):
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
131 include ./platform/xlib
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
132 when defined(windows):
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
133 include ./platform/win32
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
134
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
135 func VK_MAKE_API_VERSION*(
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
136 variant: uint32, major: uint32, minor: uint32, patch: uint32
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
137 ): uint32 {.compileTime.} =
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
138 (variant shl 29) or (major shl 22) or (minor shl 12) or patch
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
139
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
140
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
141 """
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
142
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
143 echo "type"
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
144
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
145 for t in types:
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
146 if t.attr("deprecated") == "true":
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
147 continue
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
148 echo t
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
149 echo ""
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
150
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
151 # generate consts ===============================================================================
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
152 echo "const"
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
153 for c in consts:
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
154 var value = c.value
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
155 if value.endsWith("U"):
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
156 value = value[0 ..^ 2] & "'u32"
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
157 elif value.endsWith("ULL"):
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
158 value = value[0 ..^ 4] & "'u64"
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
159 if value[0] == '~':
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
160 value = "not " & value[1 ..^ 1]
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
161 echo &" {c.name}*: {c.datatype} = {value}"
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
162 echo ""
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
163
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
164 # generate enums ===============================================================================
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
165 echo "type"
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
166 for edef in enums.values():
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
167 if edef.values.len > 0:
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
168 echo &" {edef.name}* {{.size: 4.}} = enum"
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
169 for ee in edef.values:
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
170 echo &" {ee.name} = {ee.value}"
172ac338f820 add: prep to add new vulkan api
sam <sam@basx.dev>
parents:
diff changeset
171 echo ""