Generate Vulkan framework from Vulkan registry

Instead of using the manually created vulkan.api file for generating the
Vulkan framework, we generate it directly from the vulkan registry
(vk.xml)

Bug: 134711355
Test: Build and flash, dEQP tests
Change-Id: I7e85cd4b64d13b8ed2c54678090f405171854a40
diff --git a/vulkan/scripts/api_generator.py b/vulkan/scripts/api_generator.py
new file mode 100644
index 0000000..05dc995
--- /dev/null
+++ b/vulkan/scripts/api_generator.py
@@ -0,0 +1,344 @@
+#!/usr/bin/env python3
+#
+# Copyright 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This script provides the functions required for generating the
+# vulkan api framework directly from the vulkan registry (vk.xml)
+
+import os
+import generator_common as gencom
+
+def isInstanceDispatchTableEntry(functionName):
+  if functionName == 'vkEnumerateDeviceLayerProperties': # deprecated, unused internally - @dbd33bc
+    return False
+  if gencom.gencom.isFunctionExported(functionName) and gencom.isInstanceDispatched(functionName):
+    return True
+  return False
+
+def isDeviceDispatchTableEntry(functionName):
+  if gencom.gencom.isFunctionExported(functionName) and gencom.gencom.isDeviceDispatched(functionName):
+    return True
+  return False
+
+def api_genh():
+
+  header = """#ifndef LIBVULKAN_API_GEN_H
+#define LIBVULKAN_API_GEN_H
+
+#include <vulkan/vulkan.h>
+
+#include <bitset>
+
+#include "driver_gen.h"
+
+namespace vulkan {
+namespace api {
+
+"""
+
+  tail = """
+bool InitDispatchTable(
+    VkInstance instance,
+    PFN_vkGetInstanceProcAddr get_proc,
+    const std::bitset<driver::ProcHook::EXTENSION_COUNT>& extensions);
+bool InitDispatchTable(
+    VkDevice dev,
+    PFN_vkGetDeviceProcAddr get_proc,
+    const std::bitset<driver::ProcHook::EXTENSION_COUNT>& extensions);
+
+}  // namespace api
+}  // namespace vulkan
+
+#endif  // LIBVULKAN_API_GEN_H
+"""
+  genfile = os.path.join(os.path.dirname(__file__),'..','libvulkan','api_gen2.h')
+  with open(genfile, 'w') as f:
+    instanceDispatchTableEntries = []
+    deviceDispatchTableEntries = []
+    for commands in gencom.allCommandsList:
+      if commands not in gencom.aliasDict:
+        if gencom.isInstanceDispatchTableEntry(commands):
+          instanceDispatchTableEntries.append('PFN_'+commands+' '+commands[2:]+';')
+        elif gencom.isDeviceDispatchTableEntry(commands):
+          deviceDispatchTableEntries.append('PFN_'+commands+' '+commands[2:]+';')
+
+    f.write (gencom.copyright)
+    f.write (gencom.warning)
+    f.write (header)
+    f.write ('struct InstanceDispatchTable {\n')
+    gencom.clang_off(f,1)
+    for functions in instanceDispatchTableEntries:
+      f.write(gencom.clang_off_spaces + functions + '\n')
+    gencom.clang_on(f,1)
+    f.write ('};\n\n')
+
+    f.write ('struct DeviceDispatchTable {\n')
+    gencom.clang_off(f,1)
+    for functions in deviceDispatchTableEntries:
+      f.write(gencom.clang_off_spaces + functions + '\n')
+    gencom.clang_on(f,1)
+    f.write ('};\n')
+
+    f.write (tail)
+    f.close()
+
+def defineInitProc(name, f):
+  f.write ('#define UNLIKELY(expr) __builtin_expect((expr), 0)\n')
+  f.write ('\n')
+  f.write ("""#define INIT_PROC(required, obj, proc)                                 \\
+    do {                                                               \\
+        data.""" + name + """.proc =                                           \\
+            reinterpret_cast<PFN_vk##proc>(get_proc(obj, "vk" #proc)); \\
+        if (UNLIKELY(required && !data.""" + name + """.proc)) {               \\
+            ALOGE("missing " #obj " proc: vk" #proc);                  \\
+            success = false;                                           \\
+        }                                                              \\
+    } while (0)\n\n""")
+
+def defineInitProcExt(f):
+  f.write ('// Exported extension functions may be invoked even when their extensions\n')
+  f.write ('// are disabled.  Dispatch to stubs when that happens.\n')
+  f.write ("""#define INIT_PROC_EXT(ext, required, obj, proc)  \\
+    do {                                         \\
+        if (extensions[driver::ProcHook::ext])   \\
+            INIT_PROC(required, obj, proc);      \\
+        else                                     \\
+            data.dispatch.proc = disabled##proc; \\
+    } while (0)\n\n""")
+
+def defineExtensionStub(functionName, f):
+  if functionName in gencom.extensionsDict and gencom.isFunctionExported(functionName):
+    extname = gencom.extensionsDict[functionName]
+    base_name = functionName[2:]
+    pList = gencom.paramDict[functionName]
+    firstParam = pList[0][0] + pList[0][1]
+    tailParams = [x[0][:-1] for x in pList[1:]]
+    tailP = ', '.join(tailParams)
+    f.write ('VKAPI_ATTR ' + gencom.returnTypeDict[functionName] + ' disabled' + base_name + '(' + firstParam + ', ' + tailP + ') {\n')
+    f.write (gencom.clang_off_spaces)
+    f.write ('driver::Logger(' + pList[0][1] + ').Err(' + pList[0][1] + ', \"' + extname + ' not enabled. Exported ' + functionName + ' not executed.\");\n')
+    if gencom.returnTypeDict[functionName] != 'void':
+      f.write(gencom.clang_off_spaces + 'return VK_SUCCESS;\n')
+    f.write ('}\n\n')
+
+def isIntercepted(functionName):
+  if gencom.isFunctionSupported(functionName):
+    if gencom.isGloballyDispatched(functionName):
+      return True
+    elif functionName == 'vkCreateDevice':
+      return True
+    elif functionName == 'vkEnumerateDeviceLayerProperties':
+      return True
+    elif functionName == 'vkEnumerateDeviceExtensionProperties':
+      return True
+    elif functionName == 'vkDestroyInstance':
+      return True
+    elif functionName == 'vkDestroyDevice':
+      return True
+  return False
+
+def interceptInstanceProcAddr(functionName, f):
+  indent = 1
+  f.write (gencom.clang_off_spaces*indent + '// global functions\n' + gencom.clang_off_spaces*indent+ 'if (instance == VK_NULL_HANDLE) {\n')
+  indent = indent + 1
+  for cmds in gencom.allCommandsList:
+    if gencom.isGloballyDispatched(cmds):
+      f.write(gencom.clang_off_spaces*indent + 'if (strcmp(pName, \"' + cmds + '\") == 0) return reinterpret_cast<PFN_vkVoidFunction>(' + cmds[2:] + ');\n')
+
+  f.write ('\n')
+  f.write ("""        ALOGE("invalid vkGetInstanceProcAddr(VK_NULL_HANDLE, \\\"%s\\\") call", pName);
+        return nullptr;
+    }
+
+    static const struct Hook {
+        const char* name;
+        PFN_vkVoidFunction proc;
+    } hooks[] = {\n""")
+  sortedCommandsList = sorted(gencom.allCommandsList)
+  for cmds in sortedCommandsList:
+    if gencom.isFunctionExported(cmds):
+      if gencom.isGloballyDispatched(cmds):
+        f.write (gencom.clang_off_spaces*2 + '{ \"' + cmds + '\", nullptr },\n')
+      elif isIntercepted(cmds) or cmds == 'vkGetInstanceProcAddr' or gencom.isDeviceDispatched(cmds):
+        f.write (gencom.clang_off_spaces*2 + '{ \"' + cmds + '\", reinterpret_cast<PFN_vkVoidFunction>(' + cmds[2:] + ') },\n')
+  f.write (gencom.clang_off_spaces + """};
+    // clang-format on
+    constexpr size_t count = sizeof(hooks) / sizeof(hooks[0]);
+    auto hook = std::lower_bound(
+        hooks, hooks + count, pName,
+        [](const Hook& h, const char* n) { return strcmp(h.name, n) < 0; });
+    if (hook < hooks + count && strcmp(hook->name, pName) == 0) {
+        if (!hook->proc) {
+            vulkan::driver::Logger(instance).Err(
+                instance, "invalid vkGetInstanceProcAddr(%p, \\\"%s\\\") call",
+                instance, pName);
+        }
+        return hook->proc;
+    }
+    // clang-format off\n\n""")
+
+def interceptDeviceProcAddr(functionName, f):
+  f.write (gencom.clang_off_spaces + """if (device == VK_NULL_HANDLE) {
+        ALOGE("invalid vkGetDeviceProcAddr(VK_NULL_HANDLE, ...) call");
+        return nullptr;
+    }\n\n""")
+  f.write (gencom.clang_off_spaces + 'static const char* const known_non_device_names[] = {\n')
+  sortedCommandsList = sorted(gencom.allCommandsList)
+  for cmds in sortedCommandsList:
+    if gencom.isFunctionSupported(cmds):
+      if not gencom.isDeviceDispatched(cmds):
+        f.write(gencom.clang_off_spaces*2 + '\"' + cmds + '\",\n')
+  f.write(gencom.clang_off_spaces + '};\n')
+  f.write(gencom.clang_off_spaces + """// clang-format on
+    constexpr size_t count =
+        sizeof(known_non_device_names) / sizeof(known_non_device_names[0]);
+    if (!pName ||
+        std::binary_search(
+            known_non_device_names, known_non_device_names + count, pName,
+            [](const char* a, const char* b) { return (strcmp(a, b) < 0); })) {
+        vulkan::driver::Logger(device).Err(
+            device, "invalid vkGetDeviceProcAddr(%p, \\\"%s\\\") call", device,
+            (pName) ? pName : "(null)");
+        return nullptr;
+    }
+    // clang-format off\n\n""")
+  for cmds in gencom.allCommandsList:
+    if gencom.isDeviceDispatched(cmds):
+      if isIntercepted(cmds) or cmds == 'vkGetDeviceProcAddr':
+        f.write (gencom.clang_off_spaces + 'if (strcmp(pName, "' + cmds + '") == 0) return reinterpret_cast<PFN_vkVoidFunction>(' + cmds[2:] + ');\n')
+  f.write ('\n')
+
+def apiDispatch(functionName, f):
+  assert not isIntercepted(functionName)
+
+  f.write (gencom.clang_off_spaces)
+  if gencom.returnTypeDict[functionName] != 'void':
+    f.write ('return ')
+
+  paramList = gencom.paramDict[functionName]
+  p0 = paramList[0][1]
+  f.write('GetData(' + p0 + ').dispatch.' + functionName[2:] + '(' + ', '.join(i[1] for i in paramList) + ');\n')
+
+
+def api_gencpp():
+  genfile = os.path.join(os.path.dirname(__file__),'..','libvulkan','api_gen2.cpp')
+  header = """#include <log/log.h>
+#include <string.h>
+
+#include <algorithm>
+
+// to catch mismatches between vulkan.h and this file
+#undef VK_NO_PROTOTYPES
+#include "api.h"
+
+namespace vulkan {
+namespace api {
+
+"""
+  with open(genfile, 'w') as f:
+    f.write (gencom.copyright)
+    f.write (gencom.warning)
+    f.write ("""#include <log/log.h>
+#include <string.h>
+
+#include <algorithm>
+
+// to catch mismatches between vulkan.h and this file
+#undef VK_NO_PROTOTYPES
+#include "api.h"
+
+namespace vulkan {
+namespace api {\n\n""")
+    defineInitProc('dispatch',f)
+    defineInitProcExt(f)
+    f.write ('namespace {\n\n')
+    gencom.clang_off(f,0)
+    f.write ('\n')
+    for cmds in gencom.allCommandsList:
+      defineExtensionStub(cmds,f)
+    gencom.clang_on(f,0)
+    f.write ('\n}  // namespace\n\n')
+    f.write ("""bool InitDispatchTable(
+    VkInstance instance,
+    PFN_vkGetInstanceProcAddr get_proc,
+    const std::bitset<driver::ProcHook::EXTENSION_COUNT>& extensions) {
+    auto& data = GetData(instance);
+    bool success = true;\n\n""")
+    gencom.clang_off(f,1)
+    for cmds in gencom.allCommandsList:
+      if gencom.isInstanceDispatchTableEntry(cmds):
+        gencom.initProc(cmds, f)
+    gencom.clang_on(f,1)
+    f.write ('\n')
+    f.write ('    return success;\n}\n\n')
+    f.write ("""bool InitDispatchTable(
+    VkDevice dev,
+    PFN_vkGetDeviceProcAddr get_proc,
+    const std::bitset<driver::ProcHook::EXTENSION_COUNT>& extensions) {
+    auto& data = GetData(dev);
+    bool success = true;\n\n""")
+
+    gencom.clang_off(f,1)
+    for cmds in gencom.allCommandsList:
+      if gencom.isDeviceDispatchTableEntry(cmds):
+        gencom.initProc(cmds, f)
+    gencom.clang_on(f,1)
+    f.write ('\n')
+    f.write ('    return success;\n}\n\n')
+
+    gencom.clang_off(f,0)
+
+    f.write ('\nnamespace {\n\n')
+    f.write('// forward declarations needed by GetInstanceProcAddr and GetDeviceProcAddr\n')
+    for cmds in gencom.allCommandsList:
+      if gencom.isFunctionExported(cmds) and not isIntercepted(cmds):
+        paramList = [''.join(i) for i in gencom.paramDict[cmds]]
+        f.write ('VKAPI_ATTR '+gencom.returnTypeDict[cmds] + ' ' + cmds[2:] + '(' + ', '.join(paramList) + ');\n')
+
+    f.write ('\n')
+
+    for cmds in gencom.allCommandsList:
+      if gencom.isFunctionExported(cmds) and not isIntercepted(cmds):
+        paramList = [''.join(i) for i in gencom.paramDict[cmds]]
+        f.write ('VKAPI_ATTR ' + gencom.returnTypeDict[cmds] + ' ' + cmds[2:] + '(' + ', '.join(paramList) + ') {\n')
+        if cmds == 'vkGetInstanceProcAddr':
+          interceptInstanceProcAddr(cmds, f)
+        elif cmds == 'vkGetDeviceProcAddr':
+          interceptDeviceProcAddr(cmds, f)
+        apiDispatch(cmds, f)
+        f.write('}\n\n')
+    f.write ("""\n}  // anonymous namespace
+
+// clang-format on
+
+}  // namespace api
+}  // namespace vulkan
+
+// clang-format off\n\n""")
+
+    for cmds in gencom.allCommandsList:
+      if gencom.isFunctionExported(cmds):
+        paramList = [''.join(i) for i in gencom.paramDict[cmds]]
+        f.write ('__attribute__((visibility("default")))\n')
+        f.write ('VKAPI_ATTR ' + gencom.returnTypeDict[cmds] + ' ' + cmds + '(' + ', '.join(paramList) + ') {\n')
+        f.write (gencom.clang_off_spaces)
+        if gencom.returnTypeDict[cmds] != 'void':
+          f.write ('return ')
+        paramList = gencom.paramDict[cmds]
+        f.write ('vulkan::api::' + cmds[2:] + '(' + ', '.join(i[1] for i in paramList) + ');\n')
+        f.write ('}\n\n')
+
+    gencom.clang_on(f, 0)
+
diff --git a/vulkan/scripts/code_generator.py b/vulkan/scripts/code_generator.py
new file mode 100644
index 0000000..91c0d30
--- /dev/null
+++ b/vulkan/scripts/code_generator.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# Copyright 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This script provides the main function for generating
+# vulkan framework directly from the vulkan registry (vk.xml).
+
+import generator_common as gencom
+import api_generator as apigen
+
+if __name__ == '__main__':
+  gencom.parseVulkanRegistry()
+  apigen.api_genh()
+  apigen.api_gencpp()
diff --git a/vulkan/scripts/generator_common.py b/vulkan/scripts/generator_common.py
new file mode 100644
index 0000000..313357d
--- /dev/null
+++ b/vulkan/scripts/generator_common.py
@@ -0,0 +1,238 @@
+#!/usr/bin/env python3
+#
+# Copyright 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This script provides the common functions for generating the
+# vulkan framework directly from the vulkan registry (vk.xml).
+
+copyright = """/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+"""
+
+warning = '// WARNING: This file is generated. See ../README.md for instructions.\n\n'
+
+blacklistedExtensions = [
+    'VK_KHR_display',
+    'VK_KHR_display_swapchain',
+    'VK_KHR_mir_surface',
+    'VK_KHR_xcb_surface',
+    'VK_KHR_xlib_surface',
+    'VK_KHR_wayland_surface',
+    'VK_KHR_win32_surface',
+    'VK_KHR_external_memory_win32',
+    'VK_KHR_win32_keyed_mutex',
+    'VK_KHR_external_semaphore_win32',
+    'VK_KHR_external_fence_win32',
+    'VK_EXT_acquire_xlib_display',
+    'VK_EXT_direct_mode_display',
+    'VK_EXT_display_surface_counter',
+    'VK_EXT_display_control',
+    'VK_FUCHSIA_imagepipe_surface',
+    'VK_MVK_ios_surface',
+    'VK_MVK_macos_surface',
+    'VK_NN_vi_surface',
+    'VK_NV_external_memory_win32',
+    'VK_NV_win32_keyed_mutex',
+    'VK_EXT_metal_surface', #not present in vulkan.api
+    'VK_NVX_image_view_handle', #not present in vulkan.api
+    'VK_NV_cooperative_matrix' #not present in vulkan.api
+]
+
+exportedExtensions = [
+    'VK_KHR_surface',
+    'VK_KHR_swapchain',
+    'VK_KHR_android_surface',
+    'VK_ANDROID_external_memory_android_hardware_buffer'
+]
+
+def isFunctionSupported(functionName):
+  if functionName not in extensionsDict:
+    return True
+  else:
+    if extensionsDict[functionName] not in blacklistedExtensions:
+      return True
+  return False
+
+def isInstanceDispatched(functionName):
+  return isFunctionSupported(functionName) and getDispatchTableType(functionName) == 'Instance'
+
+def isDeviceDispatched(functionName):
+  return isFunctionSupported(functionName) and getDispatchTableType(functionName) == 'Device'
+
+def isGloballyDispatched(functionName):
+  return isFunctionSupported(functionName) and getDispatchTableType(functionName) == 'Global'
+
+def isExtensionExported(extensionName):
+  if extensionName in exportedExtensions:
+    return True
+  return False
+
+def isFunctionExported(functionName):
+  if isFunctionSupported(functionName):
+    if functionName in extensionsDict:
+      return isExtensionExported(extensionsDict[functionName])
+    return True
+  return False
+
+def getDispatchTableType(functionName):
+  if functionName not in paramDict:
+    return None
+
+  switchCase = {
+      'VkInstance ' : 'Instance',
+      'VkPhysicalDevice ' : 'Instance',
+      'VkDevice ' : 'Device',
+      'VkQueue ' : 'Device',
+      'VkCommandBuffer ' : 'Device'
+  }
+
+  if len(paramDict[functionName])>0:
+    return switchCase.get(paramDict[functionName][0][0], 'Global')
+  return 'Global'
+
+def isInstanceDispatchTableEntry(functionName):
+  if functionName == 'vkEnumerateDeviceLayerProperties': # deprecated, unused internally - @dbd33bc
+    return False
+  if isFunctionExported(functionName) and isInstanceDispatched(functionName):
+    return True
+  return False
+
+def isDeviceDispatchTableEntry(functionName):
+  if isFunctionExported(functionName) and isDeviceDispatched(functionName):
+    return True
+  return False
+
+
+def clang_on(f, indent):
+  f.write (clang_off_spaces * indent + '// clang-format on\n')
+
+def clang_off(f, indent):
+  f.write (clang_off_spaces * indent + '// clang-format off\n')
+
+clang_off_spaces = ' '*4
+
+parametersList = []
+paramDict = {}
+allCommandsList = []
+extensionsDict = {}
+returnTypeDict = {}
+versionDict = {}
+aliasDict = {}
+
+def parseVulkanRegistry():
+  import xml.etree.ElementTree as ET
+  import os
+  vulkan_registry = os.path.join(os.path.dirname(__file__),'..','..','..','..','external','vulkan-headers','registry','vk.xml')
+  tree = ET.parse(vulkan_registry)
+  root = tree.getroot()
+  protoset = False
+  fnName = ""
+  fnType = ""
+  for commands in root.iter('commands'):
+    for command in commands:
+      if command.tag == 'command':
+        if protoset == True:
+          paramDict[fnName] = parametersList.copy()
+        parametersList.clear()
+        protoset = False
+        if command.get('alias') != None:
+          alias = command.get('alias')
+          fnName = command.get('name')
+          aliasDict[fnName] = alias
+          allCommandsList.append(fnName)
+          paramDict[fnName] = paramDict[alias].copy()
+        for params in command:
+          if(params.tag == 'param'):
+            paramtype = ""
+            if params.text!=None:
+              paramtype = params.text
+            typeval = params.find('type')
+            paramtype = paramtype + typeval.text
+            if typeval.tail!=None:
+              paramtype = paramtype + typeval.tail
+            pname = params.find('name')
+            paramname = pname.text
+            if pname.tail != None:
+              parametersList.append((paramtype,paramname,pname.tail))
+            else:
+              parametersList.append((paramtype,paramname))
+          if params.tag == 'proto':
+            for c in params:
+              if c.tag == 'type':
+                fnType = c.text
+              if c.tag == 'name':
+                fnName = c.text
+                protoset = True
+                allCommandsList.append(fnName)
+                returnTypeDict[fnName] = fnType
+
+  for exts in root.iter('extensions'):
+    for extension in exts:
+      apiversion = ""
+      if extension.tag == 'extension':
+        extname = extension.get('name')
+        for req in extension:
+          if req.get('feature')!=None:
+            apiversion = req.get('feature')
+          for commands in req:
+            if commands.tag == 'command':
+              commandname = commands.get('name')
+              if commandname not in extensionsDict:
+                extensionsDict[commandname] = extname
+                if apiversion != "":
+                  versionDict[commandname] = apiversion
+
+  for feature in root.iter('feature'):
+    apiversion = feature.get('name')
+    for req in feature:
+      for command in req:
+        if command.tag == 'command':
+          cmdName = command.get('name')
+          if cmdName in allCommandsList:
+            versionDict[cmdName] = apiversion
+
+
+def initProc(name, f):
+  if name in extensionsDict:
+    f.write ('    INIT_PROC_EXT(' + extensionsDict[name][3:] + ', ')
+  else:
+    f.write ('    INIT_PROC(')
+
+  if name in versionDict and versionDict[name] == 'VK_VERSION_1_1':
+    f.write('false, ')
+  else:
+    f.write('true, ')
+
+  if isInstanceDispatched(name):
+    f.write('instance, ')
+  else:
+    f.write('dev, ')
+
+  f.write(name[2:] + ');\n')
+