// Copyright 2023-2024 The Khronos Group Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

= VK_EXT_layer_settings

:toc: left
:refpage: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/
:sectnums:

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

== 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.

== 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 link:{refpage}VkInstanceCreateInfo.html[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.

[source,c]
----
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;
----

== 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.

[source,c]
----
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);
----

== Issues

=== 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 raytracing extensions also requires implementation of raytracing 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.

=== 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.

