1 /*
2  * Copyright (c) 2021 The Khronos Group Inc.
3  * Copyright (c) 2021 Valve Corporation
4  * Copyright (c) 2021 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 "physical_device.h"
35 
36 enum class CalledICDGIPA { not_called, vk_icd_gipa, vk_gipa };
37 
38 enum class CalledNegotiateInterface { not_called, vk_icd_negotiate, vk_icd_gipa_first };
39 
40 enum class InterfaceVersionCheck {
41     not_called,
42     loader_version_too_old,
43     loader_version_too_new,
44     icd_version_too_new,
45     version_is_supported
46 };
47 
48 enum class CalledEnumerateAdapterPhysicalDevices { not_called, called, called_but_not_supported };
49 
50 enum class UsingICDProvidedWSI { not_using, is_using };
51 
52 struct TestICD {
53     fs::path manifest_file_path;
54 
55     CalledICDGIPA called_vk_icd_gipa = CalledICDGIPA::not_called;
56     CalledNegotiateInterface called_negotiate_interface = CalledNegotiateInterface::not_called;
57 
58     InterfaceVersionCheck interface_version_check = InterfaceVersionCheck::not_called;
59     BUILDER_VALUE(TestICD, uint32_t, min_icd_interface_version, 0)
60     BUILDER_VALUE(TestICD, uint32_t, max_icd_interface_version, 6)
61     uint32_t icd_interface_version_received = 0;
62 
63     CalledEnumerateAdapterPhysicalDevices called_enumerate_adapter_physical_devices =
64         CalledEnumerateAdapterPhysicalDevices::not_called;
65 
66     BUILDER_VALUE(TestICD, bool, enable_icd_wsi, false);
67     UsingICDProvidedWSI is_using_icd_wsi = UsingICDProvidedWSI::not_using;
68 
69     BUILDER_VALUE(TestICD, uint32_t, icd_api_version, VK_MAKE_VERSION(1, 0, 0))
70     BUILDER_VECTOR(TestICD, LayerDefinition, instance_layers, instance_layer)
71     BUILDER_VECTOR(TestICD, Extension, instance_extensions, instance_extension)
72 
73     BUILDER_VECTOR_MOVE_ONLY(TestICD, PhysicalDevice, physical_devices, physical_device);
74 
75     BUILDER_VECTOR(TestICD, PhysicalDeviceGroup, physical_device_groups, physical_device_group);
76 
77     DispatchableHandle<VkInstance> instance_handle;
78     std::vector<DispatchableHandle<VkDevice>> device_handles;
79     std::vector<uint64_t> surface_handles;
80     std::vector<uint64_t> messenger_handles;
81     std::vector<uint64_t> swapchain_handles;
82 
83     // Unknown instance and physical device functions. Add a `VulkanFunction` to this list which will be searched in
84     // vkGetInstanceProcAddr for custom_instance_functions and vk_icdGetPhysicalDeviceProcAddr for custom_physical_device_functions.
85     // To add unknown device functions, add it to the PhysicalDevice directly (in the known_device_functions member)
86     BUILDER_VECTOR(TestICD, VulkanFunction, custom_instance_functions, custom_instance_function)
87     BUILDER_VECTOR(TestICD, VulkanFunction, custom_physical_device_functions, custom_physical_device_function)
88 
89     // Must explicitely state support for the tooling info extension, that way we can control if vkGetInstanceProcAddr returns a
90     // function pointer for vkGetPhysicalDeviceToolPropertiesEXT
91     BUILDER_VALUE(TestICD, bool, supports_tooling_info_ext, false)
92     // List of tooling properties that this driver 'supports'
93     std::vector<VkPhysicalDeviceToolPropertiesEXT> tooling_properties;
94 
GetPhysDeviceTestICD95     PhysicalDevice& GetPhysDevice(VkPhysicalDevice physicalDevice) {
96         for (auto& phys_dev : physical_devices) {
97             if (phys_dev.vk_physical_device.handle == physicalDevice) return phys_dev;
98         }
99         assert(false && "vkPhysicalDevice not found!");
100         return physical_devices[0];
101     }
102 
GetVkInstanceCreateInfoTestICD103     InstanceCreateInfo GetVkInstanceCreateInfo() {
104         InstanceCreateInfo info;
105         for (auto& layer : instance_layers) info.enabled_layers.push_back(layer.layerName.data());
106         for (auto& ext : instance_extensions) info.enabled_extensions.push_back(ext.extensionName.data());
107         return info;
108     }
109 };
110 
111 using GetTestICDFunc = TestICD* (*)();
112 #define GET_TEST_ICD_FUNC_STR "get_test_icd_func"
113 
114 using GetNewTestICDFunc = TestICD* (*)();
115 #define RESET_ICD_FUNC_STR "reset_icd_func"