blob: 359e8f530b4f047ba87fcb66b9f7c8a9d6d5de1c [file] [log] [blame]
#!/usr/bin/python3 -i
#
# Copyright (c) 2024-2025 The Khronos Group 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.
import os
from generators.base_generator import BaseGenerator
from generators.generator_utils import PlatformGuardHelper
class TestIcdGenerator(BaseGenerator):
def __init__(self):
BaseGenerator.__init__(self)
self.manual_functions = [
'vkCreateInstance',
'vkDestroyInstance',
'vkAllocateCommandBuffers',
'vkFreeCommandBuffers',
'vkCreateCommandPool',
'vkDestroyCommandPool',
'vkEnumeratePhysicalDevices',
'vkCreateDevice',
'vkDestroyDevice',
'vkGetDeviceQueue',
'vkGetDeviceQueue2',
'vkEnumerateInstanceLayerProperties',
'vkEnumerateInstanceVersion',
'vkEnumerateDeviceLayerProperties',
'vkEnumerateInstanceExtensionProperties',
'vkEnumerateDeviceExtensionProperties',
'vkGetPhysicalDeviceSurfacePresentModesKHR',
'vkGetPhysicalDeviceSurfaceFormatsKHR',
'vkGetPhysicalDeviceSurfaceFormats2KHR',
'vkGetPhysicalDeviceSurfaceSupportKHR',
'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
'vkGetPhysicalDeviceSurfaceCapabilities2KHR',
'vkGetPhysicalDeviceSurfaceCapabilities2EXT',
'vkGetInstanceProcAddr',
'vkGetDeviceProcAddr',
'vkGetPhysicalDeviceMemoryProperties',
'vkGetPhysicalDeviceMemoryProperties2',
'vkGetPhysicalDeviceQueueFamilyProperties',
'vkGetPhysicalDeviceQueueFamilyProperties2',
'vkGetPhysicalDeviceFeatures',
'vkGetPhysicalDeviceFeatures2',
'vkGetPhysicalDeviceFormatProperties',
'vkGetPhysicalDeviceFormatProperties2',
'vkGetPhysicalDeviceImageFormatProperties',
'vkGetPhysicalDeviceImageFormatProperties2',
'vkGetPhysicalDeviceSparseImageFormatProperties',
'vkGetPhysicalDeviceSparseImageFormatProperties2',
'vkGetPhysicalDeviceProperties',
'vkGetPhysicalDeviceProperties2',
'vkGetPhysicalDeviceExternalSemaphoreProperties',
'vkGetPhysicalDeviceExternalFenceProperties',
'vkGetPhysicalDeviceExternalBufferProperties',
'vkGetBufferMemoryRequirements',
'vkGetBufferMemoryRequirements2',
'vkGetDeviceBufferMemoryRequirements',
'vkGetImageMemoryRequirements',
'vkGetImageMemoryRequirements2',
'vkGetDeviceImageMemoryRequirements',
'vkAllocateMemory',
'vkFreeMemory',
'vkMapMemory',
'vkMapMemory2',
'vkUnmapMemory',
'vkUnmapMemory2',
'vkGetImageSubresourceLayout',
'vkCreateSwapchainKHR',
'vkDestroySwapchainKHR',
'vkGetSwapchainImagesKHR',
'vkAcquireNextImageKHR',
'vkAcquireNextImage2KHR',
'vkCreateBuffer',
'vkDestroyBuffer',
'vkCreateImage',
'vkDestroyImage',
'vkEnumeratePhysicalDeviceGroups',
'vkGetPhysicalDeviceMultisamplePropertiesEXT',
'vkGetPhysicalDeviceFragmentShadingRatesKHR',
'vkGetPhysicalDeviceCalibrateableTimeDomainsKHR',
'vkGetFenceWin32HandleKHR',
'vkGetFenceFdKHR',
'vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR',
'vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR',
'vkGetShaderModuleIdentifierEXT',
'vkGetImageSparseMemoryRequirements',
'vkGetImageSparseMemoryRequirements2',
'vkGetBufferDeviceAddress',
'vkGetDescriptorSetLayoutSizeEXT',
'vkGetAccelerationStructureBuildSizesKHR',
'vkGetAccelerationStructureMemoryRequirementsNV',
'vkGetAccelerationStructureDeviceAddressKHR',
'vkGetVideoSessionMemoryRequirementsKHR',
'vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR',
'vkGetPhysicalDeviceVideoCapabilitiesKHR',
'vkGetPhysicalDeviceVideoFormatPropertiesKHR',
'vkGetDescriptorSetLayoutSupport',
'vkGetRenderAreaGranularity',
'vkGetMemoryFdKHR',
'vkGetMemoryHostPointerPropertiesEXT',
'vkGetAndroidHardwareBufferPropertiesANDROID',
'vkGetPhysicalDeviceDisplayPropertiesKHR',
'vkRegisterDisplayEventEXT',
'vkQueueSubmit',
'vkGetMemoryWin32HandlePropertiesKHR',
'vkRegisterDisplayEventEXT',
'vkCreatePipelineBinariesKHR',
'vkGetPipelineBinaryDataKHR',
]
def generate(self):
self.write(f'''// *** THIS FILE IS GENERATED - DO NOT EDIT ***
// See {os.path.basename(__file__)} for modifications
/***************************************************************************
*
* Copyright (c) 2024-2025 LunarG, 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''')
self.write('// NOLINTBEGIN') # Wrap for clang-tidy to ignore
if self.filename == 'test_icd_helper.h':
self.generateHeader()
else:
self.write(f'\nFile name {self.filename} has no code to generate\n')
self.write('// NOLINTEND') # Wrap for clang-tidy to ignore
def generateHeader(self):
out = []
out.append('''
#pragma once
#include <stdint.h>
#include <cstring>
#include <string>
#include <unordered_map>
#include <vulkan/vulkan.h>
namespace icd {
''')
guard_helper = PlatformGuardHelper()
# Needed because things like VK_KHR_get_physical_device_properties2 profile layer checks in driver
out.append('''
// Map of instance extension name to version
static const std::unordered_map<std::string, uint32_t> instance_extension_map = {
''')
for extension in [x for x in self.vk.extensions.values() if x.instance]:
out.extend(guard_helper.add_guard(extension.protect))
out.append(f'{{{extension.nameString}, {extension.specVersion}}},\n')
out.extend(guard_helper.add_guard(None))
out.append('};\n')
out.append('''
// Map of device extension name to version
static const std::unordered_map<std::string, uint32_t> device_extension_map = {
''')
for extension in [x for x in self.vk.extensions.values() if not x.instance]:
out.extend(guard_helper.add_guard(extension.protect))
out.append(f'{{{extension.nameString}, {extension.specVersion}}},\n')
out.extend(guard_helper.add_guard(None))
out.append('};\n')
for command in self.vk.commands.values():
prototype = "static " + command.cPrototype
prototype = prototype.replace("VKAPI_CALL vk", "VKAPI_CALL ")
out.extend(guard_helper.add_guard(command.protect))
out.append(f'{prototype}\n')
out.extend(guard_helper.add_guard(None))
out.append('''
// Map of all APIs to be intercepted by this layer
static const std::unordered_map<std::string, void*> name_to_func_ptr_map = {
''')
for command in self.vk.commands.values():
out.extend(guard_helper.add_guard(command.protect))
out.append(f'{{"{command.name}", (void*){command.name[2:]}}},\n')
out.extend(guard_helper.add_guard(None))
out.append('};\n')
for command in [x for x in self.vk.commands.values() if x.name not in self.manual_functions]:
out.extend(guard_helper.add_guard(command.protect))
prototype = "static " + command.cPrototype
prototype = prototype.replace("VKAPI_CALL vk", "VKAPI_CALL ")
prototype = prototype.replace(");", ") {")
out.append(f'{prototype}\n')
voidReturn = command.returnType == 'void'
# For alias that are promoted, just point to new function
if command.alias and command.alias in self.vk.commands:
paramList = [param.name for param in command.params]
params = ', '.join(paramList)
returnName = '' if voidReturn else 'return '
out.append(f'{returnName}{command.alias[2:]}({params});')
elif 'vkCreate' in command.name or 'vkAllocate' in command.name:
last_param = command.params[-1]
out.append('unique_lock_t lock(global_lock);\n')
if (last_param.length):
out.append(f'for (uint32_t i = 0; i < {last_param.length}; ++i) {{\n')
out.append(f'{last_param.name}[i] = ({last_param.type})global_unique_handle++;\n')
out.append('}\n')
else:
out.append(f'*{last_param.name} = ({last_param.type})global_unique_handle++;\n')
out.append('return VK_SUCCESS;\n')
elif not voidReturn:
out.append('return VK_SUCCESS;')
out.append('}\n\n')
out.extend(guard_helper.add_guard(None))
out.append('\n} // namespace icd')
self.write("".join(out))