1 /*
2  *
3  * Copyright (c) 2014-2022 The Khronos Group Inc.
4  * Copyright (c) 2014-2022 Valve Corporation
5  * Copyright (c) 2014-2022 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 "vulkan/vk_platform.h"
33 #include <vulkan/vulkan.h>
34 #include <vulkan/vk_layer.h>
35 #include <vulkan/vk_icd.h>
36 
37 #include "vk_loader_platform.h"
38 #include "vk_loader_layer.h"
39 #include "vk_layer_dispatch_table.h"
40 #include "vk_loader_extensions.h"
41 
42 #include "settings.h"
43 
44 typedef enum VkStringErrorFlagBits {
45     VK_STRING_ERROR_NONE = 0x00000000,
46     VK_STRING_ERROR_LENGTH = 0x00000001,
47     VK_STRING_ERROR_BAD_DATA = 0x00000002,
48     VK_STRING_ERROR_NULL_PTR = 0x00000004,
49 } VkStringErrorFlagBits;
50 typedef VkFlags VkStringErrorFlags;
51 
52 static const int MaxLoaderStringLength = 256;           // 0xFF;
53 static const unsigned char UTF8_ONE_BYTE_CODE = 192;    // 0xC0;
54 static const unsigned char UTF8_ONE_BYTE_MASK = 224;    // 0xE0;
55 static const unsigned char UTF8_TWO_BYTE_CODE = 224;    // 0xE0;
56 static const unsigned char UTF8_TWO_BYTE_MASK = 240;    // 0xF0;
57 static const unsigned char UTF8_THREE_BYTE_CODE = 240;  // 0xF0;
58 static const unsigned char UTF8_THREE_BYTE_MASK = 248;  // 0xF8;
59 static const unsigned char UTF8_DATA_BYTE_CODE = 128;   // 0x80;
60 static const unsigned char UTF8_DATA_BYTE_MASK = 192;   // 0xC0;
61 
62 // form of all dynamic lists/arrays
63 // only the list element should be changed
64 struct loader_generic_list {
65     size_t capacity;
66     uint32_t count;
67     void *list;
68 };
69 
70 struct loader_string_list {
71     uint32_t allocated_count;
72     uint32_t count;
73     char **list;
74 };
75 
76 struct loader_extension_list {
77     size_t capacity;
78     uint32_t count;
79     VkExtensionProperties *list;
80 };
81 
82 struct loader_dev_ext_props {
83     VkExtensionProperties props;
84     struct loader_string_list entrypoints;
85 };
86 
87 struct loader_device_extension_list {
88     size_t capacity;
89     uint32_t count;
90     struct loader_dev_ext_props *list;
91 };
92 
93 struct loader_name_value {
94     char *name;
95     char *value;
96 };
97 
98 struct loader_layer_functions {
99     char *str_gipa;
100     char *str_gdpa;
101     char *str_negotiate_interface;
102     PFN_vkNegotiateLoaderLayerInterfaceVersion negotiate_layer_interface;
103     PFN_vkGetInstanceProcAddr get_instance_proc_addr;
104     PFN_vkGetDeviceProcAddr get_device_proc_addr;
105     PFN_GetPhysicalDeviceProcAddr get_physical_device_proc_addr;
106 };
107 
108 // This structure is used to store the json file version in a more manageable way.
109 typedef struct {
110     uint16_t major;
111     uint16_t minor;
112     uint16_t patch;
113 } loader_api_version;
114 
115 // Enumeration used to clearly identify reason for library load failure.
116 enum loader_layer_library_status {
117     LOADER_LAYER_LIB_NOT_LOADED = 0,
118 
119     LOADER_LAYER_LIB_SUCCESS_LOADED = 1,
120 
121     LOADER_LAYER_LIB_ERROR_WRONG_BIT_TYPE = 20,
122     LOADER_LAYER_LIB_ERROR_FAILED_TO_LOAD = 21,
123     LOADER_LAYER_LIB_ERROR_OUT_OF_MEMORY = 22,
124 };
125 
126 enum layer_type_flags {
127     VK_LAYER_TYPE_FLAG_INSTANCE_LAYER = 0x1,  // If not set, indicates Device layer
128     VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER = 0x2,  // If not set, indicates Implicit layer
129     VK_LAYER_TYPE_FLAG_META_LAYER = 0x4,      // If not set, indicates standard layer
130 };
131 
132 struct loader_layer_properties {
133     VkLayerProperties info;
134     enum layer_type_flags type_flags;
135     enum loader_settings_layer_control settings_control_value;
136 
137     uint32_t interface_version;  // PFN_vkNegotiateLoaderLayerInterfaceVersion
138     char *manifest_file_name;
139     char *lib_name;
140     enum loader_layer_library_status lib_status;
141     loader_platform_dl_handle lib_handle;
142     struct loader_layer_functions functions;
143     struct loader_extension_list instance_extension_list;
144     struct loader_device_extension_list device_extension_list;
145     struct loader_name_value disable_env_var;
146     struct loader_name_value enable_env_var;
147     struct loader_string_list component_layer_names;
148     struct {
149         char *enumerate_instance_extension_properties;
150         char *enumerate_instance_layer_properties;
151         char *enumerate_instance_version;
152     } pre_instance_functions;
153     struct loader_string_list override_paths;
154     bool is_override;
155     bool keep;
156     struct loader_string_list blacklist_layer_names;
157     struct loader_string_list app_key_paths;
158 };
159 
160 // Stores a list of loader_layer_properties
161 struct loader_layer_list {
162     size_t capacity;
163     uint32_t count;
164     struct loader_layer_properties *list;
165 };
166 
167 // Stores a list of pointers to loader_layer_properties
168 // Used for app_activated_layer_list and expanded_activated_layer_list
169 struct loader_pointer_layer_list {
170     size_t capacity;
171     uint32_t count;
172     struct loader_layer_properties **list;
173 };
174 
175 typedef VkResult(VKAPI_PTR *PFN_vkDevExt)(VkDevice device);
176 
177 struct loader_dev_dispatch_table {
178     VkLayerDispatchTable core_dispatch;
179     PFN_vkDevExt ext_dispatch[MAX_NUM_UNKNOWN_EXTS];
180     struct loader_device_terminator_dispatch extension_terminator_dispatch;
181 };
182 
183 // per CreateDevice structure
184 struct loader_device {
185     struct loader_dev_dispatch_table loader_dispatch;
186     VkDevice chain_device;  // device object from the dispatch chain
187     VkDevice icd_device;    // device object from the icd
188     struct loader_physical_device_term *phys_dev_term;
189 
190     VkAllocationCallbacks alloc_callbacks;
191 
192     // List of activated device extensions that layers support (but not necessarily the driver which have functions that require
193     // trampolines to work correctly. EX - vkDebugMarkerSetObjectNameEXT can name wrapped handles like instance, physical device,
194     // or surface
195     struct {
196         bool ext_debug_marker_enabled;
197         bool ext_debug_utils_enabled;
198     } layer_extensions;
199 
200     // List of activated device extensions that have terminators implemented in the loader
201     struct {
202         bool khr_swapchain_enabled;
203         bool khr_display_swapchain_enabled;
204         bool khr_device_group_enabled;
205         bool ext_debug_marker_enabled;
206         bool ext_debug_utils_enabled;
207         bool ext_full_screen_exclusive_enabled;
208     } driver_extensions;
209 
210     struct loader_device *next;
211 
212     // Makes vkGetDeviceProcAddr check if core functions are supported by the current app_api_version.
213     // Only set to true if VK_KHR_maintenance5 is enabled.
214     bool should_ignore_device_commands_from_newer_version;
215 };
216 
217 // Per ICD information
218 
219 // Per ICD structure
220 struct loader_icd_term {
221     // pointers to find other structs
222     const struct loader_scanned_icd *scanned_icd;
223     const struct loader_instance *this_instance;
224     struct loader_device *logical_device_list;
225     VkInstance instance;  // instance object from the icd
226     struct loader_icd_term_dispatch dispatch;
227 
228     struct loader_icd_term *next;
229 
230     PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS];
231     bool supports_get_dev_prop_2;
232 };
233 
234 // Per ICD library structure
235 struct loader_icd_tramp_list {
236     size_t capacity;
237     uint32_t count;
238     struct loader_scanned_icd *scanned_list;
239 };
240 
241 struct loader_instance_dispatch_table {
242     VkLayerInstanceDispatchTable layer_inst_disp;  // must be first entry in structure
243 
244     // Physical device functions unknown to the loader
245     PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS];
246 };
247 
248 // Unique magic number identifier for the loader.
249 #define LOADER_MAGIC_NUMBER 0x10ADED010110ADEDUL
250 
251 // Per instance structure
252 struct loader_instance {
253     struct loader_instance_dispatch_table *disp;  // must be first entry in structure
254     uint64_t magic;                               // Should be LOADER_MAGIC_NUMBER
255 
256     // Store all the terminators for instance functions in case a layer queries one *after* vkCreateInstance
257     VkLayerInstanceDispatchTable terminator_dispatch;
258 
259     // Vulkan API version the app is intending to use.
260     loader_api_version app_api_version;
261 
262     // We need to manually track physical devices over time.  If the user
263     // re-queries the information, we don't want to delete old data or
264     // create new data unless necessary.
265     uint32_t total_gpu_count;
266     uint32_t phys_dev_count_term;
267     struct loader_physical_device_term **phys_devs_term;
268     uint32_t phys_dev_count_tramp;
269     struct loader_physical_device_tramp **phys_devs_tramp;
270 
271     // We also need to manually track physical device groups, but we don't need
272     // loader specific structures since we have that content in the physical
273     // device stored internal to the public structures.
274     uint32_t phys_dev_group_count_term;
275     struct VkPhysicalDeviceGroupProperties **phys_dev_groups_term;
276 
277     struct loader_instance *next;
278 
279     uint32_t total_icd_count;
280     struct loader_icd_term *icd_terms;
281     struct loader_icd_tramp_list icd_tramp_list;
282 
283     // Must store the strings inside loader_instance directly - since the asm code will offset into
284     // loader_instance to get the function name
285     uint32_t dev_ext_disp_function_count;
286     char *dev_ext_disp_functions[MAX_NUM_UNKNOWN_EXTS];
287     uint32_t phys_dev_ext_disp_function_count;
288     char *phys_dev_ext_disp_functions[MAX_NUM_UNKNOWN_EXTS];
289 
290     struct loader_msg_callback_map_entry *icd_msg_callback_map;
291 
292     struct loader_string_list enabled_layer_names;
293 
294     struct loader_layer_list instance_layer_list;
295     bool override_layer_present;
296 
297     // List of activated layers.
298     //  app_      is the version based on exactly what the application asked for.
299     //            This is what must be returned to the application on Enumerate calls.
300     //  expanded_ is the version based on expanding meta-layers into their
301     //            individual component layers.  This is what is used internally.
302     struct loader_pointer_layer_list app_activated_layer_list;
303     struct loader_pointer_layer_list expanded_activated_layer_list;
304 
305     VkInstance instance;  // layers/ICD instance returned to trampoline
306 
307     struct loader_extension_list ext_list;  // icds and loaders extensions
308     struct loader_instance_extension_enables enabled_known_extensions;
309 
310     // Stores debug callbacks - used in the log.
311     VkLayerDbgFunctionNode *current_dbg_function_head;        // Current head
312     VkLayerDbgFunctionNode *instance_only_dbg_function_head;  // Only used for instance create/destroy
313 
314     VkAllocationCallbacks alloc_callbacks;
315 
316     // Set to true after vkCreateInstance has returned - necessary for loader_gpa_instance_terminator()
317     bool instance_finished_creation;
318 
319     loader_settings settings;
320 
321     bool portability_enumeration_enabled;
322     bool portability_enumeration_flag_bit_set;
323     bool portability_enumeration_extension_enabled;
324 
325     bool wsi_surface_enabled;
326 #if defined(VK_USE_PLATFORM_WIN32_KHR)
327     bool wsi_win32_surface_enabled;
328 #endif
329 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
330     bool wsi_wayland_surface_enabled;
331 #endif
332 #if defined(VK_USE_PLATFORM_XCB_KHR)
333     bool wsi_xcb_surface_enabled;
334 #endif
335 #if defined(VK_USE_PLATFORM_XLIB_KHR)
336     bool wsi_xlib_surface_enabled;
337 #endif
338 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
339     bool wsi_directfb_surface_enabled;
340 #endif
341 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
342     bool wsi_android_surface_enabled;
343 #endif
344 #if defined(VK_USE_PLATFORM_OHOS)
345     bool wsi_ohos_surface_enabled;
346 #endif
347 #if defined(VK_USE_PLATFORM_MACOS_MVK)
348     bool wsi_macos_surface_enabled;
349 #endif
350 #if defined(VK_USE_PLATFORM_IOS_MVK)
351     bool wsi_ios_surface_enabled;
352 #endif
353 #if defined(VK_USE_PLATFORM_GGP)
354     bool wsi_ggp_surface_enabled;
355 #endif
356     bool wsi_headless_surface_enabled;
357 #if defined(VK_USE_PLATFORM_METAL_EXT)
358     bool wsi_metal_surface_enabled;
359 #endif
360 #if defined(VK_USE_PLATFORM_FUCHSIA)
361     bool wsi_imagepipe_surface_enabled;
362 #endif
363 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
364     bool wsi_screen_surface_enabled;
365 #endif
366 #if defined(VK_USE_PLATFORM_VI_NN)
367     bool wsi_vi_surface_enabled;
368 #endif
369     bool wsi_display_enabled;
370     bool wsi_display_props2_enabled;
371     bool create_terminator_invalid_extension;
372     bool supports_get_dev_prop_2;
373 };
374 
375 // VkPhysicalDevice requires special treatment by loader.  Firstly, terminator
376 // code must be able to get the struct loader_icd_term to call into the proper
377 // driver  (multiple ICD/gpu case). This can be accomplished by wrapping the
378 // created VkPhysicalDevice in loader terminate_EnumeratePhysicalDevices().
379 // Secondly, the loader must be able to handle wrapped by layer VkPhysicalDevice
380 // in trampoline code.  This implies, that the loader trampoline code must also
381 // wrap the VkPhysicalDevice object in trampoline code.  Thus, loader has to
382 // wrap the VkPhysicalDevice created object twice. In trampoline code it can't
383 // rely on the terminator object wrapping since a layer may also wrap. Since
384 // trampoline code wraps the VkPhysicalDevice this means all loader trampoline
385 // code that passes a VkPhysicalDevice should unwrap it.
386 
387 // Unique identifier for physical devices
388 #define PHYS_TRAMP_MAGIC_NUMBER 0x10ADED020210ADEDUL
389 
390 // Per enumerated PhysicalDevice structure, used to wrap in trampoline code and
391 // also same structure used to wrap in terminator code
392 struct loader_physical_device_tramp {
393     struct loader_instance_dispatch_table *disp;  // must be first entry in structure
394     struct loader_instance *this_instance;
395     uint64_t magic;             // Should be PHYS_TRAMP_MAGIC_NUMBER
396     VkPhysicalDevice phys_dev;  // object from layers/loader terminator
397 };
398 
399 // Per enumerated PhysicalDevice structure, used to wrap in terminator code
400 struct loader_physical_device_term {
401     struct loader_instance_dispatch_table *disp;  // must be first entry in structure
402     struct loader_icd_term *this_icd_term;
403     uint8_t icd_index;
404     VkPhysicalDevice phys_dev;  // object from ICD
405 };
406 
407 #if defined(LOADER_ENABLE_LINUX_SORT)
408 // Structure for storing the relevant device information for selecting a device.
409 // NOTE: Needs to be defined here so we can store this content in the term structure
410 //       for quicker sorting.
411 struct LinuxSortedDeviceInfo {
412     // Associated Vulkan Physical Device
413     VkPhysicalDevice physical_device;
414     bool default_device;
415 
416     // Loader specific items about the driver providing support for this physical device
417     uint32_t icd_index;
418     struct loader_icd_term *icd_term;
419 
420     // Some generic device properties
421     VkPhysicalDeviceType device_type;
422     char device_name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
423     uint32_t vendor_id;
424     uint32_t device_id;
425 
426     // PCI information on this device
427     bool has_pci_bus_info;
428     uint32_t pci_domain;
429     uint32_t pci_bus;
430     uint32_t pci_device;
431     uint32_t pci_function;
432 };
433 #endif  // LOADER_ENABLE_LINUX_SORT
434 
435 // Per enumerated PhysicalDeviceGroup structure, used to wrap in terminator code
436 struct loader_physical_device_group_term {
437     struct loader_icd_term *this_icd_term;
438     uint8_t icd_index;
439     VkPhysicalDeviceGroupProperties group_props;
440 #if defined(LOADER_ENABLE_LINUX_SORT)
441     struct LinuxSortedDeviceInfo internal_device_info[VK_MAX_DEVICE_GROUP_SIZE];
442 #endif  // LOADER_ENABLE_LINUX_SORT
443 };
444 
445 struct loader_struct {
446     struct loader_instance *instances;
447 };
448 
449 struct loader_scanned_icd {
450     char *lib_name;
451     loader_platform_dl_handle handle;
452     uint32_t api_version;
453     uint32_t interface_version;
454     PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
455     PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr;
456     PFN_vkCreateInstance CreateInstance;
457     PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
458 #if defined(VK_USE_PLATFORM_WIN32_KHR)
459     PFN_vk_icdEnumerateAdapterPhysicalDevices EnumerateAdapterPhysicalDevices;
460 #endif
461 };
462 
463 enum loader_data_files_type {
464     LOADER_DATA_FILE_MANIFEST_DRIVER = 0,
465     LOADER_DATA_FILE_MANIFEST_EXPLICIT_LAYER,
466     LOADER_DATA_FILE_MANIFEST_IMPLICIT_LAYER,
467     LOADER_DATA_FILE_NUM_TYPES  // Not a real field, used for possible loop terminator
468 };
469 
470 struct loader_icd_physical_devices {
471     uint32_t device_count;
472     VkPhysicalDevice *physical_devices;
473     uint32_t icd_index;
474     struct loader_icd_term *icd_term;
475 #if defined(WIN32)
476     LUID windows_adapter_luid;
477 #endif
478 };
479 
480 struct loader_msg_callback_map_entry {
481     VkDebugReportCallbackEXT icd_obj;
482     VkDebugReportCallbackEXT loader_obj;
483 };
484 
485 typedef enum loader_filter_string_type {
486     FILTER_STRING_FULLNAME = 0,
487     FILTER_STRING_SUBSTRING,
488     FILTER_STRING_PREFIX,
489     FILTER_STRING_SUFFIX,
490     FILTER_STRING_SPECIAL,
491 } loader_filter_string_type;
492 
493 struct loader_envvar_filter_value {
494     char value[VK_MAX_EXTENSION_NAME_SIZE];
495     size_t length;
496     loader_filter_string_type type;
497 };
498 
499 #define MAX_ADDITIONAL_FILTERS 16
500 struct loader_envvar_filter {
501     uint32_t count;
502     struct loader_envvar_filter_value filters[MAX_ADDITIONAL_FILTERS];
503 };
504 struct loader_envvar_disable_layers_filter {
505     struct loader_envvar_filter additional_filters;
506     bool disable_all;
507     bool disable_all_implicit;
508     bool disable_all_explicit;
509 };
510 
511 struct loader_envvar_all_filters {
512     struct loader_envvar_filter enable_filter;
513     struct loader_envvar_disable_layers_filter disable_filter;
514     struct loader_envvar_filter allow_filter;
515 };
516