blob: d67f4053177b23f9f1b3a265848f174955e888fe [file] [log] [blame]
Jon Ashburnbe582642014-12-22 12:04:40 -07001/**************************************************************************
2 *
Jon Ashburne922f712015-11-03 13:41:23 -07003 * Copyright 2014 Valve Software
Michael Lentine695f2c22015-09-09 12:39:13 -07004 * Copyright 2015 Google Inc.
Jon Ashburnbe582642014-12-22 12:04:40 -07005 * All Rights Reserved.
6 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -06007 * 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
Jon Ashburnbe582642014-12-22 12:04:40 -070010 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060011 * http://www.apache.org/licenses/LICENSE-2.0
Jon Ashburnbe582642014-12-22 12:04:40 -070012 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060013 * 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.
Jon Ashburnbe582642014-12-22 12:04:40 -070018 *
Jon Ashburne922f712015-11-03 13:41:23 -070019 * Author: Jon Ashburn <jon@lunarg.com>
20 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
21 * Author: Tobin Ehlis <tobin@lunarg.com>
Jon Ashburnbe582642014-12-22 12:04:40 -070022 **************************************************************************/
23#include <fstream>
24#include <string>
25#include <map>
26#include <string.h>
David Pinedo9316d3b2015-11-06 12:54:48 -070027#include <vulkan/vk_layer.h>
Tobin Ehlisb1df55e2015-09-15 09:55:54 -060028#include <iostream>
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -060029#include "vk_layer_config.h"
David Pinedo9316d3b2015-11-06 12:54:48 -070030#include "vulkan/vk_sdk_platform.h"
Jon Ashburnbe582642014-12-22 12:04:40 -070031
32#define MAX_CHARS_PER_LINE 4096
33
Jon Ashburn5484e0c2016-03-08 17:48:44 -070034class ConfigFile {
35 public:
Jon Ashburnbe582642014-12-22 12:04:40 -070036 ConfigFile();
37 ~ConfigFile();
38
39 const char *getOption(const std::string &_option);
Jon Ashburndec60512015-01-13 17:24:01 -070040 void setOption(const std::string &_option, const std::string &_val);
41
Jon Ashburn5484e0c2016-03-08 17:48:44 -070042 private:
Jon Ashburnbe582642014-12-22 12:04:40 -070043 bool m_fileIsParsed;
44 std::map<std::string, std::string> m_valueMap;
45
46 void parseFile(const char *filename);
47};
48
49static ConfigFile g_configFileObj;
Jon Ashburndec60512015-01-13 17:24:01 -070050
Jon Ashburn5484e0c2016-03-08 17:48:44 -070051static VkLayerDbgAction stringToDbgAction(const char *_enum) {
Jon Ashburndec60512015-01-13 17:24:01 -070052 // only handles single enum values
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060053 if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_IGNORE"))
54 return VK_DBG_LAYER_ACTION_IGNORE;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060055 else if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_LOG_MSG"))
56 return VK_DBG_LAYER_ACTION_LOG_MSG;
Courtney Goeltzenleuchter5907ac42015-10-05 14:41:34 -060057#ifdef WIN32
58 else if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_DEBUG_OUTPUT"))
59 return VK_DBG_LAYER_ACTION_DEBUG_OUTPUT;
60#endif
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060061 else if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_BREAK"))
62 return VK_DBG_LAYER_ACTION_BREAK;
Jon Ashburn5484e0c2016-03-08 17:48:44 -070063 return (VkLayerDbgAction)0;
Jon Ashburndec60512015-01-13 17:24:01 -070064}
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060065
Jon Ashburn5484e0c2016-03-08 17:48:44 -070066static VkFlags stringToDbgReportFlags(const char *_enum) {
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060067 // only handles single enum values
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -070068 if (!strcmp(_enum, "VK_DEBUG_REPORT_INFO"))
Mark Lobodzinski510e20d2016-02-11 09:26:16 -070069 return VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -070070 else if (!strcmp(_enum, "VK_DEBUG_REPORT_WARN"))
Mark Lobodzinski510e20d2016-02-11 09:26:16 -070071 return VK_DEBUG_REPORT_WARNING_BIT_EXT;
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -070072 else if (!strcmp(_enum, "VK_DEBUG_REPORT_PERF_WARN"))
Mark Lobodzinski510e20d2016-02-11 09:26:16 -070073 return VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -070074 else if (!strcmp(_enum, "VK_DEBUG_REPORT_ERROR"))
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -070075 return VK_DEBUG_REPORT_ERROR_BIT_EXT;
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -070076 else if (!strcmp(_enum, "VK_DEBUG_REPORT_DEBUG"))
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -070077 return VK_DEBUG_REPORT_DEBUG_BIT_EXT;
Jon Ashburn5484e0c2016-03-08 17:48:44 -070078 return (VkFlags)0;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060079}
80
Jon Ashburn5484e0c2016-03-08 17:48:44 -070081static unsigned int convertStringEnumVal(const char *_enum) {
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060082 unsigned int ret;
83
84 ret = stringToDbgAction(_enum);
85 if (ret)
86 return ret;
87
88 return stringToDbgReportFlags(_enum);
89}
90
Jon Ashburn5484e0c2016-03-08 17:48:44 -070091const char *getLayerOption(const char *_option) { return g_configFileObj.getOption(_option); }
Jon Ashburnbe582642014-12-22 12:04:40 -070092
Tobin Ehlisb1df55e2015-09-15 09:55:54 -060093// If option is NULL or stdout, return stdout, otherwise try to open option
94// as a filename. If successful, return file handle, otherwise stdout
Jon Ashburn5484e0c2016-03-08 17:48:44 -070095FILE *getLayerLogOutput(const char *_option, const char *layerName) {
96 FILE *log_output = NULL;
Tobin Ehlisb1df55e2015-09-15 09:55:54 -060097 if (!_option || !strcmp("stdout", _option))
98 log_output = stdout;
99 else {
100 log_output = fopen(_option, "w");
101 if (log_output == NULL) {
102 if (_option)
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700103 std::cout << std::endl
104 << layerName << " ERROR: Bad output filename specified: " << _option << ". Writing to STDOUT instead"
105 << std::endl
106 << std::endl;
Tobin Ehlisb1df55e2015-09-15 09:55:54 -0600107 log_output = stdout;
108 }
109 }
Cody Northrope3e39ef2015-09-16 08:35:29 -0600110 return log_output;
Tobin Ehlisb1df55e2015-09-15 09:55:54 -0600111}
112
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700113VkDebugReportFlagsEXT getLayerOptionFlags(const char *_option, uint32_t optionDefault) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700114 VkDebugReportFlagsEXT flags = optionDefault;
Courtney Goeltzenleuchterb874b8c2015-06-14 11:34:49 -0600115 const char *option = (g_configFileObj.getOption(_option));
116
117 /* parse comma-separated options */
118 while (option) {
119 const char *p = strchr(option, ',');
120 size_t len;
121
122 if (p)
123 len = p - option;
124 else
125 len = strlen(option);
126
127 if (len > 0) {
128 if (strncmp(option, "warn", len) == 0) {
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700129 flags |= VK_DEBUG_REPORT_WARNING_BIT_EXT;
Courtney Goeltzenleuchterb874b8c2015-06-14 11:34:49 -0600130 } else if (strncmp(option, "info", len) == 0) {
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700131 flags |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
Courtney Goeltzenleuchterb874b8c2015-06-14 11:34:49 -0600132 } else if (strncmp(option, "perf", len) == 0) {
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700133 flags |= VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
Courtney Goeltzenleuchterb874b8c2015-06-14 11:34:49 -0600134 } else if (strncmp(option, "error", len) == 0) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700135 flags |= VK_DEBUG_REPORT_ERROR_BIT_EXT;
Courtney Goeltzenleuchterb874b8c2015-06-14 11:34:49 -0600136 } else if (strncmp(option, "debug", len) == 0) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700137 flags |= VK_DEBUG_REPORT_DEBUG_BIT_EXT;
Courtney Goeltzenleuchterb874b8c2015-06-14 11:34:49 -0600138 }
139 }
140
141 if (!p)
142 break;
143
144 option = p + 1;
145 }
146 return flags;
147}
148
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700149bool getLayerOptionEnum(const char *_option, uint32_t *optionDefault) {
Jon Ashburna8aa8372015-03-03 15:07:15 -0700150 bool res;
Mark Lobodzinski8a2b75b2015-02-25 12:23:20 -0600151 const char *option = (g_configFileObj.getOption(_option));
152 if (option != NULL) {
Jon Ashburna8aa8372015-03-03 15:07:15 -0700153 *optionDefault = convertStringEnumVal(option);
154 res = false;
Mark Lobodzinski0d6e66d2015-02-25 15:14:06 -0600155 } else {
Jon Ashburna8aa8372015-03-03 15:07:15 -0700156 res = true;
Mark Lobodzinski8a2b75b2015-02-25 12:23:20 -0600157 }
Jon Ashburna8aa8372015-03-03 15:07:15 -0700158 return res;
Mark Lobodzinski8a2b75b2015-02-25 12:23:20 -0600159}
160
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700161void setLayerOptionEnum(const char *_option, const char *_valEnum) {
Jon Ashburndec60512015-01-13 17:24:01 -0700162 unsigned int val = convertStringEnumVal(_valEnum);
163 char strVal[24];
164 snprintf(strVal, 24, "%u", val);
165 g_configFileObj.setOption(_option, strVal);
166}
167
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700168void setLayerOption(const char *_option, const char *_val) { g_configFileObj.setOption(_option, _val); }
Jon Ashburndec60512015-01-13 17:24:01 -0700169
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700170ConfigFile::ConfigFile() : m_fileIsParsed(false) {}
Jon Ashburnbe582642014-12-22 12:04:40 -0700171
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700172ConfigFile::~ConfigFile() {}
Jon Ashburnbe582642014-12-22 12:04:40 -0700173
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700174const char *ConfigFile::getOption(const std::string &_option) {
Jon Ashburnbe582642014-12-22 12:04:40 -0700175 std::map<std::string, std::string>::const_iterator it;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700176 if (!m_fileIsParsed) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600177 parseFile("vk_layer_settings.txt");
Jon Ashburnbe582642014-12-22 12:04:40 -0700178 }
179
180 if ((it = m_valueMap.find(_option)) == m_valueMap.end())
181 return NULL;
182 else
183 return it->second.c_str();
184}
185
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700186void ConfigFile::setOption(const std::string &_option, const std::string &_val) {
187 if (!m_fileIsParsed) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600188 parseFile("vk_layer_settings.txt");
Jon Ashburndec60512015-01-13 17:24:01 -0700189 }
190
191 m_valueMap[_option] = _val;
192}
193
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700194void ConfigFile::parseFile(const char *filename) {
Jon Ashburnbe582642014-12-22 12:04:40 -0700195 std::ifstream file;
196 char buf[MAX_CHARS_PER_LINE];
197
198 m_fileIsParsed = true;
199 m_valueMap.clear();
200
201 file.open(filename);
202 if (!file.good())
203 return;
204
205 // read tokens from the file and form option, value pairs
206 file.getline(buf, MAX_CHARS_PER_LINE);
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700207 while (!file.eof()) {
Jon Ashburnbe582642014-12-22 12:04:40 -0700208 char option[512];
209 char value[512];
210
211 char *pComment;
212
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700213 // discard any comments delimited by '#' in the line
Jon Ashburnbe582642014-12-22 12:04:40 -0700214 pComment = strchr(buf, '#');
215 if (pComment)
216 *pComment = '\0';
217
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700218 if (sscanf(buf, " %511[^\n\t =] = %511[^\n \t]", option, value) == 2) {
Jon Ashburnbe582642014-12-22 12:04:40 -0700219 std::string optStr(option);
220 std::string valStr(value);
221 m_valueMap[optStr] = valStr;
222 }
223 file.getline(buf, MAX_CHARS_PER_LINE);
224 }
225}
226
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700227void print_msg_flags(VkFlags msgFlags, char *msg_flags) {
Courtney Goeltzenleuchterf85e3612015-06-14 11:33:06 -0600228 bool separator = false;
229
230 msg_flags[0] = 0;
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700231 if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
Courtney Goeltzenleuchterf85e3612015-06-14 11:33:06 -0600232 strcat(msg_flags, "DEBUG");
233 separator = true;
234 }
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700235 if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700236 if (separator)
237 strcat(msg_flags, ",");
Courtney Goeltzenleuchterf85e3612015-06-14 11:33:06 -0600238 strcat(msg_flags, "INFO");
239 separator = true;
240 }
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700241 if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700242 if (separator)
243 strcat(msg_flags, ",");
Courtney Goeltzenleuchterf85e3612015-06-14 11:33:06 -0600244 strcat(msg_flags, "WARN");
245 separator = true;
246 }
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700247 if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700248 if (separator)
249 strcat(msg_flags, ",");
Courtney Goeltzenleuchterf85e3612015-06-14 11:33:06 -0600250 strcat(msg_flags, "PERF");
251 separator = true;
252 }
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700253 if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700254 if (separator)
255 strcat(msg_flags, ",");
Courtney Goeltzenleuchterf85e3612015-06-14 11:33:06 -0600256 strcat(msg_flags, "ERROR");
257 }
258}