blob: e916cfe6d8691c8e03cd4ec1c7ae1633ee029fcb [file] [log] [blame]
Jon Ashburn47e92892014-12-22 12:04:40 -07001/**************************************************************************
2 *
Jon Ashburnc5a5d632015-11-03 13:41:23 -07003 * Copyright 2014 Valve Software
Michael Lentine92689442015-09-09 12:39:13 -07004 * Copyright 2015 Google Inc.
Jon Ashburn47e92892014-12-22 12:04:40 -07005 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 *
Jon Ashburnc5a5d632015-11-03 13:41:23 -070025 * Author: Jon Ashburn <jon@lunarg.com>
26 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
27 * Author: Tobin Ehlis <tobin@lunarg.com>
Jon Ashburn47e92892014-12-22 12:04:40 -070028 **************************************************************************/
29#include <fstream>
30#include <string>
31#include <map>
32#include <string.h>
David Pinedo329ca9e2015-11-06 12:54:48 -070033#include <vulkan/vk_layer.h>
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -060034#include <iostream>
Tobin Ehlis56d204a2015-07-03 10:15:26 -060035#include "vk_layer_config.h"
David Pinedo329ca9e2015-11-06 12:54:48 -070036#include "vulkan/vk_sdk_platform.h"
Jon Ashburn47e92892014-12-22 12:04:40 -070037
38#define MAX_CHARS_PER_LINE 4096
39
Jon Ashburn491a3cd2016-03-08 17:48:44 -070040class ConfigFile {
41 public:
Jon Ashburn47e92892014-12-22 12:04:40 -070042 ConfigFile();
43 ~ConfigFile();
44
45 const char *getOption(const std::string &_option);
Jon Ashburn0f1dbf12015-01-13 17:24:01 -070046 void setOption(const std::string &_option, const std::string &_val);
47
Jon Ashburn491a3cd2016-03-08 17:48:44 -070048 private:
Jon Ashburn47e92892014-12-22 12:04:40 -070049 bool m_fileIsParsed;
50 std::map<std::string, std::string> m_valueMap;
51
52 void parseFile(const char *filename);
53};
54
55static ConfigFile g_configFileObj;
Jon Ashburn0f1dbf12015-01-13 17:24:01 -070056
Jon Ashburn491a3cd2016-03-08 17:48:44 -070057static VkLayerDbgAction stringToDbgAction(const char *_enum) {
Jon Ashburn0f1dbf12015-01-13 17:24:01 -070058 // only handles single enum values
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060059 if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_IGNORE"))
60 return VK_DBG_LAYER_ACTION_IGNORE;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060061 else if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_LOG_MSG"))
62 return VK_DBG_LAYER_ACTION_LOG_MSG;
Courtney Goeltzenleuchterb94f0512015-10-05 14:41:34 -060063#ifdef WIN32
64 else if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_DEBUG_OUTPUT"))
65 return VK_DBG_LAYER_ACTION_DEBUG_OUTPUT;
66#endif
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060067 else if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_BREAK"))
68 return VK_DBG_LAYER_ACTION_BREAK;
Jon Ashburn491a3cd2016-03-08 17:48:44 -070069 return (VkLayerDbgAction)0;
Jon Ashburn0f1dbf12015-01-13 17:24:01 -070070}
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060071
Jon Ashburn491a3cd2016-03-08 17:48:44 -070072static VkFlags stringToDbgReportFlags(const char *_enum) {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060073 // only handles single enum values
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -070074 if (!strcmp(_enum, "VK_DEBUG_REPORT_INFO"))
Mark Lobodzinski5c13d4d2016-02-11 09:26:16 -070075 return VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -070076 else if (!strcmp(_enum, "VK_DEBUG_REPORT_WARN"))
Mark Lobodzinski5c13d4d2016-02-11 09:26:16 -070077 return VK_DEBUG_REPORT_WARNING_BIT_EXT;
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -070078 else if (!strcmp(_enum, "VK_DEBUG_REPORT_PERF_WARN"))
Mark Lobodzinski5c13d4d2016-02-11 09:26:16 -070079 return VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -070080 else if (!strcmp(_enum, "VK_DEBUG_REPORT_ERROR"))
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -070081 return VK_DEBUG_REPORT_ERROR_BIT_EXT;
Courtney Goeltzenleuchterf8fe1282015-11-25 10:30:56 -070082 else if (!strcmp(_enum, "VK_DEBUG_REPORT_DEBUG"))
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -070083 return VK_DEBUG_REPORT_DEBUG_BIT_EXT;
Jon Ashburn491a3cd2016-03-08 17:48:44 -070084 return (VkFlags)0;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060085}
86
Jon Ashburn491a3cd2016-03-08 17:48:44 -070087static unsigned int convertStringEnumVal(const char *_enum) {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060088 unsigned int ret;
89
90 ret = stringToDbgAction(_enum);
91 if (ret)
92 return ret;
93
94 return stringToDbgReportFlags(_enum);
95}
96
Jon Ashburn491a3cd2016-03-08 17:48:44 -070097const char *getLayerOption(const char *_option) { return g_configFileObj.getOption(_option); }
Jon Ashburn47e92892014-12-22 12:04:40 -070098
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -060099// If option is NULL or stdout, return stdout, otherwise try to open option
100// as a filename. If successful, return file handle, otherwise stdout
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700101FILE *getLayerLogOutput(const char *_option, const char *layerName) {
102 FILE *log_output = NULL;
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -0600103 if (!_option || !strcmp("stdout", _option))
104 log_output = stdout;
105 else {
106 log_output = fopen(_option, "w");
107 if (log_output == NULL) {
108 if (_option)
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700109 std::cout << std::endl
110 << layerName << " ERROR: Bad output filename specified: " << _option << ". Writing to STDOUT instead"
111 << std::endl
112 << std::endl;
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -0600113 log_output = stdout;
114 }
115 }
Cody Northrop866bb9c2015-09-16 08:35:29 -0600116 return log_output;
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -0600117}
118
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700119VkDebugReportFlagsEXT getLayerOptionFlags(const char *_option, uint32_t optionDefault) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700120 VkDebugReportFlagsEXT flags = optionDefault;
Courtney Goeltzenleuchter35b4da92015-06-14 11:34:49 -0600121 const char *option = (g_configFileObj.getOption(_option));
122
123 /* parse comma-separated options */
124 while (option) {
125 const char *p = strchr(option, ',');
126 size_t len;
127
128 if (p)
129 len = p - option;
130 else
131 len = strlen(option);
132
133 if (len > 0) {
134 if (strncmp(option, "warn", len) == 0) {
Mark Lobodzinski5c13d4d2016-02-11 09:26:16 -0700135 flags |= VK_DEBUG_REPORT_WARNING_BIT_EXT;
Courtney Goeltzenleuchter35b4da92015-06-14 11:34:49 -0600136 } else if (strncmp(option, "info", len) == 0) {
Mark Lobodzinski5c13d4d2016-02-11 09:26:16 -0700137 flags |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
Courtney Goeltzenleuchter35b4da92015-06-14 11:34:49 -0600138 } else if (strncmp(option, "perf", len) == 0) {
Mark Lobodzinski5c13d4d2016-02-11 09:26:16 -0700139 flags |= VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
Courtney Goeltzenleuchter35b4da92015-06-14 11:34:49 -0600140 } else if (strncmp(option, "error", len) == 0) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700141 flags |= VK_DEBUG_REPORT_ERROR_BIT_EXT;
Courtney Goeltzenleuchter35b4da92015-06-14 11:34:49 -0600142 } else if (strncmp(option, "debug", len) == 0) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700143 flags |= VK_DEBUG_REPORT_DEBUG_BIT_EXT;
Courtney Goeltzenleuchter35b4da92015-06-14 11:34:49 -0600144 }
145 }
146
147 if (!p)
148 break;
149
150 option = p + 1;
151 }
152 return flags;
153}
154
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700155bool getLayerOptionEnum(const char *_option, uint32_t *optionDefault) {
Jon Ashburne4722392015-03-03 15:07:15 -0700156 bool res;
Mark Lobodzinskic5eaea62015-02-25 12:23:20 -0600157 const char *option = (g_configFileObj.getOption(_option));
158 if (option != NULL) {
Jon Ashburne4722392015-03-03 15:07:15 -0700159 *optionDefault = convertStringEnumVal(option);
160 res = false;
Mark Lobodzinski1ee9f3a2015-02-25 15:14:06 -0600161 } else {
Jon Ashburne4722392015-03-03 15:07:15 -0700162 res = true;
Mark Lobodzinskic5eaea62015-02-25 12:23:20 -0600163 }
Jon Ashburne4722392015-03-03 15:07:15 -0700164 return res;
Mark Lobodzinskic5eaea62015-02-25 12:23:20 -0600165}
166
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700167void setLayerOptionEnum(const char *_option, const char *_valEnum) {
Jon Ashburn0f1dbf12015-01-13 17:24:01 -0700168 unsigned int val = convertStringEnumVal(_valEnum);
169 char strVal[24];
170 snprintf(strVal, 24, "%u", val);
171 g_configFileObj.setOption(_option, strVal);
172}
173
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700174void setLayerOption(const char *_option, const char *_val) { g_configFileObj.setOption(_option, _val); }
Jon Ashburn0f1dbf12015-01-13 17:24:01 -0700175
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700176ConfigFile::ConfigFile() : m_fileIsParsed(false) {}
Jon Ashburn47e92892014-12-22 12:04:40 -0700177
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700178ConfigFile::~ConfigFile() {}
Jon Ashburn47e92892014-12-22 12:04:40 -0700179
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700180const char *ConfigFile::getOption(const std::string &_option) {
Jon Ashburn47e92892014-12-22 12:04:40 -0700181 std::map<std::string, std::string>::const_iterator it;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700182 if (!m_fileIsParsed) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600183 parseFile("vk_layer_settings.txt");
Jon Ashburn47e92892014-12-22 12:04:40 -0700184 }
185
186 if ((it = m_valueMap.find(_option)) == m_valueMap.end())
187 return NULL;
188 else
189 return it->second.c_str();
190}
191
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700192void ConfigFile::setOption(const std::string &_option, const std::string &_val) {
193 if (!m_fileIsParsed) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600194 parseFile("vk_layer_settings.txt");
Jon Ashburn0f1dbf12015-01-13 17:24:01 -0700195 }
196
197 m_valueMap[_option] = _val;
198}
199
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700200void ConfigFile::parseFile(const char *filename) {
Jon Ashburn47e92892014-12-22 12:04:40 -0700201 std::ifstream file;
202 char buf[MAX_CHARS_PER_LINE];
203
204 m_fileIsParsed = true;
205 m_valueMap.clear();
206
207 file.open(filename);
208 if (!file.good())
209 return;
210
211 // read tokens from the file and form option, value pairs
212 file.getline(buf, MAX_CHARS_PER_LINE);
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700213 while (!file.eof()) {
Jon Ashburn47e92892014-12-22 12:04:40 -0700214 char option[512];
215 char value[512];
216
217 char *pComment;
218
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700219 // discard any comments delimited by '#' in the line
Jon Ashburn47e92892014-12-22 12:04:40 -0700220 pComment = strchr(buf, '#');
221 if (pComment)
222 *pComment = '\0';
223
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700224 if (sscanf(buf, " %511[^\n\t =] = %511[^\n \t]", option, value) == 2) {
Jon Ashburn47e92892014-12-22 12:04:40 -0700225 std::string optStr(option);
226 std::string valStr(value);
227 m_valueMap[optStr] = valStr;
228 }
229 file.getline(buf, MAX_CHARS_PER_LINE);
230 }
231}
232
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700233void print_msg_flags(VkFlags msgFlags, char *msg_flags) {
Courtney Goeltzenleuchter065843d2015-06-14 11:33:06 -0600234 bool separator = false;
235
236 msg_flags[0] = 0;
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700237 if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
Courtney Goeltzenleuchter065843d2015-06-14 11:33:06 -0600238 strcat(msg_flags, "DEBUG");
239 separator = true;
240 }
Mark Lobodzinski5c13d4d2016-02-11 09:26:16 -0700241 if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700242 if (separator)
243 strcat(msg_flags, ",");
Courtney Goeltzenleuchter065843d2015-06-14 11:33:06 -0600244 strcat(msg_flags, "INFO");
245 separator = true;
246 }
Mark Lobodzinski5c13d4d2016-02-11 09:26:16 -0700247 if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700248 if (separator)
249 strcat(msg_flags, ",");
Courtney Goeltzenleuchter065843d2015-06-14 11:33:06 -0600250 strcat(msg_flags, "WARN");
251 separator = true;
252 }
Mark Lobodzinski5c13d4d2016-02-11 09:26:16 -0700253 if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700254 if (separator)
255 strcat(msg_flags, ",");
Courtney Goeltzenleuchter065843d2015-06-14 11:33:06 -0600256 strcat(msg_flags, "PERF");
257 separator = true;
258 }
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700259 if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700260 if (separator)
261 strcat(msg_flags, ",");
Courtney Goeltzenleuchter065843d2015-06-14 11:33:06 -0600262 strcat(msg_flags, "ERROR");
263 }
264}