blob: 85bacd611a2ca856c4b124f7392a9d9298653d4a [file] [log] [blame]
#!/usr/bin/python3 -i
#
# Copyright (c) 2015-2023 The Khronos Group Inc.
# Copyright (c) 2015-2023 Valve Corporation
# Copyright (c) 2015-2023 LunarG, Inc.
# Copyright (c) 2015-2023 Google Inc.
# Copyright (c) 2023-2023 RasterGrid Kft.
#
# 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.
import os
from generators.base_generator import BaseGenerator
class ObjectTypesOutputGenerator(BaseGenerator):
def __init__(self):
BaseGenerator.__init__(self)
def generate(self):
# Helper for VkDebugReportObjectTypeEXT
# Maps [ 'VkBuffer' : 'VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT' ]
# Will be 'VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT' if no type
debugReportObject = dict()
# Search all fields of the Enum to see if has a DEBUG_REPORT_OBJECT
for handle in self.vk.handles.values():
debugObjects = ([enum.name for enum in self.vk.enums['VkDebugReportObjectTypeEXT'].fields if f'{handle.type[3:]}_EXT' in enum.name])
object = 'VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT' if len(debugObjects) == 0 else debugObjects[0]
debugReportObject[handle.name] = object
out = []
out.append(f'''// *** THIS FILE IS GENERATED - DO NOT EDIT ***
// See {os.path.basename(__file__)} for modifications
/***************************************************************************
*
* Copyright (c) 2015-2023 The Khronos Group Inc.
* Copyright (c) 2015-2023 Valve Corporation
* Copyright (c) 2015-2023 LunarG, Inc.
* Copyright (c) 2015-2023 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.
****************************************************************************/\n''')
out.append('// NOLINTBEGIN') # Wrap for clang-tidy to ignore
out.append('// clang-format off')
out.append('''
#pragma once
#include "utils/cast_utils.h"
\n''')
out.append('''
// Object Type enum for validation layer internal object handling
typedef enum VulkanObjectType {
kVulkanObjectTypeUnknown = 0,\n''')
for count, handle in enumerate(self.vk.handles.values(), start=1):
out.append(f' kVulkanObjectType{handle.name[2:]} = {count},\n')
out.append(f' kVulkanObjectTypeMax = {len(self.vk.handles) + 1}\n')
out.append('} VulkanObjectType;\n')
out.append('''
// Array of object name strings for OBJECT_TYPE enum conversion
static const char * const object_string[kVulkanObjectTypeMax] = {
"VkNonDispatchableHandle",\n''')
out.extend([f' "{handle.name}",\n' for handle in self.vk.handles.values()])
out.append('};\n')
out.append('''
// Helper array to get Vulkan VK_EXT_debug_report object type enum from the internal layers version
const VkDebugReportObjectTypeEXT get_debug_report_enum[] = {
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeUnknown\n''')
out.extend([f' {debugReportObject[handle.name]}, // kVulkanObjectType{handle.name[2:]}\n' for handle in self.vk.handles.values()])
out.append('};\n')
out.append('''
// Helper function to get Official Vulkan VkObjectType enum from the internal layers version
static inline VkObjectType ConvertVulkanObjectToCoreObject(VulkanObjectType internal_type) {
switch (internal_type) {\n''')
out.extend([f' case kVulkanObjectType{handle.name[2:]}: return {handle.type};\n' for handle in self.vk.handles.values()])
out.append(''' default: return VK_OBJECT_TYPE_UNKNOWN;
}
}\n''')
out.append('''
// Helper function to get internal layers object ids from the official Vulkan VkObjectType enum
static inline VulkanObjectType ConvertCoreObjectToVulkanObject(VkObjectType vulkan_object_type) {
switch (vulkan_object_type) {\n''')
out.extend([f' case {handle.type}: return kVulkanObjectType{handle.name[2:]};\n' for handle in self.vk.handles.values()])
out.append(''' default: return kVulkanObjectTypeUnknown;
}
}\n''')
out.append('''
static inline VkDebugReportObjectTypeEXT convertCoreObjectToDebugReportObject(VkObjectType core_report_obj) {
switch (core_report_obj) {
case VK_OBJECT_TYPE_UNKNOWN: return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;\n''')
for handle in self.vk.handles.values():
object = debugReportObject[handle.name]
if object != 'VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT':
out.append(f' case {handle.type}: return {object};\n')
out.append(''' default: return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
}
}\n''')
out.append('''
// Traits objects from each type statically map from Vk<handleType> to the various enums
template <typename VkType> struct VkHandleInfo {};
template <VulkanObjectType id> struct VulkanObjectTypeInfo {};
// The following line must match the vulkan_core.h condition guarding VK_DEFINE_NON_DISPATCHABLE_HANDLE
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || \
defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
#define TYPESAFE_NONDISPATCHABLE_HANDLES
#else
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkNonDispatchableHandle)
template <> struct VkHandleInfo<VkNonDispatchableHandle> {
static const VulkanObjectType kVulkanObjectType = kVulkanObjectTypeUnknown;
static const VkDebugReportObjectTypeEXT kDebugReportObjectType = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
static const VkObjectType kVkObjectType = VK_OBJECT_TYPE_UNKNOWN;
static const char* Typename() {
return "VkNonDispatchableHandle";
}
};
template <> struct VulkanObjectTypeInfo<kVulkanObjectTypeUnknown> {
typedef VkNonDispatchableHandle Type;
};
#endif // VK_DEFINE_HANDLE logic duplication\n''')
for handle in [x for x in self.vk.handles.values() if x.dispatchable]:
out.extend([f'#ifdef {handle.protect}\n'] if handle.protect else [])
out.append(f'''
template <> struct VkHandleInfo<{handle.name}> {{
static const VulkanObjectType kVulkanObjectType = kVulkanObjectType{handle.name[2:]};
static const VkDebugReportObjectTypeEXT kDebugReportObjectType = {debugReportObject[handle.name]};
static const VkObjectType kVkObjectType = {handle.type};
static const char* Typename() {{
return "{handle.name}";
}}
}};
template <> struct VulkanObjectTypeInfo<kVulkanObjectType{handle.name[2:]}> {{
typedef {handle.name} Type;
}};\n''')
out.extend([f'#endif //{handle.protect}\n'] if handle.protect else [])
out.append('#ifdef TYPESAFE_NONDISPATCHABLE_HANDLES\n')
for handle in [x for x in self.vk.handles.values() if not x.dispatchable]:
out.extend([f'#ifdef {handle.protect}\n'] if handle.protect else [])
out.append(f'''
template <> struct VkHandleInfo<{handle.name}> {{
static const VulkanObjectType kVulkanObjectType = kVulkanObjectType{handle.name[2:]};
static const VkDebugReportObjectTypeEXT kDebugReportObjectType = {debugReportObject[handle.name]};
static const VkObjectType kVkObjectType = {handle.type};
static const char* Typename() {{
return "{handle.name}";
}}
}};
template <> struct VulkanObjectTypeInfo<kVulkanObjectType{handle.name[2:]}> {{
typedef {handle.name} Type;
}};\n''')
out.extend([f'#endif //{handle.protect}\n'] if handle.protect else [])
out.append('#endif // TYPESAFE_NONDISPATCHABLE_HANDLES\n')
out.append('''
struct VulkanTypedHandle {
uint64_t handle;
VulkanObjectType type;
template <typename Handle>
VulkanTypedHandle(Handle handle_, VulkanObjectType type_) :
handle(CastToUint64(handle_)),
type(type_) {
#ifdef TYPESAFE_NONDISPATCHABLE_HANDLES
// For 32 bit it's not always safe to check for traits <-> type
// as all non-dispatchable handles have the same type-id and thus traits,
// but on 64 bit we can validate the passed type matches the passed handle
assert(type == VkHandleInfo<Handle>::kVulkanObjectType);
#endif // TYPESAFE_NONDISPATCHABLE_HANDLES
}
template <typename Handle>
Handle Cast() const {
#ifdef TYPESAFE_NONDISPATCHABLE_HANDLES
assert(type == VkHandleInfo<Handle>::kVulkanObjectType);
#endif // TYPESAFE_NONDISPATCHABLE_HANDLES
return CastFromUint64<Handle>(handle);
}
VulkanTypedHandle() :
handle(CastToUint64(VK_NULL_HANDLE)),
type(kVulkanObjectTypeUnknown) {}
operator bool() const { return handle != 0; }
};\n''')
out.append('// clang-format on')
out.append('// NOLINTEND') # Wrap for clang-tidy to ignore
self.write("".join(out))