Copyright © 2015-2021 LunarG, Inc.

# VK_LAYER_LUNARG_device_simulation

## Overview

### Extend your Vulkan test coverage with the LunarG Device Simulation Layer

The LunarG Device Simulation layer helps test across a wide range of hardware capabilities without requiring a physical copy of every device. It can be applied without modifying any application binaries, and in a fully automated fashion. The Device Simulation layer (aka DevSim) is a Vulkan layer that can override the values returned by your application’s queries of the GPU. DevSim uses a JSON text configuration file to make your application see a different driver/GPU than is actually in your system. This capability is useful to verify that your application both a) properly queries the limits from Vulkan, and b) obeys those limits.

The DevSim layer library is available pre-built in the Vulkan SDK, and continues to evolve. DevSim works for all Vulkan platforms (Linux, Windows, macOS, and Android), and is open-source software hosted on GitHub.The DevSim layer can be enabled and configured using the Vulkan Configurator included with the Vulkan SDK.

The role of DevSim is to "simulate" a less-capable Vulkan implementation by constraining the features and resources of a more-capable implementation. Note that the actual device in your machine should be more capable than that which you are simulating. DevSim does not add capabilities to your existing Vulkan implementation by "emulating" additional capabilities with software; e.g. DevSim cannot add geometry shader capability to an actual device that doesn’t already provide it. Also, DevSim does not "enforce" the features being simulated. For enforcement, you would continue to use the Validation Layers as usual, in conjunction with DevSim.

### Using DevSim

DevSim supports a flexible configuration file format using JSON syntax. The configuration file format is defined by a formal JSON schema available on the Khronos website, so any configuration file may be verified to be correct using freely available JSON validators. Browsing through the schema file, you can see the extent of parameters that are available for your configuration. As a convenience, DevSim supports loading multiple JSON files, so your configuration data can be split among separate files for modularity as desired.

### Android

To enable, use a setting with the path of configuration file to load:

    adb shell settings put global debug.vulkan.devsim.filepath <path/to/DevSim/JSON/configuration/file>

Example of a DevSim JSON configuration file: tiny1.json

Optional: use settings to enable debugging output and exit-on-error:

    adb shell settings put global debug.vulkan.devsim.debugenable 1
    adb shell settings put global debug.vulkan.devsim.exitonerror 1

### How DevSim Works

DevSim builds its internal data tables by querying the capabilities of the underlying actual device, then applying each of the configuration files “on top of” those tables. Therefore you only need to specify the features you wish to modify from the actual device; tweaking a single feature is easy. Here’s an example of a valid configuration file for changing only the maximum permitted viewport size:

    {
       "$schema": "https://schema.khronos.org/vulkan/devsim_1_0_0.json#",
       "VkPhysicalDeviceProperties": {
           "limits": { "maxViewportDimensions": [1024, 1024] }
       }
    }

### Simulating Entire Real-World Devices

If you instead wish to simulate entire real-world devices, LunarG has collaborated with the Vulkan Hardware Database to make their data compatible with the DevSim schema. You can download device configurations from the website in JSON format, and use those configuration files directly with DevSim.

# Technical Details

The Device Simulation Layer is a Vulkan layer that can modify the results of Vulkan PhysicalDevice queries based on a JSON configuration file, thus simulating some of the capabilities of device by overriding the capabilities of the actual device under test.

Please note that this device simulation layer "simulates", rather than "emulates", another device. By that we mean that the layer cannot add emulated capabilities that do not already exist in the system's underlying actual device; DevSim will not enable a less-capable device to emulate a more-capable device. This layer enables a more-capable device to simulate a less-capable device by removing some of the capabilities reported by queries; you can change or reduce what is already present in the underlying actual implementation.

Application code can be tested to verify it responds correctly to the capabilities reported by the simulated device. That could include:

- Properly querying the capabilities of the device.
- Properly complying with the limits reported from the device.
- Verifying all necessary capabilities are reported present, rather than assuming they are available.
- Exercising fall-back code paths, if optional capabilities are not available.

The DevSim layer does not enforce the capabilities returned by queries. The application is still responsible for querying and complying with the capabilities reported. If an application erroneously attempts to overcommit a resource, or use a disabled feature, the DevSim layer will not generate errors. To detect such errors, use the Vulkan Validation layers, as with any non-simulated device.

The DevSim layer will work with other Vulkan layers, such as Validation. When configuring the order of the layers list, the DevSim layer should be "last"; i.e.: closest to the driver, farthest from the application. That allows the Validation layer to see the results of the DevSim layer, and permit Validation to enforce the simulated capabilities.

