1 /*
2  *
3  * Copyright (c) 2023 The Khronos Group Inc.
4  * Copyright (c) 2023 Valve Corporation
5  * Copyright (c) 2023 LunarG, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *
20  * Author: Charles Giessen <charles@lunarg.com>
21  *
22  */
23 
24 #pragma once
25 
26 #include <stdio.h>
27 #include <stddef.h>
28 #include <stdbool.h>
29 #include <stdint.h>
30 
31 #include "vulkan/vulkan_core.h"
32 
33 #include "log.h"
34 
35 struct loader_instance;
36 struct loader_layer_list;
37 struct loader_pointer_layer_list;
38 struct loader_envvar_all_filters;
39 typedef struct log_configuration log_configuration;
40 
41 typedef enum loader_settings_layer_control {
42     LOADER_SETTINGS_LAYER_CONTROL_DEFAULT,          // layer is not enabled by settings file but can be enabled through other means
43     LOADER_SETTINGS_LAYER_CONTROL_ON,               // layer is enabled by settings file
44     LOADER_SETTINGS_LAYER_CONTROL_OFF,              // layer is prevented from being enabled
45     LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION  // special control indicating unspecified layers should go here. If this is not
46                                                     // in the settings file, then the loader assume no other layers should be
47                                                     // searched & loaded.
48 } loader_settings_layer_control;
49 
50 // If a loader_settings_layer_configuration has a name of loader_settings_unknown_layers_location, then it specifies that the
51 // layer configuration it was found in shall be the location all layers not listed in the settings file that are enabled.
52 #define LOADER_SETTINGS_UNKNOWN_LAYERS_LOCATION "loader_settings_unknown_layers_location"
53 
54 #define LOADER_SETTINGS_MAX_NAME_SIZE 256U;
55 
56 typedef struct loader_settings_layer_configuration {
57     char* name;
58     char* path;
59     loader_settings_layer_control control;
60     bool treat_as_implicit_manifest;  // whether or not the layer should be parsed as if it is implicit
61 
62 } loader_settings_layer_configuration;
63 
64 typedef struct loader_settings {
65     bool settings_active;
66     bool has_unordered_layer_location;
67     enum vulkan_loader_debug_flags debug_level;
68 
69     uint32_t layer_configuration_count;
70     loader_settings_layer_configuration* layer_configurations;
71 
72     char* settings_file_path;
73 } loader_settings;
74 
75 // Call this function to get the current settings that the loader should use.
76 // It will open up the current loader settings file and return a loader_settings in out_loader_settings if it.
77 // It should be called on every call to the global functions excluding vkGetInstanceProcAddr
78 // Caller is responsible for cleaning up by calling free_loader_settings()
79 VkResult get_loader_settings(const struct loader_instance* inst, loader_settings* out_loader_settings);
80 
81 void free_loader_settings(const struct loader_instance* inst, loader_settings* loader_settings);
82 
83 // Log the settings to the console
84 void log_settings(const struct loader_instance* inst, loader_settings* settings);
85 
86 // Every global function needs to call this at startup to insure that
87 VkResult update_global_loader_settings(void);
88 
89 // Needs to be called during startup -
90 void init_global_loader_settings(void);
91 void teardown_global_loader_settings(void);
92 
93 // Check the global settings and return true if msg_type does not correspond to the active global loader settings
94 bool should_skip_logging_global_messages(VkFlags msg_type);
95 
96 // Query the current settings (either global or per-instance) and return the list of layers contained within.
97 // should_search_for_other_layers tells the caller if the settings file should be used exclusively for layer searching or not
98 VkResult get_settings_layers(const struct loader_instance* inst, struct loader_layer_list* settings_layers,
99                              bool* should_search_for_other_layers);
100 
101 // Take the provided list of settings_layers and add in the layers from regular search paths
102 // Only adds layers that aren't already present in the settings_layers and in the location of the
103 // layer configuration with LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION set
104 VkResult combine_settings_layers_with_regular_layers(const struct loader_instance* inst, struct loader_layer_list* settings_layers,
105                                                      struct loader_layer_list* regular_layers,
106                                                      struct loader_layer_list* output_layers);
107 
108 // Fill out activated_layer_list with the layers that should be activated, based on environment variables, VkInstanceCreateInfo, and
109 // the settings
110 VkResult enable_correct_layers_from_settings(const struct loader_instance* inst, const struct loader_envvar_all_filters* filters,
111                                              uint32_t app_enabled_name_count, const char* const* app_enabled_names,
112                                              const struct loader_layer_list* instance_layers,
113                                              struct loader_pointer_layer_list* target_layer_list,
114                                              struct loader_pointer_layer_list* activated_layer_list);
115