layers: Add environment var for settings file
authorLenny Komow <lenny@lunarg.com>
Fri, 30 Sep 2016 20:15:25 +0000 (14:15 -0600)
committerLenny Komow <lenny@lunarg.com>
Wed, 5 Oct 2016 23:33:39 +0000 (17:33 -0600)
Change-Id: I8a614f915ab9b61eca5b3b94f4cf43a33cacf250

layers/README.md
layers/vk_layer_config.cpp

index b496e75..8de8f18 100644 (file)
@@ -21,13 +21,14 @@ vkXXXXGetProcAddr is used internally by the Layers and Loader to initialize disp
 Layers can also be activated via the VK_INSTANCE_LAYERS environment variable.
 
 All validation layers work with the DEBUG_REPORT extension to provide validation feedback.
-When a validation layer is enabled, it will look for a vk_layer_settings.txt file to define
-its logging behavior, which can include sending output to a file, stdout, or debug output (Windows).
-Applications can also register debug callback functions via the DEBUG_REPORT extension to receive
-callbacks when validation events occur. Application callbacks are independent of settings in a
-vk_layer_settings.txt file which will be carried out separately. If no vk_layer_settings.txt
-file is present and no application callbacks are registered, error messages will be output
-through default logging callbacks.
+When a validation layer is enabled, it will look for a vk_layer_settings.txt file (see"Using
+Layers" section below for more details) to define its logging behavior, which can include
+sending output to a file, stdout, or debug output (Windows). Applications can also register
+debug callback functions via the DEBUG_REPORT extension to receive callbacks when validation
+events occur. Application callbacks are independent of settings in a vk_layer_settings.txt
+file which will be carried out separately. If no vk_layer_settings.txt file is present and
+no application callbacks are registered, error messages will be output through default
+logging callbacks.
 
 ### Layer library example code
 
@@ -72,9 +73,9 @@ layers/swapchain.cpp (name=`VK_LAYER_LUNARG_swapchain`) - Check that WSI extensi
     This is required for the Loader to be able to scan and enumerate your library.
     Alternatively, use the `VK_LAYER_PATH` environment variable to specify where the layer libraries reside.
 
-3. Create a vk_layer_settings.txt file in the same directory to specify how your layers should behave.
+3. To specify how your layers should behave, create a vk_layer_settings.txt file. This file can exist in the same directory as your app or in a directory given by the `VK_LAYER_SETTINGS_PATH` environment variable. Alternatively, you can use any filename you want if you set `VK_LAYER_SETTINGS_PATH` to the full path of the file, rather than the directory that contains it.
 
-    Model it after the following example:  [*vk_layer_settings.txt*](vk_layer_settings.txt)
+    Model the file after the following example:  [*vk_layer_settings.txt*](vk_layer_settings.txt)
 
 4. Specify which layers to activate using environment variables.
 
index ec50744..d8fe87d 100644 (file)
  * Author: Tobin Ehlis <tobin@lunarg.com>
  * Author: Mark Lobodzinski <mark@lunarg.com>
  **************************************************************************/
+#include "vk_layer_config.h"
+#include "vulkan/vk_sdk_platform.h"
 #include <fstream>
-#include <string>
+#include <iostream>
 #include <map>
 #include <string.h>
+#include <string>
+#include <sys/stat.h>
 #include <vulkan/vk_layer.h>
-#include <iostream>
-#include "vk_layer_config.h"
-#include "vulkan/vk_sdk_platform.h"
 
 #define MAX_CHARS_PER_LINE 4096
 
@@ -49,6 +50,25 @@ class ConfigFile {
 
 static ConfigFile g_configFileObj;
 
+std::string getEnvironment(const char *variable) {
+#if !defined(__ANDROID__) && !defined(_WIN32)
+    const char *output = getenv(variable);
+    return output == NULL ? "" : output;
+#elif defined(_WIN32)
+    int size = GetEnvironmentVariable(variable, NULL, 0);
+    if (size == 0) {
+        return "";
+    }
+    char *buffer = new char[size];
+    GetEnvironmentVariable(variable, buffer, size);
+    std::string output = buffer;
+    delete[] buffer;
+    return output;
+#else
+    return "";
+#endif
+}
+
 const char *getLayerOption(const char *_option) { return g_configFileObj.getOption(_option); }
 
 // If option is NULL or stdout, return stdout, otherwise try to open option
@@ -155,7 +175,19 @@ ConfigFile::~ConfigFile() {}
 const char *ConfigFile::getOption(const std::string &_option) {
     std::map<std::string, std::string>::const_iterator it;
     if (!m_fileIsParsed) {
-        parseFile("vk_layer_settings.txt");
+        std::string envPath = getEnvironment("VK_LAYER_SETTINGS_PATH");
+
+        // If the path exists use it, else use vk_layer_settings
+        struct stat info;
+        if (stat(envPath.c_str(), &info) == 0) {
+            // If this is a directory, look for vk_layer_settings within the directory
+            if (info.st_mode & S_IFDIR) {
+                envPath += "/vk_layer_settings.txt";
+            }
+            parseFile(envPath.c_str());
+        } else {
+            parseFile("vk_layer_settings.txt");
+        }
     }
 
     if ((it = m_valueMap.find(_option)) == m_valueMap.end())
@@ -166,7 +198,19 @@ const char *ConfigFile::getOption(const std::string &_option) {
 
 void ConfigFile::setOption(const std::string &_option, const std::string &_val) {
     if (!m_fileIsParsed) {
-        parseFile("vk_layer_settings.txt");
+        std::string envPath = getEnvironment("VK_LAYER_SETTINGS_PATH");
+
+        // If the path exists use it, else use vk_layer_settings
+        struct stat info;
+        if (stat(envPath.c_str(), &info) == 0) {
+            // If this is a directory, look for vk_layer_settings within the directory
+            if (info.st_mode & S_IFDIR) {
+                envPath += "/vk_layer_settings.txt";
+            }
+            parseFile(envPath.c_str());
+        } else {
+            parseFile("vk_layer_settings.txt");
+        }
     }
 
     m_valueMap[_option] = _val;