Please report issues to LunarG's VulkanTools GitHub repository and include "DevSim" in the title text.

### Layer name

`VK_LAYER_LUNARG_device_simulation`

### DevSim Layer operation and configuration

At application startup, during vkCreateInstance(), the DevSim layer initializes its internal tables from the actual physical device in the system, then loads its configuration file, which specifies override values to apply to those internal tables.

How the JSON configuration values are applied depends on whether the top-level section begins with "ArrayOf" or not.

- If the section is not an array, values are applied if they appear in the JSON; if a value is not present in the JSON, the previous value is not modified. Therefore not every parameter needs to be specified, only a sparse set of values that need to be changed.
- If the section defines an array (i.e.: begins with "ArrayOf"), then all previous contents of that array are cleared, and the JSON must specify all values of each desired array element.

JSON file formats consumed by the DevSim layer are specified by one of the JSON schemas in the table below.

Schema Use | Canonical URI
--- | ---
Vulkan v1.0 | https://schema.khronos.org/vulkan/devsim_1_0_0.json#
Vulkan v1.1 | https://schema.khronos.org/vulkan/devsim_1_1_0.json#
Vulkan v1.2 | https://schema.khronos.org/vulkan/devsim_1_2_0.json#
VK_KHR_portability_subset | https://schema.khronos.org/vulkan/devsim_VK_KHR_portability_subset-provisional-1.json#
VK_KHR_8bit_storage | https://schema.khronos.org/vulkan/devsim_VK_KHR_8bit_storage_1.json#
VK_KHR_16bit_storage | https://schema.khronos.org/vulkan/devsim_VK_KHR_16bit_storage_1.json#
VK_KHR_buffer_device_address | https://schema.khronos.org/vulkan/devsim_VK_KHR_buffer_device_address_1.json#
VK_KHR_depth_stencil_resolve | https://schema.khronos.org/vulkan/devsim_VK_KHR_depth_stencil_resolve_1.json#
VK_EXT_descriptor_indexing | https://schema.khronos.org/vulkan/devsim_VK_EXT_descriptor_indexing_1.json#
VK_EXT_host_query_reset | https://schema.khronos.org/vulkan/devsim_VK_EXT_host_query_reset_1.json#
VK_KHR_imageless_framebuffer | https://schema.khronos.org/vulkan/devsim_VK_KHR_imageless_framebuffer_1.json#
VK_KHR_maintenance2 | https://schema.khronos.org/vulkan/devsim_VK_KHR_maintenance2_1.json#
VK_KHR_maintenance3 | https://schema.khronos.org/vulkan/devsim_VK_KHR_maintenance3_1.json#
VK_KHR_multiview | https://schema.khronos.org/vulkan/devsim_VK_KHR_multiview_1.json#
VK_EXT_sampler_filter_minmax | https://schema.khronos.org/vulkan/devsim_VK_EXT_sampler_filter_minmax_1.json#
VK_KHR_sampler_ycbcr_conversion | https://schema.khronos.org/vulkan/devsim_VK_KHR_sampler_ycbcr_conversion_1.json#
VK_EXT_scalar_block_layout | https://schema.khronos.org/vulkan/devsim_VK_EXT_scalar_block_layout_1.json#
VK_KHR_separate_depth_stencil_layouts | https://schema.khronos.org/vulkan/devsim_VK_KHR_separate_depth_stencil_layouts_1.json#
VK_KHR_shader_atomic_int64 | https://schema.khronos.org/vulkan/devsim_VK_KHR_shader_atomic_int64_1.json#
VK_KHR_shader_float_controls | https://schema.khronos.org/vulkan/devsim_VK_KHR_shader_float_controls_1.json#
VK_KHR_shader_float16_int8 | https://schema.khronos.org/vulkan/devsim_VK_KHR_shader_float16_int8_1.json#
VK_KHR_shader_subgroup_extended_types | https://schema.khronos.org/vulkan/devsim_VK_KHR_shader_subgroup_extended_types_1.json#
VK_KHR_timeline_semaphore | https://schema.khronos.org/vulkan/devsim_VK_KHR_timeline_semaphore_1.json#
VK_KHR_uniform_buffer_standard_layout | https://schema.khronos.org/vulkan/devsim_VK_KHR_uniform_buffer_standard_layout_1.json#
VK_KHR_variable_pointers | https://schema.khronos.org/vulkan/devsim_VK_KHR_variable_pointers_1.json#
VK_KHR_vulkan_memory_model | https://schema.khronos.org/vulkan/devsim_VK_KHR_vulkan_memory_model_1.json#

