• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <functional>
33 
34 #include "layer/layer_util.h"
35 
36 #include "loader/generated/vk_layer_dispatch_table.h"
37 
38 /*
39 Interface Version 0
40 */
41 
42 /*
43 must export the following: -- always exported
44 vkEnumerateInstanceLayerProperties
45 vkEnumerateInstanceExtensionProperties
46 Must export the following but nothing -- always exported
47 vkEnumerateDeviceLayerProperties
48 vkEnumerateDeviceExtensionProperties
49 */
50 
51 // export test_layer_GetInstanceProcAddr(instance, pName)
52 // TEST_LAYER_EXPORT_LAYER_NAMED_GIPA
53 // or (single layer binary)
54 // export vkGetInstanceProcAddr
55 // TEST_LAYER_EXPORT_NO_NAME_GIPA
56 
57 // export test_layer_GetDeviceProcAddr(device, pName)
58 // TEST_LAYER_EXPORT_LAYER_NAMED_GDPA
59 // or (single layer binary)
60 // export vkGetDeviceProcAddr
61 // TEST_LAYER_EXPORT_NO_NAME_GDPA
62 
63 /*
64 Interface Version 1
65 */
66 // export GetInstanceProcAddr
67 // TEST_LAYER_EXPORT_NO_PREFIX_GIPA
68 
69 // export GetDeviceProcAddr
70 // TEST_LAYER_EXPORT_NO_PREFIX_GDPA
71 
72 // Layer Manifest can override the names of the GetInstanceProcAddr and GetDeviceProcAddrfunctions
73 
74 /*
75 Interface Version 2
76 */
77 // export vk_layerGetPhysicalDeviceProcAddr
78 // TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR
79 
80 // export vkNegotiateLoaderLayerInterfaceVersion
81 // TEST_LAYER_EXPORT_NEGOTIATE_LOADER_LAYER_INTERFACE_VERSION
82 
83 // Added manifest version 1.1.0
84 
85 struct TestLayer;
86 
87 // Callbacks allow tests to implement custom functionality without modifying the layer binary
88 // TestLayer* layer - Access to the TestLayer object itself
89 // void* data - pointer to test specific thing, used to pass data from the test into the TestLayer
90 // Returns VkResult - This value will be used as the return value of the function
91 using FP_layer_callback = VkResult (*)(TestLayer& layer, void* data);
92 
93 struct TestLayer {
94     std::filesystem::path manifest_file_path;
95     uint32_t manifest_version = VK_MAKE_API_VERSION(0, 1, 1, 2);
96 
97     BUILDER_VALUE(TestLayer, bool, is_meta_layer, false)
98 
99     BUILDER_VALUE(TestLayer, uint32_t, api_version, VK_API_VERSION_1_0)
100     BUILDER_VALUE(TestLayer, uint32_t, reported_layer_props, 1)
101     BUILDER_VALUE(TestLayer, uint32_t, reported_extension_props, 0)
102     BUILDER_VALUE(TestLayer, uint32_t, reported_instance_version, VK_API_VERSION_1_0)
103     BUILDER_VALUE(TestLayer, uint32_t, implementation_version, 2)
104     BUILDER_VALUE(TestLayer, uint32_t, min_implementation_version, 0)
105     BUILDER_VALUE(TestLayer, std::string, description, {})
106 
107     // Some layers may try to change the API version during instance creation - we should allow testing of such behavior
108     BUILDER_VALUE(TestLayer, uint32_t, alter_api_version, VK_API_VERSION_1_0)
109 
110     BUILDER_VECTOR(TestLayer, std::string, alternative_function_names, alternative_function_name)
111 
112     BUILDER_VECTOR(TestLayer, Extension, instance_extensions, instance_extension)
113     std::vector<Extension> enabled_instance_extensions;
114 
115     BUILDER_VECTOR(TestLayer, Extension, device_extensions, device_extension)
116 
117     BUILDER_VALUE(TestLayer, std::string, enable_environment, {});
118     BUILDER_VALUE(TestLayer, std::string, disable_environment, {});
119 
120     // Modifies the extension list returned by vkEnumerateInstanceExtensionProperties to include what is in this vector
121     BUILDER_VECTOR(TestLayer, Extension, injected_instance_extensions, injected_instance_extension)
122     // Modifies the extension list returned by  vkEnumerateDeviceExtensionProperties to include what is in this vector
123     BUILDER_VECTOR(TestLayer, Extension, injected_device_extensions, injected_device_extension)
124 
125     BUILDER_VECTOR(TestLayer, LayerDefinition, meta_component_layers, meta_component_layer);
126 
127     BUILDER_VALUE(TestLayer, bool, intercept_vkEnumerateInstanceExtensionProperties, false)
128     BUILDER_VALUE(TestLayer, bool, intercept_vkEnumerateInstanceLayerProperties, false)
129     // Called in vkCreateInstance after calling down the chain & returning
130     BUILDER_VALUE(TestLayer, std::function<VkResult(TestLayer& layer)>, create_instance_callback, {})
131     // Called in vkCreateDevice after calling down the chain & returning
132     BUILDER_VALUE(TestLayer, std::function<VkResult(TestLayer& layer)>, create_device_callback, {})
133 
134     // Physical device modifier test flags and members.  This data is primarily used to test adding, removing and
135     // re-ordering physical device data in a layer.
136     BUILDER_VALUE(TestLayer, bool, add_phys_devs, false)
137     BUILDER_VALUE(TestLayer, bool, remove_phys_devs, false)
138     BUILDER_VALUE(TestLayer, bool, reorder_phys_devs, false)
139     BUILDER_VECTOR(TestLayer, VkPhysicalDevice, complete_physical_devices, complete_physical_device)
140     BUILDER_VECTOR(TestLayer, VkPhysicalDevice, removed_physical_devices, removed_physical_device)
141     BUILDER_VECTOR(TestLayer, VkPhysicalDevice, added_physical_devices, added_physical_device)
142     BUILDER_VECTOR(TestLayer, VkPhysicalDeviceGroupProperties, complete_physical_device_groups, complete_physical_device_group)
143     BUILDER_VECTOR(TestLayer, VkPhysicalDeviceGroupProperties, removed_physical_device_groups, removed_physical_device_group)
144     BUILDER_VECTOR(TestLayer, VkPhysicalDeviceGroupProperties, added_physical_device_groups, added_physical_device_group)
145 
146     BUILDER_VECTOR(TestLayer, VulkanFunction, custom_physical_device_implementation_functions,
147                    custom_physical_device_implementation_function)
148     BUILDER_VECTOR(TestLayer, VulkanFunction, custom_device_implementation_functions, custom_device_implementation_function)
149 
150     // Only need a single map for all 'custom' function - assumes that all function names are distinct, IE there cannot be a
151     // physical device and device level function with the same name
152     std::unordered_map<std::string, PFN_vkVoidFunction> custom_dispatch_functions;
153     std::vector<VulkanFunction> custom_physical_device_interception_functions;
add_custom_physical_device_intercept_functionTestLayer154     TestLayer& add_custom_physical_device_intercept_function(std::string func_name, PFN_vkVoidFunction function) {
155         custom_physical_device_interception_functions.push_back({func_name, function});
156         custom_dispatch_functions[func_name] = nullptr;
157         return *this;
158     }
159     std::vector<VulkanFunction> custom_device_interception_functions;
add_custom_device_interception_functionTestLayer160     TestLayer& add_custom_device_interception_function(std::string func_name, PFN_vkVoidFunction function) {
161         custom_device_interception_functions.push_back({func_name, function});
162         custom_dispatch_functions[func_name] = nullptr;
163         return *this;
164     }
get_custom_intercept_functionTestLayer165     PFN_vkVoidFunction get_custom_intercept_function(const char* name) {
166         if (custom_dispatch_functions.count(name) > 0) {
167             return custom_dispatch_functions.at(name);
168         }
169         return nullptr;
170     }
171 
172     // Allows distinguishing different layers (that use the same binary)
173     BUILDER_VALUE(TestLayer, std::string, make_spurious_log_in_create_instance, "")
174     BUILDER_VALUE(TestLayer, bool, do_spurious_allocations_in_create_instance, false)
175     void* spurious_instance_memory_allocation = nullptr;
176     BUILDER_VALUE(TestLayer, bool, do_spurious_allocations_in_create_device, false)
177     struct DeviceMemAlloc {
178         void* allocation;
179         VkDevice device;
180     };
181     std::vector<DeviceMemAlloc> spurious_device_memory_allocations;
182 
183     // By default query GPDPA from GIPA, don't use value given from pNext
184     BUILDER_VALUE(TestLayer, bool, use_gipa_GetPhysicalDeviceProcAddr, true)
185 
186     // Have a layer query for vkCreateDevice with a NULL instance handle
187     BUILDER_VALUE(TestLayer, bool, buggy_query_of_vkCreateDevice, false)
188 
189     // Makes the layer try to create a device using the loader provided function in the layer chain
190     BUILDER_VALUE(TestLayer, bool, call_create_device_while_create_device_is_called, false)
191     BUILDER_VALUE(TestLayer, uint32_t, physical_device_index_to_use_during_create_device, 0)
192 
193     BUILDER_VALUE(TestLayer, bool, check_if_EnumDevExtProps_is_same_as_queried_function, false)
194 
195     // Clober the data pointed to by pInstance to overwrite the magic value
196     BUILDER_VALUE(TestLayer, bool, clobber_pInstance, false)
197     // Clober the data pointed to by pDevice to overwrite the magic value
198     BUILDER_VALUE(TestLayer, bool, clobber_pDevice, false)
199 
200     BUILDER_VALUE(TestLayer, bool, query_vkEnumerateInstanceLayerProperties, false)
201     BUILDER_VALUE(TestLayer, bool, query_vkEnumerateInstanceExtensionProperties, false)
202     BUILDER_VALUE(TestLayer, bool, query_vkEnumerateInstanceVersion, false)
203 
204     PFN_vkGetInstanceProcAddr next_vkGetInstanceProcAddr = VK_NULL_HANDLE;
205     PFN_GetPhysicalDeviceProcAddr next_GetPhysicalDeviceProcAddr = VK_NULL_HANDLE;
206     PFN_vkGetDeviceProcAddr next_vkGetDeviceProcAddr = VK_NULL_HANDLE;
207 
208     VkInstance instance_handle = VK_NULL_HANDLE;
209     VkLayerInstanceDispatchTable instance_dispatch_table{};
210 
211     struct Device {
212         VkDevice device_handle = VK_NULL_HANDLE;
213         VkLayerDispatchTable dispatch_table{};
214         std::vector<Extension> enabled_extensions;
215     };
216     std::vector<Device> created_devices;
217 
218     // Stores the callback that allows layers to create devices on their own
219     PFN_vkLayerCreateDevice callback_vkCreateDevice{};
220     PFN_vkLayerDestroyDevice callback_vkDestroyDevice{};
221     std::vector<VkPhysicalDevice> queried_physical_devices;
222     Device second_device_created_during_create_device{};
223 };
224 
225 using GetTestLayerFunc = TestLayer* (*)();
226 #define GET_TEST_LAYER_FUNC_STR "get_test_layer_func"
227 
228 using GetNewTestLayerFunc = TestLayer* (*)();
229 #define RESET_LAYER_FUNC_STR "reset_layer_func"
230