VK_EXT_layer_settings

Adds an extension that allows applications to provide layer settings to any layers implementing the extension during instance creation.

1. Problem Statement

Typically, Vulkan layers can be configured using either environment variables or the vk_layer_settings.txt file. Alternatively, the Vulkan validation layer can be configure programmatically using the VK_EXT_validation_features.

VK_EXT_validation_features enables configuring the validation layer at instance creation time which allows running multiple Vulkan instances in parallel with different layer setting values for each Vulkan instance. A use case is C.I., providing shorter runs.

However, the VK_EXT_validation_features extension has multiple issues: * The VK_EXT_validation_features extension is dedicated to the validation layer exposing explicitly each validation layer feature. * Each time a new validation layer feature is implemented (which is quite often), the validation layer developer should theoretically create a new extension to expose the new feature. * Each layer that would want to expose layer settings programmatically would need to create Vulkan extensions. * Not all layer developers are Khronos members, preventing them or at least making it difficult to submit extensions.

2. Proposal

The goal of VK_EXT_layer_settings is to provide a generic mechanism to configure layer settings programmatically, a single extension that could be implemented by any layer. It is currently implemented by the validation layer, the profiles layer, the API dump layer, the screenshot layer, the memory decompression layer, the synchronization 2 layer and the shader object layer.

The intent of the extension is to be implemented in any layer that has settings to provide a consistent method across layers.

VK_EXT_layer_settings extends the pNext chain of VkInstanceCreateInfo to provide a list of structures which contain the information needed by the layers to configure their settings.

Each setting is built around a basic type (bool32, int32, int64, uint32, uint64, float32, float64 and strings) which can be an array. This restricts how settings are expressed, if the intent of the layer developer for a setting is a structure, then the structure will be split into multiple settings, one for each member.

This approach is designed to be compatible with existing alternative methods to configure layer settings: * Environment variables * vk_layer_settings.txt (hand-written or generated by Vulkan Configurator)

All three methods are implemented by the Vulkan Layer Settings library which can be easily integrated in any layer code base to provide a consistent design across layers.

typedef enum VkLayerSettingTypeEXT {
    VK_LAYER_SETTING_TYPE_BOOL32_EXT = 0,
    VK_LAYER_SETTING_TYPE_INT32_EXT,
    VK_LAYER_SETTING_TYPE_INT64_EXT,
    VK_LAYER_SETTING_TYPE_UINT32_EXT,
    VK_LAYER_SETTING_TYPE_UINT64_EXT,
    VK_LAYER_SETTING_TYPE_FLOAT32_EXT,
    VK_LAYER_SETTING_TYPE_FLOAT64_EXT,
    VK_LAYER_SETTING_TYPE_STRING_EXT
} VkLayerSettingTypeEXT;

typedef struct VkLayerSettingEXT {
    const char *pLayerName;
    const char *pSettingName;
    VkLayerSettingTypeEXT type;
    uint32_t count;
    const void *pValues;
} VkLayerSettingEXT;

typedef struct VkLayerSettingsCreateInfoEXT {
    VkStructureType sType;
    const void *pNext;
    uint32_t settingCount;
    const VkLayerSettingEXT *pSettings;
} VkLayerSettingsCreateInfoEXT;

3. Example Usage

This example shows a typical usage to configure the Profiles layer programmatically, here clamping the system capabilities to the Vulkan Roadmap 2022 profile set of capabilities.

const char* profile_file_data = JSON_TEST_FILES_PATH "VP_KHR_roadmap_2022.json";
const char* profile_name_data = "VP_KHR_roadmap_2022";
VkBool32 emulate_portability_data = VK_TRUE;
const char* simulate_capabilities[] = {
    "SIMULATE_API_VERSION_BIT",
    "SIMULATE_FEATURES_BIT",
    "SIMULATE_PROPERTIES_BIT",
    "SIMULATE_EXTENSIONS_BIT",
    "SIMULATE_FORMATS_BIT",
    "SIMULATE_QUEUE_FAMILY_PROPERTIES_BIT"
};
const char* debug_reports[] = {
    "DEBUG_REPORT_ERROR_BIT",
    "DEBUG_REPORT_WARNING_BIT",
    "DEBUG_REPORT_NOTIFICATION_BIT",
    "DEBUG_REPORT_DEBUG_BIT"
};

const VkLayerSettingEXT settings[] = {
     {kLayerName, kLayerSettingsProfileFile, VK_LAYER_SETTING_TYPE_STRING_EXT, 1, &profile_file_data},
     {kLayerName, kLayerSettingsProfileName, VK_LAYER_SETTING_TYPE_STRING_EXT, 1, &profile_name_data},
     {kLayerName, kLayerSettingsEmulatePortability, VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &emulate_portability_data},
     {kLayerName, kLayerSettingsSimulateCapabilities, VK_LAYER_SETTING_TYPE_STRING_EXT,
        static_cast<uint32_t>(std::size(simulate_capabilities)), simulate_capabilities},
     {kLayerName, kLayerSettingsDebugReports, VK_LAYER_SETTING_TYPE_STRING_EXT,
        static_cast<uint32_t>(std::size(debug_reports)), debug_reports}
};

const VkLayerSettingsCreateInfoEXT layer_settings_create_info{
    VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr,
    static_cast<uint32_t>(std::size(settings)), settings};

VkInstanceCreateInfo inst_create_info = {};
...
inst_create_info.pNext = &layer_settings_create_info;
vkCreateInstance(&inst_create_info, nullptr, &_instances);

4. Issues

4.1. RESOLVED: Should the extension provide a query to list the layers settings?

No, deferred to a separated extension is necessary.

Typically, just like any Vulkan extension, to use a setting, this setting must be understood by the Vulkan application developer because they affect the behavior of the application. So simply querying the settings list is not a relevant use case for an application developer. Basically, just like enabling the ray tracing extensions also requires implementation of ray tracing by the application.

Most importantly, we want the layer developers to be responsible of maintening layer settings compatibility between layer versions instead of the application developers. This approach would ensure for Vulkan application developer that layers remain easy to use, to upgrade and to support across versions.

Finally, there is the problem that the query would be an instance level extension that would require a Vulkan Loader change to be exposed. Hence, up to date loader version on the system running the layer to be able to expose the extension…​ This may or may not be an issue depending on the use cases and platforms. Consequently, if some relevant use cases for a query API are identified, we should create a dedicated extension so that VK_EXT_layer_settings would be expose and the dedicated extension would be expose only when the Vulkan loader is up to date.

4.2. RESOLVED: Should this extension deprecate VK_EXT_validation_features?

The validation layer implements both VK_EXT_layer_settings and VK_EXT_validation_features for backward compatibility and there is no plan to remove VK_EXT_validation_features yet.