Usually you will be using configuration files validated with the Vulkan v1.2 schema.

The top-level sections of such configuration files are processed as follows:

- `$schema` - Mandatory. Must be the URI string referencing the JSON schema.
- `comments` - Optional. May contain arbitrary comments, description, copyright, etc.
- `VkPhysicalDeviceProperties` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceDepthStencilResolveProperties` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceDescriptorIndexingProperties` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceFloatControlsProperties` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceMaintenance3Properties` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceMultiviewProperties` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDevicePointClippingProperties` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceProtectedMemoryProperties` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceSamplerFilterMinmaxProperties` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceTimelineSemaphoreProperties` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDevice16BitStorageFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDevice8BitStorageFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceDescriptorIndexingFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceHostQueryResetFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceImagelessFramebufferFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceMultiviewFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceProtectedMemoryFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceSamplerYcbcrConversionFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceScalarBlockLayoutFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceShaderAtomicInt64Features` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceShaderDrawParametersFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceShaderFloat16Int8Features` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceTimelineSemaphoreFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceUniformBufferStandardLayoutFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceVariablePointersFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceVulkanMemoryModelFeatures` - Optional. Only values specified in the JSON will be modified.
- `VkPhysicalDeviceMemoryProperties` - Optional. Only values specified in the JSON will be modified.
- `ArrayOfVkQueueFamilyProperties` - Optional. If present, all values of all elements must be specified.
- `ArrayOfVkFormatProperties` - Optional. If present, all values of all elements must be specified.
- `ArrayOfVkExtensionProperties` - Optional. If present, all values of all elements must be specified. Modifies the list returned by `vkEnumerateDeviceExtensionProperties`.
- `Vulkan12Features` - Optional. Only values specified in the JSON will be modified.
- `Vulkan12Properties` - Optional. Only values specified in the JSON will be modified.
- The remaining top-level sections of the schema are not yet supported by DevSim.

The schema permits additional top-level sections to be optionally included in configuration files; any additional top-level sections will be ignored by DevSim.

The schemas define basic range checking for common Vulkan data types, but they cannot detect whether a particular configuration makes no sense. If a configuration defines capabilities beyond what the actual device is natively capable of providing, the results are undefined. DevSim has some simple checking of configuration values and writes debug messages (if enabled) for values that are incompatible with the capabilities of the actual device.

This version of DevSim currently supports Vulkan v1.2 and below. If the application requests an unsupported version of the Vulkan API, DevSim will emit an error message. If you wish DevSim to terminate on errors, set the `VK_DEVSIM_EXIT_ON_ERROR` environment variable (see below).

### Example of a DevSim JSON configuration file

    {
        "$schema": "https://schema.khronos.org/vulkan/devsim_1_0_0.json#",
        "comments": {
            "info": "You may add whatever you wish to this comments section",
            "filename": "layersvt/device_simulation_examples/tiny1.json",
            "desc": "A tiny and valid DevSim JSON config file",
            "author": "mikew@lunarg.com"
        },
        "VkPhysicalDeviceProperties": {
            "deviceName": "override viewport capabilties",
            "limits": {
                "maxViewports": 1,
                "maxViewportDimensions": [1024, 1024]
            }
        }
    }

#### Additional sample JSON configuration files

Sample Name | Description | Link
--- | --- | ---
iOS_gpu_family_3_portability.json | JSON configuration file describing iOS GPU family 3 portability features and properties. | Link
iOS_gpu_family_5_portability.json | JSON configuration file describing iOS GPU family 5 portability features and properties. | Link
macOS_gpu_family_1_portability.json | JSON configuration file describing macOS GPU family 1 portability features and properties. | Link
portability_minimum_vulkan_1_0.json | JSON configuration file for Vulkan 1.0 minimum requirements as defined by the Vulkan Specification. Values are modified to cover the Vulkan Portability Subset | Link
portability_minimum_vulkan_1_1.json | JSON configuration file for Vulkan 1.1 minimum requirements as defined by the Vulkan Specification. Values are modified to cover the Vulkan Portability Subset | Link
portability_minimum_vulkan_1_2.json | JSON configuration file for Vulkan 1.2 minimum requirements as defined by the Vulkan Specification. Values are modified to cover the Vulkan Portability Subset | Link
spec_minimum_vulkan_1_0.json | JSON configuration file for Vulkan 1.0 minimum requirements as defined by the Vulkan Specification. | Link
spec_minimum_vulkan_1_1.json | JSON configuration file for Vulkan 1.1 minimum requirements as defined by the Vulkan Specification. | Link
spec_minimum_vulkan_1_2.json | JSON configuration file for Vulkan 1.2 minimum requirements as defined by the Vulkan Specification. | Link

