xref: /aosp_15_r20/external/vulkan-validation-layers/layers/vk_layer_config.cpp (revision b7893ccf7851cd6a48cc5a1e965257d8a5cdcc70)
1*b7893ccfSSadaf Ebrahimi /**************************************************************************
2*b7893ccfSSadaf Ebrahimi  *
3*b7893ccfSSadaf Ebrahimi  * Copyright 2014-2019 Valve Software
4*b7893ccfSSadaf Ebrahimi  * Copyright 2015-2019 Google Inc.
5*b7893ccfSSadaf Ebrahimi  * Copyright 2019 LunarG, Inc.
6*b7893ccfSSadaf Ebrahimi  * All Rights Reserved.
7*b7893ccfSSadaf Ebrahimi  *
8*b7893ccfSSadaf Ebrahimi  * Licensed under the Apache License, Version 2.0 (the "License");
9*b7893ccfSSadaf Ebrahimi  * you may not use this file except in compliance with the License.
10*b7893ccfSSadaf Ebrahimi  * You may obtain a copy of the License at
11*b7893ccfSSadaf Ebrahimi  *
12*b7893ccfSSadaf Ebrahimi  *     http://www.apache.org/licenses/LICENSE-2.0
13*b7893ccfSSadaf Ebrahimi  *
14*b7893ccfSSadaf Ebrahimi  * Unless required by applicable law or agreed to in writing, software
15*b7893ccfSSadaf Ebrahimi  * distributed under the License is distributed on an "AS IS" BASIS,
16*b7893ccfSSadaf Ebrahimi  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17*b7893ccfSSadaf Ebrahimi  * See the License for the specific language governing permissions and
18*b7893ccfSSadaf Ebrahimi  * limitations under the License.
19*b7893ccfSSadaf Ebrahimi  *
20*b7893ccfSSadaf Ebrahimi  * Author: Jon Ashburn <[email protected]>
21*b7893ccfSSadaf Ebrahimi  * Author: Courtney Goeltzenleuchter <[email protected]>
22*b7893ccfSSadaf Ebrahimi  * Author: Tobin Ehlis <[email protected]>
23*b7893ccfSSadaf Ebrahimi  * Author: Mark Lobodzinski <[email protected]>
24*b7893ccfSSadaf Ebrahimi  **************************************************************************/
25*b7893ccfSSadaf Ebrahimi #include "vk_layer_config.h"
26*b7893ccfSSadaf Ebrahimi #include "vulkan/vk_sdk_platform.h"
27*b7893ccfSSadaf Ebrahimi #include <fstream>
28*b7893ccfSSadaf Ebrahimi #include <iostream>
29*b7893ccfSSadaf Ebrahimi #include <map>
30*b7893ccfSSadaf Ebrahimi #include <sstream>
31*b7893ccfSSadaf Ebrahimi #include <string.h>
32*b7893ccfSSadaf Ebrahimi #include <string>
33*b7893ccfSSadaf Ebrahimi #include <sys/stat.h>
34*b7893ccfSSadaf Ebrahimi #include <vulkan/vk_layer.h>
35*b7893ccfSSadaf Ebrahimi 
36*b7893ccfSSadaf Ebrahimi #if defined(_WIN32)
37*b7893ccfSSadaf Ebrahimi #include <windows.h>
38*b7893ccfSSadaf Ebrahimi #endif
39*b7893ccfSSadaf Ebrahimi 
40*b7893ccfSSadaf Ebrahimi #define MAX_CHARS_PER_LINE 4096
41*b7893ccfSSadaf Ebrahimi 
42*b7893ccfSSadaf Ebrahimi class ConfigFile {
43*b7893ccfSSadaf Ebrahimi    public:
44*b7893ccfSSadaf Ebrahimi     ConfigFile();
45*b7893ccfSSadaf Ebrahimi     ~ConfigFile();
46*b7893ccfSSadaf Ebrahimi 
47*b7893ccfSSadaf Ebrahimi     const char *getOption(const std::string &_option);
48*b7893ccfSSadaf Ebrahimi     void setOption(const std::string &_option, const std::string &_val);
49*b7893ccfSSadaf Ebrahimi     std::string vk_layer_disables_env_var{};
50*b7893ccfSSadaf Ebrahimi 
51*b7893ccfSSadaf Ebrahimi    private:
52*b7893ccfSSadaf Ebrahimi     bool m_fileIsParsed;
53*b7893ccfSSadaf Ebrahimi     std::map<std::string, std::string> m_valueMap;
54*b7893ccfSSadaf Ebrahimi 
55*b7893ccfSSadaf Ebrahimi     std::string FindSettings();
56*b7893ccfSSadaf Ebrahimi     void parseFile(const char *filename);
57*b7893ccfSSadaf Ebrahimi };
58*b7893ccfSSadaf Ebrahimi 
59*b7893ccfSSadaf Ebrahimi static ConfigFile g_configFileObj;
60*b7893ccfSSadaf Ebrahimi 
getEnvironment(const char * variable)61*b7893ccfSSadaf Ebrahimi std::string getEnvironment(const char *variable) {
62*b7893ccfSSadaf Ebrahimi #if !defined(__ANDROID__) && !defined(_WIN32)
63*b7893ccfSSadaf Ebrahimi     const char *output = getenv(variable);
64*b7893ccfSSadaf Ebrahimi     return output == NULL ? "" : output;
65*b7893ccfSSadaf Ebrahimi #elif defined(_WIN32)
66*b7893ccfSSadaf Ebrahimi     int size = GetEnvironmentVariable(variable, NULL, 0);
67*b7893ccfSSadaf Ebrahimi     if (size == 0) {
68*b7893ccfSSadaf Ebrahimi         return "";
69*b7893ccfSSadaf Ebrahimi     }
70*b7893ccfSSadaf Ebrahimi     char *buffer = new char[size];
71*b7893ccfSSadaf Ebrahimi     GetEnvironmentVariable(variable, buffer, size);
72*b7893ccfSSadaf Ebrahimi     std::string output = buffer;
73*b7893ccfSSadaf Ebrahimi     delete[] buffer;
74*b7893ccfSSadaf Ebrahimi     return output;
75*b7893ccfSSadaf Ebrahimi #else
76*b7893ccfSSadaf Ebrahimi     return "";
77*b7893ccfSSadaf Ebrahimi #endif
78*b7893ccfSSadaf Ebrahimi }
79*b7893ccfSSadaf Ebrahimi 
getLayerOption(const char * _option)80*b7893ccfSSadaf Ebrahimi VK_LAYER_EXPORT const char *getLayerOption(const char *_option) { return g_configFileObj.getOption(_option); }
GetLayerEnvVar(const char * _option)81*b7893ccfSSadaf Ebrahimi VK_LAYER_EXPORT const char *GetLayerEnvVar(const char *_option) {
82*b7893ccfSSadaf Ebrahimi     g_configFileObj.vk_layer_disables_env_var = getEnvironment(_option);
83*b7893ccfSSadaf Ebrahimi     return g_configFileObj.vk_layer_disables_env_var.c_str();
84*b7893ccfSSadaf Ebrahimi }
85*b7893ccfSSadaf Ebrahimi 
86*b7893ccfSSadaf Ebrahimi // If option is NULL or stdout, return stdout, otherwise try to open option
87*b7893ccfSSadaf Ebrahimi // as a filename. If successful, return file handle, otherwise stdout
getLayerLogOutput(const char * _option,const char * layerName)88*b7893ccfSSadaf Ebrahimi VK_LAYER_EXPORT FILE *getLayerLogOutput(const char *_option, const char *layerName) {
89*b7893ccfSSadaf Ebrahimi     FILE *log_output = NULL;
90*b7893ccfSSadaf Ebrahimi     if (!_option || !strcmp("stdout", _option))
91*b7893ccfSSadaf Ebrahimi         log_output = stdout;
92*b7893ccfSSadaf Ebrahimi     else {
93*b7893ccfSSadaf Ebrahimi         log_output = fopen(_option, "w");
94*b7893ccfSSadaf Ebrahimi         if (log_output == NULL) {
95*b7893ccfSSadaf Ebrahimi             if (_option)
96*b7893ccfSSadaf Ebrahimi                 std::cout << std::endl
97*b7893ccfSSadaf Ebrahimi                           << layerName << " ERROR: Bad output filename specified: " << _option << ". Writing to STDOUT instead"
98*b7893ccfSSadaf Ebrahimi                           << std::endl
99*b7893ccfSSadaf Ebrahimi                           << std::endl;
100*b7893ccfSSadaf Ebrahimi             log_output = stdout;
101*b7893ccfSSadaf Ebrahimi         }
102*b7893ccfSSadaf Ebrahimi     }
103*b7893ccfSSadaf Ebrahimi     return log_output;
104*b7893ccfSSadaf Ebrahimi }
105*b7893ccfSSadaf Ebrahimi 
106*b7893ccfSSadaf Ebrahimi // Map option strings to flag enum values
GetLayerOptionFlags(std::string _option,std::unordered_map<std::string,VkFlags> const & enum_data,uint32_t option_default)107*b7893ccfSSadaf Ebrahimi VK_LAYER_EXPORT VkFlags GetLayerOptionFlags(std::string _option, std::unordered_map<std::string, VkFlags> const &enum_data,
108*b7893ccfSSadaf Ebrahimi                                             uint32_t option_default) {
109*b7893ccfSSadaf Ebrahimi     VkDebugReportFlagsEXT flags = option_default;
110*b7893ccfSSadaf Ebrahimi     std::string option_list = g_configFileObj.getOption(_option.c_str());
111*b7893ccfSSadaf Ebrahimi 
112*b7893ccfSSadaf Ebrahimi     while (option_list.length() != 0) {
113*b7893ccfSSadaf Ebrahimi         // Find length of option string
114*b7893ccfSSadaf Ebrahimi         std::size_t option_length = option_list.find(",");
115*b7893ccfSSadaf Ebrahimi         if (option_length == option_list.npos) {
116*b7893ccfSSadaf Ebrahimi             option_length = option_list.size();
117*b7893ccfSSadaf Ebrahimi         }
118*b7893ccfSSadaf Ebrahimi 
119*b7893ccfSSadaf Ebrahimi         // Get first option in list
120*b7893ccfSSadaf Ebrahimi         const std::string option = option_list.substr(0, option_length);
121*b7893ccfSSadaf Ebrahimi 
122*b7893ccfSSadaf Ebrahimi         auto enum_value = enum_data.find(option);
123*b7893ccfSSadaf Ebrahimi         if (enum_value != enum_data.end()) {
124*b7893ccfSSadaf Ebrahimi             flags |= enum_value->second;
125*b7893ccfSSadaf Ebrahimi         }
126*b7893ccfSSadaf Ebrahimi 
127*b7893ccfSSadaf Ebrahimi         // Remove first option from option_list
128*b7893ccfSSadaf Ebrahimi         option_list.erase(0, option_length);
129*b7893ccfSSadaf Ebrahimi         // Remove possible comma separator
130*b7893ccfSSadaf Ebrahimi         std::size_t char_position = option_list.find(",");
131*b7893ccfSSadaf Ebrahimi         if (char_position == 0) {
132*b7893ccfSSadaf Ebrahimi             option_list.erase(char_position, 1);
133*b7893ccfSSadaf Ebrahimi         }
134*b7893ccfSSadaf Ebrahimi         // Remove possible space
135*b7893ccfSSadaf Ebrahimi         char_position = option_list.find(" ");
136*b7893ccfSSadaf Ebrahimi         if (char_position == 0) {
137*b7893ccfSSadaf Ebrahimi             option_list.erase(char_position, 1);
138*b7893ccfSSadaf Ebrahimi         }
139*b7893ccfSSadaf Ebrahimi     }
140*b7893ccfSSadaf Ebrahimi     return flags;
141*b7893ccfSSadaf Ebrahimi }
142*b7893ccfSSadaf Ebrahimi 
setLayerOption(const char * _option,const char * _val)143*b7893ccfSSadaf Ebrahimi VK_LAYER_EXPORT void setLayerOption(const char *_option, const char *_val) { g_configFileObj.setOption(_option, _val); }
144*b7893ccfSSadaf Ebrahimi 
145*b7893ccfSSadaf Ebrahimi // Constructor for ConfigFile. Initialize layers to log error messages to stdout by default. If a vk_layer_settings file is present,
146*b7893ccfSSadaf Ebrahimi // its settings will override the defaults.
ConfigFile()147*b7893ccfSSadaf Ebrahimi ConfigFile::ConfigFile() : m_fileIsParsed(false) {
148*b7893ccfSSadaf Ebrahimi     m_valueMap["khronos_validation.report_flags"] = "error";
149*b7893ccfSSadaf Ebrahimi     m_valueMap["lunarg_core_validation.report_flags"] = "error";
150*b7893ccfSSadaf Ebrahimi     m_valueMap["lunarg_object_tracker.report_flags"] = "error";
151*b7893ccfSSadaf Ebrahimi     m_valueMap["lunarg_parameter_validation.report_flags"] = "error";
152*b7893ccfSSadaf Ebrahimi     m_valueMap["google_threading.report_flags"] = "error";
153*b7893ccfSSadaf Ebrahimi     m_valueMap["google_unique_objects.report_flags"] = "error";
154*b7893ccfSSadaf Ebrahimi 
155*b7893ccfSSadaf Ebrahimi #ifdef WIN32
156*b7893ccfSSadaf Ebrahimi     // For Windows, enable message logging AND OutputDebugString
157*b7893ccfSSadaf Ebrahimi     m_valueMap["khronos_validation.debug_action"] =
158*b7893ccfSSadaf Ebrahimi         "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
159*b7893ccfSSadaf Ebrahimi     m_valueMap["lunarg_core_validation.debug_action"] =
160*b7893ccfSSadaf Ebrahimi         "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
161*b7893ccfSSadaf Ebrahimi     m_valueMap["lunarg_object_tracker.debug_action"] =
162*b7893ccfSSadaf Ebrahimi         "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
163*b7893ccfSSadaf Ebrahimi     m_valueMap["lunarg_parameter_validation.debug_action"] =
164*b7893ccfSSadaf Ebrahimi         "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
165*b7893ccfSSadaf Ebrahimi     m_valueMap["google_threading.debug_action"] =
166*b7893ccfSSadaf Ebrahimi         "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
167*b7893ccfSSadaf Ebrahimi     m_valueMap["google_unique_objects.debug_action"] =
168*b7893ccfSSadaf Ebrahimi         "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
169*b7893ccfSSadaf Ebrahimi #else   // WIN32
170*b7893ccfSSadaf Ebrahimi     m_valueMap["khronos_validation.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
171*b7893ccfSSadaf Ebrahimi     m_valueMap["lunarg_core_validation.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
172*b7893ccfSSadaf Ebrahimi     m_valueMap["lunarg_object_tracker.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
173*b7893ccfSSadaf Ebrahimi     m_valueMap["lunarg_parameter_validation.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
174*b7893ccfSSadaf Ebrahimi     m_valueMap["google_threading.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
175*b7893ccfSSadaf Ebrahimi     m_valueMap["google_unique_objects.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
176*b7893ccfSSadaf Ebrahimi #endif  // WIN32
177*b7893ccfSSadaf Ebrahimi     m_valueMap["khronos_validation.log_filename"] = "stdout";
178*b7893ccfSSadaf Ebrahimi     m_valueMap["lunarg_core_validation.log_filename"] = "stdout";
179*b7893ccfSSadaf Ebrahimi     m_valueMap["lunarg_object_tracker.log_filename"] = "stdout";
180*b7893ccfSSadaf Ebrahimi     m_valueMap["lunarg_parameter_validation.log_filename"] = "stdout";
181*b7893ccfSSadaf Ebrahimi     m_valueMap["google_threading.log_filename"] = "stdout";
182*b7893ccfSSadaf Ebrahimi     m_valueMap["google_unique_objects.log_filename"] = "stdout";
183*b7893ccfSSadaf Ebrahimi }
184*b7893ccfSSadaf Ebrahimi 
~ConfigFile()185*b7893ccfSSadaf Ebrahimi ConfigFile::~ConfigFile() {}
186*b7893ccfSSadaf Ebrahimi 
getOption(const std::string & _option)187*b7893ccfSSadaf Ebrahimi const char *ConfigFile::getOption(const std::string &_option) {
188*b7893ccfSSadaf Ebrahimi     std::map<std::string, std::string>::const_iterator it;
189*b7893ccfSSadaf Ebrahimi     if (!m_fileIsParsed) {
190*b7893ccfSSadaf Ebrahimi         std::string settings_file = FindSettings();
191*b7893ccfSSadaf Ebrahimi         parseFile(settings_file.c_str());
192*b7893ccfSSadaf Ebrahimi     }
193*b7893ccfSSadaf Ebrahimi 
194*b7893ccfSSadaf Ebrahimi     if ((it = m_valueMap.find(_option)) == m_valueMap.end())
195*b7893ccfSSadaf Ebrahimi         return "";
196*b7893ccfSSadaf Ebrahimi     else
197*b7893ccfSSadaf Ebrahimi         return it->second.c_str();
198*b7893ccfSSadaf Ebrahimi }
199*b7893ccfSSadaf Ebrahimi 
setOption(const std::string & _option,const std::string & _val)200*b7893ccfSSadaf Ebrahimi void ConfigFile::setOption(const std::string &_option, const std::string &_val) {
201*b7893ccfSSadaf Ebrahimi     if (!m_fileIsParsed) {
202*b7893ccfSSadaf Ebrahimi         std::string settings_file = FindSettings();
203*b7893ccfSSadaf Ebrahimi         parseFile(settings_file.c_str());
204*b7893ccfSSadaf Ebrahimi     }
205*b7893ccfSSadaf Ebrahimi 
206*b7893ccfSSadaf Ebrahimi     m_valueMap[_option] = _val;
207*b7893ccfSSadaf Ebrahimi }
208*b7893ccfSSadaf Ebrahimi 
FindSettings()209*b7893ccfSSadaf Ebrahimi std::string ConfigFile::FindSettings() {
210*b7893ccfSSadaf Ebrahimi     struct stat info;
211*b7893ccfSSadaf Ebrahimi 
212*b7893ccfSSadaf Ebrahimi #if defined(WIN32)
213*b7893ccfSSadaf Ebrahimi     HKEY hive;
214*b7893ccfSSadaf Ebrahimi     LSTATUS err = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Khronos\\Vulkan\\Settings", 0, KEY_READ, &hive);
215*b7893ccfSSadaf Ebrahimi     if (err == ERROR_SUCCESS) {
216*b7893ccfSSadaf Ebrahimi         char name[2048];
217*b7893ccfSSadaf Ebrahimi         DWORD i = 0, name_size = sizeof(name), type, value, value_size = sizeof(value);
218*b7893ccfSSadaf Ebrahimi         while (ERROR_SUCCESS ==
219*b7893ccfSSadaf Ebrahimi                RegEnumValue(hive, i++, name, &name_size, nullptr, &type, reinterpret_cast<LPBYTE>(&value), &value_size)) {
220*b7893ccfSSadaf Ebrahimi             // Check if the registry entry is a dword with a value of zero
221*b7893ccfSSadaf Ebrahimi             if (type != REG_DWORD || value != 0) {
222*b7893ccfSSadaf Ebrahimi                 continue;
223*b7893ccfSSadaf Ebrahimi             }
224*b7893ccfSSadaf Ebrahimi 
225*b7893ccfSSadaf Ebrahimi             // Check if this actually points to a file
226*b7893ccfSSadaf Ebrahimi             if ((stat(name, &info) != 0) || !(info.st_mode & S_IFREG)) {
227*b7893ccfSSadaf Ebrahimi                 continue;
228*b7893ccfSSadaf Ebrahimi             }
229*b7893ccfSSadaf Ebrahimi 
230*b7893ccfSSadaf Ebrahimi             // Use this file
231*b7893ccfSSadaf Ebrahimi             RegCloseKey(hive);
232*b7893ccfSSadaf Ebrahimi             return name;
233*b7893ccfSSadaf Ebrahimi         }
234*b7893ccfSSadaf Ebrahimi 
235*b7893ccfSSadaf Ebrahimi         RegCloseKey(hive);
236*b7893ccfSSadaf Ebrahimi     }
237*b7893ccfSSadaf Ebrahimi #else
238*b7893ccfSSadaf Ebrahimi     std::string search_path = getEnvironment("XDG_DATA_HOME");
239*b7893ccfSSadaf Ebrahimi     if (search_path == "") {
240*b7893ccfSSadaf Ebrahimi         search_path = getEnvironment("HOME");
241*b7893ccfSSadaf Ebrahimi         if (search_path != "") {
242*b7893ccfSSadaf Ebrahimi             search_path += "/.local/share";
243*b7893ccfSSadaf Ebrahimi         }
244*b7893ccfSSadaf Ebrahimi     }
245*b7893ccfSSadaf Ebrahimi 
246*b7893ccfSSadaf Ebrahimi     // Use the vk_layer_settings.txt file from here, if it is present
247*b7893ccfSSadaf Ebrahimi     if (search_path != "") {
248*b7893ccfSSadaf Ebrahimi         std::string home_file = search_path + "/vulkan/settings.d/vk_layer_settings.txt";
249*b7893ccfSSadaf Ebrahimi         if (stat(home_file.c_str(), &info) == 0) {
250*b7893ccfSSadaf Ebrahimi             if (info.st_mode & S_IFREG) {
251*b7893ccfSSadaf Ebrahimi                 return home_file;
252*b7893ccfSSadaf Ebrahimi             }
253*b7893ccfSSadaf Ebrahimi         }
254*b7893ccfSSadaf Ebrahimi     }
255*b7893ccfSSadaf Ebrahimi 
256*b7893ccfSSadaf Ebrahimi #endif
257*b7893ccfSSadaf Ebrahimi 
258*b7893ccfSSadaf Ebrahimi     std::string env_path = getEnvironment("VK_LAYER_SETTINGS_PATH");
259*b7893ccfSSadaf Ebrahimi 
260*b7893ccfSSadaf Ebrahimi     // If the path exists use it, else use vk_layer_settings
261*b7893ccfSSadaf Ebrahimi     if (stat(env_path.c_str(), &info) == 0) {
262*b7893ccfSSadaf Ebrahimi         // If this is a directory, look for vk_layer_settings within the directory
263*b7893ccfSSadaf Ebrahimi         if (info.st_mode & S_IFDIR) {
264*b7893ccfSSadaf Ebrahimi             return env_path + "/vk_layer_settings.txt";
265*b7893ccfSSadaf Ebrahimi         }
266*b7893ccfSSadaf Ebrahimi         return env_path;
267*b7893ccfSSadaf Ebrahimi     }
268*b7893ccfSSadaf Ebrahimi     return "vk_layer_settings.txt";
269*b7893ccfSSadaf Ebrahimi }
270*b7893ccfSSadaf Ebrahimi 
parseFile(const char * filename)271*b7893ccfSSadaf Ebrahimi void ConfigFile::parseFile(const char *filename) {
272*b7893ccfSSadaf Ebrahimi     std::ifstream file;
273*b7893ccfSSadaf Ebrahimi     char buf[MAX_CHARS_PER_LINE];
274*b7893ccfSSadaf Ebrahimi 
275*b7893ccfSSadaf Ebrahimi     m_fileIsParsed = true;
276*b7893ccfSSadaf Ebrahimi 
277*b7893ccfSSadaf Ebrahimi     file.open(filename);
278*b7893ccfSSadaf Ebrahimi     if (!file.good()) {
279*b7893ccfSSadaf Ebrahimi         return;
280*b7893ccfSSadaf Ebrahimi     }
281*b7893ccfSSadaf Ebrahimi 
282*b7893ccfSSadaf Ebrahimi     // read tokens from the file and form option, value pairs
283*b7893ccfSSadaf Ebrahimi     file.getline(buf, MAX_CHARS_PER_LINE);
284*b7893ccfSSadaf Ebrahimi     while (!file.eof()) {
285*b7893ccfSSadaf Ebrahimi         char option[512];
286*b7893ccfSSadaf Ebrahimi         char value[512];
287*b7893ccfSSadaf Ebrahimi 
288*b7893ccfSSadaf Ebrahimi         char *pComment;
289*b7893ccfSSadaf Ebrahimi 
290*b7893ccfSSadaf Ebrahimi         // discard any comments delimited by '#' in the line
291*b7893ccfSSadaf Ebrahimi         pComment = strchr(buf, '#');
292*b7893ccfSSadaf Ebrahimi         if (pComment) *pComment = '\0';
293*b7893ccfSSadaf Ebrahimi 
294*b7893ccfSSadaf Ebrahimi         if (sscanf(buf, " %511[^\n\t =] = %511[^\n \t]", option, value) == 2) {
295*b7893ccfSSadaf Ebrahimi             std::string optStr(option);
296*b7893ccfSSadaf Ebrahimi             std::string valStr(value);
297*b7893ccfSSadaf Ebrahimi             m_valueMap[optStr] = valStr;
298*b7893ccfSSadaf Ebrahimi         }
299*b7893ccfSSadaf Ebrahimi         file.getline(buf, MAX_CHARS_PER_LINE);
300*b7893ccfSSadaf Ebrahimi     }
301*b7893ccfSSadaf Ebrahimi }
302*b7893ccfSSadaf Ebrahimi 
PrintMessageFlags(VkFlags vk_flags,char * msg_flags)303*b7893ccfSSadaf Ebrahimi VK_LAYER_EXPORT void PrintMessageFlags(VkFlags vk_flags, char *msg_flags) {
304*b7893ccfSSadaf Ebrahimi     bool separator = false;
305*b7893ccfSSadaf Ebrahimi 
306*b7893ccfSSadaf Ebrahimi     msg_flags[0] = 0;
307*b7893ccfSSadaf Ebrahimi     if (vk_flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
308*b7893ccfSSadaf Ebrahimi         strcat(msg_flags, "DEBUG");
309*b7893ccfSSadaf Ebrahimi         separator = true;
310*b7893ccfSSadaf Ebrahimi     }
311*b7893ccfSSadaf Ebrahimi     if (vk_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
312*b7893ccfSSadaf Ebrahimi         if (separator) strcat(msg_flags, ",");
313*b7893ccfSSadaf Ebrahimi         strcat(msg_flags, "INFO");
314*b7893ccfSSadaf Ebrahimi         separator = true;
315*b7893ccfSSadaf Ebrahimi     }
316*b7893ccfSSadaf Ebrahimi     if (vk_flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
317*b7893ccfSSadaf Ebrahimi         if (separator) strcat(msg_flags, ",");
318*b7893ccfSSadaf Ebrahimi         strcat(msg_flags, "WARN");
319*b7893ccfSSadaf Ebrahimi         separator = true;
320*b7893ccfSSadaf Ebrahimi     }
321*b7893ccfSSadaf Ebrahimi     if (vk_flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
322*b7893ccfSSadaf Ebrahimi         if (separator) strcat(msg_flags, ",");
323*b7893ccfSSadaf Ebrahimi         strcat(msg_flags, "PERF");
324*b7893ccfSSadaf Ebrahimi         separator = true;
325*b7893ccfSSadaf Ebrahimi     }
326*b7893ccfSSadaf Ebrahimi     if (vk_flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
327*b7893ccfSSadaf Ebrahimi         if (separator) strcat(msg_flags, ",");
328*b7893ccfSSadaf Ebrahimi         strcat(msg_flags, "ERROR");
329*b7893ccfSSadaf Ebrahimi     }
330*b7893ccfSSadaf Ebrahimi }
331*b7893ccfSSadaf Ebrahimi 
PrintMessageSeverity(VkFlags vk_flags,char * msg_flags)332*b7893ccfSSadaf Ebrahimi VK_LAYER_EXPORT void PrintMessageSeverity(VkFlags vk_flags, char *msg_flags) {
333*b7893ccfSSadaf Ebrahimi     bool separator = false;
334*b7893ccfSSadaf Ebrahimi 
335*b7893ccfSSadaf Ebrahimi     msg_flags[0] = 0;
336*b7893ccfSSadaf Ebrahimi     if (vk_flags & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) {
337*b7893ccfSSadaf Ebrahimi         strcat(msg_flags, "VERBOSE");
338*b7893ccfSSadaf Ebrahimi         separator = true;
339*b7893ccfSSadaf Ebrahimi     }
340*b7893ccfSSadaf Ebrahimi     if (vk_flags & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
341*b7893ccfSSadaf Ebrahimi         if (separator) strcat(msg_flags, ",");
342*b7893ccfSSadaf Ebrahimi         strcat(msg_flags, "INFO");
343*b7893ccfSSadaf Ebrahimi         separator = true;
344*b7893ccfSSadaf Ebrahimi     }
345*b7893ccfSSadaf Ebrahimi     if (vk_flags & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
346*b7893ccfSSadaf Ebrahimi         if (separator) strcat(msg_flags, ",");
347*b7893ccfSSadaf Ebrahimi         strcat(msg_flags, "WARN");
348*b7893ccfSSadaf Ebrahimi         separator = true;
349*b7893ccfSSadaf Ebrahimi     }
350*b7893ccfSSadaf Ebrahimi     if (vk_flags & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
351*b7893ccfSSadaf Ebrahimi         if (separator) strcat(msg_flags, ",");
352*b7893ccfSSadaf Ebrahimi         strcat(msg_flags, "ERROR");
353*b7893ccfSSadaf Ebrahimi     }
354*b7893ccfSSadaf Ebrahimi }
355*b7893ccfSSadaf Ebrahimi 
PrintMessageType(VkFlags vk_flags,char * msg_flags)356*b7893ccfSSadaf Ebrahimi VK_LAYER_EXPORT void PrintMessageType(VkFlags vk_flags, char *msg_flags) {
357*b7893ccfSSadaf Ebrahimi     bool separator = false;
358*b7893ccfSSadaf Ebrahimi 
359*b7893ccfSSadaf Ebrahimi     msg_flags[0] = 0;
360*b7893ccfSSadaf Ebrahimi     if (vk_flags & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT) {
361*b7893ccfSSadaf Ebrahimi         strcat(msg_flags, "GEN");
362*b7893ccfSSadaf Ebrahimi         separator = true;
363*b7893ccfSSadaf Ebrahimi     }
364*b7893ccfSSadaf Ebrahimi     if (vk_flags & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) {
365*b7893ccfSSadaf Ebrahimi         strcat(msg_flags, "SPEC");
366*b7893ccfSSadaf Ebrahimi         separator = true;
367*b7893ccfSSadaf Ebrahimi     }
368*b7893ccfSSadaf Ebrahimi     if (vk_flags & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) {
369*b7893ccfSSadaf Ebrahimi         if (separator) strcat(msg_flags, ",");
370*b7893ccfSSadaf Ebrahimi         strcat(msg_flags, "PERF");
371*b7893ccfSSadaf Ebrahimi         separator = true;
372*b7893ccfSSadaf Ebrahimi     }
373*b7893ccfSSadaf Ebrahimi }
374