Home | History | Annotate | Download | only in vulkan-validation-layers
      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 # Permission is hereby granted, free of charge, to any person obtaining a copy
      9 # of this software and/or associated documentation files (the "Materials"), to
     10 # deal in the Materials without restriction, including without limitation the
     11 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
     12 # sell copies of the Materials, and to permit persons to whom the Materials
     13 # are furnished to do so, subject to the following conditions:
     14 #
     15 # The above copyright notice(s) and this permission notice shall be included
     16 # in all copies or substantial portions of the Materials.
     17 #
     18 # THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     21 #
     22 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
     23 # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     24 # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
     25 # USE OR OTHER DEALINGS IN THE MATERIALS
     26 #
     27 # Author: Chia-I Wu <olv (at] lunarg.com>
     28 # Author: Courtney Goeltzenleuchter <courtney (at] LunarG.com>
     29 # Author: Jon Ashburn <jon (at] lunarg.com>
     30 # Author: Gwan-gyeong Mun <kk.moon (at] samsung.com>
     31 
     32 import sys
     33 
     34 import vulkan
     35 
     36 def generate_get_proc_addr_check(name):
     37     return "    if (!%s || %s[0] != 'v' || %s[1] != 'k')\n" \
     38            "        return NULL;" % ((name,) * 3)
     39 
     40 class Subcommand(object):
     41     def __init__(self, argv):
     42         self.argv = argv
     43         self.headers = vulkan.headers
     44         self.protos = vulkan.protos
     45 
     46     def run(self):
     47         print(self.generate())
     48 
     49     def generate(self):
     50         copyright = self.generate_copyright()
     51         header = self.generate_header()
     52         body = self.generate_body()
     53         footer = self.generate_footer()
     54 
     55         contents = []
     56         if copyright:
     57             contents.append(copyright)
     58         if header:
     59             contents.append(header)
     60         if body:
     61             contents.append(body)
     62         if footer:
     63             contents.append(footer)
     64 
     65         return "\n\n".join(contents)
     66 
     67     def generate_copyright(self):
     68         return """/* THIS FILE IS GENERATED.  DO NOT EDIT. */
     69 
     70 /*
     71  * Copyright (c) 2015-2016 The Khronos Group Inc.
     72  * Copyright (c) 2015-2016 Valve Corporation
     73  * Copyright (c) 2015-2016 LunarG, Inc.
     74  *
     75  * Permission is hereby granted, free of charge, to any person obtaining a copy
     76  * of this software and/or associated documentation files (the "Materials"), to
     77  * deal in the Materials without restriction, including without limitation the
     78  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
     79  * sell copies of the Materials, and to permit persons to whom the Materials are
     80  * furnished to do so, subject to the following conditions:
     81  *
     82  * The above copyright notice(s) and this permission notice shall be included in
     83  * all copies or substantial portions of the Materials.
     84  *
     85  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     86  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     87  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     88  *
     89  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
     90  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     91  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
     92  * USE OR OTHER DEALINGS IN THE MATERIALS.
     93  *
     94  * Author: Courtney Goeltzenleuchter <courtney (at] LunarG.com>
     95  */"""
     96 
     97     def generate_header(self):
     98         return "\n".join(["#include <" + h + ">" for h in self.headers])
     99 
    100     def generate_body(self):
    101         pass
    102 
    103     def generate_footer(self):
    104         pass
    105 
    106 class DispatchTableOpsSubcommand(Subcommand):
    107     def run(self):
    108         if len(self.argv) != 1:
    109             print("DispatchTableOpsSubcommand: <prefix> unspecified")
    110             return
    111 
    112         self.prefix = self.argv[0]
    113         super(DispatchTableOpsSubcommand, self).run()
    114 
    115     def generate_header(self):
    116         return "\n".join(["#include <vulkan/vulkan.h>",
    117                           "#include <vulkan/vk_layer.h>",
    118                           "#include <string.h>"])
    119 
    120     def _generate_init_dispatch(self, type):
    121         stmts = []
    122         func = []
    123         if type == "device":
    124             # GPA has to be first one and uses wrapped object
    125             stmts.append("memset(table, 0, sizeof(*table));")
    126             stmts.append("table->GetDeviceProcAddr =(PFN_vkGetDeviceProcAddr)  gpa(device,\"vkGetDeviceProcAddr\");")
    127             for proto in self.protos:
    128                 if proto.name == "CreateInstance" or proto.name == "EnumerateInstanceExtensionProperties" or proto.name == "EnumerateInstanceLayerProperties" or proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice":
    129                     continue
    130                 if proto.name != "GetDeviceProcAddr" and 'KHR' not in proto.name:
    131                     stmts.append("table->%s = (PFN_vk%s) gpa(device, \"vk%s\");" %
    132                         (proto.name, proto.name, proto.name))
    133             func.append("static inline void %s_init_device_dispatch_table(VkDevice device,"
    134                 % self.prefix)
    135             func.append("%s                                               VkLayerDispatchTable *table,"
    136                 % (" " * len(self.prefix)))
    137             func.append("%s                                               PFN_vkGetDeviceProcAddr gpa)"
    138                 % (" " * len(self.prefix)))
    139         else:
    140             stmts.append("table->GetInstanceProcAddr =(PFN_vkGetInstanceProcAddr)  gpa(instance,\"vkGetInstanceProcAddr\");")
    141             for proto in self.protos:
    142                 if proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice":
    143                     continue
    144                 if proto.name == "CreateDevice":
    145                     continue
    146                 if proto.name != "GetInstanceProcAddr" and 'KHR' not in proto.name:
    147                     stmts.append("table->%s = (PFN_vk%s) gpa(instance, \"vk%s\");" %
    148                           (proto.name, proto.name, proto.name))
    149             func.append("static inline void %s_init_instance_dispatch_table(" % self.prefix)
    150             func.append("%s        VkInstance instance," % (" " * len(self.prefix)))
    151             func.append("%s        VkLayerInstanceDispatchTable *table," % (" " * len(self.prefix)))
    152             func.append("%s        PFN_vkGetInstanceProcAddr gpa)" % (" " * len(self.prefix)))
    153         func.append("{")
    154         func.append("    %s" % "\n    ".join(stmts))
    155         func.append("}")
    156 
    157         return "\n".join(func)
    158 
    159     def generate_body(self):
    160         body = [self._generate_init_dispatch("device"),
    161                 self._generate_init_dispatch("instance")]
    162 
    163         return "\n\n".join(body)
    164 
    165 class WinDefFileSubcommand(Subcommand):
    166     def run(self):
    167         library_exports = {
    168                 "all": [],
    169                 "icd": [
    170                     "vk_icdGetInstanceProcAddr",
    171                 ],
    172                 "layer": [
    173                     "vkGetInstanceProcAddr",
    174                     "vkGetDeviceProcAddr",
    175                     "vkEnumerateInstanceLayerProperties",
    176                     "vkEnumerateInstanceExtensionProperties"
    177                 ],
    178                 "layer_multi": [
    179                     "multi2GetInstanceProcAddr",
    180                     "multi1GetDeviceProcAddr"
    181                 ]
    182         }
    183 
    184         if len(self.argv) != 2 or self.argv[1] not in library_exports:
    185             print("WinDefFileSubcommand: <library-name> {%s}" %
    186                     "|".join(library_exports.keys()))
    187             return
    188 
    189         self.library = self.argv[0]
    190         if self.library == "VkLayer_multi":
    191             self.exports = library_exports["layer_multi"]
    192         else:
    193             self.exports = library_exports[self.argv[1]]
    194 
    195         super().run()
    196 
    197     def generate_copyright(self):
    198         return """; THIS FILE IS GENERATED.  DO NOT EDIT.
    199 
    200 ;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    201 ; Vulkan
    202 ;
    203 ; Copyright (c) 2015-2016 The Khronos Group Inc.
    204 ; Copyright (c) 2015-2016 Valve Corporation
    205 ; Copyright (c) 2015-2016 LunarG, Inc.
    206 ;
    207 ; Permission is hereby granted, free of charge, to any person obtaining a copy
    208 ; of this software and/or associated documentation files (the "Materials"), to
    209 ; deal in the Materials without restriction, including without limitation the
    210 ; rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    211 ; sell copies of the Materials, and to permit persons to whom the Materials are
    212 ; furnished to do so, subject to the following conditions:
    213 ;
    214 ; The above copyright notice(s) and this permission notice shall be included in
    215 ; all copies or substantial portions of the Materials.
    216 ;
    217 ; THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    218 ; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    219 ; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    220 ;
    221 ; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    222 ; DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    223 ; OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
    224 ; USE OR OTHER DEALINGS IN THE MATERIALS.
    225 ;
    226 ;  Author: Courtney Goeltzenleuchter <courtney (at] LunarG.com>
    227 ;;;;  End Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"""
    228 
    229     def generate_header(self):
    230         return "; The following is required on Windows, for exporting symbols from the DLL"
    231 
    232     def generate_body(self):
    233         body = []
    234 
    235         body.append("LIBRARY " + self.library)
    236         body.append("EXPORTS")
    237 
    238         for proto in self.exports:
    239             if self.library != "VkLayerSwapchain" or proto != "vkEnumerateInstanceExtensionProperties" and proto != "vkEnumerateInstanceLayerProperties":
    240                 body.append( proto)
    241 
    242         return "\n".join(body)
    243 
    244 def main():
    245     wsi = {
    246             "Win32",
    247             "Android",
    248             "Xcb",
    249             "Xlib",
    250             "Wayland",
    251             "Mir"
    252     }
    253     subcommands = {
    254             "dispatch-table-ops": DispatchTableOpsSubcommand,
    255             "win-def-file": WinDefFileSubcommand,
    256     }
    257 
    258     if len(sys.argv) < 3 or sys.argv[1] not in wsi or sys.argv[2] not in subcommands:
    259         print("Usage: %s <wsi> <subcommand> [options]" % sys.argv[0])
    260         print
    261         print("Available sucommands are: %s" % " ".join(subcommands))
    262         exit(1)
    263 
    264     subcmd = subcommands[sys.argv[2]](sys.argv[3:])
    265     subcmd.run()
    266 
    267 if __name__ == "__main__":
    268     main()
    269