1 /* 2 * Copyright (c) 2021-2022 The Khronos Group Inc. 3 * Copyright (c) 2021-2022 Valve Corporation 4 * Copyright (c) 2021-2022 LunarG, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and/or associated documentation files (the "Materials"), to 8 * deal in the Materials without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Materials, and to permit persons to whom the Materials are 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice(s) and this permission notice shall be included in 14 * all copies or substantial portions of the Materials. 15 * 16 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 * 20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 23 * USE OR OTHER DEALINGS IN THE MATERIALS. 24 * 25 * Author: Charles Giessen <charles@lunarg.com> 26 */ 27 28 #pragma once 29 30 #include "test_util.h" 31 32 #include "layer/layer_util.h" 33 34 #include "loader/generated/vk_layer_dispatch_table.h" 35 36 /* 37 Interface Version 0 38 */ 39 40 /* 41 must export the following: -- always exported 42 vkEnumerateInstanceLayerProperties 43 vkEnumerateInstanceExtensionProperties 44 Must export the following but nothing -- always exported 45 vkEnumerateDeviceLayerProperties 46 vkEnumerateDeviceExtensionProperties 47 */ 48 49 // export test_layer_GetInstanceProcAddr(instance, pName) 50 // TEST_LAYER_EXPORT_LAYER_NAMED_GIPA 51 // or (single layer binary) 52 // export vkGetInstanceProcAddr 53 // TEST_LAYER_EXPORT_NO_NAME_GIPA 54 55 // export test_layer_GetDeviceProcAddr(device, pName) 56 // TEST_LAYER_EXPORT_LAYER_NAMED_GDPA 57 // or (single layer binary) 58 // export vkGetDeviceProcAddr 59 // TEST_LAYER_EXPORT_NO_NAME_GDPA 60 61 /* 62 Interface Version 1 63 */ 64 // export GetInstanceProcAddr 65 // TEST_LAYER_EXPORT_NO_PREFIX_GIPA 66 67 // export GetDeviceProcAddr 68 // TEST_LAYER_EXPORT_NO_PREFIX_GDPA 69 70 // Layer Manifest can override the names of the GetInstanceProcAddr and GetDeviceProcAddrfunctions 71 72 /* 73 Interface Version 2 74 */ 75 // export vk_layerGetPhysicalDeviceProcAddr 76 // TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR 77 78 // export vkNegotiateLoaderLayerInterfaceVersion 79 // TEST_LAYER_EXPORT_NEGOTIATE_LOADER_LAYER_INTERFACE_VERSION 80 81 // Added manifest version 1.1.0 82 83 struct TestLayer; 84 85 // Callbacks allow tests to implement custom functionality without modifying the layer binary 86 // TestLayer* layer - Access to the TestLayer object itself 87 // void* data - pointer to test specific thing, used to pass data from the test into the TestLayer 88 // Returns VkResult - This value will be used as the return value of the function 89 using FP_layer_callback = VkResult (*)(TestLayer& layer, void* data); 90 91 struct TestLayer { 92 fs::path manifest_file_path; 93 uint32_t manifest_version = VK_MAKE_API_VERSION(0, 1, 1, 2); 94 95 BUILDER_VALUE(TestLayer, bool, is_meta_layer, false) 96 97 BUILDER_VALUE(TestLayer, uint32_t, api_version, VK_API_VERSION_1_0) 98 BUILDER_VALUE(TestLayer, uint32_t, reported_layer_props, 1) 99 BUILDER_VALUE(TestLayer, uint32_t, reported_extension_props, 0) 100 BUILDER_VALUE(TestLayer, uint32_t, reported_instance_version, VK_API_VERSION_1_0) 101 BUILDER_VALUE(TestLayer, uint32_t, implementation_version, 2) 102 BUILDER_VALUE(TestLayer, uint32_t, min_implementation_version, 0) 103 BUILDER_VALUE(TestLayer, std::string, description, {}) 104 105 // Some layers may try to change the API version during instance creation - we should allow testing of such behavior 106 BUILDER_VALUE(TestLayer, uint32_t, alter_api_version, VK_API_VERSION_1_0) 107 108 BUILDER_VECTOR(TestLayer, std::string, alternative_function_names, alternative_function_name) 109 110 BUILDER_VECTOR(TestLayer, Extension, instance_extensions, instance_extension) 111 std::vector<Extension> enabled_instance_extensions; 112 113 BUILDER_VECTOR(TestLayer, Extension, device_extensions, device_extension) 114 115 BUILDER_VALUE(TestLayer, std::string, enable_environment, {}); 116 BUILDER_VALUE(TestLayer, std::string, disable_environment, {}); 117 118 // Modifies the extension list returned by vkEnumerateInstanceExtensionProperties to include what is in this vector 119 BUILDER_VECTOR(TestLayer, Extension, injected_instance_extensions, injected_instance_extension) 120 // Modifies the extension list returned by vkEnumerateDeviceExtensionProperties to include what is in this vector 121 BUILDER_VECTOR(TestLayer, Extension, injected_device_extensions, injected_device_extension) 122 123 BUILDER_VECTOR(TestLayer, LayerDefinition, meta_component_layers, meta_component_layer); 124 125 BUILDER_VALUE(TestLayer, bool, intercept_vkEnumerateInstanceExtensionProperties, false) 126 BUILDER_VALUE(TestLayer, bool, intercept_vkEnumerateInstanceLayerProperties, false) 127 // Called in vkCreateInstance after calling down the chain & returning 128 BUILDER_VALUE(TestLayer, std::function<VkResult(TestLayer& layer)>, create_instance_callback, {}) 129 // Called in vkCreateDevice after calling down the chain & returning 130 BUILDER_VALUE(TestLayer, std::function<VkResult(TestLayer& layer)>, create_device_callback, {}) 131 132 // Physical device modifier test flags and members. This data is primarily used to test adding, removing and 133 // re-ordering physical device data in a layer. 134 BUILDER_VALUE(TestLayer, bool, add_phys_devs, false) 135 BUILDER_VALUE(TestLayer, bool, remove_phys_devs, false) 136 BUILDER_VALUE(TestLayer, bool, reorder_phys_devs, false) 137 BUILDER_VECTOR(TestLayer, VkPhysicalDevice, complete_physical_devices, complete_physical_device) 138 BUILDER_VECTOR(TestLayer, VkPhysicalDevice, removed_physical_devices, removed_physical_device) 139 BUILDER_VECTOR(TestLayer, VkPhysicalDevice, added_physical_devices, added_physical_device) 140 BUILDER_VECTOR(TestLayer, VkPhysicalDeviceGroupProperties, complete_physical_device_groups, complete_physical_device_group) 141 BUILDER_VECTOR(TestLayer, VkPhysicalDeviceGroupProperties, removed_physical_device_groups, removed_physical_device_group) 142 BUILDER_VECTOR(TestLayer, VkPhysicalDeviceGroupProperties, added_physical_device_groups, added_physical_device_group) 143 144 BUILDER_VECTOR(TestLayer, VulkanFunction, custom_physical_device_implementation_functions, 145 custom_physical_device_implementation_function) 146 BUILDER_VECTOR(TestLayer, VulkanFunction, custom_device_implementation_functions, custom_device_implementation_function) 147 148 // Only need a single map for all 'custom' function - assumes that all function names are distinct, IE there cannot be a 149 // physical device and device level function with the same name 150 std::unordered_map<std::string, PFN_vkVoidFunction> custom_dispatch_functions; 151 std::vector<VulkanFunction> custom_physical_device_interception_functions; add_custom_physical_device_intercept_functionTestLayer152 TestLayer& add_custom_physical_device_intercept_function(std::string func_name, PFN_vkVoidFunction function) { 153 custom_physical_device_interception_functions.push_back({func_name, function}); 154 custom_dispatch_functions[func_name] = nullptr; 155 return *this; 156 } 157 std::vector<VulkanFunction> custom_device_interception_functions; add_custom_device_interception_functionTestLayer158 TestLayer& add_custom_device_interception_function(std::string func_name, PFN_vkVoidFunction function) { 159 custom_device_interception_functions.push_back({func_name, function}); 160 custom_dispatch_functions[func_name] = nullptr; 161 return *this; 162 } get_custom_intercept_functionTestLayer163 PFN_vkVoidFunction get_custom_intercept_function(const char* name) { 164 if (custom_dispatch_functions.count(name) > 0) { 165 return custom_dispatch_functions.at(name); 166 } 167 return nullptr; 168 } 169 170 // Allows distinguishing different layers (that use the same binary) 171 BUILDER_VALUE(TestLayer, std::string, make_spurious_log_in_create_instance, "") 172 BUILDER_VALUE(TestLayer, bool, do_spurious_allocations_in_create_instance, false) 173 void* spurious_instance_memory_allocation = nullptr; 174 BUILDER_VALUE(TestLayer, bool, do_spurious_allocations_in_create_device, false) 175 struct DeviceMemAlloc { 176 void* allocation; 177 VkDevice device; 178 }; 179 std::vector<DeviceMemAlloc> spurious_device_memory_allocations; 180 181 // By default query GPDPA from GIPA, don't use value given from pNext 182 BUILDER_VALUE(TestLayer, bool, use_gipa_GetPhysicalDeviceProcAddr, true) 183 184 // Have a layer query for vkCreateDevice with a NULL instance handle 185 BUILDER_VALUE(TestLayer, bool, buggy_query_of_vkCreateDevice, false) 186 187 // Makes the layer try to create a device using the loader provided function in the layer chain 188 BUILDER_VALUE(TestLayer, bool, call_create_device_while_create_device_is_called, false) 189 BUILDER_VALUE(TestLayer, uint32_t, physical_device_index_to_use_during_create_device, 0) 190 191 BUILDER_VALUE(TestLayer, bool, check_if_EnumDevExtProps_is_same_as_queried_function, false) 192 193 // Clober the data pointed to by pInstance to overwrite the magic value 194 BUILDER_VALUE(TestLayer, bool, clobber_pInstance, false) 195 // Clober the data pointed to by pDevice to overwrite the magic value 196 BUILDER_VALUE(TestLayer, bool, clobber_pDevice, false) 197 198 PFN_vkGetInstanceProcAddr next_vkGetInstanceProcAddr = VK_NULL_HANDLE; 199 PFN_GetPhysicalDeviceProcAddr next_GetPhysicalDeviceProcAddr = VK_NULL_HANDLE; 200 PFN_vkGetDeviceProcAddr next_vkGetDeviceProcAddr = VK_NULL_HANDLE; 201 202 VkInstance instance_handle = VK_NULL_HANDLE; 203 VkLayerInstanceDispatchTable instance_dispatch_table{}; 204 205 struct Device { 206 VkDevice device_handle = VK_NULL_HANDLE; 207 VkLayerDispatchTable dispatch_table{}; 208 std::vector<Extension> enabled_extensions; 209 }; 210 std::vector<Device> created_devices; 211 212 // Stores the callback that allows layers to create devices on their own 213 PFN_vkLayerCreateDevice callback_vkCreateDevice{}; 214 PFN_vkLayerDestroyDevice callback_vkDestroyDevice{}; 215 std::vector<VkPhysicalDevice> queried_physical_devices; 216 Device second_device_created_during_create_device{}; 217 }; 218 219 using GetTestLayerFunc = TestLayer* (*)(); 220 #define GET_TEST_LAYER_FUNC_STR "get_test_layer_func" 221 222 using GetNewTestLayerFunc = TestLayer* (*)(); 223 #define RESET_LAYER_FUNC_STR "reset_layer_func" 224