These and other sample files can be found in the ${VulkanTools}/layersvt/device_simulation_examples/sdk_sample_configs directory.

### `VK_KHR_portability_subset` Emulation

The DevSim layer provides the ability to emulate the `VK_KHR_portability_subset` extension on devices that do not implement this extension. This feature allows users to test their application with limitations found on non-conformant Vulkan implementations. To turn on this feature, set the `VK_DEVSIM_EMULATE_PORTABILITY_SUBSET_EXTENSION` environment variable (or the corresponding vk_layer_settings.txt option `lunarg_device_simulation.emulate_portability`) to a positive integer. DevSim config files that use this feature should validate to the portability specific schema https://schema.khronos.org/vulkan/devsim_VK_KHR_portability_subset-provisional-1.json#.

### DevSim Layer Options

#### Devsim JSON configuration file

- Environment Variable: `VK_LUNARG_DEVICE_SIMULATION_FILENAME`
- `vk_layer_settings.txt` Option: `lunarg_device_simulation.filename`
- Android Option: `debug.vulkan.lunarg_device_simulation.filename`
- Default Value: Not set

Name of one or more configuration file(s) to load. Added in v1.2.1: This variable can have a delimited list of files to be loaded. On Windows, the delimiter is `;` else it is `:`. Files are loaded in order. Later files can override settings from earlier files.

#### Debug Enable

- Environment Variable: `VK_LUNARG_DEVICE_SIMULATION_DEBUG_ENABLE`
- `vk_layer_settings.txt` Option: `lunarg_device_simulation.debug_enable`
- Android Option: `debug.vulkan.lunarg_device_simulation.debug_enable`
- Default Value: false

Enables debug message output.

#### Emulate `VK_KHR_portability_subset`

- Environment Variable: `VK_LUNARG_DEVICE_SIMULATION_EMULATE_PORTABILITY`
- `vk_layer_settings.txt` Option: `lunarg_device_simulation.emulate_portability`
- Android Option: `debug.vulkan.lunarg_device_simulation.emulate_portability`
- Default Value: false

Enables emulation of the `VK_KHR_portability_subset` extension.

#### Exit on Error

- Environment Variable: `VK_LUNARG_DEVICE_SIMULATION_EXIT_ON_ERROR`
- `vk_layer_settings.txt` Option: `lunarg_device_simulation.exit_on_error`
- Android Option: `debug.vulkan.lunarg_device_simulation.exit_on_error`
- Default Value: false

Enables exit-on-error.

#### Modify Device Extension list

- Environment Variable: `VK_LUNARG_DEVICE_SIMULATION_MODIFY_EXTENSION_LIST`
- `vk_layer_settings.txt` Option: `lunarg_device_simulation.modify_extension_list`
- Android Option: `debug.vulkan.lunarg_device_simulation.modify_extension_list`
- Default Value: none

Enables modification of the device extensions list from the JSON config file. Valid options are "none", "replace", "whitelist", "blacklist", and "intersect".

#### Modify Device Memory Flags

- Environment Variable: `VK_LUNARG_DEVICE_SIMULATION_MODIFY_MEMORY_FLAGS`
- `vk_layer_settings.txt` Option: `lunarg_device_simulation.modify_memory_flags`
- Android Option: `debug.vulkan.lunarg_device_simulation.modify_memory_flags`
- Default Value: false

Enables modification of the device memory heap flags and memory type flags from the JSON config file.

#### Modify Device Format list

- Environment Variable: `VK_LUNARG_DEVICE_SIMULATION_MODIFY_FORMAT_LIST`
- `vk_layer_settings.txt` Option: `lunarg_device_simulation.modify_format_list`
- Android Option: `debug.vulkan.lunarg_device_simulation.modify_format_list`
- Default Value: none

Enables modification of the device format list from the JSON config file. Valid options are "none", "replace", "whitelist", "blacklist", and "intersect".

#### Modify Device Format Properties

- Environment Variable: `VK_LUNARG_DEVICE_SIMULATION_MODIFY_FORMAT_PROPERTIES`
- `vk_layer_settings.txt` Option: `lunarg_device_simulation.modify_format_properties`
- Android Option: `debug.vulkan.lunarg_device_simulation.modify_format_properties`
- Default Value: none

