layers: Change 'VS' to 'vertex shader'
[platform/upstream/Vulkan-LoaderAndValidationLayers.git] / vk-generate.py
1 #!/usr/bin/env python3
2 #
3 # Copyright (c) 2015-2016 The Khronos Group Inc.
4 # Copyright (c) 2015-2016 Valve Corporation
5 # Copyright (c) 2015-2016 LunarG, Inc.
6 # Copyright (c) 2015-2016 Google Inc.
7 #
8 # Licensed under the Apache License, Version 2.0 (the "License");
9 # you may not use this file except in compliance with the License.
10 # You may obtain a copy of the License at
11 #
12 #     http://www.apache.org/licenses/LICENSE-2.0
13 #
14 # Unless required by applicable law or agreed to in writing, software
15 # distributed under the License is distributed on an "AS IS" BASIS,
16 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 # See the License for the specific language governing permissions and
18 # limitations under the License.
19 #
20 # Author: Chia-I Wu <olv@lunarg.com>
21 # Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
22 # Author: Jon Ashburn <jon@lunarg.com>
23 # Author: Gwan-gyeong Mun <kk.moon@samsung.com>
24
25 import sys
26
27 import vulkan
28
29 def generate_get_proc_addr_check(name):
30     return "    if (!%s || %s[0] != 'v' || %s[1] != 'k')\n" \
31            "        return NULL;" % ((name,) * 3)
32
33 class Subcommand(object):
34     def __init__(self, argv):
35         self.argv = argv
36         self.headers = vulkan.headers
37         self.protos = vulkan.protos
38         self.outfile = None
39
40     def run(self):
41         if self.outfile:
42             with open(self.outfile, "w") as outfile:
43                 outfile.write(self.generate())
44         else:
45             print(self.generate())
46
47     def generate(self):
48         copyright = self.generate_copyright()
49         header = self.generate_header()
50         body = self.generate_body()
51         footer = self.generate_footer()
52
53         contents = []
54         if copyright:
55             contents.append(copyright)
56         if header:
57             contents.append(header)
58         if body:
59             contents.append(body)
60         if footer:
61             contents.append(footer)
62
63         return "\n\n".join(contents)
64
65     def generate_copyright(self):
66         return """/* THIS FILE IS GENERATED.  DO NOT EDIT. */
67
68 /*
69  * Copyright (c) 2015-2016 The Khronos Group Inc.
70  * Copyright (c) 2015-2016 Valve Corporation
71  * Copyright (c) 2015-2016 LunarG, Inc.
72  *
73  * Licensed under the Apache License, Version 2.0 (the "License");
74  * you may not use this file except in compliance with the License.
75  * You may obtain a copy of the License at
76  *
77  *     http://www.apache.org/licenses/LICENSE-2.0
78  *
79  * Unless required by applicable law or agreed to in writing, software
80  * distributed under the License is distributed on an "AS IS" BASIS,
81  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82  * See the License for the specific language governing permissions and
83  * limitations under the License.
84  *
85  * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
86  */"""
87
88     def generate_header(self):
89         return "\n".join(["#include <" + h + ">" for h in self.headers])
90
91     def generate_body(self):
92         pass
93
94     def generate_footer(self):
95         pass
96
97 class DispatchTableOpsSubcommand(Subcommand):
98     def __init__(self, argv):
99         self.argv = argv
100         self.headers = vulkan.headers_all
101         self.protos = vulkan.protos_all
102         self.outfile = None
103
104     def run(self):
105         if len(self.argv) < 1:
106             print("DispatchTableOpsSubcommand: <prefix> unspecified")
107             return
108
109         self.prefix = self.argv[0]
110
111         if len(self.argv) > 2:
112             print("DispatchTableOpsSubcommand: <prefix> [outfile]")
113             return
114
115         if len(self.argv) == 2:
116             self.outfile = self.argv[1]
117
118         super(DispatchTableOpsSubcommand, self).run()
119
120     def generate_header(self):
121         return "\n".join(["#include <vulkan/vulkan.h>",
122                           "#include <vulkan/vk_layer.h>",
123                           "#include <string.h>"])
124
125     def _generate_init_dispatch(self, type):
126         stmts = []
127         func = []
128         if type == "device":
129             # GPA has to be first one and uses wrapped object
130             stmts.append("    memset(table, 0, sizeof(*table));")
131             stmts.append("    // Core device function pointers")
132             stmts.append("    table->GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) gpa(device, \"vkGetDeviceProcAddr\");")
133
134             for proto in self.protos:
135                 if proto.name == "CreateInstance" or proto.name == "EnumerateInstanceExtensionProperties" or \
136                   proto.name == "EnumerateInstanceLayerProperties" or proto.params[0].ty == "VkInstance" or \
137                   proto.params[0].ty == "VkPhysicalDevice" or proto.name == "GetDeviceProcAddr":
138                     continue
139                 if proto.name == "GetMemoryWin32HandleNV":
140                     stmts.append("#ifdef VK_USE_PLATFORM_WIN32_KHR")
141                     stmts.append("    table->%s = (PFN_vk%s) gpa(device, \"vk%s\");" %
142                             (proto.name, proto.name, proto.name))
143                     stmts.append("#endif // VK_USE_PLATFORM_WIN32_KHR")
144                 else:
145                     stmts.append("    table->%s = (PFN_vk%s) gpa(device, \"vk%s\");" %
146                             (proto.name, proto.name, proto.name))
147             func.append("static inline void %s_init_device_dispatch_table(VkDevice device,"
148                 % self.prefix)
149             func.append("%s                                               VkLayerDispatchTable *table,"
150                 % (" " * len(self.prefix)))
151             func.append("%s                                               PFN_vkGetDeviceProcAddr gpa)"
152                 % (" " * len(self.prefix)))
153         else:
154             stmts.append("    memset(table, 0, sizeof(*table));")
155             stmts.append("    // Core instance function pointers")
156             stmts.append("    table->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) gpa(instance, \"vkGetInstanceProcAddr\");")
157
158             KHR_printed = False
159             EXT_printed = False
160             Win32_printed = False
161             XLIB_printed = False
162             XCB_printed = False
163             MIR_printed = False
164             WAY_printed = False
165             Android_printed = False
166             for proto in self.protos:
167                 if proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice" or \
168                   proto.name == "CreateDevice" or proto.name == "GetInstanceProcAddr":
169                     continue
170                 if Win32_printed and 'Win32' not in proto.name:
171                     stmts.append("#endif // VK_USE_PLATFORM_WIN32_KHR")
172                     Win32_printed = False
173                 if XLIB_printed and 'Xlib' not in proto.name:
174                     stmts.append("#endif // VK_USE_PLATFORM_XLIB_KHR")
175                     XLIB_printed = False
176                 if XCB_printed and 'Xcb' not in proto.name:
177                     stmts.append("#endif // VK_USE_PLATFORM_XCB_KHR")
178                     XCB_printed = False
179                 if MIR_printed and 'Mir' not in proto.name:
180                     stmts.append("#endif // VK_USE_PLATFORM_MIR_KHR")
181                     MIR_printed = False
182                 if WAY_printed and 'Wayland' not in proto.name:
183                     stmts.append("#endif // VK_USE_PLATFORM_WAYLAND_KHR")
184                     WAY_printed = False
185                 if Android_printed and 'Android' not in proto.name:
186                     stmts.append("#endif // VK_USE_PLATFORM_ANDROID_KHR")
187                     Android_printed = False
188                 if 'KHR' in proto.name and 'Win32' in proto.name:
189                     if not Win32_printed:
190                         stmts.append("#ifdef VK_USE_PLATFORM_WIN32_KHR")
191                         Win32_printed = True
192                 if 'KHR' in proto.name and 'Xlib' in proto.name:
193                     if not XLIB_printed:
194                         stmts.append("#ifdef VK_USE_PLATFORM_XLIB_KHR")
195                         XLIB_printed = True
196                 if 'KHR' in proto.name and 'Xcb' in proto.name:
197                     if not XCB_printed:
198                         stmts.append("#ifdef VK_USE_PLATFORM_XCB_KHR")
199                         XCB_printed = True
200                 if 'KHR' in proto.name and 'Mir' in proto.name:
201                     if not MIR_printed:
202                         stmts.append("#ifdef VK_USE_PLATFORM_MIR_KHR")
203                         MIR_printed = True
204                 if 'KHR' in proto.name and 'Wayland' in proto.name:
205                     if not WAY_printed:
206                         stmts.append("#ifdef VK_USE_PLATFORM_WAYLAND_KHR")
207                         WAY_printed = True
208                 if 'KHR' in proto.name and 'Android' in proto.name:
209                     if not Android_printed:
210                         stmts.append("#ifdef VK_USE_PLATFORM_ANDROID_KHR")
211                         Android_printed = True
212                 if 'KHR' in proto.name and not KHR_printed:
213                     stmts.append("    // KHR instance extension function pointers")
214                     KHR_printed = True
215                 if 'EXT' in proto.name and not EXT_printed:
216                     stmts.append("    // EXT instance extension function pointers")
217                     EXT_printed = True
218                 stmts.append("    table->%s = (PFN_vk%s) gpa(instance, \"vk%s\");" %
219                       (proto.name, proto.name, proto.name))
220             func.append("static inline void %s_init_instance_dispatch_table(" % self.prefix)
221             func.append("%s        VkInstance instance," % (" " * len(self.prefix)))
222             func.append("%s        VkLayerInstanceDispatchTable *table," % (" " * len(self.prefix)))
223             func.append("%s        PFN_vkGetInstanceProcAddr gpa)" % (" " * len(self.prefix)))
224         func.append("{")
225         func.append("%s" % "\n".join(stmts))
226         func.append("}")
227
228         return "\n".join(func)
229
230     def generate_body(self):
231         body = [self._generate_init_dispatch("device"),
232                 self._generate_init_dispatch("instance")]
233
234         return "\n\n".join(body)
235
236 class WinDefFileSubcommand(Subcommand):
237     def run(self):
238         library_exports = {
239                 "all": [],
240                 "icd": [
241                     "vk_icdGetInstanceProcAddr",
242                 ],
243                 "layer": [
244                     "vkGetInstanceProcAddr",
245                     "vkGetDeviceProcAddr",
246                     "vkEnumerateInstanceLayerProperties",
247                     "vkEnumerateInstanceExtensionProperties"
248                 ],
249                 "layer_multi": [
250                     "multi2GetInstanceProcAddr",
251                     "multi1GetDeviceProcAddr"
252                 ]
253         }
254
255         if len(self.argv) < 2 or len(self.argv) > 3 or self.argv[1] not in library_exports:
256             print("WinDefFileSubcommand: <library-name> {%s} [outfile]" %
257                     "|".join(library_exports.keys()))
258             return
259
260         self.library = self.argv[0]
261         if self.library == "VkLayer_multi":
262             self.exports = library_exports["layer_multi"]
263         else:
264             self.exports = library_exports[self.argv[1]]
265
266         if len(self.argv) == 3:
267             self.outfile = self.argv[2]
268
269         super(WinDefFileSubcommand, self).run()
270
271     def generate_copyright(self):
272         return """; THIS FILE IS GENERATED.  DO NOT EDIT.
273
274 ;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
275 ; Vulkan
276 ;
277 ; Copyright (c) 2015-2016 The Khronos Group Inc.
278 ; Copyright (c) 2015-2016 Valve Corporation
279 ; Copyright (c) 2015-2016 LunarG, Inc.
280 ;
281 ; Licensed under the Apache License, Version 2.0 (the "License");
282 ; you may not use this file except in compliance with the License.
283 ; You may obtain a copy of the License at
284 ;
285 ;     http://www.apache.org/licenses/LICENSE-2.0
286 ;
287 ; Unless required by applicable law or agreed to in writing, software
288 ; distributed under the License is distributed on an "AS IS" BASIS,
289 ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
290 ; See the License for the specific language governing permissions and
291 ; limitations under the License.
292 ;
293 ;  Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
294 ;;;;  End Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"""
295
296     def generate_header(self):
297         return "; The following is required on Windows, for exporting symbols from the DLL"
298
299     def generate_body(self):
300         body = []
301
302         body.append("LIBRARY " + self.library)
303         body.append("EXPORTS")
304
305         for proto in self.exports:
306             if self.library != "VkLayerSwapchain" or proto != "vkEnumerateInstanceExtensionProperties" and proto != "vkEnumerateInstanceLayerProperties":
307                 body.append( proto)
308
309         return "\n".join(body)
310
311 def main():
312     wsi = {
313             "Win32",
314             "Android",
315             "Xcb",
316             "Xlib",
317             "Wayland",
318             "Mir",
319             "Display",
320             "AllPlatforms"
321     }
322     subcommands = {
323             "dispatch-table-ops": DispatchTableOpsSubcommand,
324             "win-def-file": WinDefFileSubcommand,
325     }
326
327     if len(sys.argv) < 3 or sys.argv[1] not in wsi or sys.argv[2] not in subcommands:
328         print("Usage: %s <wsi> <subcommand> [options]" % sys.argv[0])
329         print
330         print("Available sucommands are: %s" % " ".join(subcommands))
331         exit(1)
332
333     subcmd = subcommands[sys.argv[2]](sys.argv[3:])
334     subcmd.run()
335
336 if __name__ == "__main__":
337     main()