diff --git a/include/vulkan/layer/vk_layer_settings.h b/include/vulkan/layer/vk_layer_settings.h index c9e55fb..17901db 100644 --- a/include/vulkan/layer/vk_layer_settings.h +++ b/include/vulkan/layer/vk_layer_settings.h @@ -15,22 +15,15 @@ extern "C" { #include "vk_layer_settings_ext.h" -VK_DEFINE_HANDLE(VlLayerSettingSet) - -typedef void *(*VL_LAYER_SETTING_LOG_CALLBACK)(const char *pSettingName, const char *pMessage); - -// Create a layer setting set. If 'pCallback' is set to NULL, the messages are outputed to stderr. -VkResult vlCreateLayerSettingSet(const char *pLayerName, const VkLayerSettingsCreateInfoEXT *pCreateInfo, - const VkAllocationCallbacks *pAllocator, - VL_LAYER_SETTING_LOG_CALLBACK pCallback, VlLayerSettingSet *pLayerSettingSet); - -void vlDestroyLayerSettingSet(VlLayerSettingSet layerSettingSet, const VkAllocationCallbacks *pAllocator); +// Configure layer settings. If 'pCallback' is set to NULL, the messages are outputed to stderr. +VkResult vlRegisterLayerSettings(VkInstance instance, const char *pLayerName, + uint32_t settingCount, VkLayerSettingPropertiesEXT *pSettings, const VkAllocationCallbacks *pAllocator); // Check whether a setting was set either programmatically, from vk_layer_settings.txt or an environment variable -VkBool32 vlHasLayerSetting(VlLayerSettingSet layerSettingSet, const char *pSettingName); +VkBool32 vlHasLayerSetting(VkInstance instance, const char *pLayerName, const char *pSettingName); // Query setting values -VkResult vlGetLayerSettingValues(VlLayerSettingSet layerSettingSet, const char *pSettingName, VkLayerSettingTypeEXT type, +VkResult vlGetLayerSettingValues(VkInstance instance, const char *pLayerName, const char *pSettingName, VkLayerSettingTypeEXT type, uint32_t *pValueCount, void *pValues); const VkLayerSettingsCreateInfoEXT *vlFindLayerSettingsCreateInfo(const VkInstanceCreateInfo *pCreateInfo); diff --git a/include/vulkan/layer/vk_layer_settings_ext.h b/include/vulkan/layer/vk_layer_settings_ext.h index 8e91f07..38136fc 100644 --- a/include/vulkan/layer/vk_layer_settings_ext.h +++ b/include/vulkan/layer/vk_layer_settings_ext.h @@ -15,53 +15,14 @@ extern "C" { #include -// VK_EXT_layer_settings -// -// Name String -// VK_EXT_layer_settings -// -// Extension Type -// Instance extension -// -// Revision -// 1 -// -// Extension and Version Dependencies -// Requires Vulkan 1.0 -// -// Contact -// Christophe Riccio christophe-lunarg -// -// Contributors -// Christophe Riccio -// Mark Lobodzinski -// -// Description -// This extension provides a mechanism for configuring programmatically through -// the Vulkan API the behavior of layers. -// -// This extension provides the [VkLayerSettingsCreateInfoEXT] struct that can be -// included in the [pNext] chain of the [VkInstanceCreateInfo] -// structure passed as the [pCreateInfo] parameter of [vkCreateInstance]. -// -// The structure contains an array of [VkLayerSettingEXT] structure -// values that configure specific features of layers. -// -// Note -// The [VK_EXT_layer_settings] extension subsumes all the functionality provided in the [VK_EXT_validation_flags] extension -// and the [VK_EXT_validation_features] extension. - #define VK_EXT_layer_settings 1 #define VK_EXT_LAYER_SETTINGS_SPEC_VERSION 1 #define VK_EXT_LAYER_SETTINGS_EXTENSION_NAME "VK_EXT_layer_settings" -// This extension is exclusively used by VVL, and is NOT intended as a deliverable. -// The value of the VK_STRUCTURE_TYPE is arbitrary. The only requirement, -// is that it must not conflict with existing sTypes. -// // NOTE: VK_STRUCTURE_TYPE_MAX_ENUM - 1 is used by the intel driver. // NOTE: VK_STRUCTURE_TYPE_MAX_ENUM - 42 is used by the validation layers #define VK_STRUCTURE_TYPE_LAYER_SETTINGS_EXT ((VkStructureType)(VK_STRUCTURE_TYPE_MAX_ENUM - 43)) +#define VK_STRUCTURE_TYPE_LAYER_SETTING_PROPERTIES_EXT ((VkStructureType)(VK_STRUCTURE_TYPE_MAX_ENUM - 44)) typedef enum VkLayerSettingTypeEXT { VK_LAYER_SETTING_TYPE_BOOL32_EXT = 0, @@ -96,6 +57,16 @@ typedef struct VkLayerSettingsCreateInfoEXT { const VkLayerSettingEXT *pSettings; } VkLayerSettingsCreateInfoEXT; +typedef struct VkLayerSettingPropertiesEXT { + VkStructureType sType; + const void *pNext; + char key[VK_MAX_DESCRIPTION_SIZE]; + VkLayerSettingTypeEXT type; +} VkLayerSettingPropertiesEXT; + +VkResult vkEnumerateInstanceLayerSettingsEXT(VkInstance instance, const char *pLayerName, uint32_t *pPropertyCount, + VkLayerSettingPropertiesEXT *pProperties); + #ifdef __cplusplus } #endif diff --git a/src/layer/CMakeLists.txt b/src/layer/CMakeLists.txt index e28e0a1..c40822f 100644 --- a/src/layer/CMakeLists.txt +++ b/src/layer/CMakeLists.txt @@ -13,6 +13,7 @@ target_compile_features(VulkanLayerSettings PRIVATE cxx_std_17) target_sources(VulkanLayerSettings PRIVATE vk_layer_settings.cpp vk_layer_settings_helper.cpp + vk_layer_settings_interface.cpp layer_settings_manager.cpp layer_settings_manager.hpp layer_settings_util.cpp diff --git a/src/layer/layer_settings_manager.cpp b/src/layer/layer_settings_manager.cpp index a9a6010..1720136 100644 --- a/src/layer/layer_settings_manager.cpp +++ b/src/layer/layer_settings_manager.cpp @@ -103,12 +103,18 @@ static void AddWorkaroundLayerNames(std::vector &layer_names) { namespace vl { -LayerSettings::LayerSettings(const char *pLayerName, const VkLayerSettingsCreateInfoEXT *pCreateInfo, - const VkAllocationCallbacks *pAllocator, VL_LAYER_SETTING_LOG_CALLBACK callback) +LayerSettings::LayerSettings( + const char *pLayerName, + uint32_t settingCount, VkLayerSettingPropertiesEXT *pSettings, + const VkLayerSettingsCreateInfoEXT *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VL_LAYER_SETTING_LOG_CALLBACK callback) : layer_name(pLayerName), create_info(pCreateInfo), callback(callback) { (void)pAllocator; assert(pLayerName != nullptr); + this->settings.resize(settingCount); + memcpy(&this->settings[0], pSettings, sizeof(VkLayerSettingPropertiesEXT) * settingCount); + std::string settings_file = this->FindSettingsFile(); this->ParseSettingsFile(settings_file.c_str()); } diff --git a/src/layer/layer_settings_manager.hpp b/src/layer/layer_settings_manager.hpp index 7c09439..9f44163 100644 --- a/src/layer/layer_settings_manager.hpp +++ b/src/layer/layer_settings_manager.hpp @@ -17,8 +17,8 @@ namespace vl { class LayerSettings { public: - LayerSettings(const char *pLayerName, const VkLayerSettingsCreateInfoEXT *pCreateInfo, - const VkAllocationCallbacks *pAllocator, VL_LAYER_SETTING_LOG_CALLBACK callback); + LayerSettings(const char *pLayerName, uint32_t settingCount, VkLayerSettingPropertiesEXT *pSettings, + const VkAllocationCallbacks *pAllocator); ~LayerSettings(); bool HasEnvSetting(const char *pSettingName); @@ -40,8 +40,13 @@ namespace vl { std::vector &GetSettingCache(const std::string &pSettingName); private: + LayerSettings(const LayerSettings &) = delete; + LayerSettings& operator=(const LayerSettings &) = delete; + const VkLayerSettingEXT *FindLayerSettingValue(const char *pSettingName); + std::vector settings; + std::map setting_file_values; std::map> string_setting_cache; @@ -52,8 +57,6 @@ namespace vl { void ParseSettingsFile(const char *filename); std::string layer_name; - const VkLayerSettingsCreateInfoEXT *create_info{nullptr}; - VL_LAYER_SETTING_LOG_CALLBACK callback{nullptr}; }; }// namespace vl diff --git a/src/layer/layer_settings_util.cpp b/src/layer/layer_settings_util.cpp index 1b8226d..8622cda 100644 --- a/src/layer/layer_settings_util.cpp +++ b/src/layer/layer_settings_util.cpp @@ -6,6 +6,7 @@ // // Author(s): // - Christophe Riccio + #include "layer_settings_util.hpp" #include diff --git a/src/layer/vk_layer_settings.cpp b/src/layer/vk_layer_settings.cpp index e6b4977..de89f8e 100644 --- a/src/layer/vk_layer_settings.cpp +++ b/src/layer/vk_layer_settings.cpp @@ -6,6 +6,7 @@ // // Author(s): // - Christophe Riccio + #include "vulkan/layer/vk_layer_settings.h" #include "layer_settings_util.hpp" #include "layer_settings_manager.hpp" @@ -17,38 +18,34 @@ #include #include #include +#include + +static std::unordered_map layer_setting_sets; // This is used only for unit tests in test_layer_setting_file -void test_helper_SetLayerSetting(VlLayerSettingSet layerSettingSet, const char *pSettingName, const char *pValue) { - assert(layerSettingSet != VK_NULL_HANDLE); +void test_helper_SetLayerSetting(VkInstance instance, const char *pSettingName, const char *pValue) { + assert(instance != VK_NULL_HANDLE); assert(pSettingName != nullptr); assert(pValue != nullptr); - vl::LayerSettings *layer_setting_set = (vl::LayerSettings *)layerSettingSet; + vl::LayerSettings& layer_setting_set = ::layer_setting_sets[instance]; - layer_setting_set->SetFileSetting(pSettingName, pValue); + layer_setting_set.SetFileSetting(pSettingName, pValue); } -VkResult vlCreateLayerSettingSet(const char *pLayerName, const VkLayerSettingsCreateInfoEXT *pCreateInfo, - const VkAllocationCallbacks *pAllocator, VL_LAYER_SETTING_LOG_CALLBACK pCallback, - VlLayerSettingSet *pLayerSettingSet) { - (void)pAllocator; +VkResult vlRegisterLayerSettings(VkInstance instance, const char *pLayerName, uint32_t settingCount, + VkLayerSettingPropertiesEXT *pSettings, const VkAllocationCallbacks *pAllocator) { + vl::LayerSettings layer_settings(pLayerName, settingCount, pSettings, pAllocator); - vl::LayerSettings* layer_setting_set = new vl::LayerSettings(pLayerName, pCreateInfo, pAllocator, pCallback); - *pLayerSettingSet = (VlLayerSettingSet)layer_setting_set; + ::layer_setting_sets - return VK_SUCCESS; -} -void vlDestroyLayerSettingSet(VlLayerSettingSet layerSettingSet, const VkAllocationCallbacks *pAllocator) { - (void)pAllocator; + ::layer_setting_sets.insert(std::pair(instance, layer_settings)); - vl::LayerSettings *layer_setting_set = (vl::LayerSettings*)layerSettingSet; - delete layer_setting_set; + return VK_SUCCESS; } -VkBool32 vlHasLayerSetting(VlLayerSettingSet layerSettingSet, const char *pSettingName) { - assert(layerSettingSet != VK_NULL_HANDLE); +VkBool32 vlHasLayerSetting(VkInstance instance, const char *pLayerName, const char *pSettingName) { assert(pSettingName); assert(!std::string(pSettingName).empty()); @@ -61,15 +58,15 @@ VkBool32 vlHasLayerSetting(VlLayerSettingSet layerSettingSet, const char *pSetti return (has_env_setting || has_file_setting || has_api_setting) ? VK_TRUE : VK_FALSE; } -VkResult vlGetLayerSettingValues(VlLayerSettingSet layerSettingSet, const char *pSettingName, VkLayerSettingTypeEXT type, +VkResult vlGetLayerSettingValues(VkInstance instance, const char *pLayerName, const char *pSettingName, VkLayerSettingTypeEXT type, uint32_t *pValueCount, void *pValues) { assert(pValueCount != nullptr); - if (layerSettingSet == VK_NULL_HANDLE) { + if (instance == VK_NULL_HANDLE) { return VK_ERROR_INITIALIZATION_FAILED; } - if (!vlHasLayerSetting(layerSettingSet, pSettingName)) { + if (!vlHasLayerSetting(instance, pLayerName, pSettingName)) { *pValueCount = 0; return VK_SUCCESS; } diff --git a/src/layer/vk_layer_settings_helper.cpp b/src/layer/vk_layer_settings_helper.cpp index cd795bb..01bb4a5 100644 --- a/src/layer/vk_layer_settings_helper.cpp +++ b/src/layer/vk_layer_settings_helper.cpp @@ -6,6 +6,7 @@ // // Author(s): // - Christophe Riccio + #include "vulkan/layer/vk_layer_settings.hpp" static std::string Merge(const std::vector &strings) { diff --git a/src/layer/vk_layer_settings_interface.cpp b/src/layer/vk_layer_settings_interface.cpp new file mode 100644 index 0000000..bc51b21 --- /dev/null +++ b/src/layer/vk_layer_settings_interface.cpp @@ -0,0 +1,43 @@ +// Copyright 2023 The Khronos Group Inc. +// Copyright 2023 Valve Corporation +// Copyright 2023 LunarG, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Author(s): +// - Christophe Riccio + +#include "vulkan/layer/vk_layer_settings_ext.h" +#include +#include + +#if defined(__GNUC__) && __GNUC__ >= 4 +#define LAYER_EXPORT __attribute__((visibility("default"))) +#else +#define LAYER_EXPORT +#endif + +// Keep synchronized with VkLayer_khronos_profiles.def / VkLayer_khronos_profiles.map +extern "C" { + +LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerSettingsEXT( + VkInstance instance, const char* pLayerName, + uint32_t* pSettingCount, + VkLayerSettingPropertiesEXT* pSettings) { + + assert(pSettingCount != nullptr); + + if (strcmp(pLayerName, VK_EXT_LAYER_SETTINGS_EXTENSION_NAME) != 0) { + return VK_SUCCESS; + } + + if (*pSettingCount > 0 && pSettings != nullptr) { + + } else { + + } + + return VK_SUCCESS; +} + +} // extern "C"