blob: a4153ec3503468eec7c4f2eac9d2e66c5ba6ae55 [file] [log] [blame]
Jon Ashburnbe582642014-12-22 12:04:40 -07001/**************************************************************************
2 *
3 * Copyright 2014 Lunarg, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 **************************************************************************/
25#include <fstream>
26#include <string>
27#include <map>
28#include <string.h>
Tobin Ehlis0c6f9ee2015-07-03 09:42:57 -060029#include <vk_layer.h>
Tobin Ehlisb1df55e2015-09-15 09:55:54 -060030#include <iostream>
Tobin Ehlisb835d1b2015-07-03 10:34:49 -060031#include "vk_loader_platform.h"
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -060032#include "vk_layer_config.h"
Ian Elliott655cad72015-02-12 17:08:34 -070033// The following is #included again to catch certain OS-specific functions
34// being used:
Tobin Ehlisb835d1b2015-07-03 10:34:49 -060035#include "vk_loader_platform.h"
Jon Ashburnbe582642014-12-22 12:04:40 -070036
37#define MAX_CHARS_PER_LINE 4096
38
39class ConfigFile
40{
41public:
42 ConfigFile();
43 ~ConfigFile();
44
45 const char *getOption(const std::string &_option);
Jon Ashburndec60512015-01-13 17:24:01 -070046 void setOption(const std::string &_option, const std::string &_val);
47
Jon Ashburnbe582642014-12-22 12:04:40 -070048private:
49 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 Ashburndec60512015-01-13 17:24:01 -070056
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060057static VkLayerDbgAction stringToDbgAction(const char *_enum)
Jon Ashburndec60512015-01-13 17:24:01 -070058{
59 // only handles single enum values
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060060 if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_IGNORE"))
61 return VK_DBG_LAYER_ACTION_IGNORE;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060062 else if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_LOG_MSG"))
63 return VK_DBG_LAYER_ACTION_LOG_MSG;
64 else if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_BREAK"))
65 return VK_DBG_LAYER_ACTION_BREAK;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060066 return (VkLayerDbgAction) 0;
Jon Ashburndec60512015-01-13 17:24:01 -070067}
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060068
69static VkFlags stringToDbgReportFlags(const char *_enum)
70{
71 // only handles single enum values
72 if (!strcmp(_enum, "VK_DBG_REPORT_INFO"))
73 return VK_DBG_REPORT_INFO_BIT;
74 else if (!strcmp(_enum, "VK_DBG_REPORT_WARN"))
75 return VK_DBG_REPORT_WARN_BIT;
76 else if (!strcmp(_enum, "VK_DBG_REPORT_PERF_WARN"))
77 return VK_DBG_REPORT_PERF_WARN_BIT;
78 else if (!strcmp(_enum, "VK_DBG_REPORT_ERROR"))
79 return VK_DBG_REPORT_ERROR_BIT;
Courtney Goeltzenleuchterb874b8c2015-06-14 11:34:49 -060080 else if (!strcmp(_enum, "VK_DBG_REPORT_DEBUG"))
81 return VK_DBG_REPORT_DEBUG_BIT;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060082 return (VkFlags) 0;
83}
84
85static unsigned int convertStringEnumVal(const char *_enum)
86{
87 unsigned int ret;
88
89 ret = stringToDbgAction(_enum);
90 if (ret)
91 return ret;
92
93 return stringToDbgReportFlags(_enum);
94}
95
Jon Ashburnbe582642014-12-22 12:04:40 -070096const char *getLayerOption(const char *_option)
97{
Jon Ashburnbe582642014-12-22 12:04:40 -070098 return g_configFileObj.getOption(_option);
99}
100
Tobin Ehlisb1df55e2015-09-15 09:55:54 -0600101// If option is NULL or stdout, return stdout, otherwise try to open option
102// as a filename. If successful, return file handle, otherwise stdout
103FILE* getLayerLogOutput(const char *_option, const char *layerName)
104{
105 FILE* log_output = NULL;
106 if (!_option || !strcmp("stdout", _option))
107 log_output = stdout;
108 else {
109 log_output = fopen(_option, "w");
110 if (log_output == NULL) {
111 if (_option)
112 std::cout << std::endl << layerName << " ERROR: Bad output filename specified: " << _option << ". Writing to STDOUT instead" << std::endl << std::endl;
113 log_output = stdout;
114 }
115 }
Cody Northrope3e39ef2015-09-16 08:35:29 -0600116 return log_output;
Tobin Ehlisb1df55e2015-09-15 09:55:54 -0600117}
118
Courtney Goeltzenleuchterb874b8c2015-06-14 11:34:49 -0600119uint32_t getLayerOptionFlags(const char *_option, uint32_t optionDefault)
120{
121 uint32_t flags = optionDefault;
122 const char *option = (g_configFileObj.getOption(_option));
123
124 /* parse comma-separated options */
125 while (option) {
126 const char *p = strchr(option, ',');
127 size_t len;
128
129 if (p)
130 len = p - option;
131 else
132 len = strlen(option);
133
134 if (len > 0) {
135 if (strncmp(option, "warn", len) == 0) {
136 flags |= VK_DBG_REPORT_WARN_BIT;
137 } else if (strncmp(option, "info", len) == 0) {
138 flags |= VK_DBG_REPORT_INFO_BIT;
139 } else if (strncmp(option, "perf", len) == 0) {
140 flags |= VK_DBG_REPORT_PERF_WARN_BIT;
141 } else if (strncmp(option, "error", len) == 0) {
142 flags |= VK_DBG_REPORT_ERROR_BIT;
143 } else if (strncmp(option, "debug", len) == 0) {
144 flags |= VK_DBG_REPORT_DEBUG_BIT;
145 }
146 }
147
148 if (!p)
149 break;
150
151 option = p + 1;
152 }
153 return flags;
154}
155
Jon Ashburna8aa8372015-03-03 15:07:15 -0700156bool getLayerOptionEnum(const char *_option, uint32_t *optionDefault)
Mark Lobodzinski8a2b75b2015-02-25 12:23:20 -0600157{
Jon Ashburna8aa8372015-03-03 15:07:15 -0700158 bool res;
Mark Lobodzinski8a2b75b2015-02-25 12:23:20 -0600159 const char *option = (g_configFileObj.getOption(_option));
160 if (option != NULL) {
Jon Ashburna8aa8372015-03-03 15:07:15 -0700161 *optionDefault = convertStringEnumVal(option);
162 res = false;
Mark Lobodzinski0d6e66d2015-02-25 15:14:06 -0600163 } else {
Jon Ashburna8aa8372015-03-03 15:07:15 -0700164 res = true;
Mark Lobodzinski8a2b75b2015-02-25 12:23:20 -0600165 }
Jon Ashburna8aa8372015-03-03 15:07:15 -0700166 return res;
Mark Lobodzinski8a2b75b2015-02-25 12:23:20 -0600167}
168
Jon Ashburndec60512015-01-13 17:24:01 -0700169void setLayerOptionEnum(const char *_option, const char *_valEnum)
170{
171 unsigned int val = convertStringEnumVal(_valEnum);
172 char strVal[24];
173 snprintf(strVal, 24, "%u", val);
174 g_configFileObj.setOption(_option, strVal);
175}
176
177void setLayerOption(const char *_option, const char *_val)
178{
179 g_configFileObj.setOption(_option, _val);
180}
181
Jon Ashburnbe582642014-12-22 12:04:40 -0700182ConfigFile::ConfigFile() : m_fileIsParsed(false)
183{
184}
185
186ConfigFile::~ConfigFile()
187{
188}
189
190const char *ConfigFile::getOption(const std::string &_option)
191{
192 std::map<std::string, std::string>::const_iterator it;
193 if (!m_fileIsParsed)
194 {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600195 parseFile("vk_layer_settings.txt");
Jon Ashburnbe582642014-12-22 12:04:40 -0700196 }
197
198 if ((it = m_valueMap.find(_option)) == m_valueMap.end())
199 return NULL;
200 else
201 return it->second.c_str();
202}
203
Jon Ashburndec60512015-01-13 17:24:01 -0700204void ConfigFile::setOption(const std::string &_option, const std::string &_val)
205{
206 if (!m_fileIsParsed)
207 {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600208 parseFile("vk_layer_settings.txt");
Jon Ashburndec60512015-01-13 17:24:01 -0700209 }
210
211 m_valueMap[_option] = _val;
212}
213
Jon Ashburnbe582642014-12-22 12:04:40 -0700214void ConfigFile::parseFile(const char *filename)
215{
216 std::ifstream file;
217 char buf[MAX_CHARS_PER_LINE];
218
219 m_fileIsParsed = true;
220 m_valueMap.clear();
221
222 file.open(filename);
223 if (!file.good())
224 return;
225
226 // read tokens from the file and form option, value pairs
227 file.getline(buf, MAX_CHARS_PER_LINE);
228 while (!file.eof())
229 {
230 char option[512];
231 char value[512];
232
233 char *pComment;
234
235 //discard any comments delimited by '#' in the line
236 pComment = strchr(buf, '#');
237 if (pComment)
238 *pComment = '\0';
239
240 if (sscanf(buf, " %511[^\n\t =] = %511[^\n \t]", option, value) == 2)
241 {
242 std::string optStr(option);
243 std::string valStr(value);
244 m_valueMap[optStr] = valStr;
245 }
246 file.getline(buf, MAX_CHARS_PER_LINE);
247 }
248}
249
Courtney Goeltzenleuchterf85e3612015-06-14 11:33:06 -0600250void print_msg_flags(VkFlags msgFlags, char *msg_flags)
251{
252 bool separator = false;
253
254 msg_flags[0] = 0;
255 if (msgFlags & VK_DBG_REPORT_DEBUG_BIT) {
256 strcat(msg_flags, "DEBUG");
257 separator = true;
258 }
259 if (msgFlags & VK_DBG_REPORT_INFO_BIT) {
260 if (separator) strcat(msg_flags, ",");
261 strcat(msg_flags, "INFO");
262 separator = true;
263 }
264 if (msgFlags & VK_DBG_REPORT_WARN_BIT) {
265 if (separator) strcat(msg_flags, ",");
266 strcat(msg_flags, "WARN");
267 separator = true;
268 }
269 if (msgFlags & VK_DBG_REPORT_PERF_WARN_BIT) {
270 if (separator) strcat(msg_flags, ",");
271 strcat(msg_flags, "PERF");
272 separator = true;
273 }
274 if (msgFlags & VK_DBG_REPORT_ERROR_BIT) {
275 if (separator) strcat(msg_flags, ",");
276 strcat(msg_flags, "ERROR");
277 }
278}
279