mirror of
https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git
synced 2025-05-15 01:08:39 +00:00
util: Fixup and add Dispatch Table header
Fixes the vk_layer_dispatch_table.h header file so that they can be used in other projects. The contents of this header and vk_dispatch_table_helper.h have been moved into a new header vul_dispatch_table.h. The structs VulDeviceDispatchTable and VulInstanceDispatchTable struct contain function pointers for the device and instance, respectively. The functions vul_init_device_dispatch_table and vul_init_instance_dispatch_table fill out the aforementioned structs, making the task of setting up the disptach table in a layer much simpler.
This commit is contained in:
parent
8ea7803544
commit
2bd0e0d438
15 changed files with 2006 additions and 212 deletions
|
@ -38,6 +38,9 @@ if(${CMAKE_CXX_COMPILER_ID} MATCHES "(GNU|Clang)")
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_library(VulkanUtilityHeaders INTERFACE)
|
||||||
|
add_library(Vulkan::UtilityHeaders ALIAS VulkanUtilityHeaders)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(include)
|
add_subdirectory(include)
|
||||||
|
|
||||||
|
@ -49,9 +52,11 @@ if (VUL_IS_TOP_LEVEL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/vulkan" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/vulkan" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
|
||||||
set_target_properties(VulkanLayerSettings PROPERTIES EXPORT_NAME "LayerSettings")
|
set_target_properties(VulkanLayerSettings PROPERTIES EXPORT_NAME "LayerSettings")
|
||||||
install(TARGETS VulkanLayerSettings EXPORT VulkanUtilityLibrariesConfig INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
set_target_properties(VulkanUtilityHeaders PROPERTIES EXPORT_NAME "UtilityHeaders")
|
||||||
|
install(TARGETS VulkanLayerSettings VulkanUtilityHeaders EXPORT VulkanUtilityLibrariesConfig INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
install(EXPORT VulkanUtilityLibrariesConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VulkanUtilityLibraries NAMESPACE Vulkan::)
|
install(EXPORT VulkanUtilityLibrariesConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VulkanUtilityLibraries NAMESPACE Vulkan::)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -27,8 +27,8 @@ If only dealing with a single file, run `scripts/generate_source.py` with `--ta
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Example - only generates chassis.h
|
# Example - only generates chassis.h
|
||||||
scripts/generate_source.py external/Vulkan-Headers/registry/ --target vk_layer_dispatch_table.h
|
scripts/generate_source.py external/Vulkan-Headers/registry/ --target vul_dispatch_table.h
|
||||||
```
|
```
|
||||||
|
|
||||||
When making change to the `scripts/` folder, make sure to run `generate_source.py`
|
When making change to the `scripts/` folder, make sure to run `generate_source.py`
|
||||||
(Code generation does **not** happen automatically at build time.)
|
(Code generation does **not** happen automatically at build time.)
|
||||||
|
|
|
@ -10,3 +10,14 @@ target_sources(VulkanLayerSettings PRIVATE
|
||||||
vulkan/layer/vk_layer_settings.hpp
|
vulkan/layer/vk_layer_settings.hpp
|
||||||
vulkan/layer/vk_layer_settings_ext.h
|
vulkan/layer/vk_layer_settings_ext.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_sources(VulkanUtilityHeaders PRIVATE
|
||||||
|
vulkan/utility/vul_dispatch_table.h
|
||||||
|
vulkan/vk_enum_string_helper.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# NOTE: Because Vulkan::Headers header files are exposed in the public facing interface
|
||||||
|
# we must expose this library as public to users.
|
||||||
|
target_link_Libraries(VulkanUtilityHeaders INTERFACE Vulkan::Headers)
|
||||||
|
|
||||||
|
target_include_directories(VulkanUtilityHeaders INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
|
||||||
|
|
1770
include/vulkan/utility/vul_dispatch_table.h
Normal file
1770
include/vulkan/utility/vul_dispatch_table.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -22,23 +22,15 @@ def RunGenerators(api: str, registry: str, targetFilter: str) -> None:
|
||||||
from reg import Registry
|
from reg import Registry
|
||||||
|
|
||||||
from generators.base_generator import BaseGeneratorOptions
|
from generators.base_generator import BaseGeneratorOptions
|
||||||
from generators.dispatch_table_helper_generator import DispatchTableHelperOutputGenerator
|
from generators.dispatch_table_generator import DispatchTableOutputGenerator
|
||||||
from generators.layer_dispatch_table_generator import LayerDispatchTableOutputGenerator
|
|
||||||
from generators.enum_string_helper_generator import EnumStringHelperOutputGenerator
|
from generators.enum_string_helper_generator import EnumStringHelperOutputGenerator
|
||||||
|
|
||||||
# Build up a list of all generators and custom options
|
# Build up a list of all generators and custom options
|
||||||
generators = {
|
generators = {
|
||||||
# TODO: vk_dispatch_table_helper.h doesn't compile.
|
'vul_dispatch_table.h' : {
|
||||||
# 'vk_dispatch_table_helper.h' : {
|
'generator' : DispatchTableOutputGenerator,
|
||||||
# 'generator' : DispatchTableHelperOutputGenerator,
|
'directory' : 'include/vulkan/utility',
|
||||||
# 'directory' : 'include/vulkan',
|
},
|
||||||
#},
|
|
||||||
# TODO: vk_layer_dispatch_table.h doesn't compile.
|
|
||||||
#
|
|
||||||
#'vk_layer_dispatch_table.h' : {
|
|
||||||
# 'generator' : LayerDispatchTableOutputGenerator,
|
|
||||||
# 'directory' : 'include/vulkan',
|
|
||||||
#},
|
|
||||||
'vk_enum_string_helper.h' : {
|
'vk_enum_string_helper.h' : {
|
||||||
'generator' : EnumStringHelperOutputGenerator,
|
'generator' : EnumStringHelperOutputGenerator,
|
||||||
'directory' : 'include/vulkan',
|
'directory' : 'include/vulkan',
|
||||||
|
|
93
scripts/generators/dispatch_table_generator.py
Normal file
93
scripts/generators/dispatch_table_generator.py
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
#!/usr/bin/python3 -i
|
||||||
|
#
|
||||||
|
# Copyright 2023 The Khronos Group Inc.
|
||||||
|
# Copyright 2023 Valve Corporation
|
||||||
|
# Copyright 2023 LunarG, Inc.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import os
|
||||||
|
from generators.base_generator import BaseGenerator
|
||||||
|
|
||||||
|
class DispatchTableOutputGenerator(BaseGenerator):
|
||||||
|
def __init__(self):
|
||||||
|
BaseGenerator.__init__(self)
|
||||||
|
|
||||||
|
def generate(self):
|
||||||
|
out = []
|
||||||
|
out.append(f'''// *** THIS FILE IS GENERATED - DO NOT EDIT ***
|
||||||
|
// See {os.path.basename(__file__)} for modifications
|
||||||
|
// Copyright 2023 The Khronos Group Inc.
|
||||||
|
// Copyright 2023 Valve Corporation
|
||||||
|
// Copyright 2023 LunarG, Inc.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
\n''')
|
||||||
|
|
||||||
|
out.append('''
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName);
|
||||||
|
''')
|
||||||
|
out.append('''
|
||||||
|
// Instance function pointer dispatch table
|
||||||
|
typedef struct VulInstanceDispatchTable_ {
|
||||||
|
PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr;
|
||||||
|
|
||||||
|
''')
|
||||||
|
for command in [x for x in self.vk.commands.values() if x.instance]:
|
||||||
|
out.extend([f'#ifdef {command.protect}\n'] if command.protect else [])
|
||||||
|
out.append(f' PFN_{command.name} {command.name[2:]};\n')
|
||||||
|
out.extend([f'#endif //{command.protect}\n'] if command.protect else [])
|
||||||
|
out.append('} VulInstanceDispatchTable;\n')
|
||||||
|
|
||||||
|
out.append('''
|
||||||
|
// Device function pointer dispatch table
|
||||||
|
typedef struct VulDeviceDispatchTable_ {
|
||||||
|
''')
|
||||||
|
for command in [x for x in self.vk.commands.values() if x.device]:
|
||||||
|
out.extend([f'#ifdef {command.protect}\n'] if command.protect else [])
|
||||||
|
out.append(f' PFN_{command.name} {command.name[2:]};\n')
|
||||||
|
out.extend([f'#endif //{command.protect}\n'] if command.protect else [])
|
||||||
|
out.append('} VulDeviceDispatchTable;\n')
|
||||||
|
|
||||||
|
out.append('''
|
||||||
|
static inline void vulInitDeviceDispatchTable(VkDevice device, VulDeviceDispatchTable *table, PFN_vkGetDeviceProcAddr gdpa) {
|
||||||
|
memset(table, 0, sizeof(*table));
|
||||||
|
// Device function pointers
|
||||||
|
table->GetDeviceProcAddr = gdpa;
|
||||||
|
''')
|
||||||
|
|
||||||
|
for command in [x for x in self.vk.commands.values() if x.device and x.name != 'vkGetDeviceProcAddr']:
|
||||||
|
out.extend([f'#ifdef {command.protect}\n'] if command.protect else [])
|
||||||
|
out.append(f' table->{command.name[2:]} = (PFN_{command.name}) gdpa(device, "{command.name}");\n')
|
||||||
|
out.extend([f'#endif // {command.protect}\n'] if command.protect else [])
|
||||||
|
out.append('}\n')
|
||||||
|
|
||||||
|
out.append('''
|
||||||
|
static inline void vulInitInstanceDispatchTable(VkInstance instance, VulInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gipa) {
|
||||||
|
memset(table, 0, sizeof(*table));
|
||||||
|
// Instance function pointers
|
||||||
|
table->GetInstanceProcAddr = gipa;
|
||||||
|
table->GetPhysicalDeviceProcAddr = (PFN_GetPhysicalDeviceProcAddr) gipa(instance, "vk_layerGetPhysicalDeviceProcAddr");
|
||||||
|
''')
|
||||||
|
|
||||||
|
for command in [x for x in self.vk.commands.values() if x.instance and x.name not in [
|
||||||
|
'vkCreateInstance',
|
||||||
|
'vkCreateDevice',
|
||||||
|
'vkGetPhysicalDeviceProcAddr',
|
||||||
|
'vkEnumerateInstanceExtensionProperties',
|
||||||
|
'vkEnumerateInstanceLayerProperties',
|
||||||
|
'vkEnumerateInstanceVersion',
|
||||||
|
'vkGetInstanceProcAddr',
|
||||||
|
]]:
|
||||||
|
out.extend([f'#ifdef {command.protect}\n'] if command.protect else [])
|
||||||
|
out.append(f' table->{command.name[2:]} = (PFN_{command.name}) gipa(instance, "{command.name}");\n')
|
||||||
|
out.extend([f'#endif // {command.protect}\n'] if command.protect else [])
|
||||||
|
out.append('}\n')
|
||||||
|
|
||||||
|
self.write("".join(out))
|
|
@ -1,134 +0,0 @@
|
||||||
#!/usr/bin/python3 -i
|
|
||||||
|
|
||||||
# Copyright 2023 The Khronos Group Inc.
|
|
||||||
# Copyright 2023 Valve Corporation
|
|
||||||
# Copyright 2023 LunarG, Inc.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import os
|
|
||||||
from generators.base_generator import BaseGenerator
|
|
||||||
|
|
||||||
class DispatchTableHelperOutputGenerator(BaseGenerator):
|
|
||||||
"""Generate dispatch tables header based on XML element attributes"""
|
|
||||||
def __init__(self):
|
|
||||||
BaseGenerator.__init__(self)
|
|
||||||
|
|
||||||
def generate(self):
|
|
||||||
out = []
|
|
||||||
out.append(f'''// *** THIS FILE IS GENERATED - DO NOT EDIT ***
|
|
||||||
// See {os.path.basename(__file__)} for modifications
|
|
||||||
// Copyright 2023 The Khronos Group Inc.
|
|
||||||
// Copyright 2023 Valve Corporation
|
|
||||||
// Copyright 2023 LunarG, Inc.
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
\n''')
|
|
||||||
out.append('// NOLINTBEGIN') # Wrap for clang-tidy to ignore
|
|
||||||
|
|
||||||
out.append('''
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vulkan/vulkan.h>
|
|
||||||
#include <vulkan/vk_layer.h>
|
|
||||||
#include <cstring>
|
|
||||||
#include <string>
|
|
||||||
#include "vk_layer_dispatch_table.h"
|
|
||||||
#include "vk_extension_helper.h"
|
|
||||||
\n''')
|
|
||||||
|
|
||||||
for command in [x for x in self.vk.commands.values() if x.extensions or x.version]:
|
|
||||||
if command.name == 'vkEnumerateInstanceVersion':
|
|
||||||
continue # TODO - Figure out how this can be automatically detected
|
|
||||||
out.extend([f'#ifdef {command.protect}\n'] if command.protect else [])
|
|
||||||
|
|
||||||
prototype = ' '.join(command.cPrototype.split()) # remove duplicate whitespace
|
|
||||||
prototype = prototype.replace('\n', '').replace('( ', '(').replace(');', ')').replace(' vk', ' Stub')
|
|
||||||
|
|
||||||
result = '' if command.returnType == 'void' else 'return 0;'
|
|
||||||
result = 'return VK_SUCCESS;' if command.returnType == 'VkResult' else result
|
|
||||||
result = 'return VK_FALSE;' if command.returnType == 'VkBool32' else result
|
|
||||||
|
|
||||||
out.append(f'static {prototype} {{ {result} }}\n')
|
|
||||||
out.extend([f'#endif // {command.protect}\n'] if command.protect else [])
|
|
||||||
out.append('\n')
|
|
||||||
|
|
||||||
out.append('const vvl::unordered_map<std::string, small_vector<std::string, 2, size_t>> api_extension_map {\n')
|
|
||||||
for command in [x for x in self.vk.commands.values() if x.version and x.device]:
|
|
||||||
out.append(f' {{ "{command.name}", {{ "{command.version.name}" }} }},\n')
|
|
||||||
for command in [x for x in self.vk.commands.values() if x.extensions and x.device]:
|
|
||||||
extensions = ', '.join(f'"{x.name}"' for x in command.extensions)
|
|
||||||
out.append(f' {{ "{command.name}", {{ {extensions} }} }},\n')
|
|
||||||
out.append('};\n')
|
|
||||||
|
|
||||||
out.append('''
|
|
||||||
// Using the above code-generated map of APINames-to-parent extension names, this function will:
|
|
||||||
// o Determine if the API has an associated extension
|
|
||||||
// o If it does, determine if that extension name is present in the passed-in set of device or instance enabled_ext_names
|
|
||||||
// If the APIname has no parent extension, OR its parent extension name is IN one of the sets, return TRUE, else FALSE
|
|
||||||
static inline bool ApiParentExtensionEnabled(const std::string api_name, const DeviceExtensions *device_extension_info) {
|
|
||||||
auto has_ext = api_extension_map.find(api_name);
|
|
||||||
// Is this API part of an extension or feature group?
|
|
||||||
if (has_ext != api_extension_map.end()) {
|
|
||||||
|
|
||||||
// Was the extension for this API enabled in the CreateDevice call?
|
|
||||||
for (const auto& ext : has_ext->second) {
|
|
||||||
auto info = device_extension_info->get_info(ext.c_str());
|
|
||||||
if (info.state) {
|
|
||||||
return device_extension_info->*(info.state) == kEnabledByCreateinfo || device_extension_info->*(info.state) == kEnabledByInteraction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Was the extension for this API enabled in the CreateInstance call?
|
|
||||||
auto instance_extension_info = static_cast<const InstanceExtensions*>(device_extension_info);
|
|
||||||
for (const auto& ext : has_ext->second) {
|
|
||||||
auto inst_info = instance_extension_info->get_info(ext.c_str());
|
|
||||||
if (inst_info.state) {
|
|
||||||
return instance_extension_info->*(inst_info.state) == kEnabledByCreateinfo || device_extension_info->*(inst_info.state) == kEnabledByInteraction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
''')
|
|
||||||
out.append('''
|
|
||||||
static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDispatchTable *table, PFN_vkGetDeviceProcAddr gpa) {
|
|
||||||
memset(table, 0, sizeof(*table));
|
|
||||||
// Device function pointers
|
|
||||||
table->GetDeviceProcAddr = gpa;
|
|
||||||
''')
|
|
||||||
for command in [x for x in self.vk.commands.values() if x.device and x.name != 'vkGetDeviceProcAddr']:
|
|
||||||
out.extend([f'#ifdef {command.protect}\n'] if command.protect else [])
|
|
||||||
out.append(f' table->{command.name[2:]} = (PFN_{command.name}) gpa(device, "{command.name}");\n')
|
|
||||||
if command.version or command.extensions:
|
|
||||||
out.append(f' if (table->{command.name[2:]} == nullptr) {{ table->{command.name[2:]} = (PFN_{command.name})Stub{command.name[2:]}; }}\n')
|
|
||||||
out.extend([f'#endif // {command.protect}\n'] if command.protect else [])
|
|
||||||
out.append('}\n')
|
|
||||||
|
|
||||||
out.append('''
|
|
||||||
static inline void layer_init_instance_dispatch_table(VkInstance instance, VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa) {
|
|
||||||
memset(table, 0, sizeof(*table));
|
|
||||||
// Instance function pointers
|
|
||||||
table->GetInstanceProcAddr = gpa;
|
|
||||||
table->GetPhysicalDeviceProcAddr = (PFN_GetPhysicalDeviceProcAddr) gpa(instance, "vk_layerGetPhysicalDeviceProcAddr");
|
|
||||||
''')
|
|
||||||
ignoreList = [
|
|
||||||
'vkCreateInstance',
|
|
||||||
'vkCreateDevice',
|
|
||||||
'vkGetPhysicalDeviceProcAddr',
|
|
||||||
'vkEnumerateInstanceExtensionProperties',
|
|
||||||
'vkEnumerateInstanceLayerProperties',
|
|
||||||
'vkEnumerateInstanceVersion',
|
|
||||||
'vkGetInstanceProcAddr',
|
|
||||||
]
|
|
||||||
for command in [x for x in self.vk.commands.values() if x.instance and x.name not in ignoreList]:
|
|
||||||
out.extend([f'#ifdef {command.protect}\n'] if command.protect else [])
|
|
||||||
out.append(f' table->{command.name[2:]} = (PFN_{command.name}) gpa(instance, "{command.name}");\n')
|
|
||||||
if command.version or command.extensions:
|
|
||||||
out.append(f' if (table->{command.name[2:]} == nullptr) {{ table->{command.name[2:]} = (PFN_{command.name})Stub{command.name[2:]}; }}\n')
|
|
||||||
out.extend([f'#endif // {command.protect}\n'] if command.protect else [])
|
|
||||||
out.append('}\n')
|
|
||||||
|
|
||||||
out.append('// NOLINTEND') # Wrap for clang-tidy to ignore
|
|
||||||
self.write("".join(out))
|
|
|
@ -1,56 +0,0 @@
|
||||||
#!/usr/bin/python3 -i
|
|
||||||
#
|
|
||||||
# Copyright 2023 The Khronos Group Inc.
|
|
||||||
# Copyright 2023 Valve Corporation
|
|
||||||
# Copyright 2023 LunarG, Inc.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import os
|
|
||||||
from generators.base_generator import BaseGenerator
|
|
||||||
|
|
||||||
class LayerDispatchTableOutputGenerator(BaseGenerator):
|
|
||||||
def __init__(self):
|
|
||||||
BaseGenerator.__init__(self)
|
|
||||||
|
|
||||||
def generate(self):
|
|
||||||
out = []
|
|
||||||
out.append(f'''// *** THIS FILE IS GENERATED - DO NOT EDIT ***
|
|
||||||
// See {os.path.basename(__file__)} for modifications
|
|
||||||
// Copyright 2023 The Khronos Group Inc.
|
|
||||||
// Copyright 2023 Valve Corporation
|
|
||||||
// Copyright 2023 LunarG, Inc.
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
\n''')
|
|
||||||
out.append('// NOLINTBEGIN') # Wrap for clang-tidy to ignore
|
|
||||||
|
|
||||||
out.append('''
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName);
|
|
||||||
''')
|
|
||||||
out.append('''
|
|
||||||
// Instance function pointer dispatch table
|
|
||||||
typedef struct VkLayerInstanceDispatchTable_ {
|
|
||||||
PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr;
|
|
||||||
|
|
||||||
''')
|
|
||||||
for command in [x for x in self.vk.commands.values() if x.instance]:
|
|
||||||
out.extend([f'#ifdef {command.protect}\n'] if command.protect else [])
|
|
||||||
out.append(f' PFN_{command.name} {command.name[2:]};\n')
|
|
||||||
out.extend([f'#endif //{command.protect}\n'] if command.protect else [])
|
|
||||||
out.append('} VkLayerInstanceDispatchTable;\n')
|
|
||||||
|
|
||||||
out.append('''
|
|
||||||
// Device function pointer dispatch table
|
|
||||||
typedef struct VkLayerDispatchTable_ {
|
|
||||||
''')
|
|
||||||
for command in [x for x in self.vk.commands.values() if x.device]:
|
|
||||||
out.extend([f'#ifdef {command.protect}\n'] if command.protect else [])
|
|
||||||
out.append(f' PFN_{command.name} {command.name[2:]};\n')
|
|
||||||
out.extend([f'#endif //{command.protect}\n'] if command.protect else [])
|
|
||||||
out.append('} VkLayerDispatchTable;\n')
|
|
||||||
|
|
||||||
out.append('// NOLINTEND') # Wrap for clang-tidy to ignore
|
|
||||||
self.write("".join(out))
|
|
|
@ -5,3 +5,4 @@
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
add_subdirectory(layer)
|
add_subdirectory(layer)
|
||||||
add_subdirectory(generated)
|
add_subdirectory(generated)
|
||||||
|
add_subdirectory(vul_dispatch_table)
|
||||||
|
|
|
@ -15,6 +15,7 @@ target_compile_features(add_subdirectory_example PRIVATE c_std_99)
|
||||||
target_sources(add_subdirectory_example PRIVATE
|
target_sources(add_subdirectory_example PRIVATE
|
||||||
client.c
|
client.c
|
||||||
vk_enum_string_helper.c
|
vk_enum_string_helper.c
|
||||||
|
vul_dispatch_table.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# NOTE: Because VulkanHeaders is a PUBLIC dependency it needs to be found prior to VulkanUtilityLibraries
|
# NOTE: Because VulkanHeaders is a PUBLIC dependency it needs to be found prior to VulkanUtilityLibraries
|
||||||
|
@ -26,4 +27,8 @@ if (NOT TARGET Vulkan::LayerSettings)
|
||||||
message(FATAL_ERROR "Vulkan::LayerSettings target not defined!")
|
message(FATAL_ERROR "Vulkan::LayerSettings target not defined!")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(add_subdirectory_example PRIVATE Vulkan::LayerSettings)
|
if (NOT TARGET Vulkan::UtilityHeaders)
|
||||||
|
message(FATAL_ERROR "Vulkan::UtilityHeaders target not defined!")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(add_subdirectory_example PRIVATE Vulkan::LayerSettings Vulkan::UtilityHeaders)
|
||||||
|
|
|
@ -9,9 +9,9 @@ VkBool32 foobar() {
|
||||||
VlLayerSettingSet layerSettingSet = VK_NULL_HANDLE;
|
VlLayerSettingSet layerSettingSet = VK_NULL_HANDLE;
|
||||||
vlCreateLayerSettingSet("VK_LAYER_LUNARG_test", NULL, NULL, NULL, &layerSettingSet);
|
vlCreateLayerSettingSet("VK_LAYER_LUNARG_test", NULL, NULL, NULL, &layerSettingSet);
|
||||||
|
|
||||||
VkBool32 result = vlHasLayerSetting(layerSettingSet, "setting_key") ? VK_TRUE : VK_FALSE;
|
VkBool32 result = vlHasLayerSetting(layerSettingSet, "setting_key") ? VK_TRUE : VK_FALSE;
|
||||||
|
|
||||||
vlDestroyLayerSettingSet(layerSettingSet, NULL);
|
vlDestroyLayerSettingSet(layerSettingSet, NULL);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
31
tests/add_subdirectory/vul_dispatch_table.c
Normal file
31
tests/add_subdirectory/vul_dispatch_table.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2023 The Khronos Group Inc.
|
||||||
|
// Copyright 2023 Valve Corporation
|
||||||
|
// Copyright 2023 LunarG, Inc.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
#include <vulkan/utility/vul_dispatch_table.h>
|
||||||
|
|
||||||
|
PFN_vkVoidFunction local_vkGetInstanceProcAddr(VkInstance instance, const char *pName) {
|
||||||
|
(void)instance;
|
||||||
|
(void)pName;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PFN_vkVoidFunction local_vkGetDeviceProcAddr(VkDevice device, const char *pName) {
|
||||||
|
(void)device;
|
||||||
|
(void)pName;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void foobar() {
|
||||||
|
VulDeviceDispatchTable device_dispatch_table;
|
||||||
|
VulInstanceDispatchTable instance_dispatch_table;
|
||||||
|
|
||||||
|
VkInstance instance = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
vulInitInstanceDispatchTable(instance, &instance_dispatch_table, local_vkGetInstanceProcAddr);
|
||||||
|
|
||||||
|
VkDevice device = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
vulInitDeviceDispatchTable(device, &device_dispatch_table, local_vkGetDeviceProcAddr);
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ target_compile_features(find_package_example PRIVATE c_std_99)
|
||||||
target_sources(find_package_example PRIVATE
|
target_sources(find_package_example PRIVATE
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../add_subdirectory/client.c
|
${CMAKE_CURRENT_LIST_DIR}/../add_subdirectory/client.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../add_subdirectory/vk_enum_string_helper.c
|
${CMAKE_CURRENT_LIST_DIR}/../add_subdirectory/vk_enum_string_helper.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../add_subdirectory/vul_dispatch_table.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# NOTE: Because VulkanHeaders is a PUBLIC dependency it needs to be found prior to VulkanUtilityLibraries
|
# NOTE: Because VulkanHeaders is a PUBLIC dependency it needs to be found prior to VulkanUtilityLibraries
|
||||||
|
@ -26,4 +27,8 @@ if (NOT TARGET Vulkan::LayerSettings)
|
||||||
message(FATAL_ERROR "Vulkan::LayerSettings target not defined!")
|
message(FATAL_ERROR "Vulkan::LayerSettings target not defined!")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(find_package_example PRIVATE Vulkan::LayerSettings)
|
if (NOT TARGET Vulkan::UtilityHeaders)
|
||||||
|
message(FATAL_ERROR "Vulkan::UtilityHeaders target not defined!")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(find_package_example PRIVATE Vulkan::LayerSettings Vulkan::UtilityHeaders)
|
||||||
|
|
26
tests/vul_dispatch_table/CMakeLists.txt
Normal file
26
tests/vul_dispatch_table/CMakeLists.txt
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# Copyright 2023 The Khronos Group Inc.
|
||||||
|
# Copyright 2023 Valve Corporation
|
||||||
|
# Copyright 2023 LunarG, Inc.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
find_package(GTest REQUIRED CONFIG)
|
||||||
|
|
||||||
|
include(GoogleTest)
|
||||||
|
|
||||||
|
add_executable(test_vul_dispatch_table test_interface.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(test_vul_dispatch_table PRIVATE
|
||||||
|
GTest::gtest
|
||||||
|
GTest::gtest_main
|
||||||
|
Vulkan::UtilityHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
if(${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
|
||||||
|
add_compile_options(-Wpedantic -Wall -Wextra -Werror)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
target_include_directories(test_vul_dispatch_table PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
|
||||||
|
|
||||||
|
gtest_discover_tests(test_vul_dispatch_table)
|
45
tests/vul_dispatch_table/test_interface.cpp
Normal file
45
tests/vul_dispatch_table/test_interface.cpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright 2023 The Khronos Group Inc.
|
||||||
|
// Copyright 2023 Valve Corporation
|
||||||
|
// Copyright 2023 LunarG, Inc.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <vulkan/utility/vul_dispatch_table.h>
|
||||||
|
|
||||||
|
// Only exists so that local_vkGetDeviceProcAddr can return a 'real' function pointer
|
||||||
|
inline void empty_func() {}
|
||||||
|
|
||||||
|
inline PFN_vkVoidFunction local_vkGetInstanceProcAddr(VkInstance instance, const char *pName) {
|
||||||
|
if (instance == VK_NULL_HANDLE) return NULL;
|
||||||
|
|
||||||
|
if (strcmp(pName, "vkGetInstanceProcAddr")) return reinterpret_cast<PFN_vkVoidFunction>(&local_vkGetInstanceProcAddr);
|
||||||
|
|
||||||
|
return reinterpret_cast<PFN_vkVoidFunction>(&empty_func);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PFN_vkVoidFunction local_vkGetDeviceProcAddr(VkDevice device, const char *pName) {
|
||||||
|
if (device == VK_NULL_HANDLE) return NULL;
|
||||||
|
|
||||||
|
if (strcmp(pName, "vkGetDeviceProcAddr")) return reinterpret_cast<PFN_vkVoidFunction>(&local_vkGetDeviceProcAddr);
|
||||||
|
return reinterpret_cast<PFN_vkVoidFunction>(&empty_func);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(test_vul_dispatch_table, cpp_interface) {
|
||||||
|
VulDeviceDispatchTable device_dispatch_table{};
|
||||||
|
VulInstanceDispatchTable instance_dispatch_table{};
|
||||||
|
|
||||||
|
VkInstance instance{};
|
||||||
|
|
||||||
|
vulInitInstanceDispatchTable(instance, &instance_dispatch_table, local_vkGetInstanceProcAddr);
|
||||||
|
|
||||||
|
ASSERT_EQ(instance_dispatch_table.GetInstanceProcAddr, local_vkGetInstanceProcAddr);
|
||||||
|
|
||||||
|
VkDevice device{};
|
||||||
|
|
||||||
|
vulInitDeviceDispatchTable(device, &device_dispatch_table, local_vkGetDeviceProcAddr);
|
||||||
|
|
||||||
|
ASSERT_EQ(device_dispatch_table.GetDeviceProcAddr, local_vkGetDeviceProcAddr);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue