1 /*
2  *
3  * Copyright (c) 2014-2021 The Khronos Group Inc.
4  * Copyright (c) 2014-2021 Valve Corporation
5  * Copyright (c) 2014-2021 LunarG, Inc.
6  * Copyright (C) 2015 Google Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  * Author: Jon Ashburn <jon@lunarg.com>
21  * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
22  * Author: Chia-I Wu <olvaffe@gmail.com>
23  * Author: Chia-I Wu <olv@lunarg.com>
24  * Author: Mark Lobodzinski <mark@LunarG.com>
25  * Author: Lenny Komow <lenny@lunarg.com>
26  * Author: Charles Giessen <charles@lunarg.com>
27  *
28  */
29 
30 #pragma once
31 
32 #include "vk_loader_platform.h"
33 
34 enum layer_type_flags {
35     VK_LAYER_TYPE_FLAG_INSTANCE_LAYER = 0x1,  // If not set, indicates Device layer
36     VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER = 0x2,  // If not set, indicates Implicit layer
37     VK_LAYER_TYPE_FLAG_META_LAYER = 0x4,      // If not set, indicates standard layer
38 };
39 
40 typedef enum VkStringErrorFlagBits {
41     VK_STRING_ERROR_NONE = 0x00000000,
42     VK_STRING_ERROR_LENGTH = 0x00000001,
43     VK_STRING_ERROR_BAD_DATA = 0x00000002,
44     VK_STRING_ERROR_NULL_PTR = 0x00000004,
45 } VkStringErrorFlagBits;
46 typedef VkFlags VkStringErrorFlags;
47 
48 static const int MaxLoaderStringLength = 256;
49 static const char UTF8_ONE_BYTE_CODE = 0xC0;
50 static const char UTF8_ONE_BYTE_MASK = 0xE0;
51 static const char UTF8_TWO_BYTE_CODE = 0xE0;
52 static const char UTF8_TWO_BYTE_MASK = 0xF0;
53 static const char UTF8_THREE_BYTE_CODE = 0xF0;
54 static const char UTF8_THREE_BYTE_MASK = 0xF8;
55 static const char UTF8_DATA_BYTE_CODE = 0x80;
56 static const char UTF8_DATA_BYTE_MASK = 0xC0;
57 
58 // form of all dynamic lists/arrays
59 // only the list element should be changed
60 struct loader_generic_list {
61     size_t capacity;
62     uint32_t count;
63     void *list;
64 };
65 
66 struct loader_extension_list {
67     size_t capacity;
68     uint32_t count;
69     VkExtensionProperties *list;
70 };
71 
72 struct loader_dev_ext_props {
73     VkExtensionProperties props;
74     uint32_t entrypoint_count;
75     char **entrypoints;
76 };
77 
78 struct loader_device_extension_list {
79     size_t capacity;
80     uint32_t count;
81     struct loader_dev_ext_props *list;
82 };
83 
84 struct loader_name_value {
85     char name[MAX_STRING_SIZE];
86     char value[MAX_STRING_SIZE];
87 };
88 
89 struct loader_layer_functions {
90     char str_gipa[MAX_STRING_SIZE];
91     char str_gdpa[MAX_STRING_SIZE];
92     char str_negotiate_interface[MAX_STRING_SIZE];
93     PFN_vkNegotiateLoaderLayerInterfaceVersion negotiate_layer_interface;
94     PFN_vkGetInstanceProcAddr get_instance_proc_addr;
95     PFN_vkGetDeviceProcAddr get_device_proc_addr;
96     PFN_GetPhysicalDeviceProcAddr get_physical_device_proc_addr;
97 };
98 
99 struct loader_override_expiration {
100     uint16_t year;
101     uint8_t month;
102     uint8_t day;
103     uint8_t hour;
104     uint8_t minute;
105 };
106 
107 struct loader_layer_properties {
108     VkLayerProperties info;
109     enum layer_type_flags type_flags;
110     uint32_t interface_version;  // PFN_vkNegotiateLoaderLayerInterfaceVersion
111     char manifest_file_name[MAX_STRING_SIZE];
112     char lib_name[MAX_STRING_SIZE];
113     loader_platform_dl_handle lib_handle;
114     struct loader_layer_functions functions;
115     struct loader_extension_list instance_extension_list;
116     struct loader_device_extension_list device_extension_list;
117     struct loader_name_value disable_env_var;
118     struct loader_name_value enable_env_var;
119     uint32_t num_component_layers;
120     char (*component_layer_names)[MAX_STRING_SIZE];
121     struct {
122         char enumerate_instance_extension_properties[MAX_STRING_SIZE];
123         char enumerate_instance_layer_properties[MAX_STRING_SIZE];
124         char enumerate_instance_version[MAX_STRING_SIZE];
125     } pre_instance_functions;
126     uint32_t num_override_paths;
127     char (*override_paths)[MAX_STRING_SIZE];
128     bool is_override;
129     bool has_expiration;
130     struct loader_override_expiration expiration;
131     bool keep;
132     uint32_t num_blacklist_layers;
133     char (*blacklist_layer_names)[MAX_STRING_SIZE];
134     uint32_t num_app_key_paths;
135     char (*app_key_paths)[MAX_STRING_SIZE];
136 };
137 
138 struct loader_layer_list {
139     size_t capacity;
140     uint32_t count;
141     struct loader_layer_properties *list;
142 };
143 
144 struct loader_dispatch_hash_list {
145     size_t capacity;
146     uint32_t count;
147     uint32_t *index;  // index into the dev_ext dispatch table
148 };
149 
150 // loader_dispatch_hash_entry and loader_dev_ext_dispatch_table.dev_ext have
151 // one to one correspondence; one loader_dispatch_hash_entry for one dev_ext
152 // dispatch entry.
153 // Also have a one to one correspondence with functions in dev_ext_trampoline.c
154 struct loader_dispatch_hash_entry {
155     char *func_name;
156     struct loader_dispatch_hash_list list;  // to handle hashing collisions
157 };
158 
159 typedef VkResult(VKAPI_PTR *PFN_vkDevExt)(VkDevice device);
160 struct loader_dev_ext_dispatch_table {
161     PFN_vkDevExt dev_ext[MAX_NUM_UNKNOWN_EXTS];
162 };
163 
164 struct loader_dev_dispatch_table {
165     VkLayerDispatchTable core_dispatch;
166     struct loader_dev_ext_dispatch_table ext_dispatch;
167 };
168 
169 // per CreateDevice structure
170 struct loader_device {
171     struct loader_dev_dispatch_table loader_dispatch;
172     VkDevice chain_device;  // device object from the dispatch chain
173     VkDevice icd_device;    // device object from the icd
174     struct loader_physical_device_term *phys_dev_term;
175 
176     // List of activated layers.
177     //  app_      is the version based on exactly what the application asked for.
178     //            This is what must be returned to the application on Enumerate calls.
179     //  expanded_ is the version based on expanding meta-layers into their
180     //            individual component layers.  This is what is used internally.
181     struct loader_layer_list app_activated_layer_list;
182     struct loader_layer_list expanded_activated_layer_list;
183 
184     VkAllocationCallbacks alloc_callbacks;
185 
186     // List of activated device extensions that have terminators implemented in the loader
187     struct {
188         bool khr_swapchain_enabled;
189         bool khr_display_swapchain_enabled;
190         bool khr_device_group_enabled;
191         bool ext_debug_marker_enabled;
192         bool ext_debug_utils_enabled;
193         bool ext_full_screen_exclusive_enabled;
194     } extensions;
195 
196     struct loader_device *next;
197 };
198 
199 // Per ICD information
200 
201 // Per ICD structure
202 struct loader_icd_term {
203     // pointers to find other structs
204     const struct loader_scanned_icd *scanned_icd;
205     const struct loader_instance *this_instance;
206     struct loader_device *logical_device_list;
207     VkInstance instance;  // instance object from the icd
208     struct loader_icd_term_dispatch dispatch;
209 
210     struct loader_icd_term *next;
211 
212     PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS];
213 };
214 
215 // Per ICD library structure
216 struct loader_icd_tramp_list {
217     size_t capacity;
218     uint32_t count;
219     struct loader_scanned_icd *scanned_list;
220 };
221 
222 struct loader_instance_dispatch_table {
223     VkLayerInstanceDispatchTable layer_inst_disp;  // must be first entry in structure
224 
225     // Physical device functions unknown to the loader
226     PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS];
227 };
228 
229 // Unique magic number identifier for the loader.
230 #define LOADER_MAGIC_NUMBER 0x10ADED010110ADEDUL
231 
232 // Per instance structure
233 struct loader_instance {
234     struct loader_instance_dispatch_table *disp;  // must be first entry in structure
235     uint64_t magic;                               // Should be LOADER_MAGIC_NUMBER
236 
237     // Vulkan API version the app is intending to use.
238     uint16_t app_api_major_version;
239     uint16_t app_api_minor_version;
240 
241     // We need to manually track physical devices over time.  If the user
242     // re-queries the information, we don't want to delete old data or
243     // create new data unless necessary.
244     uint32_t total_gpu_count;
245     uint32_t phys_dev_count_term;
246     struct loader_physical_device_term **phys_devs_term;
247     uint32_t phys_dev_count_tramp;
248     struct loader_physical_device_tramp **phys_devs_tramp;
249 
250     // We also need to manually track physical device groups, but we don't need
251     // loader specific structures since we have that content in the physical
252     // device stored internal to the public structures.
253     uint32_t phys_dev_group_count_term;
254     struct VkPhysicalDeviceGroupProperties **phys_dev_groups_term;
255     uint32_t phys_dev_group_count_tramp;
256     struct VkPhysicalDeviceGroupProperties **phys_dev_groups_tramp;
257 
258     struct loader_instance *next;
259 
260     uint32_t total_icd_count;
261     struct loader_icd_term *icd_terms;
262     struct loader_icd_tramp_list icd_tramp_list;
263 
264     struct loader_dispatch_hash_entry dev_ext_disp_hash[MAX_NUM_UNKNOWN_EXTS];
265     struct loader_dispatch_hash_entry phys_dev_ext_disp_hash[MAX_NUM_UNKNOWN_EXTS];
266 
267     struct loader_msg_callback_map_entry *icd_msg_callback_map;
268 
269     struct loader_layer_list instance_layer_list;
270     bool override_layer_present;
271 
272     // List of activated layers.
273     //  app_      is the version based on exactly what the application asked for.
274     //            This is what must be returned to the application on Enumerate calls.
275     //  expanded_ is the version based on expanding meta-layers into their
276     //            individual component layers.  This is what is used internally.
277     struct loader_layer_list app_activated_layer_list;
278     struct loader_layer_list expanded_activated_layer_list;
279 
280     VkInstance instance;  // layers/ICD instance returned to trampoline
281 
282     struct loader_extension_list ext_list;  // icds and loaders extensions
283     union loader_instance_extension_enables enabled_known_extensions;
284 
285     VkLayerDbgFunctionNode *DbgFunctionHead;
286     uint32_t num_tmp_report_callbacks;
287     VkDebugReportCallbackCreateInfoEXT *tmp_report_create_infos;
288     VkDebugReportCallbackEXT *tmp_report_callbacks;
289     uint32_t num_tmp_messengers;
290     VkDebugUtilsMessengerCreateInfoEXT *tmp_messenger_create_infos;
291     VkDebugUtilsMessengerEXT *tmp_messengers;
292 
293     VkAllocationCallbacks alloc_callbacks;
294 
295     bool wsi_surface_enabled;
296 #ifdef VK_USE_PLATFORM_WIN32_KHR
297     bool wsi_win32_surface_enabled;
298 #endif
299 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
300     bool wsi_wayland_surface_enabled;
301 #endif
302 #ifdef VK_USE_PLATFORM_XCB_KHR
303     bool wsi_xcb_surface_enabled;
304 #endif
305 #ifdef VK_USE_PLATFORM_XLIB_KHR
306     bool wsi_xlib_surface_enabled;
307 #endif
308 #ifdef VK_USE_PLATFORM_DIRECTFB_EXT
309     bool wsi_directfb_surface_enabled;
310 #endif
311 #ifdef VK_USE_PLATFORM_ANDROID_KHR
312     bool wsi_android_surface_enabled;
313 #endif
314 #ifdef VK_USE_PLATFORM_MACOS_MVK
315     bool wsi_macos_surface_enabled;
316 #endif
317 #ifdef VK_USE_PLATFORM_IOS_MVK
318     bool wsi_ios_surface_enabled;
319 #endif
320 #ifdef VK_USE_PLATFORM_GGP
321     bool wsi_ggp_surface_enabled;
322 #endif
323     bool wsi_headless_surface_enabled;
324 #if defined(VK_USE_PLATFORM_METAL_EXT)
325     bool wsi_metal_surface_enabled;
326 #endif
327 #ifdef VK_USE_PLATFORM_FUCHSIA
328     bool wsi_imagepipe_surface_enabled;
329 #endif
330 #ifdef VK_USE_PLATFORM_SCREEN_QNX
331     bool wsi_screen_surface_enabled;
332 #endif
333     bool wsi_display_enabled;
334     bool wsi_display_props2_enabled;
335     bool create_terminator_invalid_extension;
336 };
337 
338 // VkPhysicalDevice requires special treatment by loader.  Firstly, terminator
339 // code must be able to get the struct loader_icd_term to call into the proper
340 // driver  (multiple ICD/gpu case). This can be accomplished by wrapping the
341 // created VkPhysicalDevice in loader terminate_EnumeratePhysicalDevices().
342 // Secondly, the loader must be able to handle wrapped by layer VkPhysicalDevice
343 // in trampoline code.  This implies, that the loader trampoline code must also
344 // wrap the VkPhysicalDevice object in trampoline code.  Thus, loader has to
345 // wrap the VkPhysicalDevice created object twice. In trampoline code it can't
346 // rely on the terminator object wrapping since a layer may also wrap. Since
347 // trampoline code wraps the VkPhysicalDevice this means all loader trampoline
348 // code that passes a VkPhysicalDevice should unwrap it.
349 
350 // Unique identifier for physical devices
351 #define PHYS_TRAMP_MAGIC_NUMBER 0x10ADED020210ADEDUL
352 
353 // Per enumerated PhysicalDevice structure, used to wrap in trampoline code and
354 // also same structure used to wrap in terminator code
355 struct loader_physical_device_tramp {
356     struct loader_instance_dispatch_table *disp;  // must be first entry in structure
357     struct loader_instance *this_instance;
358     uint64_t magic;             // Should be PHYS_TRAMP_MAGIC_NUMBER
359     VkPhysicalDevice phys_dev;  // object from layers/loader terminator
360 };
361 
362 // Per enumerated PhysicalDevice structure, used to wrap in terminator code
363 struct loader_physical_device_term {
364     struct loader_instance_dispatch_table *disp;  // must be first entry in structure
365     struct loader_icd_term *this_icd_term;
366     uint8_t icd_index;
367     VkPhysicalDevice phys_dev;  // object from ICD
368 };
369 
370 struct loader_struct {
371     struct loader_instance *instances;
372 };
373 
374 struct loader_scanned_icd {
375     char *lib_name;
376     loader_platform_dl_handle handle;
377     uint32_t api_version;
378     uint32_t interface_version;
379     PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
380     PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr;
381     PFN_vkCreateInstance CreateInstance;
382     PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
383 #if defined(VK_USE_PLATFORM_WIN32_KHR)
384     PFN_vk_icdEnumerateAdapterPhysicalDevices EnumerateAdapterPhysicalDevices;
385 #endif
386 };
387 
388 struct loader_phys_dev_per_icd {
389     uint32_t count;
390     VkPhysicalDevice *phys_devs;
391     struct loader_icd_term *this_icd_term;
392 };
393 
394 enum loader_data_files_type {
395     LOADER_DATA_FILE_MANIFEST_ICD = 0,
396     LOADER_DATA_FILE_MANIFEST_LAYER,
397     LOADER_DATA_FILE_NUM_TYPES  // Not a real field, used for possible loop terminator
398 };
399 
400 struct loader_data_files {
401     uint32_t count;
402     uint32_t alloc_count;
403     char **filename_list;
404 };
405 
406 struct LoaderSortedPhysicalDevice {
407     uint32_t device_count;
408     VkPhysicalDevice *physical_devices;
409     uint32_t icd_index;
410     struct loader_icd_term *icd_term;
411 };
412 
413 struct loader_msg_callback_map_entry {
414     VkDebugReportCallbackEXT icd_obj;
415     VkDebugReportCallbackEXT loader_obj;
416 };