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/*
37Interface Version 0
38*/
39
40/*
41must export the following: -- always exported
42vkEnumerateInstanceLayerProperties
43vkEnumerateInstanceExtensionProperties
44Must export the following but nothing -- always exported
45vkEnumerateDeviceLayerProperties
46vkEnumerateDeviceExtensionProperties
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/*
62Interface 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/*
73Interface 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
83struct 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
89using FP_layer_callback = VkResult (*)(TestLayer& layer, void* data);
90
91struct 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;
152    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;
158    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    }
163    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
219using GetTestLayerFunc = TestLayer* (*)();
220#define GET_TEST_LAYER_FUNC_STR "get_test_layer_func"
221
222using GetNewTestLayerFunc = TestLayer* (*)();
223#define RESET_LAYER_FUNC_STR "reset_layer_func"
224