blob: b95ffd7130a0b49efd750256b008a169e24f1f45 [file] [log] [blame]
Mark Lobodzinski92f22f32016-12-06 11:14:50 -07001#!/usr/bin/python3 -i
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: Mark Lobodzinski <mark@lunarg.com>
21
22import os,re,sys
23import xml.etree.ElementTree as etree
24from generator import *
25from collections import namedtuple
26
27#
28# DispatchTableOutputGeneratorOptions - subclass of GeneratorOptions.
29class DispatchTableOutputGeneratorOptions(GeneratorOptions):
30 def __init__(self,
31 filename = None,
32 directory = '.',
33 apiname = None,
34 profile = None,
35 versions = '.*',
36 emitversions = '.*',
37 defaultExtensions = None,
38 addExtensions = None,
39 removeExtensions = None,
40 sortProcedure = regSortFeatures,
41 prefixText = "",
42 genFuncPointers = True,
43 protectFile = True,
44 protectFeature = True,
45 protectProto = None,
46 protectProtoStr = None,
47 apicall = '',
48 apientry = '',
49 apientryp = '',
50 alignFuncParam = 0):
51 GeneratorOptions.__init__(self, filename, directory, apiname, profile,
52 versions, emitversions, defaultExtensions,
53 addExtensions, removeExtensions, sortProcedure)
54 self.prefixText = prefixText
55 self.genFuncPointers = genFuncPointers
56 self.prefixText = None
57 self.protectFile = protectFile
58 self.protectFeature = protectFeature
59 self.protectProto = protectProto
60 self.protectProtoStr = protectProtoStr
61 self.apicall = apicall
62 self.apientry = apientry
63 self.apientryp = apientryp
64 self.alignFuncParam = alignFuncParam
65#
66# DispatchTableOutputGenerator - subclass of OutputGenerator.
67# Generates dispatch table helper header files for LVL
68class DispatchTableOutputGenerator(OutputGenerator):
69 """Generate dispatch table helper header based on XML element attributes"""
70 def __init__(self,
71 errFile = sys.stderr,
72 warnFile = sys.stderr,
73 diagFile = sys.stdout):
74 OutputGenerator.__init__(self, errFile, warnFile, diagFile)
75 # Internal state - accumulators for different inner block text
76 self.instance_dispatch_list = [] # List of entries for instance dispatch list
77 self.device_dispatch_list = [] # List of entries for device dispatch list
78 #
79 # Called once at the beginning of each run
80 def beginFile(self, genOpts):
81 OutputGenerator.beginFile(self, genOpts)
82 # User-supplied prefix text, if any (list of strings)
83 if (genOpts.prefixText):
84 for s in genOpts.prefixText:
85 write(s, file=self.outFile)
86 # File Comment
87 file_comment = '// *** THIS FILE IS GENERATED - DO NOT EDIT ***\n'
88 file_comment += '// See dispatch_table_generator.py for modifications\n'
89 write(file_comment, file=self.outFile)
90 # Copyright Notice
91 copyright = '/*\n'
92 copyright += ' * Copyright (c) 2015-2016 The Khronos Group Inc.\n'
93 copyright += ' * Copyright (c) 2015-2016 Valve Corporation\n'
94 copyright += ' * Copyright (c) 2015-2016 LunarG, Inc.\n'
95 copyright += ' *\n'
96 copyright += ' * Licensed under the Apache License, Version 2.0 (the "License");\n'
97 copyright += ' * you may not use this file except in compliance with the License.\n'
98 copyright += ' * You may obtain a copy of the License at\n'
99 copyright += ' *\n'
100 copyright += ' * http://www.apache.org/licenses/LICENSE-2.0\n'
101 copyright += ' *\n'
102 copyright += ' * Unless required by applicable law or agreed to in writing, software\n'
103 copyright += ' * distributed under the License is distributed on an "AS IS" BASIS,\n'
104 copyright += ' * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n'
105 copyright += ' * See the License for the specific language governing permissions and\n'
106 copyright += ' * limitations under the License.\n'
107 copyright += ' *\n'
108 copyright += ' * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>\n'
109 copyright += ' * Author: Jon Ashburn <jon@lunarg.com>\n'
110 copyright += ' * Author: Mark Lobodzinski <mark@lunarg.com>\n'
111 copyright += ' */\n'
112
113 preamble = ''
114 preamble += '#include <vulkan/vulkan.h>\n'
115 preamble += '#include <vulkan/vk_layer.h>\n'
116 preamble += '#include <string.h>\n'
117
118 write(copyright, file=self.outFile)
119 write(preamble, file=self.outFile)
120 #
121 # Write generate and write dispatch tables to output file
122 def endFile(self):
123 device_table = ''
124 instance_table = ''
125
126 device_table += self.OutputDispatchTable('device')
127 instance_table += self.OutputDispatchTable('instance')
128
129 write(device_table, file=self.outFile);
130 write(instance_table, file=self.outFile);
131
132 # Finish processing in superclass
133 OutputGenerator.endFile(self)
134 #
135 # Process commands, adding to appropriate dispatch tables
136 def genCmd(self, cmdinfo, name):
137 OutputGenerator.genCmd(self, cmdinfo, name)
138
139 avoid_entries = ['vkCreateInstance',
140 'vkCreateDevice']
141 # Get first param type
142 params = cmdinfo.elem.findall('param')
143 info = self.getTypeNameTuple(params[0])
144
145 if name not in avoid_entries:
146 self.AddCommandToDispatchList(name, info[0], self.featureExtraProtect)
147
148 #
149 # Determine if this API should be ignored or added to the instance or device dispatch table
150 def AddCommandToDispatchList(self, name, handle_type, protect):
151 handle = self.registry.tree.find("types/type/[name='" + handle_type + "'][@category='handle']")
152 if handle == None:
153 return
154 if handle_type != 'VkInstance' and handle_type != 'VkPhysicalDevice' and name != 'vkGetInstanceProcAddr':
155 self.device_dispatch_list.append((name, self.featureExtraProtect))
156 else:
157 self.instance_dispatch_list.append((name, self.featureExtraProtect))
158 return
159 #
160 # Retrieve the type and name for a parameter
161 def getTypeNameTuple(self, param):
162 type = ''
163 name = ''
164 for elem in param:
165 if elem.tag == 'type':
166 type = noneStr(elem.text)
167 elif elem.tag == 'name':
168 name = noneStr(elem.text)
169 return (type, name)
170 #
171 # Create a dispatch table from the appropriate list and return it as a string
172 def OutputDispatchTable(self, table_type):
173 entries = []
174 table = ''
175 if table_type == 'device':
176 entries = self.device_dispatch_list
177 table += 'static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDispatchTable *table, PFN_vkGetDeviceProcAddr gpa) {\n'
178 table += ' memset(table, 0, sizeof(*table));\n'
179 table += ' // Device function pointers\n'
180 else:
181 entries = self.instance_dispatch_list
182 table += 'static inline void layer_init_instance_dispatch_table(VkInstance instance, VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa) {\n'
183 table += ' memset(table, 0, sizeof(*table));\n'
184 table += ' // Instance function pointers\n'
185
186 for item in entries:
187 # Remove 'vk' from proto name
188 base_name = item[0][2:]
189
190 if item[1] is not None:
191 table += '#ifdef %s\n' % item[1]
192 table += ' table->%s = (PFN_%s) gpa(%s, "%s");\n' % (base_name, item[0], table_type, item[0])
193 if item[1] is not None:
194 table += '#endif // %s\n' % item[1]
195 table += '}\n\n'
196 return table