blob: 313357d288770acb99a385c206907879acb082c5 [file] [log] [blame]
Adithya Srinivasan751a7dc2019-07-02 17:17:25 -07001#!/usr/bin/env python3
2#
3# Copyright 2019 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17# This script provides the common functions for generating the
18# vulkan framework directly from the vulkan registry (vk.xml).
19
20copyright = """/*
21 * Copyright 2016 The Android Open Source Project
22 *
23 * Licensed under the Apache License, Version 2.0 (the "License");
24 * you may not use this file except in compliance with the License.
25 * You may obtain a copy of the License at
26 *
27 * http://www.apache.org/licenses/LICENSE-2.0
28 *
29 * Unless required by applicable law or agreed to in writing, software
30 * distributed under the License is distributed on an "AS IS" BASIS,
31 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32 * See the License for the specific language governing permissions and
33 * limitations under the License.
34 */
35
36"""
37
38warning = '// WARNING: This file is generated. See ../README.md for instructions.\n\n'
39
40blacklistedExtensions = [
41 'VK_KHR_display',
42 'VK_KHR_display_swapchain',
43 'VK_KHR_mir_surface',
44 'VK_KHR_xcb_surface',
45 'VK_KHR_xlib_surface',
46 'VK_KHR_wayland_surface',
47 'VK_KHR_win32_surface',
48 'VK_KHR_external_memory_win32',
49 'VK_KHR_win32_keyed_mutex',
50 'VK_KHR_external_semaphore_win32',
51 'VK_KHR_external_fence_win32',
52 'VK_EXT_acquire_xlib_display',
53 'VK_EXT_direct_mode_display',
54 'VK_EXT_display_surface_counter',
55 'VK_EXT_display_control',
56 'VK_FUCHSIA_imagepipe_surface',
57 'VK_MVK_ios_surface',
58 'VK_MVK_macos_surface',
59 'VK_NN_vi_surface',
60 'VK_NV_external_memory_win32',
61 'VK_NV_win32_keyed_mutex',
62 'VK_EXT_metal_surface', #not present in vulkan.api
63 'VK_NVX_image_view_handle', #not present in vulkan.api
64 'VK_NV_cooperative_matrix' #not present in vulkan.api
65]
66
67exportedExtensions = [
68 'VK_KHR_surface',
69 'VK_KHR_swapchain',
70 'VK_KHR_android_surface',
71 'VK_ANDROID_external_memory_android_hardware_buffer'
72]
73
74def isFunctionSupported(functionName):
75 if functionName not in extensionsDict:
76 return True
77 else:
78 if extensionsDict[functionName] not in blacklistedExtensions:
79 return True
80 return False
81
82def isInstanceDispatched(functionName):
83 return isFunctionSupported(functionName) and getDispatchTableType(functionName) == 'Instance'
84
85def isDeviceDispatched(functionName):
86 return isFunctionSupported(functionName) and getDispatchTableType(functionName) == 'Device'
87
88def isGloballyDispatched(functionName):
89 return isFunctionSupported(functionName) and getDispatchTableType(functionName) == 'Global'
90
91def isExtensionExported(extensionName):
92 if extensionName in exportedExtensions:
93 return True
94 return False
95
96def isFunctionExported(functionName):
97 if isFunctionSupported(functionName):
98 if functionName in extensionsDict:
99 return isExtensionExported(extensionsDict[functionName])
100 return True
101 return False
102
103def getDispatchTableType(functionName):
104 if functionName not in paramDict:
105 return None
106
107 switchCase = {
108 'VkInstance ' : 'Instance',
109 'VkPhysicalDevice ' : 'Instance',
110 'VkDevice ' : 'Device',
111 'VkQueue ' : 'Device',
112 'VkCommandBuffer ' : 'Device'
113 }
114
115 if len(paramDict[functionName])>0:
116 return switchCase.get(paramDict[functionName][0][0], 'Global')
117 return 'Global'
118
119def isInstanceDispatchTableEntry(functionName):
120 if functionName == 'vkEnumerateDeviceLayerProperties': # deprecated, unused internally - @dbd33bc
121 return False
122 if isFunctionExported(functionName) and isInstanceDispatched(functionName):
123 return True
124 return False
125
126def isDeviceDispatchTableEntry(functionName):
127 if isFunctionExported(functionName) and isDeviceDispatched(functionName):
128 return True
129 return False
130
131
132def clang_on(f, indent):
133 f.write (clang_off_spaces * indent + '// clang-format on\n')
134
135def clang_off(f, indent):
136 f.write (clang_off_spaces * indent + '// clang-format off\n')
137
138clang_off_spaces = ' '*4
139
140parametersList = []
141paramDict = {}
142allCommandsList = []
143extensionsDict = {}
144returnTypeDict = {}
145versionDict = {}
146aliasDict = {}
147
148def parseVulkanRegistry():
149 import xml.etree.ElementTree as ET
150 import os
151 vulkan_registry = os.path.join(os.path.dirname(__file__),'..','..','..','..','external','vulkan-headers','registry','vk.xml')
152 tree = ET.parse(vulkan_registry)
153 root = tree.getroot()
154 protoset = False
155 fnName = ""
156 fnType = ""
157 for commands in root.iter('commands'):
158 for command in commands:
159 if command.tag == 'command':
160 if protoset == True:
161 paramDict[fnName] = parametersList.copy()
162 parametersList.clear()
163 protoset = False
164 if command.get('alias') != None:
165 alias = command.get('alias')
166 fnName = command.get('name')
167 aliasDict[fnName] = alias
168 allCommandsList.append(fnName)
169 paramDict[fnName] = paramDict[alias].copy()
170 for params in command:
171 if(params.tag == 'param'):
172 paramtype = ""
173 if params.text!=None:
174 paramtype = params.text
175 typeval = params.find('type')
176 paramtype = paramtype + typeval.text
177 if typeval.tail!=None:
178 paramtype = paramtype + typeval.tail
179 pname = params.find('name')
180 paramname = pname.text
181 if pname.tail != None:
182 parametersList.append((paramtype,paramname,pname.tail))
183 else:
184 parametersList.append((paramtype,paramname))
185 if params.tag == 'proto':
186 for c in params:
187 if c.tag == 'type':
188 fnType = c.text
189 if c.tag == 'name':
190 fnName = c.text
191 protoset = True
192 allCommandsList.append(fnName)
193 returnTypeDict[fnName] = fnType
194
195 for exts in root.iter('extensions'):
196 for extension in exts:
197 apiversion = ""
198 if extension.tag == 'extension':
199 extname = extension.get('name')
200 for req in extension:
201 if req.get('feature')!=None:
202 apiversion = req.get('feature')
203 for commands in req:
204 if commands.tag == 'command':
205 commandname = commands.get('name')
206 if commandname not in extensionsDict:
207 extensionsDict[commandname] = extname
208 if apiversion != "":
209 versionDict[commandname] = apiversion
210
211 for feature in root.iter('feature'):
212 apiversion = feature.get('name')
213 for req in feature:
214 for command in req:
215 if command.tag == 'command':
216 cmdName = command.get('name')
217 if cmdName in allCommandsList:
218 versionDict[cmdName] = apiversion
219
220
221def initProc(name, f):
222 if name in extensionsDict:
223 f.write (' INIT_PROC_EXT(' + extensionsDict[name][3:] + ', ')
224 else:
225 f.write (' INIT_PROC(')
226
227 if name in versionDict and versionDict[name] == 'VK_VERSION_1_1':
228 f.write('false, ')
229 else:
230 f.write('true, ')
231
232 if isInstanceDispatched(name):
233 f.write('instance, ')
234 else:
235 f.write('dev, ')
236
237 f.write(name[2:] + ');\n')
238