15db71995Sopenharmony_ci#!/usr/bin/python3 -i 25db71995Sopenharmony_ci# 35db71995Sopenharmony_ci# Copyright (c) 2015-2021 The Khronos Group Inc. 45db71995Sopenharmony_ci# Copyright (c) 2015-2021 Valve Corporation 55db71995Sopenharmony_ci# Copyright (c) 2015-2021 LunarG, Inc. 65db71995Sopenharmony_ci# Copyright (c) 2015-2021 Google Inc. 75db71995Sopenharmony_ci# 85db71995Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 95db71995Sopenharmony_ci# you may not use this file except in compliance with the License. 105db71995Sopenharmony_ci# You may obtain a copy of the License at 115db71995Sopenharmony_ci# 125db71995Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 135db71995Sopenharmony_ci# 145db71995Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 155db71995Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 165db71995Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 175db71995Sopenharmony_ci# See the License for the specific language governing permissions and 185db71995Sopenharmony_ci# limitations under the License. 195db71995Sopenharmony_ci# 205db71995Sopenharmony_ci# Author: Mark Lobodzinski <mark@lunarg.com> 215db71995Sopenharmony_ci 225db71995Sopenharmony_ciimport os,re,sys 235db71995Sopenharmony_ciimport xml.etree.ElementTree as etree 245db71995Sopenharmony_cifrom generator import * 255db71995Sopenharmony_cifrom collections import namedtuple 265db71995Sopenharmony_cifrom common_codegen import * 275db71995Sopenharmony_ci 285db71995Sopenharmony_cireturn_type_table = {"VkResult": "VK_SUCCESS", 295db71995Sopenharmony_ci "uint32_t": "0", 305db71995Sopenharmony_ci "uint64_t": "0L", 315db71995Sopenharmony_ci "VkDeviceAddress": "0L", 325db71995Sopenharmony_ci "VkDeviceSize": "0L"} 335db71995Sopenharmony_ci 345db71995Sopenharmony_ci# 355db71995Sopenharmony_ci# DispatchTableHelperOutputGeneratorOptions - subclass of GeneratorOptions. 365db71995Sopenharmony_ciclass DispatchTableHelperOutputGeneratorOptions(GeneratorOptions): 375db71995Sopenharmony_ci def __init__(self, 385db71995Sopenharmony_ci conventions = None, 395db71995Sopenharmony_ci filename = None, 405db71995Sopenharmony_ci directory = '.', 415db71995Sopenharmony_ci genpath = None, 425db71995Sopenharmony_ci apiname = None, 435db71995Sopenharmony_ci profile = None, 445db71995Sopenharmony_ci versions = '.*', 455db71995Sopenharmony_ci emitversions = '.*', 465db71995Sopenharmony_ci defaultExtensions = None, 475db71995Sopenharmony_ci addExtensions = None, 485db71995Sopenharmony_ci removeExtensions = None, 495db71995Sopenharmony_ci emitExtensions = None, 505db71995Sopenharmony_ci sortProcedure = regSortFeatures, 515db71995Sopenharmony_ci prefixText = "", 525db71995Sopenharmony_ci genFuncPointers = True, 535db71995Sopenharmony_ci apicall = '', 545db71995Sopenharmony_ci apientry = '', 555db71995Sopenharmony_ci apientryp = '', 565db71995Sopenharmony_ci alignFuncParam = 0, 575db71995Sopenharmony_ci expandEnumerants = True): 585db71995Sopenharmony_ci GeneratorOptions.__init__(self, 595db71995Sopenharmony_ci conventions = conventions, 605db71995Sopenharmony_ci filename = filename, 615db71995Sopenharmony_ci directory = directory, 625db71995Sopenharmony_ci genpath = genpath, 635db71995Sopenharmony_ci apiname = apiname, 645db71995Sopenharmony_ci profile = profile, 655db71995Sopenharmony_ci versions = versions, 665db71995Sopenharmony_ci emitversions = emitversions, 675db71995Sopenharmony_ci defaultExtensions = defaultExtensions, 685db71995Sopenharmony_ci addExtensions = addExtensions, 695db71995Sopenharmony_ci removeExtensions = removeExtensions, 705db71995Sopenharmony_ci emitExtensions = emitExtensions, 715db71995Sopenharmony_ci sortProcedure = sortProcedure) 725db71995Sopenharmony_ci self.prefixText = prefixText 735db71995Sopenharmony_ci self.genFuncPointers = genFuncPointers 745db71995Sopenharmony_ci self.prefixText = None 755db71995Sopenharmony_ci self.apicall = apicall 765db71995Sopenharmony_ci self.apientry = apientry 775db71995Sopenharmony_ci self.apientryp = apientryp 785db71995Sopenharmony_ci self.alignFuncParam = alignFuncParam 795db71995Sopenharmony_ci# 805db71995Sopenharmony_ci# DispatchTableHelperOutputGenerator - subclass of OutputGenerator. 815db71995Sopenharmony_ci# Generates dispatch table helper header files for LVL 825db71995Sopenharmony_ciclass DispatchTableHelperOutputGenerator(OutputGenerator): 835db71995Sopenharmony_ci """Generate dispatch table helper header based on XML element attributes""" 845db71995Sopenharmony_ci def __init__(self, 855db71995Sopenharmony_ci errFile = sys.stderr, 865db71995Sopenharmony_ci warnFile = sys.stderr, 875db71995Sopenharmony_ci diagFile = sys.stdout): 885db71995Sopenharmony_ci OutputGenerator.__init__(self, errFile, warnFile, diagFile) 895db71995Sopenharmony_ci # Internal state - accumulators for different inner block text 905db71995Sopenharmony_ci self.instance_dispatch_list = [] # List of entries for instance dispatch list 915db71995Sopenharmony_ci self.device_dispatch_list = [] # List of entries for device dispatch list 925db71995Sopenharmony_ci self.dev_ext_stub_list = [] # List of stub functions for device extension functions 935db71995Sopenharmony_ci self.device_extension_list = [] # List of device extension functions 945db71995Sopenharmony_ci self.extension_type = '' 955db71995Sopenharmony_ci # 965db71995Sopenharmony_ci # Called once at the beginning of each run 975db71995Sopenharmony_ci def beginFile(self, genOpts): 985db71995Sopenharmony_ci OutputGenerator.beginFile(self, genOpts) 995db71995Sopenharmony_ci write("#pragma once", file=self.outFile) 1005db71995Sopenharmony_ci # User-supplied prefix text, if any (list of strings) 1015db71995Sopenharmony_ci if (genOpts.prefixText): 1025db71995Sopenharmony_ci for s in genOpts.prefixText: 1035db71995Sopenharmony_ci write(s, file=self.outFile) 1045db71995Sopenharmony_ci # File Comment 1055db71995Sopenharmony_ci file_comment = '// *** THIS FILE IS GENERATED - DO NOT EDIT ***\n' 1065db71995Sopenharmony_ci file_comment += '// See dispatch_table_helper_generator.py for modifications\n' 1075db71995Sopenharmony_ci write(file_comment, file=self.outFile) 1085db71995Sopenharmony_ci # Copyright Notice 1095db71995Sopenharmony_ci copyright = '/*\n' 1105db71995Sopenharmony_ci copyright += ' * Copyright (c) 2015-2021 The Khronos Group Inc.\n' 1115db71995Sopenharmony_ci copyright += ' * Copyright (c) 2015-2021 Valve Corporation\n' 1125db71995Sopenharmony_ci copyright += ' * Copyright (c) 2015-2021 LunarG, Inc.\n' 1135db71995Sopenharmony_ci copyright += ' *\n' 1145db71995Sopenharmony_ci copyright += ' * Licensed under the Apache License, Version 2.0 (the "License");\n' 1155db71995Sopenharmony_ci copyright += ' * you may not use this file except in compliance with the License.\n' 1165db71995Sopenharmony_ci copyright += ' * You may obtain a copy of the License at\n' 1175db71995Sopenharmony_ci copyright += ' *\n' 1185db71995Sopenharmony_ci copyright += ' * http://www.apache.org/licenses/LICENSE-2.0\n' 1195db71995Sopenharmony_ci copyright += ' *\n' 1205db71995Sopenharmony_ci copyright += ' * Unless required by applicable law or agreed to in writing, software\n' 1215db71995Sopenharmony_ci copyright += ' * distributed under the License is distributed on an "AS IS" BASIS,\n' 1225db71995Sopenharmony_ci copyright += ' * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n' 1235db71995Sopenharmony_ci copyright += ' * See the License for the specific language governing permissions and\n' 1245db71995Sopenharmony_ci copyright += ' * limitations under the License.\n' 1255db71995Sopenharmony_ci copyright += ' *\n' 1265db71995Sopenharmony_ci copyright += ' * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>\n' 1275db71995Sopenharmony_ci copyright += ' * Author: Jon Ashburn <jon@lunarg.com>\n' 1285db71995Sopenharmony_ci copyright += ' * Author: Mark Lobodzinski <mark@lunarg.com>\n' 1295db71995Sopenharmony_ci copyright += ' */\n' 1305db71995Sopenharmony_ci 1315db71995Sopenharmony_ci preamble = '' 1325db71995Sopenharmony_ci preamble += '#include <vulkan/vulkan.h>\n' 1335db71995Sopenharmony_ci preamble += '#include <vulkan/vk_layer.h>\n' 1345db71995Sopenharmony_ci preamble += '#include <string.h>\n' 1355db71995Sopenharmony_ci preamble += '#include "loader/generated/vk_layer_dispatch_table.h"\n' 1365db71995Sopenharmony_ci 1375db71995Sopenharmony_ci write(copyright, file=self.outFile) 1385db71995Sopenharmony_ci write(preamble, file=self.outFile) 1395db71995Sopenharmony_ci # 1405db71995Sopenharmony_ci # Write generate and write dispatch tables to output file 1415db71995Sopenharmony_ci def endFile(self): 1425db71995Sopenharmony_ci device_table = '' 1435db71995Sopenharmony_ci instance_table = '' 1445db71995Sopenharmony_ci 1455db71995Sopenharmony_ci device_table += self.OutputDispatchTableHelper('device') 1465db71995Sopenharmony_ci instance_table += self.OutputDispatchTableHelper('instance') 1475db71995Sopenharmony_ci 1485db71995Sopenharmony_ci for stub in self.dev_ext_stub_list: 1495db71995Sopenharmony_ci write(stub, file=self.outFile) 1505db71995Sopenharmony_ci write("\n\n", file=self.outFile) 1515db71995Sopenharmony_ci write(device_table, file=self.outFile); 1525db71995Sopenharmony_ci write("\n", file=self.outFile) 1535db71995Sopenharmony_ci write(instance_table, file=self.outFile); 1545db71995Sopenharmony_ci 1555db71995Sopenharmony_ci # Finish processing in superclass 1565db71995Sopenharmony_ci OutputGenerator.endFile(self) 1575db71995Sopenharmony_ci # 1585db71995Sopenharmony_ci # Processing at beginning of each feature or extension 1595db71995Sopenharmony_ci def beginFeature(self, interface, emit): 1605db71995Sopenharmony_ci OutputGenerator.beginFeature(self, interface, emit) 1615db71995Sopenharmony_ci self.featureExtraProtect = GetFeatureProtect(interface) 1625db71995Sopenharmony_ci self.extension_type = interface.get('type') 1635db71995Sopenharmony_ci 1645db71995Sopenharmony_ci # 1655db71995Sopenharmony_ci # Process commands, adding to appropriate dispatch tables 1665db71995Sopenharmony_ci def genCmd(self, cmdinfo, name, alias): 1675db71995Sopenharmony_ci OutputGenerator.genCmd(self, cmdinfo, name, alias) 1685db71995Sopenharmony_ci 1695db71995Sopenharmony_ci avoid_entries = ['vkCreateInstance', 1705db71995Sopenharmony_ci 'vkCreateDevice'] 1715db71995Sopenharmony_ci # Get first param type 1725db71995Sopenharmony_ci params = cmdinfo.elem.findall('param') 1735db71995Sopenharmony_ci info = self.getTypeNameTuple(params[0]) 1745db71995Sopenharmony_ci 1755db71995Sopenharmony_ci if name not in avoid_entries: 1765db71995Sopenharmony_ci self.AddCommandToDispatchList(name, info[0], self.featureExtraProtect, cmdinfo) 1775db71995Sopenharmony_ci 1785db71995Sopenharmony_ci # 1795db71995Sopenharmony_ci # Determine if this API should be ignored or added to the instance or device dispatch table 1805db71995Sopenharmony_ci def AddCommandToDispatchList(self, name, handle_type, protect, cmdinfo): 1815db71995Sopenharmony_ci handle = self.registry.tree.find("types/type/[name='" + handle_type + "'][@category='handle']") 1825db71995Sopenharmony_ci if handle is None: 1835db71995Sopenharmony_ci return 1845db71995Sopenharmony_ci if handle_type != 'VkInstance' and handle_type != 'VkPhysicalDevice' and name != 'vkGetInstanceProcAddr': 1855db71995Sopenharmony_ci self.device_dispatch_list.append((name, self.featureExtraProtect)) 1865db71995Sopenharmony_ci else: 1875db71995Sopenharmony_ci self.instance_dispatch_list.append((name, self.featureExtraProtect)) 1885db71995Sopenharmony_ci return 1895db71995Sopenharmony_ci # 1905db71995Sopenharmony_ci # Retrieve the type and name for a parameter 1915db71995Sopenharmony_ci def getTypeNameTuple(self, param): 1925db71995Sopenharmony_ci type = '' 1935db71995Sopenharmony_ci name = '' 1945db71995Sopenharmony_ci for elem in param: 1955db71995Sopenharmony_ci if elem.tag == 'type': 1965db71995Sopenharmony_ci type = noneStr(elem.text) 1975db71995Sopenharmony_ci elif elem.tag == 'name': 1985db71995Sopenharmony_ci name = noneStr(elem.text) 1995db71995Sopenharmony_ci return (type, name) 2005db71995Sopenharmony_ci # 2015db71995Sopenharmony_ci # Create a dispatch table from the appropriate list and return it as a string 2025db71995Sopenharmony_ci def OutputDispatchTableHelper(self, table_type): 2035db71995Sopenharmony_ci entries = [] 2045db71995Sopenharmony_ci table = '' 2055db71995Sopenharmony_ci if table_type == 'device': 2065db71995Sopenharmony_ci entries = self.device_dispatch_list 2075db71995Sopenharmony_ci table += 'static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDispatchTable *table, PFN_vkGetDeviceProcAddr gpa) {\n' 2085db71995Sopenharmony_ci table += ' memset(table, 0, sizeof(*table));\n' 2095db71995Sopenharmony_ci table += ' table->magic = DEVICE_DISP_TABLE_MAGIC_NUMBER;\n\n' 2105db71995Sopenharmony_ci table += ' // Device function pointers\n' 2115db71995Sopenharmony_ci else: 2125db71995Sopenharmony_ci entries = self.instance_dispatch_list 2135db71995Sopenharmony_ci table += 'static inline void layer_init_instance_dispatch_table(VkInstance instance, VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa) {\n' 2145db71995Sopenharmony_ci table += ' memset(table, 0, sizeof(*table));\n\n' 2155db71995Sopenharmony_ci table += ' // Instance function pointers\n' 2165db71995Sopenharmony_ci 2175db71995Sopenharmony_ci for item in entries: 2185db71995Sopenharmony_ci # Remove 'vk' from proto name 2195db71995Sopenharmony_ci base_name = item[0][2:] 2205db71995Sopenharmony_ci 2215db71995Sopenharmony_ci if item[1] is not None: 2225db71995Sopenharmony_ci table += '#if defined(%s)\n' % item[1] 2235db71995Sopenharmony_ci 2245db71995Sopenharmony_ci # If we're looking for the proc we are passing in, just point the table to it. This fixes the issue where 2255db71995Sopenharmony_ci # a layer overrides the function name for the loader. 2265db71995Sopenharmony_ci if (table_type == 'device' and base_name == 'GetDeviceProcAddr'): 2275db71995Sopenharmony_ci table += ' table->GetDeviceProcAddr = gpa;\n' 2285db71995Sopenharmony_ci elif (table_type != 'device' and base_name == 'GetInstanceProcAddr'): 2295db71995Sopenharmony_ci table += ' table->GetInstanceProcAddr = gpa;\n' 2305db71995Sopenharmony_ci else: 2315db71995Sopenharmony_ci table += ' table->%s = (PFN_%s) gpa(%s, "%s");\n' % (base_name, item[0], table_type, item[0]) 2325db71995Sopenharmony_ci if item[1] is not None: 2335db71995Sopenharmony_ci table += '#endif // %s\n' % item[1] 2345db71995Sopenharmony_ci 2355db71995Sopenharmony_ci table += '}' 2365db71995Sopenharmony_ci return table 237