mirror of
https://github.com/openharmony/third_party_vulkan-loader.git
synced 2026-07-20 20:15:56 -04:00
035140a542
Validate the Vulkan dispatchable handles (VkInstance, VkPhysicalDevice, etc) for any trampoline functions the loader uses to query the dispatch table from. This is so we can at least report errors before something bad happens. Also, add tests to the test framework to catch this case. Right now they simply check to make sure we aborted, but they don't know why the loader aborted. Eventually, we need to come back and check the loader messages and make sure it aborted for the reasons we want. Fix a generator warning in dispatch_table_helper_generator.py where a compare was the wrong type. Fixes GH Issue #64.
501 lines
26 KiB
Python
501 lines
26 KiB
Python
#!/usr/bin/python3 -i
|
|
#
|
|
# Copyright (c) 2015-2017 The Khronos Group Inc.
|
|
# Copyright (c) 2015-2017 Valve Corporation
|
|
# Copyright (c) 2015-2017 LunarG, Inc.
|
|
# Copyright (c) 2015-2017 Google Inc.
|
|
#
|
|
# 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.
|
|
#
|
|
# Author: Mark Lobodzinski <mark@lunarg.com>
|
|
# Author: Tobin Ehlis <tobine@google.com>
|
|
# Author: John Zulauf <jzulauf@lunarg.com>
|
|
|
|
import os,re,sys
|
|
import xml.etree.ElementTree as etree
|
|
from generator import *
|
|
from collections import namedtuple
|
|
from common_codegen import *
|
|
|
|
#
|
|
# HelperFileOutputGeneratorOptions - subclass of GeneratorOptions.
|
|
class HelperFileOutputGeneratorOptions(GeneratorOptions):
|
|
def __init__(self,
|
|
conventions = None,
|
|
filename = None,
|
|
directory = '.',
|
|
genpath = None,
|
|
apiname = None,
|
|
profile = None,
|
|
versions = '.*',
|
|
emitversions = '.*',
|
|
defaultExtensions = None,
|
|
addExtensions = None,
|
|
removeExtensions = None,
|
|
emitExtensions = None,
|
|
sortProcedure = regSortFeatures,
|
|
prefixText = "",
|
|
genFuncPointers = True,
|
|
protectFile = True,
|
|
protectFeature = True,
|
|
apicall = '',
|
|
apientry = '',
|
|
apientryp = '',
|
|
alignFuncParam = 0,
|
|
library_name = '',
|
|
expandEnumerants = True,
|
|
helper_file_type = ''):
|
|
GeneratorOptions.__init__(self,
|
|
conventions = conventions,
|
|
filename = filename,
|
|
directory = directory,
|
|
genpath = genpath,
|
|
apiname = apiname,
|
|
profile = profile,
|
|
versions = versions,
|
|
emitversions = emitversions,
|
|
defaultExtensions = defaultExtensions,
|
|
addExtensions = addExtensions,
|
|
removeExtensions = removeExtensions,
|
|
emitExtensions = emitExtensions,
|
|
sortProcedure = sortProcedure)
|
|
self.prefixText = prefixText
|
|
self.genFuncPointers = genFuncPointers
|
|
self.protectFile = protectFile
|
|
self.protectFeature = protectFeature
|
|
self.apicall = apicall
|
|
self.apientry = apientry
|
|
self.apientryp = apientryp
|
|
self.alignFuncParam = alignFuncParam
|
|
self.library_name = library_name
|
|
self.helper_file_type = helper_file_type
|
|
#
|
|
# HelperFileOutputGenerator - subclass of OutputGenerator. Outputs Vulkan helper files
|
|
class HelperFileOutputGenerator(OutputGenerator):
|
|
"""Generate helper file based on XML element attributes"""
|
|
def __init__(self,
|
|
errFile = sys.stderr,
|
|
warnFile = sys.stderr,
|
|
diagFile = sys.stdout):
|
|
OutputGenerator.__init__(self, errFile, warnFile, diagFile)
|
|
# Internal state - accumulators for different inner block text
|
|
self.enum_output = '' # string built up of enum string routines
|
|
# Internal state - accumulators for different inner block text
|
|
self.structNames = [] # List of Vulkan struct typenames
|
|
self.structTypes = dict() # Map of Vulkan struct typename to required VkStructureType
|
|
self.structMembers = [] # List of StructMemberData records for all Vulkan structs
|
|
self.object_types = [] # List of all handle types
|
|
self.object_type_aliases = [] # Aliases to handles types (for handles that were extensions)
|
|
self.debug_report_object_types = [] # Handy copy of debug_report_object_type enum data
|
|
self.core_object_types = [] # Handy copy of core_object_type enum data
|
|
self.device_extension_info = dict() # Dict of device extension name defines and ifdef values
|
|
self.instance_extension_info = dict() # Dict of instance extension name defines and ifdef values
|
|
|
|
# Named tuples to store struct and command data
|
|
self.StructType = namedtuple('StructType', ['name', 'value'])
|
|
self.CommandParam = namedtuple('CommandParam', ['type', 'name', 'ispointer', 'isstaticarray', 'isconst', 'iscount', 'len', 'extstructs', 'cdecl'])
|
|
self.StructMemberData = namedtuple('StructMemberData', ['name', 'members', 'ifdef_protect'])
|
|
|
|
self.custom_construct_params = {
|
|
# safe_VkGraphicsPipelineCreateInfo needs to know if subpass has color and\or depth\stencil attachments to use its pointers
|
|
'VkGraphicsPipelineCreateInfo' :
|
|
', const bool uses_color_attachment, const bool uses_depthstencil_attachment',
|
|
# safe_VkPipelineViewportStateCreateInfo needs to know if viewport and scissor is dynamic to use its pointers
|
|
'VkPipelineViewportStateCreateInfo' :
|
|
', const bool is_dynamic_viewports, const bool is_dynamic_scissors',
|
|
}
|
|
#
|
|
# Called once at the beginning of each run
|
|
def beginFile(self, genOpts):
|
|
OutputGenerator.beginFile(self, genOpts)
|
|
# User-supplied prefix text, if any (list of strings)
|
|
self.helper_file_type = genOpts.helper_file_type
|
|
self.library_name = genOpts.library_name
|
|
# File Comment
|
|
file_comment = '// *** THIS FILE IS GENERATED - DO NOT EDIT ***\n'
|
|
file_comment += '// See helper_file_generator.py for modifications\n'
|
|
write(file_comment, file=self.outFile)
|
|
# Copyright Notice
|
|
copyright = ''
|
|
copyright += '\n'
|
|
copyright += '/***************************************************************************\n'
|
|
copyright += ' *\n'
|
|
copyright += ' * Copyright (c) 2015-2017 The Khronos Group Inc.\n'
|
|
copyright += ' * Copyright (c) 2015-2017 Valve Corporation\n'
|
|
copyright += ' * Copyright (c) 2015-2017 LunarG, Inc.\n'
|
|
copyright += ' * Copyright (c) 2015-2017 Google Inc.\n'
|
|
copyright += ' *\n'
|
|
copyright += ' * Licensed under the Apache License, Version 2.0 (the "License");\n'
|
|
copyright += ' * you may not use this file except in compliance with the License.\n'
|
|
copyright += ' * You may obtain a copy of the License at\n'
|
|
copyright += ' *\n'
|
|
copyright += ' * http://www.apache.org/licenses/LICENSE-2.0\n'
|
|
copyright += ' *\n'
|
|
copyright += ' * Unless required by applicable law or agreed to in writing, software\n'
|
|
copyright += ' * distributed under the License is distributed on an "AS IS" BASIS,\n'
|
|
copyright += ' * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n'
|
|
copyright += ' * See the License for the specific language governing permissions and\n'
|
|
copyright += ' * limitations under the License.\n'
|
|
copyright += ' *\n'
|
|
copyright += ' * Author: Mark Lobodzinski <mark@lunarg.com>\n'
|
|
copyright += ' * Author: Courtney Goeltzenleuchter <courtneygo@google.com>\n'
|
|
copyright += ' * Author: Tobin Ehlis <tobine@google.com>\n'
|
|
copyright += ' * Author: Chris Forbes <chrisforbes@google.com>\n'
|
|
copyright += ' * Author: John Zulauf<jzulauf@lunarg.com>\n'
|
|
copyright += ' *\n'
|
|
copyright += ' ****************************************************************************/\n'
|
|
write(copyright, file=self.outFile)
|
|
#
|
|
# Write generated file content to output file
|
|
def endFile(self):
|
|
dest_file = ''
|
|
dest_file += self.OutputDestFile()
|
|
# Remove blank lines at EOF
|
|
if dest_file.endswith('\n'):
|
|
dest_file = dest_file[:-1]
|
|
write(dest_file, file=self.outFile);
|
|
# Finish processing in superclass
|
|
OutputGenerator.endFile(self)
|
|
#
|
|
# Override parent class to be notified of the beginning of an extension
|
|
def beginFeature(self, interface, emit):
|
|
# Start processing in superclass
|
|
OutputGenerator.beginFeature(self, interface, emit)
|
|
self.featureExtraProtect = GetFeatureProtect(interface)
|
|
|
|
if interface.tag != 'extension':
|
|
return
|
|
name = self.featureName
|
|
nameElem = interface[0][1]
|
|
name_define = nameElem.get('name')
|
|
if 'EXTENSION_NAME' not in name_define:
|
|
print("Error in vk.xml file -- extension name is not available")
|
|
requires = interface.get('requires')
|
|
if requires is not None:
|
|
required_extensions = requires.split(',')
|
|
else:
|
|
required_extensions = list()
|
|
info = { 'define': name_define, 'ifdef':self.featureExtraProtect, 'reqs':required_extensions }
|
|
if interface.get('type') == 'instance':
|
|
self.instance_extension_info[name] = info
|
|
else:
|
|
self.device_extension_info[name] = info
|
|
|
|
#
|
|
# Override parent class to be notified of the end of an extension
|
|
def endFeature(self):
|
|
# Finish processing in superclass
|
|
OutputGenerator.endFeature(self)
|
|
#
|
|
# Grab group (e.g. C "enum" type) info to output for enum-string conversion helper
|
|
def genGroup(self, groupinfo, groupName, alias):
|
|
OutputGenerator.genGroup(self, groupinfo, groupName, alias)
|
|
groupElem = groupinfo.elem
|
|
# For enum_string_header
|
|
if self.helper_file_type == 'enum_string_header':
|
|
value_set = set()
|
|
for elem in groupElem.findall('enum'):
|
|
if elem.get('supported') != 'disabled' and elem.get('alias') is None:
|
|
value_set.add(elem.get('name'))
|
|
self.enum_output += self.GenerateEnumStringConversion(groupName, value_set)
|
|
elif self.helper_file_type == 'object_types_header':
|
|
if groupName == 'VkDebugReportObjectTypeEXT':
|
|
for elem in groupElem.findall('enum'):
|
|
if elem.get('supported') != 'disabled':
|
|
item_name = elem.get('name')
|
|
self.debug_report_object_types.append(item_name)
|
|
elif groupName == 'VkObjectType':
|
|
for elem in groupElem.findall('enum'):
|
|
if elem.get('supported') != 'disabled':
|
|
item_name = elem.get('name')
|
|
self.core_object_types.append(item_name)
|
|
|
|
#
|
|
# Called for each type -- if the type is a struct/union, grab the metadata
|
|
def genType(self, typeinfo, name, alias):
|
|
OutputGenerator.genType(self, typeinfo, name, alias)
|
|
typeElem = typeinfo.elem
|
|
# If the type is a struct type, traverse the imbedded <member> tags generating a structure.
|
|
# Otherwise, emit the tag text.
|
|
category = typeElem.get('category')
|
|
if category == 'handle':
|
|
if alias:
|
|
self.object_type_aliases.append((name,alias))
|
|
else:
|
|
self.object_types.append(name)
|
|
elif (category == 'struct' or category == 'union'):
|
|
self.structNames.append(name)
|
|
self.genStruct(typeinfo, name, alias)
|
|
#
|
|
# Generate a VkStructureType based on a structure typename
|
|
def genVkStructureType(self, typename):
|
|
# Add underscore between lowercase then uppercase
|
|
value = re.sub('([a-z0-9])([A-Z])', r'\1_\2', typename)
|
|
# Change to uppercase
|
|
value = value.upper()
|
|
# Add STRUCTURE_TYPE_
|
|
return re.sub('VK_', 'VK_STRUCTURE_TYPE_', value)
|
|
#
|
|
# Check if the parameter passed in is a pointer
|
|
def paramIsPointer(self, param):
|
|
ispointer = False
|
|
for elem in param:
|
|
if ((elem.tag != 'type') and (elem.tail is not None)) and '*' in elem.tail:
|
|
ispointer = True
|
|
return ispointer
|
|
#
|
|
# Check if the parameter passed in is a static array
|
|
def paramIsStaticArray(self, param):
|
|
isstaticarray = 0
|
|
paramname = param.find('name')
|
|
if (paramname.tail is not None) and ('[' in paramname.tail):
|
|
isstaticarray = paramname.tail.count('[')
|
|
return isstaticarray
|
|
#
|
|
# Retrieve the type and name for a parameter
|
|
def getTypeNameTuple(self, param):
|
|
type = ''
|
|
name = ''
|
|
for elem in param:
|
|
if elem.tag == 'type':
|
|
type = noneStr(elem.text)
|
|
elif elem.tag == 'name':
|
|
name = noneStr(elem.text)
|
|
return (type, name)
|
|
#
|
|
# Retrieve the value of the len tag
|
|
def getLen(self, param):
|
|
result = None
|
|
len = param.attrib.get('len')
|
|
if len and len != 'null-terminated':
|
|
# For string arrays, 'len' can look like 'count,null-terminated', indicating that we
|
|
# have a null terminated array of strings. We strip the null-terminated from the
|
|
# 'len' field and only return the parameter specifying the string count
|
|
if 'null-terminated' in len:
|
|
result = len.split(',')[0]
|
|
else:
|
|
result = len
|
|
if 'altlen' in param.attrib:
|
|
# Elements with latexmath 'len' also contain a C equivalent 'altlen' attribute
|
|
# Use indexing operator instead of get() so we fail if the attribute is missing
|
|
result = param.attrib['altlen']
|
|
# Spec has now notation for len attributes, using :: instead of platform specific pointer symbol
|
|
result = str(result).replace('::', '->')
|
|
return result
|
|
#
|
|
# Check if a structure is or contains a dispatchable (dispatchable = True) or
|
|
# non-dispatchable (dispatchable = False) handle
|
|
def TypeContainsObjectHandle(self, handle_type, dispatchable):
|
|
if dispatchable:
|
|
type_key = 'VK_DEFINE_HANDLE'
|
|
else:
|
|
type_key = 'VK_DEFINE_NON_DISPATCHABLE_HANDLE'
|
|
handle = self.registry.tree.find("types/type/[name='" + handle_type + "'][@category='handle']")
|
|
if handle is not None and handle.find('type').text == type_key:
|
|
return True
|
|
# if handle_type is a struct, search its members
|
|
if handle_type in self.structNames:
|
|
member_index = next((i for i, v in enumerate(self.structMembers) if v[0] == handle_type), None)
|
|
if member_index is not None:
|
|
for item in self.structMembers[member_index].members:
|
|
handle = self.registry.tree.find("types/type/[name='" + item.type + "'][@category='handle']")
|
|
if handle is not None and handle.find('type').text == type_key:
|
|
return True
|
|
return False
|
|
#
|
|
# Generate local ready-access data describing Vulkan structures and unions from the XML metadata
|
|
def genStruct(self, typeinfo, typeName, alias):
|
|
OutputGenerator.genStruct(self, typeinfo, typeName, alias)
|
|
members = typeinfo.elem.findall('.//member')
|
|
# Iterate over members once to get length parameters for arrays
|
|
lens = set()
|
|
for member in members:
|
|
len = self.getLen(member)
|
|
if len:
|
|
lens.add(len)
|
|
# Generate member info
|
|
membersInfo = []
|
|
for member in members:
|
|
# Get the member's type and name
|
|
info = self.getTypeNameTuple(member)
|
|
type = info[0]
|
|
name = info[1]
|
|
cdecl = self.makeCParamDecl(member, 1)
|
|
# Process VkStructureType
|
|
if type == 'VkStructureType':
|
|
# Extract the required struct type value from the comments
|
|
# embedded in the original text defining the 'typeinfo' element
|
|
rawXml = etree.tostring(typeinfo.elem).decode('ascii')
|
|
result = re.search(r'VK_STRUCTURE_TYPE_\w+', rawXml)
|
|
if result:
|
|
value = result.group(0)
|
|
else:
|
|
value = self.genVkStructureType(typeName)
|
|
# Store the required type value
|
|
self.structTypes[typeName] = self.StructType(name=name, value=value)
|
|
# Store pointer/array/string info
|
|
isstaticarray = self.paramIsStaticArray(member)
|
|
membersInfo.append(self.CommandParam(type=type,
|
|
name=name,
|
|
ispointer=self.paramIsPointer(member),
|
|
isstaticarray=isstaticarray,
|
|
isconst=True if 'const' in cdecl else False,
|
|
iscount=True if name in lens else False,
|
|
len=self.getLen(member),
|
|
extstructs=self.registry.validextensionstructs[typeName] if name == 'pNext' else None,
|
|
cdecl=cdecl))
|
|
self.structMembers.append(self.StructMemberData(name=typeName, members=membersInfo, ifdef_protect=self.featureExtraProtect))
|
|
#
|
|
# Enum_string_header: Create a routine to convert an enumerated value into a string
|
|
def GenerateEnumStringConversion(self, groupName, value_list):
|
|
outstring = '\n'
|
|
outstring += 'static inline const char* string_%s(%s input_value)\n' % (groupName, groupName)
|
|
outstring += '{\n'
|
|
outstring += ' switch ((%s)input_value)\n' % groupName
|
|
outstring += ' {\n'
|
|
for item in value_list:
|
|
outstring += ' case %s:\n' % item
|
|
outstring += ' return "%s";\n' % item
|
|
outstring += ' default:\n'
|
|
outstring += ' return "Unhandled %s";\n' % groupName
|
|
outstring += ' }\n'
|
|
outstring += '}\n'
|
|
return outstring
|
|
#
|
|
# Combine object types helper header file preamble with body text and return
|
|
def GenerateObjectTypesHelperHeader(self):
|
|
object_types_helper_header = '\n'
|
|
object_types_helper_header += '#pragma once\n'
|
|
object_types_helper_header += '\n'
|
|
object_types_helper_header += '#include <vulkan/vulkan.h>\n\n'
|
|
object_types_helper_header += self.GenerateObjectTypesHeader()
|
|
return object_types_helper_header
|
|
#
|
|
# Object types header: create object enum type header file
|
|
def GenerateObjectTypesHeader(self):
|
|
object_types_header = ''
|
|
object_types_header += '// Object Type enum for validation layer internal object handling\n'
|
|
object_types_header += 'typedef enum VulkanObjectType {\n'
|
|
object_types_header += ' kVulkanObjectTypeUnknown = 0,\n'
|
|
enum_num = 1
|
|
type_list = [];
|
|
enum_entry_map = {}
|
|
|
|
# Output enum definition as each handle is processed, saving the names to use for the conversion routine
|
|
for item in self.object_types:
|
|
fixup_name = item[2:]
|
|
enum_entry = 'kVulkanObjectType%s' % fixup_name
|
|
enum_entry_map[item] = enum_entry
|
|
object_types_header += ' ' + enum_entry
|
|
object_types_header += ' = %d,\n' % enum_num
|
|
enum_num += 1
|
|
type_list.append(enum_entry)
|
|
object_types_header += ' kVulkanObjectTypeMax = %d,\n' % enum_num
|
|
object_types_header += ' // Aliases for backwards compatibilty of "promoted" types\n'
|
|
for (name, alias) in self.object_type_aliases:
|
|
fixup_name = name[2:]
|
|
object_types_header += ' kVulkanObjectType{} = {},\n'.format(fixup_name, enum_entry_map[alias])
|
|
object_types_header += '} VulkanObjectType;\n\n'
|
|
|
|
# Output name string helper
|
|
object_types_header += '// Array of object name strings for OBJECT_TYPE enum conversion\n'
|
|
object_types_header += 'static const char * const object_string[kVulkanObjectTypeMax] = {\n'
|
|
object_types_header += ' "Unknown",\n'
|
|
for item in self.object_types:
|
|
fixup_name = item[2:]
|
|
object_types_header += ' "%s",\n' % fixup_name
|
|
object_types_header += '};\n'
|
|
|
|
# Key creation helper for map comprehensions that convert between k<Name> and VK<Name> symbols
|
|
def to_key(regex, raw_key): return re.search(regex, raw_key).group(1).lower().replace("_","")
|
|
|
|
# Output a conversion routine from the layer object definitions to the debug report definitions
|
|
# As the VK_DEBUG_REPORT types are not being updated, specify UNKNOWN for unmatched types
|
|
object_types_header += '\n'
|
|
object_types_header += '// Helper array to get Vulkan VK_EXT_debug_report object type enum from the internal layers version\n'
|
|
object_types_header += 'const VkDebugReportObjectTypeEXT get_debug_report_enum[] = {\n'
|
|
object_types_header += ' VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeUnknown\n'
|
|
|
|
dbg_re = '^VK_DEBUG_REPORT_OBJECT_TYPE_(.*)_EXT$'
|
|
dbg_map = {to_key(dbg_re, dbg) : dbg for dbg in self.debug_report_object_types}
|
|
dbg_default = 'VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT'
|
|
for object_type in type_list:
|
|
vk_object_type = dbg_map.get(object_type.replace("kVulkanObjectType", "").lower(), dbg_default)
|
|
object_types_header += ' %s, // %s\n' % (vk_object_type, object_type)
|
|
object_types_header += '};\n'
|
|
|
|
# Output a conversion routine from the layer object definitions to the core object type definitions
|
|
# This will intentionally *fail* for unmatched types as the VK_OBJECT_TYPE list should match the kVulkanObjectType list
|
|
object_types_header += '\n'
|
|
object_types_header += '// Helper array to get Official Vulkan VkObjectType enum from the internal layers version\n'
|
|
object_types_header += 'const VkObjectType get_object_type_enum[] = {\n'
|
|
object_types_header += ' VK_OBJECT_TYPE_UNKNOWN, // kVulkanObjectTypeUnknown\n'
|
|
|
|
vko_re = '^VK_OBJECT_TYPE_(.*)'
|
|
vko_map = {to_key(vko_re, vko) : vko for vko in self.core_object_types}
|
|
for object_type in type_list:
|
|
vk_object_type = vko_map[object_type.replace("kVulkanObjectType", "").lower()]
|
|
object_types_header += ' %s, // %s\n' % (vk_object_type, object_type)
|
|
object_types_header += '};\n'
|
|
|
|
# Create a function to convert from VkDebugReportObjectTypeEXT to VkObjectType
|
|
object_types_header += '\n'
|
|
object_types_header += '// Helper function to convert from VkDebugReportObjectTypeEXT to VkObjectType\n'
|
|
object_types_header += 'static inline VkObjectType convertDebugReportObjectToCoreObject(VkDebugReportObjectTypeEXT debug_report_obj){\n'
|
|
object_types_header += ' if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT) {\n'
|
|
object_types_header += ' return VK_OBJECT_TYPE_UNKNOWN;\n'
|
|
for core_object_type in self.core_object_types:
|
|
core_target_type = core_object_type.replace("VK_OBJECT_TYPE_", "").lower()
|
|
core_target_type = core_target_type.replace("_", "")
|
|
for dr_object_type in self.debug_report_object_types:
|
|
dr_target_type = dr_object_type.replace("VK_DEBUG_REPORT_OBJECT_TYPE_", "").lower()
|
|
dr_target_type = dr_target_type[:-4]
|
|
dr_target_type = dr_target_type.replace("_", "")
|
|
if core_target_type == dr_target_type:
|
|
object_types_header += ' } else if (debug_report_obj == %s) {\n' % dr_object_type
|
|
object_types_header += ' return %s;\n' % core_object_type
|
|
break
|
|
object_types_header += ' }\n'
|
|
object_types_header += ' return VK_OBJECT_TYPE_UNKNOWN;\n'
|
|
object_types_header += '}\n'
|
|
|
|
# Create a function to convert from VkObjectType to VkDebugReportObjectTypeEXT
|
|
object_types_header += '\n'
|
|
object_types_header += '// Helper function to convert from VkDebugReportObjectTypeEXT to VkObjectType\n'
|
|
object_types_header += 'static inline VkDebugReportObjectTypeEXT convertCoreObjectToDebugReportObject(VkObjectType core_report_obj){\n'
|
|
object_types_header += ' if (core_report_obj == VK_OBJECT_TYPE_UNKNOWN) {\n'
|
|
object_types_header += ' return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;\n'
|
|
for core_object_type in self.core_object_types:
|
|
core_target_type = core_object_type.replace("VK_OBJECT_TYPE_", "").lower()
|
|
core_target_type = core_target_type.replace("_", "")
|
|
for dr_object_type in self.debug_report_object_types:
|
|
dr_target_type = dr_object_type.replace("VK_DEBUG_REPORT_OBJECT_TYPE_", "").lower()
|
|
dr_target_type = dr_target_type[:-4]
|
|
dr_target_type = dr_target_type.replace("_", "")
|
|
if core_target_type == dr_target_type:
|
|
object_types_header += ' } else if (core_report_obj == %s) {\n' % core_object_type
|
|
object_types_header += ' return %s;\n' % dr_object_type
|
|
break
|
|
object_types_header += ' }\n'
|
|
object_types_header += ' return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;\n'
|
|
object_types_header += '}\n'
|
|
return object_types_header
|
|
|
|
#
|
|
# Create a helper file and return it as a string
|
|
def OutputDestFile(self):
|
|
if self.helper_file_type == 'object_types_header':
|
|
return self.GenerateObjectTypesHelperHeader()
|
|
else:
|
|
return 'Bad Helper File Generator Option %s' % self.helper_file_type
|