Enables modification of the device format properties from the JSON config file. Valid options are "none", "replace", "whitelist", "blacklist", and "intersect".

#### Modify Device Surface Formats

- Environment Variable: `VK_LUNARG_DEVICE_SIMULATION_MODIFY_SURFACE_FORMATS`
- `vk_layer_settings.txt` Option: `lunarg_device_simulation.modify_surface_formats`
- Android Option: `debug.vulkan.lunarg_device_simulation.modify_surface_formats`
- Default Value: none

Enables modification of the surface format list from the JSON config file. Valid options are "none", "replace", "whitelist", "blacklist", and "intersect".

#### Modify Device Present Modes

- Environment Variable: `VK_LUNARG_DEVICE_SIMULATION_MODIFY_PRESENT_MODES`
- `vk_layer_settings.txt` Option: `lunarg_device_simulation.modify_present_modes`
- Android Option: `debug.vulkan.lunarg_device_simulation.modify_present_modes`
- Default Value: none

Enables modification of the surface present mode list from the JSON config file. Valid options are "none", "replace", "whitelist", "blacklist", and "intersect".

Note: Environment variables take precedence over `vk_layer_settings.txt` options.

#### Array Combination Mode Options Descriptions

- none: Turns off modification of the device's properties list. Uses the device's real properties list.
- replace: Fully replaces the device's properties list with the properties list provided by the DevSim configuration file.
- whitelist: Includes properties from the devsim configuration file only if they are supported by the device.
- blacklist: Removes properties from the device's properties list if they are included in the devsim configuration file's properties list.
- intersect: Adds the list of properties from the devsim configuration file to the device's properties list while avoiding repeats.

### Example using the DevSim layer using Linux environment variables

    # Configure bash to find the Vulkan SDK.
    source $VKSDK/setup-env.sh

    # Set loader parameters to find and load the DevSim layer from your local VulkanTools build.
    export VK_LAYER_PATH="${VulkanTools}/build/layersvt"
    export VK_INSTANCE_LAYERS="VK_LAYER_LUNARG_device_simulation"

    # Specify the simulated device's configuration file.
    export VK_DEVSIM_FILENAME="${VulkanTools}/layersvt/device_simulation_examples/tiny1.json"
    # A list of files could look like:
    # export VK_DEVSIM_FILENAME="/home/foo/first.json:/home/foo/second.json"

    # Enable verbose messages from the DevSim layer.
    export VK_DEVSIM_DEBUG_ENABLE="1"

    # Run a Vulkan application through the DevSim layer.
    vulkaninfo
    # Compare the results with that app running without the DevSim layer.

See also

- ${VulkanTools}/tests/devsim_layer_test.sh - a test runner script.
- ${VulkanTools}/tests/devsim_test1.json - an example configuration file, containing bogus test data.

### Device configuration data from vulkan.gpuinfo.org

A large and growing database of device capabilities is available at https://vulkan.gpuinfo.org/

That device data can be downloaded in JSON format, compatible with the DevSim JSON schema.

A JSON index of the available device records can be queried with https://vulkan.gpuinfo.org/api/v2/devsim/getreportlist.php

That index includes URLs to download the specific device records in DevSim-compatible format, for example https://vulkan.gpuinfo.org/api/v2/devsim/getreport.php?id=1456

As mentioned above, attempting to use a configuration file that does not fit within the capabilities of the underlying device may produce undefined results. Downloaded device records should be reviewed to determine that their capabilities can be simulated by the underlying device.

### Device configuration data from the local system

Vulkan Info can write its output in a format compatible the DevSim JSON schema, so the configuration of the local system can be captured. Use `vulkaninfo -j` to generate output in JSON format and redirect to a file, which can be consumed directly by DevSim. See the Vulkan Info documentation for further details.

### Device configuration data from an iOS device

Vulkan Info can be built and run for iOS using the source and XCode project available from the Vulkan-Tools repository. For details on running and extracting the json files see the Vulkan Info documentation. An Apple Developer Program membership is required to deploy Vulkan Info to an iOS hardware device.

### JSON validation

The DevSim layer itself does very little sanity-checking of the configuration file, so those files should be validated to the schema using a separate tool, such as the following web-based validators.

1. http://www.jsonschemavalidator.net/
2. https://json-schema-validator.herokuapp.com/
3. https://jsonschemalint.com/#/version/draft-04/markup/json/

### Other Resources

1. http://json.org/
2. http://json-schema.org/