147e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn/**************************************************************************
247e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn *
3c5a5d63c7c7ef3d2238233fedf3be675934e30c9Jon Ashburn * Copyright 2014 Valve Software
49268944f0ecf9da8e9e49e014d2fb45faedb64ceMichael Lentine * Copyright 2015 Google Inc.
547e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn * All Rights Reserved.
647e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn *
743b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * Licensed under the Apache License, Version 2.0 (the "License");
843b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * you may not use this file except in compliance with the License.
943b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * You may obtain a copy of the License at
1047e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn *
1143b53e83705f02245da6ae61e31273866a35b833Jon Ashburn *     http://www.apache.org/licenses/LICENSE-2.0
1247e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn *
1343b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * Unless required by applicable law or agreed to in writing, software
1443b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * distributed under the License is distributed on an "AS IS" BASIS,
1543b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1643b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * See the License for the specific language governing permissions and
1743b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * limitations under the License.
1847e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn *
19c5a5d63c7c7ef3d2238233fedf3be675934e30c9Jon Ashburn * Author: Jon Ashburn <jon@lunarg.com>
20c5a5d63c7c7ef3d2238233fedf3be675934e30c9Jon Ashburn * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
21c5a5d63c7c7ef3d2238233fedf3be675934e30c9Jon Ashburn * Author: Tobin Ehlis <tobin@lunarg.com>
22c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski * Author: Mark Lobodzinski <mark@lunarg.com>
2347e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn **************************************************************************/
240b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow#include "vk_layer_config.h"
250b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow#include "vulkan/vk_sdk_platform.h"
2647e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn#include <fstream>
270b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow#include <iostream>
2847e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn#include <map>
2947e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn#include <string.h>
300b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow#include <string>
310b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow#include <sys/stat.h>
32329ca9eb16cdbee7a7644fb08ade7b3d3bb32e23David Pinedo#include <vulkan/vk_layer.h>
3347e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
3462506a77cdd670a82a7b47f6dcbf39f46231c8beMark Lobodzinski#if defined(_WIN32)
3562506a77cdd670a82a7b47f6dcbf39f46231c8beMark Lobodzinski#include <Windows.h>
3662506a77cdd670a82a7b47f6dcbf39f46231c8beMark Lobodzinski#endif
3762506a77cdd670a82a7b47f6dcbf39f46231c8beMark Lobodzinski
3847e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn#define MAX_CHARS_PER_LINE 4096
3947e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
40491a3cd11793892b996a8b5771479cc539198f99Jon Ashburnclass ConfigFile {
41cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski   public:
4247e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    ConfigFile();
4347e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    ~ConfigFile();
4447e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
4547e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    const char *getOption(const std::string &_option);
460f1dbf15031846dee079e13a243de1ddfb65aaffJon Ashburn    void setOption(const std::string &_option, const std::string &_val);
470f1dbf15031846dee079e13a243de1ddfb65aaffJon Ashburn
48cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski   private:
4947e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    bool m_fileIsParsed;
5047e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    std::map<std::string, std::string> m_valueMap;
5147e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
5247e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    void parseFile(const char *filename);
5347e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn};
5447e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
5547e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburnstatic ConfigFile g_configFileObj;
560f1dbf15031846dee079e13a243de1ddfb65aaffJon Ashburn
570b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komowstd::string getEnvironment(const char *variable) {
580b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow#if !defined(__ANDROID__) && !defined(_WIN32)
590b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow    const char *output = getenv(variable);
600b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow    return output == NULL ? "" : output;
610b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow#elif defined(_WIN32)
620b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow    int size = GetEnvironmentVariable(variable, NULL, 0);
630b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow    if (size == 0) {
640b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow        return "";
650b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow    }
660b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow    char *buffer = new char[size];
670b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow    GetEnvironmentVariable(variable, buffer, size);
680b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow    std::string output = buffer;
690b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow    delete[] buffer;
700b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow    return output;
710b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow#else
720b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow    return "";
730b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow#endif
740b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow}
750b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow
76e7818f7c38b60af949f97f5e1159a0ec2c172a3fMark LobodzinskiVK_LAYER_EXPORT const char *getLayerOption(const char *_option) { return g_configFileObj.getOption(_option); }
7747e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
78b4b6e7c2412a10c2df40493141229f79970e51bbTobin Ehlis// If option is NULL or stdout, return stdout, otherwise try to open option
79c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski// as a filename. If successful, return file handle, otherwise stdout
80e7818f7c38b60af949f97f5e1159a0ec2c172a3fMark LobodzinskiVK_LAYER_EXPORT FILE *getLayerLogOutput(const char *_option, const char *layerName) {
81491a3cd11793892b996a8b5771479cc539198f99Jon Ashburn    FILE *log_output = NULL;
82b4b6e7c2412a10c2df40493141229f79970e51bbTobin Ehlis    if (!_option || !strcmp("stdout", _option))
83b4b6e7c2412a10c2df40493141229f79970e51bbTobin Ehlis        log_output = stdout;
84b4b6e7c2412a10c2df40493141229f79970e51bbTobin Ehlis    else {
85b4b6e7c2412a10c2df40493141229f79970e51bbTobin Ehlis        log_output = fopen(_option, "w");
86b4b6e7c2412a10c2df40493141229f79970e51bbTobin Ehlis        if (log_output == NULL) {
87b4b6e7c2412a10c2df40493141229f79970e51bbTobin Ehlis            if (_option)
88491a3cd11793892b996a8b5771479cc539198f99Jon Ashburn                std::cout << std::endl
89491a3cd11793892b996a8b5771479cc539198f99Jon Ashburn                          << layerName << " ERROR: Bad output filename specified: " << _option << ". Writing to STDOUT instead"
90491a3cd11793892b996a8b5771479cc539198f99Jon Ashburn                          << std::endl
91491a3cd11793892b996a8b5771479cc539198f99Jon Ashburn                          << std::endl;
92b4b6e7c2412a10c2df40493141229f79970e51bbTobin Ehlis            log_output = stdout;
93b4b6e7c2412a10c2df40493141229f79970e51bbTobin Ehlis        }
94b4b6e7c2412a10c2df40493141229f79970e51bbTobin Ehlis    }
95866bb9c87ab16a0055978eff4e9ebd9c2a828b04Cody Northrop    return log_output;
96b4b6e7c2412a10c2df40493141229f79970e51bbTobin Ehlis}
97b4b6e7c2412a10c2df40493141229f79970e51bbTobin Ehlis
98c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski// Map option strings to flag enum values
99e7818f7c38b60af949f97f5e1159a0ec2c172a3fMark LobodzinskiVK_LAYER_EXPORT VkFlags GetLayerOptionFlags(std::string _option, std::unordered_map<std::string, VkFlags> const &enum_data,
100e7818f7c38b60af949f97f5e1159a0ec2c172a3fMark Lobodzinski                                            uint32_t option_default) {
101c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    VkDebugReportFlagsEXT flags = option_default;
102c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    std::string option_list = g_configFileObj.getOption(_option.c_str());
103c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski
104c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    while (option_list.length() != 0) {
105c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        // Find length of option string
106c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        std::size_t option_length = option_list.find(",");
107c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        if (option_length == option_list.npos) {
108c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski            option_length = option_list.size();
10935b4da96505de43ebb11978acf9859ca4bbdbe3bCourtney Goeltzenleuchter        }
11035b4da96505de43ebb11978acf9859ca4bbdbe3bCourtney Goeltzenleuchter
111c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        // Get first option in list
112c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        const std::string option = option_list.substr(0, option_length);
11335b4da96505de43ebb11978acf9859ca4bbdbe3bCourtney Goeltzenleuchter
114c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        auto enum_value = enum_data.find(option);
115c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        if (enum_value != enum_data.end()) {
116c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski            flags |= enum_value->second;
117c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        }
11835b4da96505de43ebb11978acf9859ca4bbdbe3bCourtney Goeltzenleuchter
119c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        // Remove first option from option_list
120c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        option_list.erase(0, option_length);
121c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        // Remove possible comma separator
122c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        std::size_t char_position = option_list.find(",");
123c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        if (char_position == 0) {
124c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski            option_list.erase(char_position, 1);
125c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        }
126c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        // Remove possible space
127c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        char_position = option_list.find(" ");
128c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        if (char_position == 0) {
129c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski            option_list.erase(char_position, 1);
130c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        }
131c5eaea6af58e5c83c1ec48ca066e30ea0a020d2cMark Lobodzinski    }
132c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    return flags;
1330f1dbf15031846dee079e13a243de1ddfb65aaffJon Ashburn}
1340f1dbf15031846dee079e13a243de1ddfb65aaffJon Ashburn
135e7818f7c38b60af949f97f5e1159a0ec2c172a3fMark LobodzinskiVK_LAYER_EXPORT void setLayerOption(const char *_option, const char *_val) { g_configFileObj.setOption(_option, _val); }
1360f1dbf15031846dee079e13a243de1ddfb65aaffJon Ashburn
137c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski// Constructor for ConfigFile. Initialize layers to log error messages to stdout by default. If a vk_layer_settings file is present,
138c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski// its settings will override the defaults.
139c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark LobodzinskiConfigFile::ConfigFile() : m_fileIsParsed(false) {
140c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    m_valueMap["lunarg_core_validation.report_flags"] = "error";
141c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    m_valueMap["lunarg_object_tracker.report_flags"] = "error";
142c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    m_valueMap["lunarg_parameter_validation.report_flags"] = "error";
143c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    m_valueMap["google_threading.report_flags"] = "error";
144a9d779085ecc3e28aee3b78209bb5f1ec36b3ce8Mark Lobodzinski    m_valueMap["google_unique_objects.report_flags"] = "error";
145c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski
146c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski#ifdef WIN32
147c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    // For Windows, enable message logging AND OutputDebugString
148bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski    m_valueMap["lunarg_core_validation.debug_action"] =
149bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski        "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
150bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski    m_valueMap["lunarg_object_tracker.debug_action"] =
151bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski        "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
152bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski    m_valueMap["lunarg_parameter_validation.debug_action"] =
153bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski        "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
154bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski    m_valueMap["google_threading.debug_action"] =
155bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski        "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
156bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski    m_valueMap["google_unique_objects.debug_action"] =
157bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski        "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
158cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#else   // WIN32
159c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    m_valueMap["lunarg_core_validation.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
160c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    m_valueMap["lunarg_object_tracker.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
161c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    m_valueMap["lunarg_parameter_validation.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
162c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    m_valueMap["google_threading.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
163a9d779085ecc3e28aee3b78209bb5f1ec36b3ce8Mark Lobodzinski    m_valueMap["google_unique_objects.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
164cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#endif  // WIN32
165c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski
166c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    m_valueMap["lunarg_core_validation.log_filename"] = "stdout";
167c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    m_valueMap["lunarg_object_tracker.log_filename"] = "stdout";
168c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    m_valueMap["lunarg_parameter_validation.log_filename"] = "stdout";
169c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    m_valueMap["google_threading.log_filename"] = "stdout";
170a9d779085ecc3e28aee3b78209bb5f1ec36b3ce8Mark Lobodzinski    m_valueMap["google_unique_objects.log_filename"] = "stdout";
171c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski}
17247e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
173491a3cd11793892b996a8b5771479cc539198f99Jon AshburnConfigFile::~ConfigFile() {}
17447e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
175491a3cd11793892b996a8b5771479cc539198f99Jon Ashburnconst char *ConfigFile::getOption(const std::string &_option) {
17647e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    std::map<std::string, std::string>::const_iterator it;
177491a3cd11793892b996a8b5771479cc539198f99Jon Ashburn    if (!m_fileIsParsed) {
1780b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow        std::string envPath = getEnvironment("VK_LAYER_SETTINGS_PATH");
1790b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow
1800b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow        // If the path exists use it, else use vk_layer_settings
1810b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow        struct stat info;
1820b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow        if (stat(envPath.c_str(), &info) == 0) {
1830b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow            // If this is a directory, look for vk_layer_settings within the directory
1840b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow            if (info.st_mode & S_IFDIR) {
1850b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow                envPath += "/vk_layer_settings.txt";
1860b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow            }
1870b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow            parseFile(envPath.c_str());
1880b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow        } else {
1892364aa03abb7b9a1e5eca82653be05720721ac3fCody Northrop            parseFile("vk_layer_settings.txt");
1900b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow        }
19147e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    }
19247e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
19347e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    if ((it = m_valueMap.find(_option)) == m_valueMap.end())
194c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski        return "";
19547e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    else
19647e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn        return it->second.c_str();
19747e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn}
19847e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
199491a3cd11793892b996a8b5771479cc539198f99Jon Ashburnvoid ConfigFile::setOption(const std::string &_option, const std::string &_val) {
200491a3cd11793892b996a8b5771479cc539198f99Jon Ashburn    if (!m_fileIsParsed) {
2010b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow        std::string envPath = getEnvironment("VK_LAYER_SETTINGS_PATH");
2020b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow
2030b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow        // If the path exists use it, else use vk_layer_settings
2040b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow        struct stat info;
2050b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow        if (stat(envPath.c_str(), &info) == 0) {
2060b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow            // If this is a directory, look for vk_layer_settings within the directory
2070b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow            if (info.st_mode & S_IFDIR) {
2080b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow                envPath += "/vk_layer_settings.txt";
2090b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow            }
2100b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow            parseFile(envPath.c_str());
2110b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow        } else {
2122364aa03abb7b9a1e5eca82653be05720721ac3fCody Northrop            parseFile("vk_layer_settings.txt");
2130b1c1c09fd1431fcd7cc9f53d0443d69d21635d1Lenny Komow        }
2140f1dbf15031846dee079e13a243de1ddfb65aaffJon Ashburn    }
2150f1dbf15031846dee079e13a243de1ddfb65aaffJon Ashburn
2160f1dbf15031846dee079e13a243de1ddfb65aaffJon Ashburn    m_valueMap[_option] = _val;
2170f1dbf15031846dee079e13a243de1ddfb65aaffJon Ashburn}
2180f1dbf15031846dee079e13a243de1ddfb65aaffJon Ashburn
219491a3cd11793892b996a8b5771479cc539198f99Jon Ashburnvoid ConfigFile::parseFile(const char *filename) {
22047e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    std::ifstream file;
22147e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    char buf[MAX_CHARS_PER_LINE];
22247e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
22347e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    m_fileIsParsed = true;
22447e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
22547e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    file.open(filename);
226c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    if (!file.good()) {
22747e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn        return;
228c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski    }
229c34ab18ac7c064590a1020a8db4b6abf5a8d3a18Mark Lobodzinski
23047e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    // read tokens from the file and form option, value pairs
23147e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    file.getline(buf, MAX_CHARS_PER_LINE);
232491a3cd11793892b996a8b5771479cc539198f99Jon Ashburn    while (!file.eof()) {
23347e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn        char option[512];
23447e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn        char value[512];
23547e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
23647e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn        char *pComment;
23747e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
238491a3cd11793892b996a8b5771479cc539198f99Jon Ashburn        // discard any comments delimited by '#' in the line
23947e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn        pComment = strchr(buf, '#');
240cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski        if (pComment) *pComment = '\0';
24147e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
242491a3cd11793892b996a8b5771479cc539198f99Jon Ashburn        if (sscanf(buf, " %511[^\n\t =] = %511[^\n \t]", option, value) == 2) {
24347e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn            std::string optStr(option);
24447e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn            std::string valStr(value);
24547e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn            m_valueMap[optStr] = valStr;
24647e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn        }
24747e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn        file.getline(buf, MAX_CHARS_PER_LINE);
24847e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn    }
24947e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn}
25047e9289b849a08f0830ddf729fe6637ec081c731Jon Ashburn
251e7818f7c38b60af949f97f5e1159a0ec2c172a3fMark LobodzinskiVK_LAYER_EXPORT void print_msg_flags(VkFlags msgFlags, char *msg_flags) {
252065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter    bool separator = false;
253065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter
254065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter    msg_flags[0] = 0;
255acb1359c8e1528e5d67bb0101c94c48a07785098Courtney Goeltzenleuchter    if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
256065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter        strcat(msg_flags, "DEBUG");
257065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter        separator = true;
258065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter    }
2595c13d4d87fd0356003a3441e887a172b991e880fMark Lobodzinski    if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
260cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski        if (separator) strcat(msg_flags, ",");
261065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter        strcat(msg_flags, "INFO");
262065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter        separator = true;
263065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter    }
2645c13d4d87fd0356003a3441e887a172b991e880fMark Lobodzinski    if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
265cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski        if (separator) strcat(msg_flags, ",");
266065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter        strcat(msg_flags, "WARN");
267065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter        separator = true;
268065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter    }
2695c13d4d87fd0356003a3441e887a172b991e880fMark Lobodzinski    if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
270cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski        if (separator) strcat(msg_flags, ",");
271065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter        strcat(msg_flags, "PERF");
272065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter        separator = true;
273065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter    }
274acb1359c8e1528e5d67bb0101c94c48a07785098Courtney Goeltzenleuchter    if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
275cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski        if (separator) strcat(msg_flags, ",");
276065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter        strcat(msg_flags, "ERROR");
277065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter    }
278065843de24ab65bd78d4eae587661db57ef78af7Courtney Goeltzenleuchter}
279